Annotation of researchv10no/cmd/pico/gen.c, revision 1.1.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.