Annotation of coherent/d/bin/as/i8086/machine.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Instruction formatting
        !             3:  * and decoding. This is for the Intel
        !             4:  * iAPX-86 microprocessor.
        !             5:  * Small addressing model (perhaps with
        !             6:  * separated CS and SS,DS,ES).
        !             7:  * No formatting for the large model calls,
        !             8:  * returns or jumps.
        !             9:  */
        !            10: #include "asm.h"
        !            11: 
        !            12: /*
        !            13:  * Branch map.
        !            14:  */
        !            15: int    *bp;
        !            16: int    bm;
        !            17: int    bb[NB];
        !            18: 
        !            19: /*
        !            20:  * Read and format machine instructions.
        !            21:  * The argument `sp' is a pointer to the symbol
        !            22:  * table entry of the opcode. The `s_kind' field
        !            23:  * holds the operation kind; this determines the
        !            24:  * format and the semantics of the operation.
        !            25:  */
        !            26: machine(sp)
        !            27: struct sym *sp;
        !            28: {
        !            29:        register op, m1, m2;
        !            30:        struct expr e1, e2;
        !            31:        int disp, flag, ob, rf, si, rn;
        !            32: 
        !            33:        op = sp->s_addr;
        !            34:        switch (sp->s_kind) {
        !            35: 
        !            36:        case S_EVEN:
        !            37:                if ((dot->s_addr&01) != 0) {
        !            38:                        if (inbss == 0)
        !            39:                                outab(0);
        !            40:                        else
        !            41:                                ++dot->s_addr;
        !            42:                }
        !            43:                lmode = ALIST;
        !            44:                break;
        !            45: 
        !            46:        case S_ODD:
        !            47:                if ((dot->s_addr&01) == 0) {
        !            48:                        if (inbss == 0)
        !            49:                                outab(0);
        !            50:                        else
        !            51:                                ++dot->s_addr;
        !            52:                }
        !            53:                lmode = ALIST;
        !            54:                break;
        !            55: 
        !            56:        case S_INH:
        !            57:                outab(op);
        !            58:                if (op==AAM || op==AAD)         /* Need suffix byte */
        !            59:                        outab(APB);
        !            60:                break;
        !            61: 
        !            62:        case S_INT:
        !            63:                expr(&e1, 0);
        !            64:                if (isabsn(&e1, 3)) {
        !            65:                        outab(INT3);
        !            66:                        break;
        !            67:                }
        !            68:                outab(INT);
        !            69:                outrb(&e1, 0);
        !            70:                break;
        !            71: 
        !            72:        case S_SYS:
        !            73:                expr(&e1, 0);
        !            74:                if (e1.e_type == E_ACON) {
        !            75:                        outab(INT);
        !            76:                        e1.e_addr += 128;
        !            77:                        outrb(&e1, 0);
        !            78:                        break;
        !            79:                }
        !            80:                aerr("expected constant");
        !            81:                break;
        !            82: 
        !            83:        case S_OVER:
        !            84:                if (addr(&e1) == SEGR) {
        !            85:                        out3(SEGPFX, rof(e1));
        !            86:                        break;
        !            87:                }
        !            88:                aerr("segment override by non-segment register");
        !            89:                break;
        !            90: 
        !            91:        case S_RET:
        !            92:                if (more() == 0) {
        !            93:                        outab(op);
        !            94:                        break;
        !            95:                }
        !            96:                expr(&e1, 0);
        !            97:                outab(op-1);            /* Use ret n form */
        !            98:                outrw(&e1, 0);
        !            99:                break;
        !           100: 
        !           101:        case S_PUSH:
        !           102:                m1 = addr(&e1);
        !           103:                rn = rof(e1);
        !           104:                if (m1 == SEGR) {
        !           105:                        if (op == PUSH)
        !           106:                                out3(PUSHSR, rn);
        !           107:                        else {
        !           108:                                if (e1.e_mode == CS)    /* No pop CS */
        !           109:                                        aerr("no 'pop CS' instruction");
        !           110:                                out3(POPSR, rn);
        !           111:                        }
        !           112:                        break;
        !           113:                }
        !           114:                if (m1 == WR) {
        !           115:                        if (op == PUSH)
        !           116:                                outab(PUSHR | rn);
        !           117:                        else
        !           118:                                outab(POPR  | rn);
        !           119:                        break;
        !           120:                }
        !           121:                if ( m1 == IM ) {
        !           122:                        if ( (e1.e_type == E_ACON)
        !           123:                          && (  ((e1.e_addr & 0xFF80) == 0xFF80)
        !           124:                             || ((e1.e_addr & 0xFF80) == 0x0000) ) ) {
        !           125:                                outab( PUSHIB );
        !           126:                                outab( e1.e_addr );
        !           127:                        }
        !           128:                        else {
        !           129:                                outab( PUSHIW );
        !           130:                                outrw(&e1, 0);
        !           131:                        }
        !           132:                        break;
        !           133:                }
        !           134:                outgen(op, ((op==PUSH) ? 6 : 0), &e1);
        !           135:                break;
        !           136: 
        !           137:        case S_IN:
        !           138:                m1 = addr(&e1);
        !           139:                comma();
        !           140:                m2 = addr(&e2);
        !           141:        IN_OUT:
        !           142:                if (m1 == WR && rof(e1) == AX)
        !           143:                        op |= W;
        !           144:                else if (m1 == BR && rof(e1) == reg(AL))
        !           145:                        op &= ~W;
        !           146:                else {
        !           147:                        aerr("(in|out)(b|) must use AX or AL");
        !           148:                        break;
        !           149:                }
        !           150:                if (m2 == WR && rof(e2) == DX) {
        !           151:                        outab(op|010);
        !           152:                        break;
        !           153:                } else if (m2 == DIR) {
        !           154:                        outab(op);
        !           155:                        outrb(&e2, 0);
        !           156:                        break;
        !           157:                }
        !           158:                aerr("(in|out)(b|) must use DX or constant");
        !           159:                break;
        !           160: 
        !           161:        case S_OUT:
        !           162:                m2 = addr(&e2);
        !           163:                comma();
        !           164:                m1 = addr(&e1);
        !           165:                goto IN_OUT;
        !           166: 
        !           167:        case S_SHL:
        !           168:        case S_SHLB:
        !           169:                m1 = addr(&e1);
        !           170:                comma();
        !           171:                m2 = addr(&e2);
        !           172:                ob = SHL;
        !           173:                if (sp->s_kind == S_SHL)
        !           174:                        ob |= W;
        !           175:                bytecheck(ob, m1, NONE);
        !           176:                if (m2 == BR && e2.e_addr == CL)
        !           177:                        ob |= V;
        !           178:                else if ( (m2 == IM) && (e2.e_type == E_ACON) ) {
        !           179:                        if ( e2.e_addr != 1 )
        !           180:                                ob = (ob & W) ? (SHLI|W) : SHLI;
        !           181:                }
        !           182:                else
        !           183:                        aerr("Improper shift amount");
        !           184:                outgen(ob, op, &e1);
        !           185:                if ( (ob & ~W) == SHLI )
        !           186:                        outab( e2.e_addr );
        !           187:                break;
        !           188: 
        !           189:        case S_JMP:
        !           190:                if (addr(&e1) != DIR)
        !           191:                        aerr("jmp must be direct address");
        !           192:                if (pass == 0) {
        !           193:                        dot->s_addr += 3;
        !           194:                        if (op != JMP)
        !           195:                                dot->s_addr += 2;
        !           196:                } else if (pass == 1) {
        !           197:                        if (e1.e_type != E_DIR
        !           198:                        ||  e1.e_base.e_lp != dot->s_base.s_lp) {
        !           199:                                /* long */
        !           200:                                dot->s_addr += 3;
        !           201:                                if (op != JMP)
        !           202:                                        dot->s_addr += 2;
        !           203:                                flag = 1;
        !           204:                        } else {
        !           205:                                if (e1.e_addr >= dot->s_addr)
        !           206:                                        e1.e_addr -= fuzz;
        !           207:                                dot->s_addr += 2;
        !           208:                                disp = e1.e_addr - dot->s_addr;
        !           209:                                flag = 0;
        !           210:                                if (disp<-128 || disp>127) {
        !           211:                                        /* long */
        !           212:                                        flag = 1;
        !           213:                                        ++dot->s_addr;
        !           214:                                        if (op != JMP)
        !           215:                                                dot->s_addr += 2;
        !           216:                                }
        !           217:                        }
        !           218:                        setbit(flag);
        !           219:                } else if (getbit()) {
        !           220:                        if (op != JMP) {
        !           221:                                outab(op ^ 01);
        !           222:                                outab(03);
        !           223:                        }
        !           224:                        outab(0xE9);
        !           225:                        outrw(&e1, 1);
        !           226:                } else {
        !           227:                        disp = e1.e_addr - dot->s_addr - 2;
        !           228:                        outab(op);
        !           229:                        outab(disp);
        !           230:                }
        !           231:                break;
        !           232: 
        !           233:        case S_REL:
        !           234:                if (addr(&e1) != DIR
        !           235:                ||  e1.e_type != E_DIR
        !           236:                ||  e1.e_base.e_lp != dot->s_base.s_lp)
        !           237:                        aerr("not a direct address in this segment");
        !           238:                disp = e1.e_addr - dot->s_addr - 2;
        !           239:                if (disp<-128 || disp>127)
        !           240:                        aerr("address out of range");
        !           241:                outab(op);
        !           242:                outab(disp);
        !           243:                break;
        !           244: 
        !           245:        case S_IJMP:
        !           246:                addr(&e1);
        !           247:                outgen(IJORC, op, &e1);
        !           248:                break;
        !           249: 
        !           250:        case S_CALL:
        !           251:                if (addr(&e1) != DIR)
        !           252:                        aerr("not a direct address");
        !           253:                outab(DCALL);
        !           254:                outrw(&e1, 1);
        !           255:                break;
        !           256: 
        !           257:        case S_DOP:
        !           258:                m1 = addr(&e1);
        !           259:                comma();
        !           260:                m2 = addr(&e2);
        !           261:                bytecheck(op, m1, m2);
        !           262:                if (m2 == IM) {
        !           263:                        si = 0;
        !           264:                        if (isalax(&e1)) {
        !           265:                                if (op == TESTW)
        !           266:                                        op = TESTAW;
        !           267:                                else if (op == TESTB)
        !           268:                                        op = TESTAB;
        !           269:                                else
        !           270:                                        op |= 04;
        !           271:                                outab(op);
        !           272:                        } else {
        !           273:                                if (op==TESTW || op==TESTB) {
        !           274:                                        rf = 0;
        !           275:                                        if (op == TESTW)
        !           276:                                                op = TESTMW;
        !           277:                                        else
        !           278:                                                op = TESTMB;
        !           279:                                } else {
        !           280:                                        rf = (op&070)>>3;
        !           281:                                        op = (op&W)|0200;
        !           282:                                        if (ishort(sp, &e2)) {
        !           283:                                                ++si;
        !           284:                                                op |= S;
        !           285:                                        }
        !           286:                                }
        !           287:                                outgen(op, rf, &e1);
        !           288:                        }
        !           289:                        if (si || (op&W)==0)
        !           290:                                outrb(&e2, 0);
        !           291:                        else
        !           292:                                outrw(&e2, 0);
        !           293:                        break;
        !           294:                }
        !           295:                /* Dest is reg */
        !           296:                if (m1==BR || m1==WR) {
        !           297:                        if (op!=TESTB && op!=TESTW)
        !           298:                                op |= D;
        !           299:                        outgen(op, rof(e1), &e2);
        !           300:                        break;
        !           301:                }
        !           302:                /* Dest is mem */
        !           303:                outgen(op, rof(e2), &e1);
        !           304:                break;
        !           305: 
        !           306:        case S_XCHG:
        !           307:                m1 = addr(&e1);
        !           308:                comma();
        !           309:                m2 = addr(&e2);
        !           310:                bytecheck(op, m1, m2);
        !           311:                if (m1==WR && m2==WR) {
        !           312:                        if (isalax(&e1)) {
        !           313:                                outab(XCHGR | rof(e2));
        !           314:                                break;
        !           315:                        }
        !           316:                        if (isalax(&e2)) {
        !           317:                                outab(XCHGR | rof(e1));
        !           318:                                break;
        !           319:                        }
        !           320:                }
        !           321:                if (m1==BR || m1==WR) {
        !           322:                        outgen(op, rof(e1), &e2);
        !           323:                        break;
        !           324:                }
        !           325:                if (m2==BR || m2==WR) {
        !           326:                        outgen(op, rof(e2), &e1);
        !           327:                        break;
        !           328:                }
        !           329:                aerr("improper operand pair");
        !           330:                break;
        !           331: 
        !           332:        case S_SOP:
        !           333:        case S_SOPB:
        !           334:                m1 = addr(&e1);
        !           335:                ob = (op < 2) ? INCDEC : NOTNEG;
        !           336:                if (sp->s_kind == S_SOP)
        !           337:                        ob |= W;
        !           338:                bytecheck(ob, m1, NONE);
        !           339:                if (op<2 && m1==WR) {
        !           340:                        outab(IDREG | (op<<3) | rof(e1));
        !           341:                        break;
        !           342:                }
        !           343:                outgen(ob, op, &e1);
        !           344:                break;
        !           345: 
        !           346:        case S_ESC:
        !           347:                addr(&e1);
        !           348:                outgen(ESC, 0, &e1);
        !           349:                break;
        !           350: 
        !           351:        case S_LEA:
        !           352:                m1 = addr(&e1);
        !           353:                comma();
        !           354:                m2 = addr(&e2);
        !           355:                if (m1!=WR)
        !           356:                        aerr("must load address into register");
        !           357:                if(m2!=DIR && m2!=X)
        !           358:                        aerr("must load direct address");
        !           359:                outgen(op, rof(e1), &e2);
        !           360:                break;
        !           361: 
        !           362:        case S_MOV:
        !           363:                m1 = addr(&e1);
        !           364:                comma();
        !           365:                m2 = addr(&e2);
        !           366:                bytecheck(op, m1, m2);
        !           367:                if (m2 == IM) {
        !           368:                        if (m1 == BR) {
        !           369:                                outab(MVIB | rof(e1));
        !           370:                                outrb(&e2, 0);
        !           371:                                break;
        !           372:                        }
        !           373:                        if (m1 == WR) {
        !           374:                                outab(MVIW | rof(e1));
        !           375:                                outrw(&e2, 0);
        !           376:                                break;
        !           377:                        }
        !           378:                        /* To memory */
        !           379:                        outgen((MVI|(op&W)), 0, &e1);
        !           380:                        if ((op&W) == 0)
        !           381:                                outrb(&e2, 0);
        !           382:                        else
        !           383:                                outrw(&e2, 0);
        !           384:                        break;
        !           385:                }
        !           386:                /* Quick load */
        !           387:                if (isalax(&e1) && m2==DIR) {
        !           388:                        outab(MOVMA|(op&W));
        !           389:                        outrw(&e2, 0);
        !           390:                        break;
        !           391:                }
        !           392:                /* Quick store */
        !           393:                if (m1==DIR && isalax(&e2)) {
        !           394:                        outab(MOVAM|(op&W));
        !           395:                        outrw(&e1, 0);
        !           396:                        break;
        !           397:                }
        !           398:                if (m1 == SEGR)
        !           399:                        outgen(MOVSEG|D, rof(e1), &e2);
        !           400:                else if (m2 == SEGR)
        !           401:                        outgen(MOVSEG,   rof(e2), &e1);
        !           402:                else if (m1==WR || m1==BR)
        !           403:                        outgen(op|D, rof(e1), &e2);
        !           404:                else
        !           405:                        outgen(op,   rof(e2), &e1);
        !           406:                break;
        !           407: 
        !           408:        case S_MUL:
        !           409:        case S_MULB:
        !           410:                m1 = addr(&e1);
        !           411:                ob = MULDIV;
        !           412:                if (sp->s_kind == S_MUL)
        !           413:                        ob |= W;
        !           414:                bytecheck(ob, m1, NONE);
        !           415:                outgen(ob, op, &e1);
        !           416:                break;
        !           417:        case S_PROT0:
        !           418:        case S_PROT1:
        !           419:                /*
        !           420:                 * Protection control.
        !           421:                 */
        !           422:                m1 = addr(&e1);
        !           423:                if ( (m1 != WR) && (m1 != DIR) && (m1 != X) )
        !           424:                        aerr();
        !           425:                outab( 0x0F );
        !           426:                outgen( (sp->s_kind == S_PROT0) ? 0x00 : 0x01, op, &e1 );
        !           427:                break;
        !           428: 
        !           429:        case S_PROTR:
        !           430:                /*
        !           431:                 * Protection control to register.
        !           432:                 */
        !           433:                if ( op == ARPL ) {
        !           434:                        m2 = addr(&e2);
        !           435:                        comma();
        !           436:                        m1 = addr(&e1 );
        !           437:                }
        !           438:                else if ( op == CLTS ) {
        !           439:                        outab( 0x0F );
        !           440:                        outab( op );
        !           441:                        break;
        !           442:                }
        !           443:                else {
        !           444:                        m1 = addr(&e1);
        !           445:                        comma();
        !           446:                        m2 = addr(&e2);
        !           447:                }
        !           448:                if (m1!=WR || (m2!=WR &&m2!=DIR && m2!=X))
        !           449:                        aerr("Improper operand");
        !           450:                if ( op != ARPL )
        !           451:                        outab( 0x0F );
        !           452:                outgen(op, rof(e1), &e2);
        !           453:                break;
        !           454: 
        !           455:        case S_ENTER:
        !           456:                m1 = addr(&e1);
        !           457:                comma();
        !           458:                m2 = addr(&e2);
        !           459:                if ( (m1 != DIR) || (e1.e_type != E_ACON)
        !           460:                  || (m2 != DIR) || (e2.e_type != E_ACON) )
        !           461:                        aerr();
        !           462:                outab( op );
        !           463:                outrw( &e1, 0);
        !           464:                outrb( &e2, 0 );
        !           465:                break;
        !           466: 
        !           467:        /* Floating point operations. */
        !           468:        /* No operands. */
        !           469:        case S_FP_F:
        !           470:                outab((sp->s_flag==S_NW) ? FNOP : FWAIT);
        !           471:                outab(BYTE1(op));
        !           472:                outab(BYTE2(op));
        !           473:                break;
        !           474:        /* Memory operand. */
        !           475:        case S_FP_M:
        !           476:                outab((sp->s_flag==S_NW) ? FNOP : FWAIT);
        !           477:                m1 = addr(&e1);
        !           478:                if (m1 != DIR && m1 != X)
        !           479:                        qerr("invalid operand type");
        !           480:                outgen(BYTE1(op), BYTE2(op), &e1);
        !           481:                break;
        !           482:        /* Two optional fp stack operands. */
        !           483:        /* The opcode in the table is for the format "f<op> st<n>,st". */
        !           484:        /* Some nasty fudging here;  thanks again, Intel. */
        !           485:        case S_FP_S:
        !           486:                outab(FWAIT);
        !           487:                if (fp_reg2(&e1, &e2)) {
        !           488:                        if (e1.e_mode == ST) {
        !           489:                                /* "f<op> st,st<n>". */
        !           490:                                /* Change BYTE1 from 0xDC to 0xD8. */
        !           491:                                outab(BYTE1(op)^4);
        !           492:                                if (sp->s_flag == S_FIX)
        !           493:                                        outab((BYTE2(op)^8)|rof(e2));
        !           494:                                else
        !           495:                                        outab(BYTE2(op)|rof(e2));
        !           496:                        }
        !           497:                        else {
        !           498:                                /* "f<op> st<n>,st". */
        !           499:                                outab(BYTE1(op));
        !           500:                                outab(BYTE2(op)|rof(e1));
        !           501:                        }
        !           502:                }
        !           503:                else {  /* No args supplied; "f<op>" means "f<op>p st1,st". */
        !           504:                        /* Change BYTE1 from 0xDC to 0xDE. */
        !           505:                        outab(BYTE1(op)|2);
        !           506:                        outab(BYTE2(op)|1);
        !           507:                }
        !           508:                break;
        !           509:        /* Two optional fp stack operands. */
        !           510:        case S_FP_SP:
        !           511:                fp_reg2(&e1, &e2);
        !           512:                if (e2.e_mode != ST)
        !           513:                        qerr("invalid operand type");
        !           514:                outab(FWAIT);
        !           515:                outab(BYTE1(op));
        !           516:                outab((BYTE2(op))|rof(e1));
        !           517:                break;
        !           518:        /* One optional fp stack operand (default: ST). */
        !           519:        case S_FP_S1:
        !           520:                fp_reg(&e1);
        !           521:                outab(FWAIT);
        !           522:                outab(BYTE1(op));
        !           523:                outab(BYTE2(op)|rof(e1));
        !           524:                break;
        !           525: 
        !           526:        default:
        !           527:                err('o', "unknown operator");
        !           528:        }
        !           529: }
        !           530: 
        !           531: /*
        !           532:  * Check if the next non blank
        !           533:  * character is a comma. Give an error if
        !           534:  * not (and give up).
        !           535:  */
        !           536: comma()
        !           537: {
        !           538:        if (getnb() != ',')
        !           539:                qerr("expected comma");
        !           540: }
        !           541: 
        !           542: /*
        !           543:  * Output `general' format instructions.
        !           544:  * `Op' is the opcode, `r' is the general
        !           545:  * register (bits 3-5 of the postbyte) and
        !           546:  * `esp' is an address.
        !           547:  * The address must not be the flags, a
        !           548:  * segment register, (dx) or an immediate
        !           549:  * thing.
        !           550:  */
        !           551: outgen(op, r, esp)
        !           552: register struct expr *esp;
        !           553: {
        !           554:        register disp, mode, regm;
        !           555: 
        !           556:        outab(op);
        !           557:        mode = esp->e_mode & MMASK;
        !           558:        regm = esp->e_mode & RMASK;
        !           559:        if (mode==IDX || mode==ICL || mode==IM || mode==SEGR) {
        !           560:                aerr("invalid operand");
        !           561:                return;
        !           562:        }
        !           563:        if (mode==BR || mode==WR) {
        !           564:                outab(0300 | (r<<3) | regm);
        !           565:                return;
        !           566:        }
        !           567:        if (mode == DIR) {
        !           568:                outab(0006 | (r<<3));
        !           569:                outrw(esp, 0);
        !           570:                return;
        !           571:        }
        !           572:        /* Mode is X */
        !           573:        if (esp->e_type == E_ACON) {
        !           574:                disp = esp->e_addr;             /* Displacement */
        !           575:                if (regm!=6 && disp==0) {
        !           576:                        outab((r<<3) | regm);
        !           577:                        return;
        !           578:                }
        !           579:                if (disp>=-128 && disp<=127) {
        !           580:                        outab(0100 | (r<<3) | regm);
        !           581:                        outab(disp);
        !           582:                        return;
        !           583:                }
        !           584:        }
        !           585:        outab(0200 | (r<<3) | regm);
        !           586:        outrw(esp, 0);
        !           587: }
        !           588: 
        !           589: /*
        !           590:  * Output a byte that looks like
        !           591:  * `bbbbbaaa'; this is a somewhat common
        !           592:  * format on the iAPX-86.
        !           593:  */
        !           594: out3(a, b)
        !           595: {
        !           596:        outab(a | (b<<3));
        !           597: }
        !           598: 
        !           599: /*
        !           600:  * Some consistancy checks.
        !           601:  * The `op' is an opcode with a valid `W' bit.
        !           602:  * `m1' and `m2' are modes.
        !           603:  */
        !           604: bytecheck(op, m1, m2)
        !           605: register op, m1, m2;
        !           606: {
        !           607:        register bad;
        !           608: 
        !           609:        bad = 0;
        !           610:        if (m1 == BR) {
        !           611:                if ((op&W) != 0)
        !           612:                        ++bad;
        !           613:                if (m2==WR || m2==SEGR)
        !           614:                        ++bad;
        !           615:        }
        !           616:        if (m1==WR || m1==SEGR) {
        !           617:                if ((op&W) == 0)
        !           618:                        ++bad;
        !           619:                if (m2 == BR)
        !           620:                        ++bad;
        !           621:        }
        !           622:        if (m2 == BR) {
        !           623:                if ((op&W) != 0)
        !           624:                        ++bad;
        !           625:                if (m1==WR || m1==SEGR)
        !           626:                        ++bad;
        !           627:        }
        !           628:        if (m2==WR || m2==SEGR) {
        !           629:                if ((op&W) == 0)
        !           630:                        ++bad;
        !           631:                if (m1 == BR)
        !           632:                        ++bad;
        !           633:        }
        !           634:        if (bad)
        !           635:                aerr("invalid operand");
        !           636: }
        !           637: 
        !           638: /*
        !           639:  * Check to see if an address is
        !           640:  * one of the two machine accumulator registers.
        !           641:  * (AX or AL).
        !           642:  * True return if so.
        !           643:  */
        !           644: isalax(esp)
        !           645: register struct expr *esp;
        !           646: {
        !           647:        if (esp->e_mode==AX || esp->e_mode==AL)
        !           648:                return (1);
        !           649:        return (0);
        !           650: }
        !           651: 
        !           652: /*
        !           653:  * Set up the big bit table
        !           654:  * used by the branch adjustment code.
        !           655:  */
        !           656: minit()
        !           657: {
        !           658:        bp = bb;
        !           659:        bm = 1;
        !           660: }
        !           661: 
        !           662: /*
        !           663:  * Store `b' in the next slot of the
        !           664:  * bit table.
        !           665:  * If no room, throw it away.
        !           666:  */
        !           667: setbit(b)
        !           668: {
        !           669:        if (bp >= &bb[NB])
        !           670:                return;
        !           671:        if (b)
        !           672:                *bp |= bm;
        !           673:        bm <<= 1;
        !           674:        if (bm == 0) {
        !           675:                bm = 1;
        !           676:                ++bp;
        !           677:        }
        !           678: }
        !           679: 
        !           680: /*
        !           681:  * Get the next bit from the bit
        !           682:  * table.
        !           683:  * If none left, return a `1'.
        !           684:  * This will get the long form of
        !           685:  * branches.
        !           686:  */
        !           687: getbit()
        !           688: {
        !           689:        register f;
        !           690: 
        !           691:        if (bp >= &bb[NB])
        !           692:                return (1);
        !           693:        f = *bp & bm;
        !           694:        bm <<= 1;
        !           695:        if (bm == 0) {
        !           696:                bm = 1;
        !           697:                ++bp;
        !           698:        }
        !           699:        return (f);
        !           700: }
        !           701: 
        !           702: /*
        !           703:  * This routine checks if the expression
        !           704:  * pointed to by `esp' is an absolute expression
        !           705:  * and has value `n'. This is used to check out
        !           706:  * the address fields of shifts and of interrupt
        !           707:  * request instructions.
        !           708:  */
        !           709: isabsn(esp, n)
        !           710: register struct expr *esp;
        !           711: {
        !           712:        if (esp->e_type==E_ACON && esp->e_addr==n)
        !           713:                return (1);
        !           714:        return (0);
        !           715: }
        !           716: 
        !           717: /*
        !           718:  * This routine checks if an immediate
        !           719:  * operand fits in 8 bits. It is used to check
        !           720:  * for immediate length in instructions that
        !           721:  * can take the w:s immediate.
        !           722:  */
        !           723: ishort(sp, esp)
        !           724: register struct sym  *sp;
        !           725: register struct expr *esp;
        !           726: {
        !           727:        register n;
        !           728: 
        !           729:        if ((sp->s_flag&S_OBL) == 0)
        !           730:                return (0);
        !           731:        if (esp->e_type != E_ACON)
        !           732:                return (0);
        !           733:        n = esp->e_addr&0177600;
        !           734:        if (n!=0 && n!=0177600)
        !           735:                return (0);
        !           736:        return (1);
        !           737: }
        !           738: 
        !           739: /*
        !           740:  * Make up the initial set of
        !           741:  * location counters.
        !           742:  * Poke one in every nonsegmented
        !           743:  * space. Add a special one for
        !           744:  * the C compiler's strings.
        !           745:  */
        !           746: locinit()
        !           747: {
        !           748:        struct loc *locdef();
        !           749: 
        !           750:        defloc = locdef(".shri", L_SHRI);
        !           751:        locdef(".prvi", L_PRVI);
        !           752:        locdef(".bssi", L_BSSI);
        !           753:        locdef(".shrd", L_SHRD);
        !           754:        locdef(".prvd", L_PRVD);
        !           755:        locdef(".bssd", L_BSSD);
        !           756:        locdef(".strn", L_PRVD);
        !           757:        locdef(".symt", L_DEBUG);
        !           758:        nloc = NLSEG;
        !           759: }
        !           760: 
        !           761: struct loc *
        !           762: locdef(cp, t)
        !           763: char *cp;
        !           764: {
        !           765:        register char *cp1, *cp2;
        !           766:        register struct loc *lp;
        !           767:        struct sym *sp;
        !           768:        struct loc *lp1, *lp2;
        !           769:        int c;
        !           770:        char id[NCPLN];
        !           771: 
        !           772:        lp = (struct loc *) new(sizeof(struct loc));
        !           773:        lp->l_seg = t;
        !           774:        lp->l_lp = NULL;
        !           775:        lp->l_fuzz = 0;
        !           776:        lp->l_break = 0;
        !           777:        lp->l_offset = 0;
        !           778:        lp1 = NULL;
        !           779:        lp2 = loc[t];
        !           780:        while (lp2 != NULL) {
        !           781:                lp1 = lp2;
        !           782:                lp2 = lp2->l_lp;
        !           783:        }
        !           784:        if (lp1 == NULL)
        !           785:                loc[t] = lp; else
        !           786:                lp1->l_lp = lp;
        !           787:        cp1 = cp;
        !           788:        cp2 = &id[0];
        !           789:        while (c = *cp1++)
        !           790:                if (cp2 < &id[NCPLN])
        !           791:                        *cp2++ = c;
        !           792:        while (cp2 < &id[NCPLN])
        !           793:                *cp2++ = 0;
        !           794:        sp = lookup(id, 1);
        !           795:        sp->s_kind = S_LOC;
        !           796:        sp->s_flag = 0;
        !           797:        sp->s_addr = (address)lp;
        !           798:        return (lp);
        !           799: }

unix.superglobalmegacorp.com

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