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

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

unix.superglobalmegacorp.com

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