Annotation of coherent/b/bin/c/n2/i8086/peep.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Peephole optimizer. Look through the
        !             3:  * code graph, tracking the state of the machine
        !             4:  * and deleting and/or simplifing instructions that
        !             5:  * have no change on the machine state. This code
        !             6:  * is machine independent in spirit, but is in fact
        !             7:  * only for the Intel 8086.
        !             8:  */
        !             9: #ifdef   vax
        !            10: #include "INC$LIB:cc2.h"
        !            11: #else
        !            12: #include "cc2.h"
        !            13: #endif
        !            14: 
        !            15: /*
        !            16:  * Machine registers. These codes are the
        !            17:  * same as the ones used by the processor in the
        !            18:  * REGM field of an instruction. This makes it easier
        !            19:  * to get the register code from an AFIELD. Unless
        !            20:  * Intel changes the chip, do not change the values
        !            21:  * here.
        !            22:  */
        !            23: #define        MAX     0
        !            24: #define        MCX     1
        !            25: #define        MDX     2
        !            26: #define        MBX     3
        !            27: #define        MSP     4
        !            28: #define        MBP     5
        !            29: #define        MSI     6
        !            30: #define        MDI     7
        !            31: 
        !            32: #define        MES     0
        !            33: #define        MCS     1
        !            34: #define        MSS     2
        !            35: #define        MDS     3
        !            36: 
        !            37: #define        NMREG   8
        !            38: #define        NSREG   4
        !            39: 
        !            40: /*
        !            41:  * Register state tables. Just an AFIELD
        !            42:  * structure for each kind of register (machine or
        !            43:  * segment). An "a_mode" of "A_NONE" means the
        !            44:  * register is empty or contains unknown information.
        !            45:  * Indexed by machine register code.
        !            46:  */
        !            47: AFIELD mregstate[NMREG];
        !            48: AFIELD sregstate[NSREG];
        !            49: 
        !            50: AFIELD *afresolve();
        !            51: 
        !            52: AFIELD afdsfakeing     = { A_SR|MDS, NULL, 0 };
        !            53: AFIELD afesfakeing     = { A_SR|MES, NULL, 0 };
        !            54: 
        !            55: /*
        !            56:  * Mainline of the peephole pass.
        !            57:  * Mark all of the world as unknown. Sweep the
        !            58:  * code graph, watching out for labels and machine
        !            59:  * code. Any label makes the entire machine state an
        !            60:  * unknown (with some flow analysis, this would not really
        !            61:  * be necessary).
        !            62:  */
        !            63: peephole()
        !            64: {
        !            65:        register INS    *ip;
        !            66:        register int    rel;
        !            67: 
        !            68:        emptyall();
        !            69:        for (ip=ins.i_fp; ip!=&ins; ip=ip->i_fp) {
        !            70:                if (ip->i_type == LLABEL)
        !            71:                        emptyall();
        !            72:                else if (ip->i_type == JUMP) {
        !            73:                        rel = ip->i_rel;
        !            74:                        if (rel==ZLOOP || rel==ZLOOPE || rel==ZLOOPNE)
        !            75:                                emptymreg(&mregstate[MCX]);
        !            76:                } else if (ip->i_type == CODE) {
        !            77:                        if (noeffect(ip)) {
        !            78:                                ip = deleteins(ip, ip->i_fp);
        !            79:                                ++nuseless;
        !            80:                                ++changes;
        !            81:                        } else {
        !            82:                                simplify(ip);
        !            83:                                track(ip);
        !            84:                        }
        !            85:                }
        !            86:        }
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * Mark all of the registers in the
        !            91:  * processor state as empty. Used whenever the
        !            92:  * state of the machine is, or will become,
        !            93:  * completely undefined.
        !            94:  */
        !            95: emptyall()
        !            96: {
        !            97:        register AFIELD *sp;
        !            98: 
        !            99:        sp = &mregstate[0];
        !           100:        while (sp < &mregstate[NMREG]) {
        !           101:                emptymreg(sp);
        !           102:                ++sp;
        !           103:        }
        !           104:        sp = &sregstate[0];
        !           105:        while (sp < &sregstate[NSREG]) {
        !           106:                emptysreg(sp);
        !           107:                ++sp;
        !           108:        }
        !           109: }
        !           110: 
        !           111: /*
        !           112:  * Flag machine register "r" as empty
        !           113:  * (contains unknown data) in the processor state.
        !           114:  * If "r" is an indexing base (BX, SI, DI) then any
        !           115:  * processor state entries based off these registers
        !           116:  * must also be set empty. Note that there is a
        !           117:  * register number change between bx and [bx], so a
        !           118:  * bit of funnyness is required.
        !           119:  */
        !           120: emptymreg(rsp)
        !           121: register AFIELD        *rsp;
        !           122: {
        !           123:        register AFIELD *sp;
        !           124:        register short  xmode;
        !           125: 
        !           126:        rsp->a_mode = A_NONE;
        !           127:        if (rsp == &mregstate[MBX]
        !           128:        ||  rsp == &mregstate[MSI]
        !           129:        ||  rsp == &mregstate[MDI]) {
        !           130:                if (rsp == &mregstate[MBX])
        !           131:                        xmode = A_XBX;
        !           132:                else if (rsp == &mregstate[MSI])
        !           133:                        xmode = A_XSI;
        !           134:                else
        !           135:                        xmode = A_XDI;
        !           136:                sp = &mregstate[0];
        !           137:                while (sp < &mregstate[NMREG]) {
        !           138:                        if ((sp->a_mode&(A_AMOD|A_REGM)) == xmode)
        !           139:                                sp->a_mode = A_NONE;
        !           140:                        ++sp;
        !           141:                }
        !           142:                sp = &sregstate[0];
        !           143:                while (sp < &sregstate[NSREG]) {
        !           144:                        if ((sp->a_mode&(A_AMOD|A_REGM)) == xmode)
        !           145:                                sp->a_mode = A_NONE;
        !           146:                        ++sp;
        !           147:                }
        !           148:        }
        !           149: }
        !           150: 
        !           151: /*
        !           152:  * Flag segment register "r" as empty
        !           153:  * (contains unknown data) in the processor state.
        !           154:  * If "r" is the ES register then all entries in the
        !           155:  * processor state being accessed through ES must also
        !           156:  * flagged as empty.
        !           157:  */
        !           158: emptysreg(rsp)
        !           159: register AFIELD        *rsp;
        !           160: {
        !           161:        register AFIELD *sp;
        !           162: 
        !           163:        rsp->a_mode = A_NONE;
        !           164:        if (rsp == &sregstate[MES]) {
        !           165:                sp = &mregstate[0];
        !           166:                while (sp < &mregstate[NMREG]) {
        !           167:                        if ((sp->a_mode&A_AMOD) != A_NONE
        !           168:                        &&  (sp->a_mode&A_PREFX) == A_ES)
        !           169:                                sp->a_mode = A_NONE;
        !           170:                        ++sp;
        !           171:                }
        !           172:                sp = &sregstate[0];
        !           173:                while (sp < &sregstate[NSREG]) {
        !           174:                        if ((sp->a_mode&A_AMOD) != A_NONE
        !           175:                        &&  (sp->a_mode&A_PREFX) == A_ES)
        !           176:                                sp->a_mode = A_NONE;
        !           177:                        ++sp;
        !           178:                }
        !           179:        }
        !           180:        if (rsp == &sregstate[MDS]) {
        !           181:                sp = &mregstate[0];
        !           182:                while (sp < &mregstate[NMREG]) {
        !           183:                        if ((sp->a_mode&A_AMOD) != A_NONE) {
        !           184:                                if ((sp->a_mode&A_PREFX) == A_DS)
        !           185:                                        sp->a_mode = A_NONE;
        !           186:                                else if ((sp->a_mode&A_PREFX) == A_NONE
        !           187:                                     &&  (sp->a_mode&(A_AMOD|A_REGM)) != A_XBP)
        !           188:                                        sp->a_mode = A_NONE;
        !           189:                        }
        !           190:                        ++sp;
        !           191:                }
        !           192:                sp = &sregstate[0];
        !           193:                while (sp < &sregstate[NSREG]) {
        !           194:                        if ((sp->a_mode&A_AMOD) != A_NONE) {
        !           195:                                if ((sp->a_mode&A_PREFX) == A_DS)
        !           196:                                        sp->a_mode = A_NONE;
        !           197:                                else if ((sp->a_mode&A_PREFX) == A_NONE
        !           198:                                     &&  (sp->a_mode&(A_AMOD|A_REGM)) != A_XBP)
        !           199:                                        sp->a_mode = A_NONE;
        !           200:                        }
        !           201:                        ++sp;
        !           202:                }
        !           203:        }
        !           204: }
        !           205: 
        !           206: /*
        !           207:  * This routine, given a pointer to
        !           208:  * a CODE node, returns 1 if the instruction has
        !           209:  * no effect on the machine state. This is determined by
        !           210:  * looking at the operands of the instruction and the value
        !           211:  * that is currently in the registers. Some care must be
        !           212:  * taken to make sure that an instruction that is being used
        !           213:  * to set the flags is not considered to have no effect.
        !           214:  */
        !           215: noeffect(ip)
        !           216: register INS   *ip;
        !           217: {
        !           218:        register AFIELD *sp;
        !           219:        register short  mode;
        !           220: 
        !           221:        if (ip->i_op == ZSUB) {
        !           222:                if ((ip->i_af[0].a_mode&A_AMOD) == A_WR
        !           223:                &&   ip->i_af[0].a_mode == ip->i_af[1].a_mode) {
        !           224:                        sp = &mregstate[ip->i_af[0].a_mode&A_REGM];
        !           225:                        if ((sp->a_mode&A_AMOD) == A_IMM
        !           226:                        &&   sp->a_sp == NULL
        !           227:                        &&   sp->a_value == 0) {
        !           228:                                /* Need flags? */
        !           229:                                if ((ip = ip->i_fp) == &ins)
        !           230:                                        return (0);
        !           231:                                if (ip->i_type==JUMP && ip->i_rel!=ZJMP)
        !           232:                                        return (0);
        !           233:                                return (1);
        !           234:                        }
        !           235:                }
        !           236:                return (0);
        !           237:        }
        !           238:        if (ip->i_op == ZLEA) {
        !           239:                if (afcompare(A_EA, &ip->i_af[0], &ip->i_af[1], 0))
        !           240:                        return (1);
        !           241:                return (0);
        !           242:        }
        !           243:        if (ip->i_op==ZLDS || ip->i_op==ZLES) {
        !           244:                sp = (ip->i_op==ZLDS) ? &sregstate[MDS] : &sregstate[MES];
        !           245:                if (afcompare(0, sp, &ip->i_af[1], 2)
        !           246:                &&  afcompare(0, &ip->i_af[0], &ip->i_af[1], 0))
        !           247:                        return (1);
        !           248:                return (0);
        !           249:        }
        !           250:        if (ip->i_op == ZMOV) {
        !           251:                mode = ip->i_af[0].a_mode&A_AMOD;
        !           252:                if ((mode==A_WR || mode==A_SR)
        !           253:                &&   afcompare(0, &ip->i_af[0], &ip->i_af[1], 0))
        !           254:                        return (1);
        !           255:                return (0);
        !           256:        }
        !           257:        return (0);
        !           258: }
        !           259: 
        !           260: /*
        !           261:  * This routine looks at a CODE node
        !           262:  * and tries to make it into a simpler node that
        !           263:  * performs the same transformation of the machine
        !           264:  * state. The current idioms understood are:
        !           265:  * 1) Look for "half loaded" "lds" and "les" instructions
        !           266:  *    that can be changed into the approproate "mov".
        !           267:  * 2) Try to replace memory operands of dual op instructions
        !           268:  *    and push instructions with old register data.
        !           269:  */
        !           270: simplify(ip)
        !           271: register INS   *ip;
        !           272: {
        !           273:        register AFIELD *sp;
        !           274: 
        !           275:        switch (ip->i_op) {
        !           276: 
        !           277:        case ZLDS:
        !           278:        case ZLES:
        !           279:                sp = (ip->i_op==ZLDS) ? &sregstate[MDS] : &sregstate[MES];
        !           280:                if (afcompare(0, sp, &ip->i_af[1], 2)) {
        !           281:                        if (!afcompare(0, &ip->i_af[0], &ip->i_af[1], 0)) {
        !           282:                                ip->i_op = ZMOV;
        !           283:                                ++nsimplify;
        !           284:                                ++changes;
        !           285:                        }
        !           286:                } else if (afcompare(0, &ip->i_af[0], &ip->i_af[1], 0)) {
        !           287:                        if (ip->i_op == ZLDS)
        !           288:                                ip->i_af[0].a_mode = A_SR|MDS; else
        !           289:                                ip->i_af[0].a_mode = A_SR|MES;
        !           290:                        ip->i_af[1].a_value += 2;
        !           291:                        ip->i_op = ZMOV;
        !           292:                        ++nsimplify;
        !           293:                        ++changes;
        !           294:                }
        !           295:                break;
        !           296: 
        !           297:        case ZADC:
        !           298:        case ZADD:
        !           299:        case ZAND:
        !           300:        case ZOR:
        !           301:        case ZSBB:
        !           302:        case ZSUB:
        !           303:        case ZXOR:
        !           304:                simpoper(&ip->i_af[1]);
        !           305:                break;
        !           306: 
        !           307:        case ZPUSH:
        !           308:                simpoper(&ip->i_af[0]);
        !           309:                break;
        !           310:        }
        !           311: }
        !           312: 
        !           313: /*
        !           314:  * The "afp" points at an AFIELD. If it is
        !           315:  * a memory AFIELD look through the processor state
        !           316:  * to see if a register contains the same value. If such
        !           317:  * a register is found adjust the AFIELD to refer to the
        !           318:  * machine register.
        !           319:  */
        !           320: simpoper(afp)
        !           321: register AFIELD        *afp;
        !           322: {
        !           323:        register AFIELD *sp;
        !           324:        register int    mode;
        !           325: 
        !           326:        mode = afp->a_mode&A_AMOD;
        !           327:        if (mode==A_IMM || mode==A_DIR || mode==A_X) {
        !           328:                sp = &mregstate[0];
        !           329:                while (sp < &mregstate[NMREG]) {
        !           330:                        if (afcompare(0, sp, afp, 0)) {
        !           331:                                afp->a_mode = A_WR | (sp-&mregstate[0]);
        !           332:                                afp->a_sp = NULL;
        !           333:                                afp->a_value = 0;
        !           334:                                ++nsimplify;
        !           335:                                ++changes;
        !           336:                                break;
        !           337:                        }
        !           338:                        ++sp;
        !           339:                }
        !           340:        }
        !           341: }
        !           342: 
        !           343: /*
        !           344:  * Look at the CODE node pointed to
        !           345:  * by "ip", and make the required changes to the processor
        !           346:  * state. Some special compiler idioms have special checks.
        !           347:  * Any instruction for which there is no special knowledge
        !           348:  * is assumed to have no effect on the machine state.
        !           349:  */
        !           350: track(ip)
        !           351: register INS   *ip;
        !           352: {
        !           353:        register AFIELD *sp;
        !           354:        register short  destmode;
        !           355:        register short  destreg;
        !           356:        register short  isbyte;
        !           357: 
        !           358:        if (ip->i_op == ZOR
        !           359:        && (ip->i_af[0].a_mode&A_AMOD) == A_WR
        !           360:        &&  ip->i_af[0].a_mode == ip->i_af[1].a_mode)
        !           361:                return;
        !           362:        if (ip->i_op == ZSUB
        !           363:        && (ip->i_af[0].a_mode&A_AMOD) == A_WR
        !           364:        &&  ip->i_af[0].a_mode == ip->i_af[1].a_mode) {
        !           365:                sp = &mregstate[ip->i_af[0].a_mode&A_REGM];
        !           366:                sp->a_mode = A_IMM;
        !           367:                sp->a_sp = NULL;
        !           368:                sp->a_value = 0;
        !           369:                return;
        !           370:        }
        !           371:        isbyte = 0;
        !           372:        switch (ip->i_op) {
        !           373: 
        !           374:        case ZAAA:
        !           375:        case ZAAD:
        !           376:        case ZAAM:
        !           377:        case ZAAS:
        !           378:        case ZCBW:
        !           379:        case ZDAA:
        !           380:        case ZDAS:
        !           381:        case ZDIVB:
        !           382:        case ZIDIVB:
        !           383:        case ZIMULB:
        !           384:        case ZIN:
        !           385:        case ZINB:
        !           386:        case ZLAHF:
        !           387:        case ZMULB:
        !           388:                emptymreg(&mregstate[MAX]);
        !           389:                break;
        !           390: 
        !           391:        case ZCWD:
        !           392:                emptymreg(&mregstate[MDX]);
        !           393:                break;
        !           394: 
        !           395:        case ZDIV:
        !           396:        case ZIDIV:
        !           397:        case ZIMUL:
        !           398:        case ZMUL:
        !           399:                emptymreg(&mregstate[MAX]);
        !           400:                emptymreg(&mregstate[MDX]);
        !           401:                break;
        !           402: 
        !           403:        case ZREPE:
        !           404:        case ZREPNE:
        !           405:                emptymreg(&mregstate[MCX]);
        !           406:                break;
        !           407: 
        !           408:        case ZCALL:
        !           409:        case ZICALL:
        !           410:        case ZIXCALL:
        !           411:        case ZXCALL:
        !           412:        case ZCMPS:
        !           413:        case ZCMPSB:
        !           414:        case ZINT:
        !           415:        case ZINTO:
        !           416:        case ZLODS:
        !           417:        case ZLODSB:
        !           418:        case ZMOVS:
        !           419:        case ZMOVSB:
        !           420:        case ZSCAS:
        !           421:        case ZSCASB:
        !           422:        case ZSTOS:
        !           423:        case ZSTOSB:
        !           424:        case ZXCHG:
        !           425:        case ZXCHGB:
        !           426:        case ZXLAT:
        !           427:                emptyall();
        !           428:                break;
        !           429: 
        !           430:        case ZADCB:
        !           431:        case ZADDB:
        !           432:        case ZANDB:
        !           433:        case ZDECB:
        !           434:        case ZINCB:
        !           435:        case ZNEGB:
        !           436:        case ZNOTB:
        !           437:        case ZORB:
        !           438:        case ZRCLB:
        !           439:        case ZRCRB:
        !           440:        case ZROLB:
        !           441:        case ZRORB:
        !           442:        case ZSALB:
        !           443:        case ZSARB:
        !           444:        case ZSBBB:
        !           445:        case ZSHLB:
        !           446:        case ZSHRB:
        !           447:        case ZSUBB:
        !           448:        case ZXORB:
        !           449:                isbyte = 1;
        !           450:        case ZADC:
        !           451:        case ZADD:
        !           452:        case ZAND:
        !           453:        case ZINC:
        !           454:        case ZDEC:
        !           455:        case ZNEG:
        !           456:        case ZNOT:
        !           457:        case ZOR:
        !           458:        case ZPOP:
        !           459:        case ZRCL:
        !           460:        case ZRCR:
        !           461:        case ZROL:
        !           462:        case ZROR:
        !           463:        case ZSAL:
        !           464:        case ZSAR:
        !           465:        case ZSBB:
        !           466:        case ZSHL:
        !           467:        case ZSHR:
        !           468:        case ZSUB:
        !           469:        case ZXOR:
        !           470:        case ZIMULI:
        !           471:                destmode = ip->i_af[0].a_mode&A_AMOD;
        !           472:                destreg  = ip->i_af[0].a_mode&A_REGM;
        !           473:                if (destmode==A_WR || destmode==A_BR) {
        !           474:                        if (isbyte != 0)
        !           475:                                destreg &= 0x03;
        !           476:                        emptymreg(&mregstate[destreg]);
        !           477:                } else if (destmode == A_SR)
        !           478:                        emptysreg(&sregstate[destreg]);
        !           479:                else if (isbyte==0 && (destmode==A_DIR || destmode==A_X))
        !           480:                        emptyaf(&ip->i_af[0]);
        !           481:                else
        !           482:                        emptyall();
        !           483:                break;
        !           484: 
        !           485:        case ZLEA:
        !           486:                afupdate(A_EA, &ip->i_af[0], &ip->i_af[1], 0);
        !           487:                break;
        !           488: 
        !           489:        case ZLDS:
        !           490:                afupdate(0, &ip->i_af[0], &ip->i_af[1], 0);
        !           491:                afupdate(0, &afdsfakeing, &ip->i_af[1], 2);
        !           492:                break;
        !           493: 
        !           494:        case ZLES:
        !           495:                afupdate(0, &ip->i_af[0], &ip->i_af[1], 0);
        !           496:                afupdate(0, &afesfakeing, &ip->i_af[1], 2);
        !           497:                break;
        !           498: 
        !           499:        case ZMOV:
        !           500:                destmode = ip->i_af[0].a_mode&A_AMOD;
        !           501:                destreg  = ip->i_af[0].a_mode&A_REGM;
        !           502:                if (destmode==A_WR || destmode==A_SR)
        !           503:                        afupdate(0, &ip->i_af[0], &ip->i_af[1], 0);
        !           504:                else if (destmode==A_DIR || destmode==A_X) {
        !           505:                        emptyaf(&ip->i_af[0]);
        !           506:                        destmode = ip->i_af[1].a_mode&A_AMOD;
        !           507:                        if (destmode==A_WR || destmode==A_SR)
        !           508:                                afupdate(0, &ip->i_af[1], &ip->i_af[0], 0);
        !           509:                } else
        !           510:                        emptyall();
        !           511:                break;
        !           512: 
        !           513:        case ZMOVB:
        !           514:                destmode = ip->i_af[0].a_mode&A_AMOD;
        !           515:                destreg  = ip->i_af[0].a_mode&A_REGM;
        !           516:                if (destmode == A_BR)
        !           517:                        emptymreg(&mregstate[destreg&0x03]);
        !           518:                else if (destmode==A_DIR || destmode==A_X)
        !           519:                        emptyaf(&ip->i_af[0]);
        !           520:                else
        !           521:                        emptyall();
        !           522:        }
        !           523: }
        !           524: 
        !           525: /*
        !           526:  * This routine compares address fields.
        !           527:  * The "afp1" and "afp2" parameters are the fields
        !           528:  * themselves. They must be "resolved" to the machine
        !           529:  * state if registers. The "afp1" argument always is
        !           530:  * the register side, and is required to have the flags
        !           531:  * that are set in "flags" in the address. The "afp2"
        !           532:  * is the lvalue side; it gets its address adjusted by
        !           533:  * "bump" bytes before the compare is done.
        !           534:  */
        !           535: afcompare(flag, afp1, afp2, bump)
        !           536: register AFIELD        *afp1;
        !           537: register AFIELD        *afp2;
        !           538: {
        !           539:        register short  mode;
        !           540: 
        !           541:        if ((afp1=afresolve(afp1, 0x00, 0)) == NULL)
        !           542:                return (0);
        !           543:        if ((afp2=afresolve(afp2, bump, 0)) == NULL)
        !           544:                return (0);
        !           545:        if (afp1->a_mode==A_NONE || afp2->a_mode==A_NONE)
        !           546:                return (0);
        !           547:        if (afp1->a_mode != afp2->a_mode)
        !           548:                return (0);
        !           549:        mode = afp1->a_mode&A_AMOD;
        !           550:        if (mode==A_IMM || mode==A_DIR || mode==A_X) {
        !           551:                if (afp1->a_sp != afp2->a_sp)
        !           552:                        return (0);
        !           553:                if (afp1->a_value != afp2->a_value+bump)
        !           554:                        return (0);
        !           555:                if ((afp1->a_mode&A_EA) != flag)
        !           556:                        return (0);
        !           557:        }
        !           558:        return (1);
        !           559: }
        !           560: 
        !           561: /*
        !           562:  * Update address fields in the processor
        !           563:  * state tables. The arguments have the same functions
        !           564:  * as their namesakes in "afcompare" (above).
        !           565:  */
        !           566: afupdate(flag, afp1, afp2, bump)
        !           567: register AFIELD        *afp1;
        !           568: register AFIELD *afp2;
        !           569: {
        !           570:        if ((afp1=afresolve(afp1, 0x00, 1)) == NULL)
        !           571:                cbotch("afupdate");
        !           572:        if ((afp2=afresolve(afp2, bump, 0)) == NULL)
        !           573:                afp1->a_mode = A_NONE;
        !           574:        else if (afdependency(afp1, afp2))
        !           575:                afp1->a_mode = A_NONE;
        !           576:        else {
        !           577:                afp1->a_mode = afp2->a_mode;
        !           578:                afp1->a_sp = afp2->a_sp;
        !           579:                afp1->a_value = afp2->a_value+bump;
        !           580:                if (afp1->a_mode != A_NONE)
        !           581:                        afp1->a_mode |= flag;
        !           582:        }
        !           583: }
        !           584: 
        !           585: /*
        !           586:  * Resolve an address descriptor to the entry
        !           587:  * in the processor state. If the entry will not map
        !           588:  * for some reason, return NULL. The "bump" argument is
        !           589:  * passed so that "afresolve" can fail on bumped registers.
        !           590:  * If "flag" is set the register descriptor is flushed.
        !           591:  */
        !           592: AFIELD *
        !           593: afresolve(afp, bump, flag)
        !           594: register AFIELD        *afp;
        !           595: {
        !           596:        register short  mode;
        !           597: 
        !           598:        if ((mode=afp->a_mode&A_AMOD) == A_BR)
        !           599:                return (NULL);
        !           600:        if (mode == A_WR) {
        !           601:                if (bump != 0)
        !           602:                        return (NULL);
        !           603:                afp = &mregstate[afp->a_mode&A_REGM];
        !           604:                if (flag != 0)
        !           605:                        emptymreg(afp);
        !           606:                return (afp);
        !           607:        }
        !           608:        if (mode == A_SR) {
        !           609:                if (bump != 0)
        !           610:                        return (NULL);
        !           611:                afp = &sregstate[afp->a_mode&A_REGM];
        !           612:                if (flag != 0)
        !           613:                        emptysreg(afp);
        !           614:                return (afp);
        !           615:        }
        !           616:        return (afp);
        !           617: }
        !           618: 
        !           619: /*
        !           620:  * Given two AFIELD nodes,
        !           621:  * return true if the second depends
        !           622:  * on the value of the first. This checks
        !           623:  * for instructions like "mov bx,3[bx]", 
        !           624:  * where you must not set the contents of
        !           625:  * "bx" to be "3[bx]".
        !           626:  */
        !           627: afdependency(afp1, afp2)
        !           628: register AFIELD        *afp1;
        !           629: register AFIELD *afp2;
        !           630: {
        !           631:        if (afp1 == &mregstate[MBX]) {
        !           632:                if ((afp2->a_mode&(A_AMOD|A_REGM)) == A_XBX)
        !           633:                        return (1);
        !           634:                return (0);
        !           635:        }
        !           636:        if (afp1 == &mregstate[MSI]) {
        !           637:                if ((afp2->a_mode&(A_AMOD|A_REGM)) == A_XSI)
        !           638:                        return (1);
        !           639:                return (0);
        !           640:        }
        !           641:        if (afp1 == &mregstate[MDI]) {
        !           642:                if ((afp2->a_mode&(A_AMOD|A_REGM)) == A_XDI)
        !           643:                        return (1);
        !           644:                return (0);
        !           645:        }
        !           646:        if (afp1 == &sregstate[MES]) {
        !           647:                if ((afp2->a_mode&A_PREFX) == A_ES)
        !           648:                        return (1);
        !           649:                return (0);
        !           650:        }
        !           651:        if (afp1 == &sregstate[MDS]) {
        !           652:                if ((afp2->a_mode&A_PREFX) == A_DS)
        !           653:                        return (1);
        !           654:                if ((afp2->a_mode&A_PREFX) == A_NONE
        !           655:                &&  (afp2->a_mode&(A_AMOD|A_REGM)) != A_XBP)
        !           656:                        return (1);
        !           657:                return (0);
        !           658:        }
        !           659:        return (0);
        !           660: }
        !           661: 
        !           662: /*
        !           663:  * Purge any processor state entries that
        !           664:  * think they are holding the value of "afp". This
        !           665:  * is used to purge the state of the world when a register
        !           666:  * is stored into memory.
        !           667:  */
        !           668: emptyaf(afp)
        !           669: register AFIELD        *afp;
        !           670: {
        !           671:        register AFIELD *sp;
        !           672: 
        !           673:        sp = &mregstate[0];
        !           674:        while (sp < &mregstate[NMREG]) {
        !           675:                if (afcompare(0, sp, afp, 0))
        !           676:                        emptymreg(sp);
        !           677:                ++sp;
        !           678:        }
        !           679:        sp = &sregstate[0];
        !           680:        while (sp < &sregstate[NSREG]) {
        !           681:                if (afcompare(0, sp, afp, 0))
        !           682:                        emptysreg(sp);
        !           683:                ++sp;
        !           684:        }
        !           685: }

unix.superglobalmegacorp.com

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