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

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

unix.superglobalmegacorp.com

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