Annotation of researchv10dc/cmd/pico/gen.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include "pico.h"
        !             3: 
        !             4: #define        NJTAB   1000
        !             5: #define        NGTAB   40
        !             6: #define        NPTAB   200
        !             7: 
        !             8: static char    *jtab[NJTAB];
        !             9: static int     jtabi;
        !            10: static int     ninstr;
        !            11: static int     spoff;
        !            12: 
        !            13: #define        LJ      1
        !            14: #define        CJ      2
        !            15: #define        INF     100
        !            16: 
        !            17: struct ptab
        !            18: {
        !            19:        char    *at;
        !            20:        char    *to;
        !            21:        short   del;
        !            22:        short   flag;
        !            23: };
        !            24: 
        !            25: static struct  ptab    ptab[NPTAB];
        !            26: static int     ptabi;
        !            27: 
        !            28: #define        TO      1
        !            29: #define        AT      2
        !            30: struct gtab
        !            31: {
        !            32:        long    name;
        !            33:        char    *ato;
        !            34:        short   flag;
        !            35: };
        !            36: 
        !            37: static struct  gtab    gtab[NGTAB];
        !            38: static int     gtabi;
        !            39: 
        !            40: static char    *p;
        !            41: 
        !            42: #define        MAXJ    0x7F
        !            43: Node   zero =
        !            44: {
        !            45:        CONST
        !            46: };
        !            47: Node   one =
        !            48: {
        !            49:        CONST
        !            50: };
        !            51: 
        !            52: /*
        !            53:  * Addressing modes
        !            54:  */
        !            55: #define        _SP             0x7E    /* -(sp) */
        !            56: #define        SPPLUS          0x8E    /* (sp)+ */
        !            57: #define        OSP             0xAE    /* x(SP) */
        !            58: #define        STARPC          0x9F    /* *(pc)+ */
        !            59: #define        R0              0x50
        !            60: #define        I0              0x40
        !            61: #define        SHORTIM(c)      c
        !            62: #define        LONGIM          0x8F    /* 32 bit immediate */
        !            63: #define        R(x)            (R0|(x))/* register var */
        !            64: #define        I(x)            (I0|(x))/* indexed var */
        !            65: /*
        !            66:  * Instructions
        !            67:  */
        !            68: #define        ADDL2   0xC0
        !            69: #define        ADDL3   0xC1
        !            70: #define        ASHL    0x78
        !            71: #define        BEQL    0x13
        !            72: #define        BICL2   0xCA
        !            73: #define        BICL3   0xCB
        !            74: #define        BGEQ    0x18
        !            75: #define        BGTR    0x14
        !            76: #define        BISL2   0xC8
        !            77: #define        BISL3   0xC9
        !            78: #define        BLEQ    0x15
        !            79: #define        BLSS    0x19
        !            80: #define        BNEQ    0x12
        !            81: #define        BRB     0x11
        !            82: #define        BRW     0x31
        !            83: #define        JSB     0x16
        !            84: #define        CALLS   0xFB
        !            85: #define        CLRL    0xD4
        !            86: #define        CMPL    0xD1
        !            87: #define        BITL    0xD3
        !            88: #define        MCOML   0xD2
        !            89: #define        MNEGL   0xCE
        !            90: #define        MOVL    0xD0
        !            91: #define MOVW   0xB0
        !            92: #define        MOVB    0x90
        !            93: #define        MOVZBL  0x9A
        !            94: #define        CLRB    0x94
        !            95: #define        MULL2   0xC4
        !            96: #define        MULL3   0xC5
        !            97: #define        PUSHL   0xDD
        !            98: #define        RSB     0x05
        !            99: #define        SUBL2   0xC2
        !           100: #define        SUBL3   0xC3
        !           101: #define        TSTL    0xD5
        !           102: #define        XORL2   0xCC
        !           103: #define        XORL3   0xCD
        !           104: #define DIVL2  0xC6
        !           105: #define DIVL3  0xC7
        !           106: #define JMP    0x17
        !           107: 
        !           108: #define        stufflong(c)    *((int *)p)=(c), p+=sizeof(long)
        !           109: #define        stuffword(c)    *((short *)p)=(c), p+=sizeof(short)
        !           110: 
        !           111: #define        TOOMANY 6       /* r6 is not available for scratch */
        !           112: 
        !           113: char *program;
        !           114: extern char seetree, optim;
        !           115: 
        !           116: compile(n, progr)
        !           117:        Node *n;
        !           118:        char *progr;
        !           119: {
        !           120:        register fd;
        !           121: 
        !           122:        program = progr;
        !           123:        one.arg = 1;
        !           124:        if (seetree && n) ptree(n, "ORIGINAL");
        !           125:        if (optim)
        !           126:        {       rewrite(n, 1);
        !           127:                if (seetree) ptree(n, "OPTIMIZED");
        !           128:        }
        !           129:        gencode(n);
        !           130:        if((fd=creat("/tmp/pico.code", 0666))>=0)
        !           131:        {       write(fd, program, p-program);
        !           132:                close(fd);
        !           133:        }
        !           134: }
        !           135: 
        !           136: gencode(n)
        !           137:        Node *n;
        !           138: {
        !           139:        spoff = 0;
        !           140:        ninstr = 0;
        !           141:        jtabi = 0;
        !           142:        ptabi = 0;
        !           143:        gtabi = 0;
        !           144:        p = program;
        !           145:        codegen(n, 0, 1, 0);
        !           146:        emitins(RSB);
        !           147:        addptab();
        !           148:        if(spoff != 0)
        !           149:                yyerror("phase error in spoff");
        !           150: }
        !           151: 
        !           152: testgen(n, used, dest, true)
        !           153:        Node *n;
        !           154: {
        !           155:        int j;
        !           156: 
        !           157:        j = BNEQ;
        !           158:        if(!true)
        !           159:                j = BEQL;
        !           160:        switch(n->type) {
        !           161:        default:
        !           162:                codegen(n, used, dest, 0);
        !           163:                break;
        !           164: 
        !           165:        case OCALL:
        !           166:        case CCALL:
        !           167:                codegen(n, used, dest, 0);
        !           168:                if(dest == 1) {
        !           169:                        emitins(TSTL);
        !           170:                        emitreg(dest);
        !           171:                }
        !           172:                break;
        !           173: 
        !           174:        case CONST:
        !           175:        case VAR:
        !           176:        case REG:
        !           177:        case OARG:
        !           178:                emitins(TSTL);
        !           179:                codegen(n, used, 0, 0);
        !           180:                break;
        !           181: 
        !           182:        case CONDI:
        !           183:                markj(0);
        !           184:                testgen(n->other, used, dest, 1);
        !           185:                        markj(0);
        !           186:                        testgen(n->right, used, dest, true);
        !           187:                markj(0);
        !           188:                markj(BRB);
        !           189:                patchj(2);
        !           190:                        markj(0);
        !           191:                        testgen(n->left, used, dest, true);
        !           192:                patchj(1);
        !           193:                        combj(0);
        !           194:                        combj(1);
        !           195:                return;
        !           196: 
        !           197:        case ONE:
        !           198:        case OLE:
        !           199:        case OGE:
        !           200:        case OEQ:
        !           201:        case OLT:
        !           202:        case OGT:
        !           203:        case OAND:
        !           204:                j = compareop(n, used, dest, true);
        !           205:                break;
        !           206: 
        !           207:        case ONOT:
        !           208:                testgen(n->left, used, dest, !true);
        !           209:                return;
        !           210: 
        !           211:        case OANDAND:
        !           212:        case OOROR:
        !           213:                if((n->type==OANDAND) ^ true) {
        !           214:                        testgen(n->left, used, dest, true);
        !           215:                        testgen(n->right, used, dest, true);
        !           216:                        return;
        !           217:                }
        !           218:                markj(0);
        !           219:                testgen(n->left, used, dest, !true);
        !           220:                markj(0);
        !           221:                testgen(n->right, used, dest, true);
        !           222:                patchj(1);
        !           223:                combj(0);
        !           224:                return;
        !           225: 
        !           226:        case OCOMMA:
        !           227:                codegen(n->left, used, dest, 0);
        !           228:                testgen(n->right, used, dest, true);
        !           229:                return;
        !           230:        }
        !           231:        markj(j);
        !           232: }
        !           233: 
        !           234: patchj(bn)
        !           235: {      int i, l;
        !           236: 
        !           237:        jtab[jtabi] = 0;
        !           238:        l = jbn(bn);
        !           239:        for(i=l+1; jtab[i]; i++) {
        !           240:                ptab[ptabi].at = jtab[i];
        !           241:                ptab[ptabi].to = p;
        !           242:                ptab[ptabi].del = 0;
        !           243:                ptab[ptabi].flag = 0;
        !           244:                if(jtab[i][-1] != BRB)
        !           245:                        ptab[ptabi].flag |= CJ;
        !           246:                ptabi++;
        !           247:                if(ptabi >= NPTAB)
        !           248:                        yyerror("NPTAB too small");
        !           249:        }
        !           250:        while(i < jtabi)
        !           251:                jtab[l++] = jtab[i++];
        !           252:        jtabi = l;
        !           253: }
        !           254: 
        !           255: pcmp(p1, p2)
        !           256:        struct ptab *p1, *p2;
        !           257: {
        !           258:        return(p1->at - p2->at);
        !           259: }
        !           260: 
        !           261: addptab()
        !           262: {      char *q;
        !           263:        int i, j, f, d;
        !           264: 
        !           265:        for(i=0; i<gtabi; i++)
        !           266:        if(gtab[i].flag & AT)
        !           267:        {       gtab[i].flag = 0;
        !           268:                for(j=0; j<gtabi; j++)
        !           269:                if(gtab[j].flag & TO && gtab[i].name == gtab[j].name)
        !           270:                {       ptab[ptabi].at = gtab[i].ato;
        !           271:                        ptab[ptabi].to = gtab[j].ato;
        !           272:                        ptab[ptabi].del = 0;
        !           273:                        ptab[ptabi].flag = 0;
        !           274:                        ptabi++;
        !           275:                        if(ptabi >= NPTAB)
        !           276:                                yyerror("NPTAB too small");
        !           277:                        break;
        !           278:                }
        !           279:                if (j == gtabi)
        !           280:                        yyerror("label not declared");
        !           281:        }
        !           282: 
        !           283:        ptab[ptabi].at = program;
        !           284:        ptab[ptabi].to = p;
        !           285:        ptab[ptabi].del = 0;
        !           286:        ptab[ptabi].flag = LJ;
        !           287:        ptabi++;
        !           288:        qsort(ptab, ptabi, sizeof ptab[0], pcmp);
        !           289: loop:
        !           290:        f = 0;
        !           291:        for(i=0; i<ptabi; i++) {
        !           292:                if(ptab[i].flag & LJ)
        !           293:                        continue;
        !           294:                d = ptab[i].to - ptab[i].at - 1;
        !           295:                if(d < 0)
        !           296:                        d = -d;
        !           297:                d += ptab[i].del;
        !           298:                if(d >= MAXJ) {
        !           299:                        f++;
        !           300:                        ptab[i].flag |= LJ;
        !           301:                        for(j=0; j<ptabi; j++)
        !           302:                        if(betwn(ptab[i].at, ptab[j])) {
        !           303:                                ptab[j].del += 1;
        !           304:                                if(ptab[i].flag & CJ)
        !           305:                                        ptab[j].del += 2;
        !           306:                        }
        !           307:                }
        !           308:        }
        !           309:        if(f)
        !           310:                goto loop;
        !           311:        q = p;
        !           312:        p += ptab[0].del;
        !           313:        for(;;) {
        !           314:                *--p = *--q;
        !           315:                if(q > ptab[ptabi-1].at)
        !           316:                        continue;
        !           317:                if(q <= program)
        !           318:                        break;
        !           319:                ptabi--;
        !           320:                d = ptab[ptabi].to - ptab[ptabi].at - 1;
        !           321:                if(ptab[ptabi].to > ptab[ptabi].at)
        !           322:                        d += ptab[ptabi].del;
        !           323:                else
        !           324:                        d -= ptab[ptabi].del;
        !           325:                f = ptab[ptabi].flag;
        !           326:                if((f & LJ) == 0) {
        !           327:                        *p = d;
        !           328:                        continue;
        !           329:                }
        !           330:                p--; q--;
        !           331:                *(short *)p = d;
        !           332:                *--p = BRW;
        !           333:                if((f & CJ) == 0)
        !           334:                        continue;
        !           335:                *--p = 3;
        !           336:                *--p = invrbr(*q & 0xFF);
        !           337:                ninstr++;
        !           338:        }
        !           339:        if(p != q)
        !           340:                yyerror("long jump phase error");
        !           341:        p = ptab[0].to + ptab[0].del;
        !           342: }
        !           343: 
        !           344: betwn(p, j)
        !           345: char *p;
        !           346: struct ptab j;
        !           347: {
        !           348: 
        !           349:        if(j.to > j.at) {
        !           350:                if(p > j.at && p < j.to)
        !           351:                        return 1;
        !           352:                return 0;
        !           353:        }
        !           354:        if(p >= j.to && p <= j.at)
        !           355:                return 1;
        !           356:        return 0;
        !           357: }
        !           358: 
        !           359: combj(bn)
        !           360: {
        !           361:        int i, l;
        !           362: 
        !           363:        l = jbn(bn);
        !           364:        i = l+1;
        !           365:        while(i < jtabi)
        !           366:                jtab[l++] = jtab[i++];
        !           367:        jtabi = l;
        !           368: }
        !           369: 
        !           370: jbn(bn)
        !           371: {
        !           372:        int i;
        !           373: 
        !           374:        i = jtabi;
        !           375:        while(bn >= 0) {
        !           376:                for(i--; jtab[i]; i--)
        !           377:                        ;
        !           378:                bn--;
        !           379:        }
        !           380:        return i;
        !           381: }
        !           382: 
        !           383: markj(j)
        !           384: {
        !           385: 
        !           386:        if(jtabi >= NJTAB)
        !           387:                yyerror("NJTAB too small");
        !           388:        if(j == 0) {
        !           389:                jtab[jtabi++] = 0;
        !           390:                return;
        !           391:        }
        !           392:        emitins(j);
        !           393:        jtab[jtabi++] = p;
        !           394:        *p++ = 0;
        !           395: }
        !           396: 
        !           397: codegen(n, used, dest, brgen)
        !           398: Node *n;
        !           399: {
        !           400:        long c;
        !           401:        int o;
        !           402: 
        !           403:        markj(0);
        !           404:        if(p-program > NPROG-10)
        !           405:                yyerror("NPROG too small");
        !           406: 
        !           407:        if(n)
        !           408:        switch(n->type)
        !           409:        {
        !           410:        default:
        !           411:                printf("unknown type = %d\n", n->type);
        !           412:                yyerror("unknown opcode in codegen");
        !           413:                break;
        !           414: 
        !           415:        case LABL:
        !           416:                if(gtabi >= NGTAB)
        !           417:                        yyerror("NGTAB too small");
        !           418:                gtab[gtabi].name = n->arg;
        !           419:                gtab[gtabi].ato = p;
        !           420:                gtab[gtabi].flag = TO;
        !           421:                gtabi++;
        !           422:                codegen(n->left, used, dest, brgen);
        !           423:                break;
        !           424: 
        !           425:        case GOTO:
        !           426:                emitins(BRB);
        !           427:                if(gtabi >= NGTAB)
        !           428:                        yyerror("NGTAB too small");
        !           429:                gtab[gtabi].name = n->arg;
        !           430:                gtab[gtabi].ato = p;
        !           431:                gtab[gtabi].flag = AT;
        !           432:                gtabi++;
        !           433:                *p++ = 0;
        !           434:                break;
        !           435: 
        !           436:        case CONSTB:
        !           437:                if(n->arg & ~63)
        !           438:                if(!dest) {
        !           439:                        *p++ = LONGIM;
        !           440:                        *p++ = n->arg;
        !           441:                        break;
        !           442:                }
        !           443:        case CONST:
        !           444:                if(dest) {
        !           445:                        if(n->arg == 0) {
        !           446:                                emitins(CLRL);
        !           447:                                emitreg(dest);
        !           448:                                break;
        !           449:                        }
        !           450:                        emitins(MOVL);
        !           451:                        codegen(n, used, 0, 0);
        !           452:                        emitreg(dest);
        !           453:                        break;
        !           454:                }
        !           455:                emitcon(n->arg);
        !           456:                break;
        !           457: 
        !           458:        case VAR:
        !           459:                if(dest) {
        !           460:                        emitins(MOVL);
        !           461:                        codegen(n, used, 0, 0);
        !           462:                        emitreg(dest);
        !           463:                        break;
        !           464:                }
        !           465:                emitabs(n->arg);
        !           466:                break;
        !           467: 
        !           468:        case OARG:
        !           469:                if(dest) {
        !           470:                        emitins(MOVL);
        !           471:                        codegen(n, used, 0, 0);
        !           472:                        emitreg(dest);
        !           473:                        break;
        !           474:                }
        !           475:                *p++ = OSP;
        !           476:                emitcon((n->arg+1)*4 + spoff);
        !           477:                break;
        !           478: 
        !           479:        case REG:
        !           480:                if(dest) {
        !           481:                        emitins(MOVL);
        !           482:                        codegen(n, used, 0, 0);
        !           483:                        emitreg(dest);
        !           484:                        break;
        !           485:                }
        !           486:                *p++ = R(n->arg);
        !           487:                break;
        !           488: 
        !           489:        case CCALL:
        !           490:        case OCALL:
        !           491:                for(o=0; o<used; o++) {
        !           492:                        emitins(MOVL);
        !           493:                        *p++ = R(o);
        !           494:                        *p++ = _SP;
        !           495:                        spoff += 4;
        !           496:                }
        !           497:                c = pushargs(n->left);
        !           498:                if(n->type == CCALL) {
        !           499:                        emitins(CALLS);
        !           500:                        emitcon(c);
        !           501:                        emitabs(n->arg);
        !           502:                } else {
        !           503:                        emitins(JSB);
        !           504:                        emitabs(n->arg);
        !           505:                        if(c) {
        !           506:                                emitins(ADDL2);
        !           507:                                emitcon(c*4);
        !           508:                                *p++ = R(0XE);
        !           509:                        }
        !           510:                }
        !           511:                spoff -= 4*c;
        !           512:                if(dest != 1) {
        !           513:                        emitins(MOVL);
        !           514:                        *p++ = R(0);
        !           515:                        *p++ = R(dest-1);
        !           516:                }
        !           517:                for(o=used-1; o>=0; o--) {
        !           518:                        emitins(MOVL);
        !           519:                        *p++ = SPPLUS;
        !           520:                        *p++ = R(o);
        !           521:                        spoff -= 4;
        !           522:                }
        !           523:                break;
        !           524: 
        !           525:        case CONDI:
        !           526:                markj(0);
        !           527:                if(!n->left) {
        !           528:                        testgen(n->other, used, dest, 1);
        !           529:                        codegen(n->right, used, dest, 0);
        !           530:                        combj(0);
        !           531:                        break;
        !           532:                }
        !           533:                if(!n->right) {
        !           534:                        testgen(n->other, used, dest, 0);
        !           535:                        codegen(n->left, used, dest, 0);
        !           536:                        combj(0);
        !           537:                        break;
        !           538:                }
        !           539:                testgen(n->other, used, dest, 1);
        !           540:                        codegen(n->right, used, dest, 1);
        !           541:                patchj(1);
        !           542:                        codegen(n->left, used, dest, 0);
        !           543:                combj(0);
        !           544:                break;
        !           545: 
        !           546:        case OADD:
        !           547:                binop(1, ADDL3, ADDL2, n, used, dest);
        !           548:                break;
        !           549: 
        !           550:        case OMUL:
        !           551:                if(n->right->type == CONST) {
        !           552:                        c = n->right->arg;
        !           553:                        if(c >= 2 && c <= 4) {
        !           554:                                if(n->left->type == REG) {
        !           555:                                        emitins(ADDL3);
        !           556:                                        codegen(n->left, used, 0, 0);
        !           557:                                        codegen(n->left, used, 0, 0);
        !           558:                                } else {
        !           559:                                        codegen(n->left, used, dest, 0);
        !           560:                                        emitins(ADDL3);
        !           561:                                        emitreg(dest);
        !           562:                                        emitreg(dest);
        !           563:                                }
        !           564:                                if(c == 3) {
        !           565:                                        *p++ = _SP;
        !           566:                                        emitins(ADDL3);
        !           567:                                        *p++ = SPPLUS;
        !           568:                                        if(n->left->type == REG)
        !           569:                                                codegen(n->left, used, 0, 0);
        !           570:                                        else
        !           571:                                                emitreg(dest);
        !           572:                                }
        !           573:                                if(c == 4) {
        !           574:                                        emitreg(dest);
        !           575:                                        emitins(ADDL3);
        !           576:                                        emitreg(dest);
        !           577:                                        emitreg(dest);
        !           578:                                }
        !           579:                                emitreg(dest);
        !           580:                                break;
        !           581:                        }
        !           582:                }
        !           583:                binop(1, MULL3, MULL2, n, used, dest);
        !           584:                break;
        !           585: 
        !           586:        case OPOW:
        !           587:                if(n->right->type == CONST) {
        !           588:                        c = n->right->arg;
        !           589:                        if(c >= 2 && c <= 4) {
        !           590:                                if(n->left->type == REG) {
        !           591:                                        emitins(MULL3);
        !           592:                                        codegen(n->left, used, 0, 0);
        !           593:                                        codegen(n->left, used, 0, 0);
        !           594:                                } else {
        !           595:                                        codegen(n->left, used, dest, 0);
        !           596:                                        emitins(MULL3);
        !           597:                                        emitreg(dest);
        !           598:                                        emitreg(dest);
        !           599:                                }
        !           600:                                if(c == 3) {
        !           601:                                        *p++ = _SP;
        !           602:                                        emitins(MULL2);
        !           603:                                        *p++ = SPPLUS;
        !           604:                                }
        !           605:                                if(c == 4) {
        !           606:                                        emitreg(dest);
        !           607:                                        emitins(MULL3);
        !           608:                                        emitreg(dest);
        !           609:                                        emitreg(dest);
        !           610:                                }
        !           611:                                emitreg(dest);
        !           612:                                break;
        !           613:                        }
        !           614:                }
        !           615:                yyerror("POW not implemented");
        !           616:                break;
        !           617: 
        !           618:        case OXOR:
        !           619:                binop(1, XORL3, XORL2, n, used, dest);
        !           620:                break;
        !           621: 
        !           622:        case OOR:
        !           623:                binop(1, BISL3, BISL2, n, used, dest);
        !           624:                break;
        !           625: 
        !           626:        case OISUB:
        !           627:                invert(n, OSUB);
        !           628:        case OSUB:
        !           629:                binop(0, SUBL3, SUBL2, n, used, dest);
        !           630:                break;
        !           631: 
        !           632:        case OIDIV:
        !           633:                invert(n, ODIV);
        !           634:        case ODIV:
        !           635:                binop(0, DIVL3, DIVL2, n, used, dest);
        !           636:                break;
        !           637: 
        !           638:        case OBIC:
        !           639:                binop(0, BICL3, BICL2, n, used, dest);
        !           640:                break;
        !           641: 
        !           642:        case OAND:
        !           643:                binop(2, BICL3, BICL2, n, used, dest);
        !           644:                break;
        !           645: 
        !           646:        case ONEG:
        !           647:                unop(MCOML, n->left, used, dest);
        !           648:                break;
        !           649: 
        !           650:        case OMINUS:
        !           651:                unop(MNEGL, n->left, used, dest);
        !           652:                break;
        !           653: 
        !           654:        case OLSH:
        !           655:                if(n->right->type == CONST) {
        !           656:                        c = n->right->arg;
        !           657:                        if(c >= 1 && c <= 2) {
        !           658:                                if(n->left->type == REG) {
        !           659:                                        emitins(ADDL3);
        !           660:                                        codegen(n->left, used, 0, 0);
        !           661:                                        codegen(n->left, used, 0, 0);
        !           662:                                } else {
        !           663:                                        codegen(n->left, used, dest, 0);
        !           664:                                        emitins(ADDL3);
        !           665:                                        emitreg(dest);
        !           666:                                        emitreg(dest);
        !           667:                                }
        !           668:                                if(c == 2) {
        !           669:                                        emitreg(dest);
        !           670:                                        emitins(ADDL3);
        !           671:                                        emitreg(dest);
        !           672:                                        emitreg(dest);
        !           673:                                }
        !           674:                                emitreg(dest);
        !           675:                                break;
        !           676:                        }
        !           677:                        n->right->type = CONSTB;
        !           678:                        binop(0, ASHL, 0, n, used, dest);
        !           679:                        n->right->type = CONST;
        !           680:                        break;
        !           681:                }
        !           682:                binop(0, ASHL, 0, n, used, dest);
        !           683:                break;
        !           684: 
        !           685:        case OCOMMA:
        !           686:                codegen(n->left, used, dest, 0);
        !           687:                codegen(n->right, used, dest, 0);
        !           688:                break;
        !           689: 
        !           690:        case OLT:
        !           691:        case OLE:
        !           692:        case OEQ:
        !           693:        case ONE:
        !           694:        case OGT:
        !           695:        case OGE:
        !           696:        case ONOT:
        !           697:        case OOROR:
        !           698:        case OANDAND:
        !           699:                markj(0);
        !           700:                testgen(n, used, dest, 1);
        !           701:                        codegen(&zero, used, dest, 1);
        !           702:                patchj(1);
        !           703:                        codegen(&one, used, dest, 0);
        !           704:                combj(0);
        !           705:                break;
        !           706: 
        !           707:        case ORETURN:
        !           708:                codegen(n->left, 0, 1, 0);
        !           709:                emitins(RSB);
        !           710:                break;
        !           711: 
        !           712:        case OASS:
        !           713:                if(complex(n->left) == 0) {
        !           714:                        codegen(n->right, used, dest, 0);
        !           715:                        emitins(MOVL);
        !           716:                        emitreg(dest);
        !           717:                        codegen(n->left, used, 0, 0);
        !           718:                        break;
        !           719:                }
        !           720:                o = n->left->type;
        !           721:                if(o != DEREFB && o != DEREFL && o != DEREFS)
        !           722:                {       fprintf(stderr, "o == %d -> %d: ", OASS, o);
        !           723:                        yyerror("assignment to non-lvalue");
        !           724:                }
        !           725:                if(complex(n->left->left))
        !           726:                        yyerror("index of non-lvalue");
        !           727:                if(o == DEREFB)
        !           728:                        o = MOVB;
        !           729:                else if (o == DEREFL)
        !           730:                        o = MOVL;
        !           731:                else
        !           732:                        o = MOVW;
        !           733:                codegen(n->right, used, dest, 0);
        !           734:                if(n->left->right) {
        !           735:                        if(n->left->right->type == REG) {
        !           736:                                emitins(o);
        !           737:                                emitreg(dest);
        !           738:                                *p++ = I(n->left->right->arg);
        !           739:                        } else {
        !           740:                                codegen(n->left->right, used+1, used+2, 0);
        !           741:                                emitins(o);
        !           742:                                emitreg(dest);
        !           743:                                *p++ = I(used+2-1);
        !           744:                        }
        !           745:                        codegen(n->left->left, used, 0, 0);
        !           746:                        break;
        !           747:                }
        !           748:                emitins(o);
        !           749:                emitreg(dest);
        !           750:                codegen(n->left->left, used, 0, 0);
        !           751:                break;
        !           752: 
        !           753:        case DEREFL:
        !           754:        case DEREFS:
        !           755:        case DEREFB:
        !           756:                o = n->type;
        !           757:                if(o == DEREFB)
        !           758:                        o = MOVZBL;
        !           759:                else if (o == DEREFL)
        !           760:                        o = MOVL;
        !           761:                else
        !           762:                        o = MOVW;
        !           763:                if(complex(n->left))
        !           764:                        yyerror("index of non-lvalue");
        !           765:                if(n->right) {
        !           766:                        if(n->right->type == REG) {
        !           767:                                emitins(o);
        !           768:                                *p++ = I(n->right->arg);
        !           769:                        } else {
        !           770:                                codegen(n->right, used, dest, 0);
        !           771:                                emitins(o);
        !           772:                                *p++ = I(dest-1);
        !           773:                        }
        !           774:                } else {
        !           775:                        emitins(o);
        !           776:                }
        !           777:                codegen(n->left, used, 0, 0);
        !           778:                emitreg(dest);
        !           779:                break;
        !           780: 
        !           781:        case COMP:
        !           782:                switch(listcount(n->left)) {
        !           783:                case 1:
        !           784:                        movsp((Node *)0, 1, used, dest);
        !           785:                        movsp(n->left, 3, used, dest);
        !           786:                        break;
        !           787:                case 2:
        !           788:                        movsp(n->left->right, 1, used, dest);
        !           789:                        movsp(n->left->left, 3, used, dest);
        !           790:                        break;
        !           791:                case 3:
        !           792:                        movsp((Node *)0, 1, used, dest);
        !           793:                        movsp(n->left->right->right, 1, used, dest);
        !           794:                        movsp(n->left->right->left, 1, used, dest);
        !           795:                        movsp(n->left->left, 1, used, dest);
        !           796:                        break;
        !           797:                case 4:
        !           798:                        movsp(n->left->right->right->right, 1, used, dest);
        !           799:                        movsp(n->left->right->right->left, 1, used, dest);
        !           800:                        movsp(n->left->right->left, 1, used, dest);
        !           801:                        movsp(n->left->left, 1, used, dest);
        !           802:                        break;
        !           803:                default:
        !           804:                        yyerror("[] must have 1<=n<=4 args");
        !           805:                }
        !           806:                emitins(MOVL);
        !           807:                *p++ = SPPLUS;
        !           808:                emitreg(dest);
        !           809:                spoff -= 4;
        !           810:                break;
        !           811:        }
        !           812:        if(brgen)
        !           813:                markj(BRB);
        !           814:        else
        !           815:                patchj(0);
        !           816: }
        !           817: 
        !           818: emitcon(c)
        !           819: {
        !           820: 
        !           821:        if((c & ~63) == 0) {
        !           822:                *p++ = SHORTIM(c);
        !           823:                return;
        !           824:        }
        !           825:        *p++ = LONGIM;
        !           826:        stufflong(c);
        !           827: }
        !           828: 
        !           829: emitabs(c)
        !           830: {
        !           831: 
        !           832:        *p++ = STARPC;
        !           833:        stufflong(c);
        !           834: }
        !           835: 
        !           836: pushargs(n)
        !           837: Node *n;
        !           838: {
        !           839:        register c;
        !           840: 
        !           841:        if(!n)
        !           842:                return 0;
        !           843:        if(n->type == ACOMMA) {
        !           844:                c = pushargs(n->right);
        !           845:                c += pushargs(n->left);
        !           846:                return c;
        !           847:        }
        !           848:        if(complex(n)) {
        !           849:                codegen(n, 0, 1, 0);
        !           850:                emitins(MOVL);
        !           851:                *p++ = R(0);
        !           852:        } else {
        !           853:                emitins(MOVL);
        !           854:                codegen(n, 0, 0, 0);
        !           855:        }
        !           856:        *p++ = _SP;
        !           857:        spoff += 4;
        !           858:        return 1;
        !           859: }
        !           860: 
        !           861: invert(n, o)
        !           862: Node *n;
        !           863: {
        !           864:        n->other = n->right;
        !           865:        n->right = n->left;
        !           866:        n->left = n->other;
        !           867:        n->other = 0;
        !           868:        n->type = o;
        !           869: }
        !           870: 
        !           871: listcount(n)
        !           872: Node *n;
        !           873: {
        !           874:        register i;
        !           875:        for(i=1; n->type==ACOMMA; i++, n=n->right)
        !           876:                ;
        !           877:        return i;
        !           878: }
        !           879: 
        !           880: movsp(n, count, used, dest)
        !           881: Node *n;
        !           882: {
        !           883:        register i, c;
        !           884:        if(n==0) {      /* push 255 */
        !           885:                emitins(MOVB);
        !           886:                *p++ = LONGIM;
        !           887:                *p++ = 255;
        !           888:                *p++ = _SP;
        !           889:                spoff += 1;
        !           890:                return;
        !           891:        }
        !           892:        c = complex(n);
        !           893:        for(i=0; i<count; i++) {
        !           894:                if(c == 0) {
        !           895:                        if(n->type == CONST) {
        !           896:                                if(n->arg == 0) {
        !           897:                                        emitins(CLRB);
        !           898:                                        *p++ = _SP;
        !           899:                                        spoff += 1;
        !           900:                                        continue;
        !           901:                                }
        !           902:                                n->type = CONSTB;
        !           903:                        }
        !           904:                        emitins(MOVB);
        !           905:                        codegen(n, used, 0, 0);
        !           906:                        *p++ = _SP;
        !           907:                        spoff += 1;
        !           908:                        continue;
        !           909:                }
        !           910:                if(i == 0)
        !           911:                        codegen(n, used, dest, 0);
        !           912:                emitins(MOVB);
        !           913:                emitreg(dest);
        !           914:                *p++ = _SP;
        !           915:                spoff += 1;
        !           916:        }
        !           917: }
        !           918: 
        !           919: binop(comm, threeaddr, twoaddr, n, used, dest)
        !           920: Node *n;
        !           921: {
        !           922:        int cl, cr;
        !           923: 
        !           924:        cl = complex(n->left);
        !           925:        cr = complex(n->right);
        !           926:        if(cl == 0 && cr == 0)
        !           927:        if(comm != 2 && threeaddr) {
        !           928:                emitins(threeaddr);
        !           929:                codegen(n->right, used, 0, 0);
        !           930:                codegen(n->left, used, 0, 0);
        !           931:                emitreg(dest);
        !           932:                return;
        !           933:        }
        !           934:        if(cr == 0) {
        !           935:                if(comm == 2) { /* OAND hack */
        !           936:                        unop(MCOML, n->left, used, dest);
        !           937:                        emitins(threeaddr);
        !           938:                        emitreg(dest);
        !           939:                        codegen(n->right, used, 0, 0);
        !           940:                        emitreg(dest);
        !           941:                        return;
        !           942:                }
        !           943:                codegen(n->left, used, dest, 0);
        !           944:                if(twoaddr) {
        !           945:                        emitins(twoaddr);
        !           946:                        codegen(n->right, used, 0, 0);
        !           947:                } else {
        !           948:                        emitins(threeaddr);
        !           949:                        codegen(n->right, used, 0, 0);
        !           950:                        emitreg(dest);
        !           951:                }
        !           952:                emitreg(dest);
        !           953:                return;
        !           954:        }
        !           955:        if(cl == 0) {
        !           956:                if(comm == 2) { /* OAND hack */
        !           957:                        unop(MCOML, n->right, used, dest);
        !           958:                        emitins(threeaddr);
        !           959:                        emitreg(dest);
        !           960:                        codegen(n->left, used, 0, 0);
        !           961:                        emitreg(dest);
        !           962:                        return;
        !           963:                }
        !           964:                codegen(n->right, used, dest, 0);
        !           965:                if(comm && twoaddr) {
        !           966:                        emitins(twoaddr);
        !           967:                } else {
        !           968:                        emitins(threeaddr);
        !           969:                        emitreg(dest);
        !           970:                }
        !           971:                codegen(n->left, used, 0, 0);
        !           972:                emitreg(dest);
        !           973:                return;
        !           974:        }
        !           975:        if(cl >= cr) {
        !           976:                codegen(n->left, used, dest, 0);
        !           977:                codegen(n->right, used+1, used+2, 0);
        !           978:                if(comm == 2) { /* OAND hack */
        !           979:                        emitins(MCOML);
        !           980:                        emitreg(used+2);
        !           981:                        emitreg(used+2);
        !           982:                }
        !           983:                if(twoaddr) {
        !           984:                        emitins(twoaddr);
        !           985:                        emitreg(used+2);
        !           986:                } else {
        !           987:                        emitins(threeaddr);
        !           988:                        emitreg(used+2);
        !           989:                        emitreg(dest);
        !           990:                }
        !           991:                emitreg(dest);
        !           992:                return;
        !           993:        }
        !           994:        codegen(n->right, used, dest, 0);
        !           995:        codegen(n->left, used+1, used+2, 0);
        !           996:        if(comm == 2) { /* OAND hack */
        !           997:                emitins(MCOML);
        !           998:                emitreg(used+2);
        !           999:                emitreg(used+2);
        !          1000:        }
        !          1001:        if(comm && twoaddr) {
        !          1002:                emitins(twoaddr);
        !          1003:        } else {
        !          1004:                emitins(threeaddr);
        !          1005:                emitreg(dest);
        !          1006:        }
        !          1007:        emitreg(used+2);
        !          1008:        emitreg(dest);
        !          1009: }
        !          1010: 
        !          1011: compareop(n, used, dest, true)
        !          1012: Node *n;
        !          1013: {
        !          1014:        int o;
        !          1015:        int cl, cr;
        !          1016: 
        !          1017:        cl = complex(n->left);
        !          1018:        if(n->right == Z) {
        !          1019:                if(cl == 0) {
        !          1020:                        emitins(TSTL);
        !          1021:                        codegen(n->left, used, 0, 0);
        !          1022:                        goto out;
        !          1023:                }
        !          1024:                codegen(n->left, used, dest, 0);
        !          1025:                o = n->left->type;
        !          1026:                if(o == OCALL || o == CCALL)
        !          1027:                if(dest == 1) {
        !          1028:                        emitins(TSTL);
        !          1029:                        emitreg(dest);
        !          1030:                }
        !          1031:                goto out;
        !          1032:        }
        !          1033:        cr = complex(n->right);
        !          1034:        o = CMPL;
        !          1035:        if(n->type == OAND)
        !          1036:                o = BITL;
        !          1037:        if(cl == 0 && cr == 0) {
        !          1038:                emitins(o);
        !          1039:                codegen(n->left, used, 0, 0);
        !          1040:                codegen(n->right, used, 0, 0);
        !          1041:                goto out;
        !          1042:        }
        !          1043:        if(cr == 0) {
        !          1044:                codegen(n->left, used, dest, 0);
        !          1045:                emitins(o);
        !          1046:                emitreg(dest);
        !          1047:                codegen(n->right, used, 0, 0);
        !          1048:                goto out;
        !          1049:        }
        !          1050:        if(cl == 0) {
        !          1051:                codegen(n->right, used, dest, 0);
        !          1052:                emitins(o);
        !          1053:                codegen(n->left, used, 0, 0);
        !          1054:                emitreg(dest);
        !          1055:                goto out;
        !          1056:        }
        !          1057:        if(cl >= cr) {
        !          1058:                codegen(n->left, used, dest, 0);
        !          1059:                codegen(n->right, used+1, used+2, 0);
        !          1060:                emitins(o);
        !          1061:                emitreg(dest);
        !          1062:                emitreg(used+2);
        !          1063:                goto out;
        !          1064:        }
        !          1065:        codegen(n->right, used, dest, 0);
        !          1066:        codegen(n->left, used+1, used+2, 0);
        !          1067:        emitins(o);
        !          1068:        emitreg(used+2);
        !          1069:        emitreg(dest);
        !          1070: 
        !          1071: out:
        !          1072:        switch(n->type)
        !          1073:        {
        !          1074:        case ONE:
        !          1075:        case OAND:      o = BNEQ; break;
        !          1076:        case OEQ:       o = BEQL; break;
        !          1077:        case OLT:       o = BLSS; break;
        !          1078:        case OLE:       o = BLEQ; break;
        !          1079:        case OGE:       o = BGEQ; break;
        !          1080:        case OGT:       o = BGTR; break;
        !          1081:        default:        yyerror("unknown compare");
        !          1082:        }
        !          1083:        if(!true)
        !          1084:                o = invrbr(o);
        !          1085:        return o;
        !          1086: }
        !          1087: 
        !          1088: invrbr(o)
        !          1089: {
        !          1090:        switch(o)
        !          1091:        {
        !          1092:        case BNEQ:      o = BEQL; break;
        !          1093:        case BEQL:      o = BNEQ; break;
        !          1094:        case BLSS:      o = BGEQ; break;
        !          1095:        case BLEQ:      o = BGTR; break;
        !          1096:        case BGEQ:      o = BLSS; break;
        !          1097:        case BGTR:      o = BLEQ; break;
        !          1098:        case BRB:       o = BRW;  break;
        !          1099:        default:        yyerror("unknown branch");
        !          1100:        }
        !          1101:        return o;
        !          1102: }
        !          1103: 
        !          1104: unop(inst, n, used, dest)
        !          1105: Node *n;
        !          1106: {
        !          1107:        int c;
        !          1108:        c = complex(n);
        !          1109:        if(c == 0) {
        !          1110:                emitins(inst);
        !          1111:                codegen(n, used, 0, 0);
        !          1112:                emitreg(dest);
        !          1113:                return;
        !          1114:        }
        !          1115:        codegen(n, used, dest, 0);
        !          1116:        emitins(inst);
        !          1117:        emitreg(dest);
        !          1118:        emitreg(dest);
        !          1119: }
        !          1120: 
        !          1121: complex(n)
        !          1122: Node *n;
        !          1123: {
        !          1124:        int cl, cr;
        !          1125: 
        !          1126:        switch(n->type) {
        !          1127:        case CONST:
        !          1128:        case CONSTB:
        !          1129:        case VAR:
        !          1130:        case REG:
        !          1131:        case OARG:
        !          1132:        case GOTO:
        !          1133:                return 0;
        !          1134: 
        !          1135:        case OCALL:
        !          1136:        case CCALL:
        !          1137:                return INF;
        !          1138: 
        !          1139:        case OADD:
        !          1140:        case OMUL:
        !          1141:        case OPOW:
        !          1142:        case OXOR:
        !          1143:        case OOR:
        !          1144:        case OSUB:
        !          1145:        case OISUB:
        !          1146:        case OBIC:
        !          1147:        case OAND:
        !          1148:        case OIDIV:
        !          1149:        case ODIV:
        !          1150:        case OLT:
        !          1151:        case OLE:
        !          1152:        case OEQ:
        !          1153:        case ONE:
        !          1154:        case OGT:
        !          1155:        case OGE:
        !          1156:        case OLSH:
        !          1157:        case DEREFB:
        !          1158:        case DEREFS:
        !          1159:        case DEREFL:
        !          1160:                cl = complex(n->left);
        !          1161:                cr = 0;
        !          1162:                if(n->right)
        !          1163:                        cr = complex(n->right);
        !          1164:                if(cl == cr)
        !          1165:                        return cl+1;
        !          1166:                if(cl > cr)
        !          1167:                        return cl;
        !          1168:                return cr;
        !          1169: 
        !          1170:        case LABL:
        !          1171:        case ORETURN:
        !          1172:                cl = complex(n->left);
        !          1173:                if(cl == 0)
        !          1174:                        cl++;
        !          1175:                return cl;
        !          1176: 
        !          1177:        case OASS:
        !          1178:                cl = complex(n->left);
        !          1179:                cr = complex(n->right);
        !          1180:                if(cl >= cr)
        !          1181:                        return cl+1;
        !          1182:                return cr;
        !          1183: 
        !          1184:        case CONDI:
        !          1185:                cl = complex(n->left);
        !          1186:                cr = complex(n->right);
        !          1187:                if(cl < cr)
        !          1188:                        cl = cr;
        !          1189:                cr = complex(n->other);
        !          1190:                if(cl < cr)
        !          1191:                        cl = cr;
        !          1192:                if(cl == 0)
        !          1193:                        cl++;
        !          1194:                return cl;
        !          1195: 
        !          1196:        case OANDAND:
        !          1197:        case OOROR:
        !          1198:        case OCOMMA:
        !          1199:        case ACOMMA:
        !          1200:                cl = complex(n->left);
        !          1201:                cr = complex(n->right);
        !          1202:                if(cl < cr)
        !          1203:                        cl = cr;
        !          1204:                if(cl == 0)
        !          1205:                        cl++;
        !          1206:                return cl;
        !          1207: 
        !          1208:        case ONEG:
        !          1209:        case ONOT:
        !          1210:        case OMINUS:
        !          1211:        case COMP:
        !          1212:                cl = complex(n->left);
        !          1213:                if(cl == 0)
        !          1214:                        cl++;
        !          1215:                return cl;
        !          1216:        }
        !          1217:        yyerror("unknown operator in complex");
        !          1218:        return 0;
        !          1219: }
        !          1220: 
        !          1221: emitins(o)
        !          1222: {
        !          1223:        *p++ = o;
        !          1224:        ninstr++;
        !          1225: }
        !          1226: 
        !          1227: emitreg(dest)
        !          1228: {
        !          1229:        if(dest>=TOOMANY)
        !          1230:                yyerror("TOOMANY too small");
        !          1231:        *p++ = R(dest-1);
        !          1232: }
        !          1233: 
        !          1234: ptree(n, s)
        !          1235: Node *n;
        !          1236: char *s;
        !          1237: {
        !          1238:        printf("== %s ==\n", s);
        !          1239:        prtree(n, 1, 0);
        !          1240: }
        !          1241: 
        !          1242: prtree(n, f, d)
        !          1243:        Node *n;
        !          1244: {      int i;
        !          1245: 
        !          1246:        if (f)
        !          1247:        for(i=0; i<d; i++)
        !          1248:                printf("  ");
        !          1249:        f = 0;
        !          1250:        d++;
        !          1251:        switch(n->type) {
        !          1252:        case LABL:      printf("Lb%d\n", n->arg); break;
        !          1253:        case GOTO:      printf("Gt%d\n", n->arg); return;
        !          1254:        case OCALL:
        !          1255:        case CCALL:     printf("()%d\n", n->arg); f = 1; break;
        !          1256:        case REG:       printf("R%d\n", n->arg); return;
        !          1257:        case VAR:       printf("V%d\n", n->arg); return;
        !          1258:        case OARG:      printf("A%d\n", n->arg); return;
        !          1259:        case CONST:     printf("C%d\n", n->arg); return;
        !          1260:        case CONDI:     printf("? "); prtree(n->other, f, d); f = 1; break;
        !          1261:        case COMP:      printf("[]"); break;
        !          1262:        case ORETURN:   printf("rt"); break;
        !          1263:        case DEREFB:    printf("b*"); break;
        !          1264:        case DEREFS:    printf("s*"); break;
        !          1265:        case DEREFL:    printf("l*"); break;
        !          1266:        case OADD:      printf("+ "); break;
        !          1267:        case OAND:      printf("& "); break;
        !          1268:        case OANDAND:   printf("&&"); break;
        !          1269:        case OASS:      printf(":="); break;
        !          1270:        case OBIC:      printf("&~"); break;
        !          1271:        case ACOMMA:    printf(", "); break;
        !          1272:        case OCOMMA:    printf("; "); break;
        !          1273:        case ODIV:      printf("/ "); break;
        !          1274:        case OEQ:       printf("=="); break;
        !          1275:        case OGE:       printf(">="); break;
        !          1276:        case OGT:       printf("> "); break;
        !          1277:        case OLE:       printf("<="); break;
        !          1278:        case OLSH:      printf("<<"); break;
        !          1279:        case OLT:       printf("< "); break;
        !          1280:        case OMINUS:    printf("u-"); break;
        !          1281:        case OMUL:      printf("* "); break;
        !          1282:        case ONE:       printf("!="); break;
        !          1283:        case ONEG:      printf("~ "); break;
        !          1284:        case ONOT:      printf("! "); break;
        !          1285:        case OOR:       printf("| "); break;
        !          1286:        case OOROR:     printf("||"); break;
        !          1287:        case OPOW:      printf("**"); break;
        !          1288:        case OSUB:      printf("- "); break;
        !          1289:        case OISUB:     printf("-i"); break;
        !          1290:        case OXOR:      printf("^ "); break;
        !          1291:        default:        printf("@"); break;
        !          1292:        }
        !          1293:        if (n->left)    { prtree(n->left,  f, d); f = 1; }
        !          1294:        if (n->right)   { prtree(n->right, f, d); f = 1; }
        !          1295:        if (!f)         printf("\n");
        !          1296: }

unix.superglobalmegacorp.com

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