Annotation of coherent/d/bin/as/i8086/machine.c,v, revision 1.1.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.