Annotation of researchv9/cmd/sun/c2/sky.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)sky.c 1.1 86/02/03 Copyr 1984 Sun Micro";
                      3: #endif
                      4: 
                      5: /*
                      6:  * Copyright (c) 1984 by Sun Microsystems, Inc.
                      7:  */
                      8: 
                      9: #include "as.h"
                     10: #include "c2.h"
                     11: 
                     12: #define SP_REG         15              /* Stack pointer: a7 */
                     13: #define        STATUS_WORD     -2              /* Offset to sky status word */
                     14: #define        IDLE            6               /* Idle bit in hibyte of status word */
                     15: 
                     16: #define SP_ADD         0x1001          /* Single add: B1 = A2 + A1 */
                     17: #define SP_ADDREG      0x104c          /* Single add: R0 = R0 + A1 */
                     18: #define SP_ADDB1       0x1003          /* Single add: B1 = R0 + A1 */
                     19: 
                     20: #define SP_SUB         0x1007          /* Single sub: B1 = A1 - A2 */
                     21: #define SP_SUBREG1     0x104f          /* Single sub: R0 = R0 - A1 */
                     22: #define SP_SUBREG2     0x1050          /* Single sub: R0 = A1 - R0 */
                     23: 
                     24: #define SP_MUL         0x100b          /* Single mul: B1 = A2 * A1 */
                     25: #define SP_MULREG      0x1052          /* Single mul: R0 = R0 * A1 */
                     26: #define SP_MULB1       0x100d          /* Single mul: B1 = R0 * A1 */
                     27: 
                     28: #define SP_DIV         0x1013          /* Single div: B1 = A2 / A1 */
                     29: #define SP_DIVREG1     0x1055          /* Single div: R0 = R0 / A1 */
                     30: #define SP_DIVREG2     0x1056          /* Single div: R0 = A1 / R0 */
                     31: 
                     32: #define        SP_LOAD         0x1031          /* Single load:  R0 = A1 */
                     33: #define        SP_STORE        0x1037          /* Single store: B1 = R0 */
                     34: 
                     35: #define isskyop(op)    (findop(op) != NULL)
                     36: 
                     37: /*
                     38:  * Struct for each sky operator that can be changed.
                     39:  * The code generator produces operations that push two operands
                     40:  * to the board and fetch one result.  The goal here is to use
                     41:  * the on board register as an accumulator.  Therefore, one
                     42:  * operand will come from register R0 and the result will be
                     43:  * left in R0.
                     44:  * For some operations (add and mul), one operand can come
                     45:  * from register R0 and the result can be fetched from the
                     46:  * board.  Otherwise (sub and div), a SKY operation to fetch
                     47:  * the result must be inserted.
                     48:  */
                     49: struct skyop   {
                     50:        int     op;                     /* Sky board opcode */
                     51:        int     arg_op[2];              /* Opcode if arg "n" in R0 */
                     52:        int     fetch;                  /* Opcode to fetch result from board */
                     53: };
                     54: 
                     55: /*
                     56:  * Info about single precision SKY board operators.
                     57:  */
                     58: struct skyop   regops[] = {
                     59:        { SP_ADD, SP_ADDREG,  SP_ADDREG,  SP_ADDB1 },
                     60:        { SP_SUB, SP_SUBREG1, SP_SUBREG2, 0 },
                     61:        { SP_MUL, SP_MULREG,  SP_MULREG,  SP_MULB1 },
                     62:        { SP_DIV, SP_DIVREG1, SP_DIVREG2, 0 },
                     63:        { 0 },
                     64: };
                     65: 
                     66: /*
                     67:  * Struct for a sky board operation
                     68:  */
                     69: struct skylist {
                     70:        NODE    *skyload;               /* Instruction to load opcode */
                     71:        NODE    *arg[2];                /* Args passed to the board */
                     72:        NODE    *result;                /* Result fetched from the board */
                     73:        NODE    *oldresult;             /* Result fetched from the board */
                     74:        int     oldop;                  /* Original sky operator */
                     75:        int     tstloop;                /* Is result preceeded by tst loop */
                     76:        struct  skylist *next;          /* Linked list */
                     77: };
                     78: 
                     79: struct oper    *newoperand();
                     80: struct skylist *get_sky();
                     81: struct skylist *bld_skylist();
                     82: struct skyop   *findop();
                     83: NODE   *newinst();
                     84: NODE   *remove();
                     85: NODE   *delete_tst_loop();
                     86: static struct  sym_bkt *skyname;
                     87: static  struct oper skybase;
                     88: 
                     89: sky()
                     90: {
                     91:        NODE *n;
                     92:        register v, regno;
                     93:        struct oper *op1;
                     94:        struct oper *op2;
                     95:        int didchange=0;
                     96:        int i, inexact;
                     97:        struct oper saveop;
                     98:        struct skylist *skylist;
                     99:        static struct oper reg  = { T_REG,   0, 0, NULL, 0, 0, 0  };
                    100:        static struct oper conz = { T_IMMED, 0, 0, NULL, 0, 0, 0  };
                    101: 
                    102:        /* initialize constant table to empty. Find __skybase */
                    103:        forgetall();
                    104:        if (skyname==NULL) skyname = lookup("__skybase");
                    105:        skybase.type_o = T_NORMAL;
                    106:        skybase.sym_o = skyname;
                    107:        skybase.value_o = 0;
                    108: 
                    109:        for (n = first.forw; n != &first; n = n->forw){
                    110:                if (n->op == OP_LABEL) {
                    111:                        /* 
                    112:                         * we really should be doing flow analysis here.
                    113:                         * lacking that, recognize special case SKY code:
                    114:                         *      1: tstw a1@(-4)
                    115:                         *         bge  1b
                    116:                         */
                    117:                        if (n->nref == 1 && n->luse == n->forw->forw && 
                    118:                            emptymask( n->forw->rset) && n->forw->forw->op == OP_JUMP) {
                    119:                                n = n->forw;
                    120:                                continue;
                    121:                        }
                    122:                        /* forget everything */
                    123:                        forgetall();
                    124:                        continue;
                    125:                }
                    126:                if (n->nref == 0) {
                    127:                        continue;
                    128:                }
                    129:                if (n->op != OP_MOVE) {
                    130:                        continue;
                    131:                }
                    132:                op1 = n->ref[0];
                    133:                op2 = n->ref[1];
                    134:                skylist = bld_skylist(&n);
                    135:                if (skylist != NULL) {
                    136:                        rewrite_list(skylist);
                    137:                        free_list(skylist);
                    138:                        n = n->back;
                    139:                } else if (op1->type_o == T_NORMAL && 
                    140:                           op1->value_o == 0 && 
                    141:                           op1->sym_o == skyname &&
                    142:                           op2->type_o==T_REG) {
                    143:                        /* move to a register */
                    144:                        con_to_reg( op2->value_o, op1, n->subop );
                    145:                }
                    146:        }
                    147: }
                    148: 
                    149: /*
                    150:  * Build a list of sky board operations that
                    151:  * can use an accumulator between them.  Two operations
                    152:  * can use an accumulator if the result of the first operation
                    153:  * is the first argument to the second operation.
                    154:  */
                    155: struct skylist *
                    156: bld_skylist(np)
                    157: NODE   **np;
                    158: {
                    159:        struct  skylist *hdr;
                    160:        struct  skylist *sky;
                    161:        struct  skylist **bpatch;
                    162:        NODE    *n;
                    163: 
                    164:        hdr = NULL;
                    165:        n = *np;
                    166:        if (is_sky_operation(n)) {
                    167:                hdr = get_sky(&n);
                    168:                if (hdr == NULL) {
                    169:                        return(NULL);
                    170:                }
                    171:                sky = hdr;
                    172:                if (result_is_reg(sky)) {
                    173:                        bpatch = &sky->next;
                    174:                        while (n->op != OP_LABEL && 
                    175:                            n->op != OP_JUMP &&
                    176:                            n->op != OP_CALL) {
                    177:                                if (result_killed(n, sky)) {
                    178:                                        break;
                    179:                                }
                    180:                                if (n == &first) {
                    181:                                        n = first.back;
                    182:                                        break;
                    183:                                }
                    184:                                if (is_sky_operation(n)) {
                    185:                                        sky = get_sky(&n);
                    186:                                        if (sky == NULL) {
                    187:                                                return(NULL);
                    188:                                        }
                    189:                                        *bpatch = sky;
                    190:                                        bpatch = &sky->next;
                    191:                                        if (!result_is_reg(sky)) {
                    192:                                                break;
                    193:                                        }
                    194:                                } else {
                    195:                                        n = n->forw;
                    196:                                }
                    197:                        }
                    198:                }
                    199:        }
                    200:        *np = n;
                    201:        return(hdr);
                    202: }
                    203: 
                    204: /*
                    205:  * Disect a sky board operation.
                    206:  * Find the opcode, the two arguments and the result that is fetched
                    207:  * off of the board.
                    208:  * If it is not a sky board operation return NULL.
                    209:  */
                    210: struct skylist *
                    211: get_sky(np)
                    212: NODE   **np;
                    213: {
                    214:        NODE    *n;
                    215:        struct  skylist *sky;
                    216:        int     i;
                    217: 
                    218:        /*
                    219:         * Get the instruction to load an opcode into the sky board
                    220:         */
                    221:        n = *np;
                    222:        sky = (struct skylist *) calloc(sizeof(*sky), 1);
                    223:        sky->skyload = n;
                    224:        n = n->forw;
                    225: 
                    226:        /*
                    227:         * Get pointers to the instructions that push arguments
                    228:         */
                    229:        for (i = 0; i < 2; i++) {
                    230:                if (!move_to_sky(n)) {
                    231:                        return(NULL);
                    232:                }
                    233:                sky->arg[i] = n;
                    234:                n = n->forw;
                    235:        }
                    236: 
                    237:        /*
                    238:         * Get the instruction to fetch the result from the board.
                    239:         * It may be preceeded by a test loop.
                    240:         */
                    241:        if (n->op == OP_LABEL) {
                    242:                for (i = 0; i < 3; i++) {
                    243:                        n = n->forw;
                    244:                }
                    245:                sky->tstloop = 1;
                    246:        }
                    247:        if (!move_from_sky(n)) {
                    248:                return(NULL);
                    249:        }
                    250:        sky->result = n;
                    251: 
                    252:        n = n->forw;
                    253:        sky->next = NULL;
                    254:        *np = n;
                    255:        return(sky);
                    256: }
                    257: 
                    258: /*
                    259:  * Is this instruction a movl to the sky board?
                    260:  */
                    261: move_to_sky(n)
                    262: NODE   *n;
                    263: {
                    264:        struct  oper    *op2;
                    265:        int     regno;
                    266:        int     inexact;
                    267: 
                    268:        if (n->op == OP_MOVE && n->subop == SUBOP_L) {
                    269:                regno = reglookup(&skybase, SUBOP_L, &inexact);
                    270:                op2 = n->ref[1];
                    271:                if (op2->type_o == T_DEFER && regno == op2->value_o) {
                    272:                        return(1);
                    273:                }
                    274:        }
                    275:        return(0);
                    276: }
                    277: 
                    278: /*
                    279:  * Is this instruction a movl from the sky board?
                    280:  */
                    281: move_from_sky(n)
                    282: NODE    *n;  
                    283: {
                    284:        struct  oper    *op1;
                    285:        int     regno;
                    286:        int     inexact;
                    287: 
                    288:        if (n->op == OP_MOVE && n->subop == SUBOP_L) {
                    289:                regno = reglookup(&skybase, SUBOP_L, &inexact);
                    290:                op1 = n->ref[0];
                    291:                if (op1->type_o == T_DEFER && regno == op1->value_o) {
                    292:                        return(1);
                    293:                }
                    294:        }
                    295:        return(0);
                    296: }
                    297: 
                    298: /*
                    299:  * See if this instruction stores the result of the sky operation
                    300:  * into memory or otherwise kills the result.
                    301:  */
                    302: result_killed(n, sky)
                    303: NODE   *n;
                    304: struct skylist *sky;
                    305: {
                    306:        struct  oper    *result;
                    307:        struct  oper    *op1;
                    308:        struct  oper    *op2;
                    309:        int     i;
                    310: 
                    311:        /*
                    312:         * Is this a movl from the register holding the sky result?
                    313:         */
                    314:        result = sky->result->ref[1];
                    315:        if (n->op == OP_MOVE && n->subop == SUBOP_L) {
                    316:                op1 = n->ref[0];
                    317:                if (op1->type_o == T_REG && op1->value_o == result->value_o) {
                    318:                        return(1);
                    319:                }
                    320:        }
                    321: 
                    322:        /*
                    323:         * Is the destination of this instruction the register holding
                    324:         * the sky result?
                    325:         */
                    326:        op2 = n->ref[1];
                    327:        if (result->type_o == T_REG && 
                    328:            op2->type_o == T_REG && 
                    329:            op2->value_o == result->value_o) {
                    330:                return(1);
                    331:        }
                    332:        return(0);
                    333: }
                    334: 
                    335: /*
                    336:  * Is the result of this sky operation assigned to a register.
                    337:  */
                    338: result_is_reg(sky)
                    339: struct skylist *sky;
                    340: {
                    341:        struct  oper    *result;
                    342:        int     i;
                    343: 
                    344:        result = sky->result->ref[1];
                    345:        if (result->type_o == T_REG) {
                    346:                return(1);
                    347:        }
                    348:        return(0);
                    349: }
                    350:        
                    351: /*
                    352:  * Is this instuction a movw of an opcode to the sky board?
                    353:  */
                    354: is_sky_operation(n)
                    355: NODE   *n;
                    356: {
                    357:        struct  oper    *op1;
                    358:        struct  oper    *op2;
                    359:        int     regno;
                    360:        int     inexact;
                    361: 
                    362:        op1 = n->ref[0];
                    363:        op2 = n->ref[1];
                    364:        if (n->op != OP_MOVE ||
                    365:            op1->type_o != T_IMMED ||
                    366:            !isskyop(op1->value_o) ||
                    367:            op2->type_o != T_DISPL) {
                    368:                return(0);
                    369:        }
                    370:        regno = reglookup(&skybase, SUBOP_L, &inexact);
                    371:        if (regno != op2->reg_o ||
                    372:            op2->value_o != -4) {
                    373:                return(0);
                    374:        }
                    375:        return(1);
                    376: }
                    377: 
                    378: /*
                    379:  * Rewrite a list of sky operations doing optimizations along the way.
                    380:  * Look the for the results of one operation being used as an operand
                    381:  * of the next operations.  Accumulator operations can be used in
                    382:  * this case.
                    383:  */
                    384: rewrite_list(sky) 
                    385: struct skylist *sky;
                    386: {
                    387:        struct  skylist *skyp;
                    388:        struct  skylist *last_changed;
                    389:        NODE    *result;
                    390:        NODE    *arg;
                    391:        int     first;
                    392:        int     i;
                    393: 
                    394:        first = 1;
                    395:        last_changed = NULL;
                    396:        for (skyp = sky; skyp->next != NULL; skyp = skyp->next) {
                    397:                result = skyp->result;
                    398:                if (result == NULL) {
                    399:                        continue;
                    400:                }
                    401:                for (i = 0; i < 2; i++) {
                    402:                        arg = skyp->next->arg[i];
                    403:                        if (sameops(result->ref[0], arg->ref[1]) &&
                    404:                            sameops(result->ref[1], arg->ref[0])) {
                    405:                                meter.nskyreg++;
                    406:                                if (first) {
                    407:                                        insert_reg_load(skyp);
                    408:                                        change_to_reg(skyp, 0);
                    409:                                }
                    410:                                change_to_reg(skyp->next, i);
                    411:                                last_changed = skyp->next;
                    412:                                first = 0;
                    413:                                break;
                    414:                        }
                    415:                }
                    416:                if (i == 2 && last_changed != NULL) {
                    417:                        fetch_result(last_changed);
                    418:                        first = 1;
                    419:                        last_changed = NULL;
                    420:                }
                    421:        }
                    422:        if (!first && last_changed != NULL) {
                    423:                fetch_result(last_changed);
                    424:        }
                    425: }
                    426: 
                    427: /*
                    428:  * Change an operation to use the accumulator and also
                    429:  * to leave its result in the accumulator.
                    430:  * Remove the instructions that fetch the result from the board.
                    431:  * Add a tst loop after the operation to wait for the result
                    432:  * to solidify.
                    433:  */
                    434: change_to_reg(sky, argn)
                    435: struct skylist *sky;
                    436: int    argn;
                    437: {
                    438:        NODE    *arg;
                    439:        NODE    *n;
                    440:        struct  skyop   *skyop;
                    441:        struct  oper    *opcode;
                    442:        int     op;
                    443:        int     i;
                    444: 
                    445:        opcode = sky->skyload->ref[0];
                    446:        op = opcode->value_o;
                    447:        sky->oldop = op;
                    448:        skyop = findop(op);
                    449:        if (skyop == NULL) {
                    450:                return;
                    451:        }
                    452:        opcode->value_o = skyop->arg_op[argn];
                    453:        arg = sky->arg[argn];
                    454:        arg = deletenode(arg);
                    455:        if (sky->tstloop) {
                    456:                n = sky->result;
                    457:                for (i = 0; i < 3; i++) {
                    458:                        n = n->back;
                    459:                }
                    460:                delete_tst_loop(n);
                    461:                sky->tstloop = 0;
                    462:        }
                    463:        sky->oldresult = remove(sky->result);
                    464:        insert_tst_loop(sky->skyload->forw, sky->skyload->ref[1]);
                    465: }
                    466: 
                    467: /*
                    468:  * Insert a test loop waiting for the SKY idle bit to turn on.
                    469:  * Insert the code:
                    470:  *     1:      btst    #6,skybase(-2)
                    471:  *             beqs    1b
                    472:  */
                    473: insert_tst_loop(node, skybase)
                    474: NODE   *node;
                    475: struct oper    *skybase;
                    476: {
                    477:        NODE    *label;
                    478:        NODE    *btst;
                    479:        NODE    *beqs;
                    480:        struct  sym_bkt *sbp;
                    481:        char    ltoken[20];
                    482:        extern  char    *ll_format;
                    483:        extern  int     ll_val[];
                    484:        static struct oper btstbit  = { T_IMMED,   0, 0, 0, NULL, NULL, 0, IDLE, 0  };
                    485:        static struct oper labelop  = { T_NORMAL,  0, 0, 0, NULL, NULL, 0, 0, 0  };
                    486: 
                    487:        sprintf(ltoken, ll_format, '1', ++ll_val[1]);
                    488:        sbp = lookup(ltoken);
                    489:        sbp->attr_s |= S_LABEL | S_DEC | S_DEF;
                    490:        sbp->csect_s = C_TEXT;
                    491: 
                    492:        label = new();
                    493:        label->op = OP_LABEL;
                    494:        label->subop = SUBOP_Z;
                    495:        label->nref = 1;
                    496:        label->name = sbp;
                    497: 
                    498:        btst = new();
                    499:        btst->op = OP_OTHER;
                    500:        btst->subop = SUBOP_B;
                    501:        btst->instr = sopcode("btst");
                    502:        btst->nref = 2;
                    503:        btst->ref[0] = newoperand(&btstbit);
                    504:        btst->ref[1] = newoperand(skybase);
                    505:        btst->ref[1]->value_o = STATUS_WORD;
                    506: 
                    507:        labelop.sym_o = sbp;
                    508:        beqs = new();
                    509:        beqs->op = OP_JUMP;
                    510:        beqs->subop = JGE;
                    511:        beqs->instr = sopcode("beqs");
                    512:        beqs->nref = 0;
                    513:        beqs->ref[0] = newoperand(&labelop);
                    514:        beqs->luse = label;
                    515: 
                    516:        label->forw = btst;
                    517:        btst->forw = beqs;
                    518:        beqs->back = btst;
                    519:        btst->back = label;
                    520:        insert(label, node);
                    521: }
                    522: 
                    523: /*
                    524:  * Remove a node from the list 
                    525:  */
                    526: NODE   *
                    527: remove(p)
                    528: NODE   *p;
                    529: {
                    530:        p->back->forw = p->forw;
                    531:        p->forw->back = p->back;
                    532:        p->back = NULL;
                    533:        p->forw = NULL;
                    534:        return(p);
                    535: }
                    536: 
                    537: /*
                    538:  * Find an opcode in the opcode table
                    539:  */
                    540: struct skyop   *
                    541: findop(op)
                    542: int    op;
                    543: {
                    544:        struct  skyop   *sp;
                    545: 
                    546:        for (sp = regops; sp->op != 0; sp++) {
                    547:                if (sp->op == op) {
                    548:                        return(sp);
                    549:                }
                    550:        }
                    551:        return(NULL);
                    552: }
                    553: 
                    554: /*
                    555:  * Insert code to load the sky register with a value.
                    556:  * Load it with the first operand of the sky operation
                    557:  * passed in here.
                    558:  */
                    559: insert_reg_load(sky)
                    560: struct skylist *sky;
                    561: {
                    562:        NODE    *p;
                    563:        NODE    *load;
                    564:        NODE    *arg;
                    565: 
                    566:        load = sky->skyload;
                    567:        p = newinst(load, load->ref[0], load->ref[1]);
                    568:        p->ref[0]->value_o = SP_LOAD;
                    569:        insert(p, load->back);
                    570: 
                    571:        arg = sky->arg[0];
                    572:        p = newinst(arg, arg->ref[0], arg->ref[1]);
                    573:        insert(p, load->back);
                    574: }
                    575: 
                    576: /*
                    577:  * Create a new instruction.
                    578:  * Copy the old one passed in and then give it the new arguments.
                    579:  */
                    580: NODE   *
                    581: newinst(oldinst, arg1, arg2)
                    582: NODE   *oldinst;
                    583: struct oper    *arg1;
                    584: struct oper    *arg2;
                    585: {
                    586:        NODE    *p;
                    587: 
                    588:        p = new();
                    589:        *p = *oldinst;
                    590:        p->forw = NULL;
                    591:        p->back = NULL;
                    592:        p->ref[0] = newoperand(arg1);
                    593:        p->ref[1] = newoperand(arg2);
                    594:        return(p);
                    595: }
                    596: 
                    597: /*
                    598:  * Change the code to fetch the result from the sky board.
                    599:  * If possible change last operation to use R0 as an operand
                    600:  * and generate a fetch'able result.
                    601:  * Otherwise, insert additional code to fetch the result.
                    602:  */
                    603: fetch_result(sky)
                    604: struct skylist *sky;
                    605: {
                    606:        NODE    *n;
                    607:        NODE    *p;
                    608:        NODE    *load;
                    609:        NODE    *result;
                    610:        struct  skyop   *skyop;
                    611:        int     i;
                    612: 
                    613:        skyop = findop(sky->oldop);
                    614:        if (skyop->fetch != 0) {
                    615:                n = sky->skyload->forw;
                    616:                n = n->forw;
                    617:                if (n->op == OP_LABEL) {
                    618:                        n = delete_tst_loop(n);
                    619:                        sky->tstloop = 0;
                    620:                }
                    621:                sky->skyload->ref[0]->value_o = skyop->fetch;
                    622:                insert(sky->oldresult, n);
                    623:        } else {
                    624:                load = sky->skyload;
                    625:                n = load->forw;
                    626:                for (i = 0; i < 3; i++) {
                    627:                        n = n->forw;
                    628:                }               
                    629:                p = newinst(load, load->ref[0], load->ref[1]);
                    630:                p->ref[0]->value_o = SP_STORE;
                    631:                insert(p, n);
                    632:                n = n->forw;
                    633: 
                    634:                result = sky->oldresult;
                    635:                p = newinst(result, result->ref[0], result->ref[1]);
                    636:                insert(p, n);
                    637:        }
                    638: }
                    639: 
                    640: /*
                    641:  * Delete a test loop.
                    642:  * The actual test and branch may differ here.
                    643:  */
                    644: NODE   *
                    645: delete_tst_loop(n)
                    646: NODE   *n;
                    647: {
                    648:        if (n->op != OP_LABEL) {
                    649:                fprintf(stderr, "c2: internal error deleting test loop\n");
                    650:                exit(1);
                    651:        }
                    652:        n = deletenode(n);      /* Label */
                    653:        n = n->forw;
                    654:        n = deletenode(n);      /* test */
                    655:        n = n->forw;
                    656:        n = deletenode(n);      /* branch */
                    657:        return(n);
                    658: }
                    659: 
                    660: /*
                    661:  * Free a list of sky structures
                    662:  */
                    663: free_list(sky)
                    664: struct skylist *sky;
                    665: {
                    666:        struct  skylist *next;
                    667:        struct  skylist *skyp;
                    668: 
                    669:        for (skyp = sky; skyp != NULL; skyp = next) {
                    670:                next = skyp->next;
                    671:                free(skyp);
                    672:        }
                    673: }
                    674: 
                    675: /*
                    676:  * Look for the sequence:
                    677:  *
                    678:  *     movl    skybaseR@,X
                    679:  *     movl    skybaseR@,Y
                    680:  *     movl    X,mem1
                    681:  *     movl    Y,mem2
                    682:  *
                    683:  * Change it to
                    684:  *
                    685:  *     movl    skybaseR@,mem1
                    686:  *     movl    skybaseR@,mem2
                    687:  *
                    688:  * This sequence occurs when a double precision value is fetched from
                    689:  * the SKY board and is stored into memory.
                    690:  */
                    691: skymove(n)
                    692: NODE   *n;
                    693: {
                    694:        NODE    *n1;
                    695:        NODE    *n2;
                    696:        NODE    *n3;
                    697:        int     reg;
                    698:        int     reg1;
                    699: 
                    700:        n1 = n->forw;
                    701:        n2 = n1->forw;
                    702:        n3 = n2->forw;
                    703:        if (skytoreg(n) && skytoreg(n1)) {
                    704:                reg = n->ref[1]->value_o;
                    705:                reg1 = n1->ref[1]->value_o;
                    706:                if (regtomem(n2, reg) && regtomem(n3, reg1)) {
                    707:                        if (!inmask(reg, n3->forw->rlive ) &&
                    708:                            !inmask(reg1, n3->forw->rlive ) ) {
                    709:                                n->ref[1] = newoperand(n2->ref[1]);
                    710:                                n1->ref[1] = newoperand(n3->ref[1]);
                    711:                                deletenode(n2);
                    712:                                deletenode(n3);
                    713:                                meter.ndpsky++;
                    714:                                return(1);
                    715:                        }
                    716:                }
                    717:        }
                    718:        return(0);
                    719: }
                    720: 
                    721: /*
                    722:  * Look for the instruction
                    723:  *
                    724:  *     movl    skybaseR@,X
                    725:  *
                    726:  * which fetches a value from the sky board and puts it in a register.
                    727:  * skybaseR is a register containing __skybase and X is a register.
                    728:  */
                    729: static
                    730: skytoreg(n)
                    731: NODE   *n;
                    732: {
                    733:        struct  oper    *op1;
                    734:        struct  oper    *op2;
                    735:        struct  oper    *con;
                    736:        struct  sym_bkt *sym;
                    737:        int     reg;
                    738:        extern  struct oper  *get_regcon();
                    739: 
                    740:        if (n->op != OP_MOVE || n->subop != SUBOP_L) {
                    741:                return(0);
                    742:        }
                    743:        op1 = n->ref[0];
                    744:        op2 = n->ref[1];
                    745:        if (op1->type_o != T_DEFER) {
                    746:                return(0);
                    747:        }
                    748:        reg = op1->value_o;
                    749:        sym = get_regcon( reg )->sym_o;
                    750:        if (skyname == NULL || sym != skyname) {
                    751:                return(0);
                    752:        }
                    753:        if (op2->type_o != T_REG) {
                    754:                return(0);
                    755:        }
                    756:        return(1);
                    757: }
                    758: 
                    759: /*
                    760:  * Look for the instruction
                    761:  *
                    762:  *     movl    X,mem
                    763:  *
                    764:  * where X is a register.
                    765:  */
                    766: static
                    767: regtomem(n, reg)
                    768: NODE   *n;
                    769: int    reg;
                    770: {
                    771:        struct  oper    *op1;
                    772:        struct  oper    *op2;
                    773: 
                    774:        if (n->op != OP_MOVE || n->subop != SUBOP_L) {
                    775:                return(0);
                    776:        }
                    777:        op1 = n->ref[0];
                    778:        op2 = n->ref[1];
                    779:        if (op1->value_o == reg && op2->type_o != T_REG) {
                    780:                return(1);
                    781:        }
                    782:        return(0);
                    783: }

unix.superglobalmegacorp.com

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