Annotation of coherent/b/bin/c/n2/i8086/peep.c, revision 1.1.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.