Annotation of researchv9/cmd/sun/c2/sky.c, revision 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.