Annotation of 43BSDReno/bin/adb/adb.vax/opset.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)opset.c    4.8 (Berkeley) 1/16/89";
                      3: #endif
                      4: 
                      5: /*
                      6:  * adb - instruction printing routines: VAX version
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: 
                     11: /*
                     12:  * Get assembler definitions; declare tables that appear in optab.c.
                     13:  */
                     14: #define        ADB
                     15: #undef INSTTAB
                     16: #include "instrs.h"
                     17: 
                     18: extern struct insttab insttab[];
                     19: extern char *regname[];
                     20: extern char *fltimm[];
                     21: 
                     22: /* these are shared with the assembler: */
                     23: extern int ty_NORELOC[];
                     24: extern int ty_nbyte[];
                     25: #ifdef notyet
                     26: extern int ty_float[];         /* must update assizetab.c */
                     27: #endif
                     28: 
                     29: /*
                     30:  * Definitions for registers and for operand classes.
                     31:  */
                     32: #define        R_PC            0xF
                     33: 
                     34: #define        OC_IMM0         0x0             /* literal, aka immediate */
                     35: #define        OC_IMM1         0x1
                     36: #define        OC_IMM2         0x2
                     37: #define        OC_IMM3         0x3
                     38: #define        OC_INDEX        0x4             /*   [rN]  */
                     39: #define        OC_REG          0x5             /*    rN   */
                     40: #define        OC_DREG         0x6             /*   (rN)  */
                     41: #define        OC_ADREG        0x7             /*  -(rN)  */
                     42: #define        OC_AIREG        0x8             /*   (rN)+ */
                     43: #define        OC_DAIREG       0x9             /*  *(rN)+ */
                     44: #define        OC_BDISP        0xA             /*  b(rN)  */
                     45: #define        OC_DBDISP       0xB             /* *b(rN)  */
                     46: #define        OC_WDISP        0xC             /*  w(rN)  */
                     47: #define        OC_DWDISP       0xD             /* *w(rN)  */
                     48: #define        OC_LDISP        0xE             /*  l(rN)  */
                     49: #define        OC_DLDISP       0xF             /* *l(rN)  */
                     50: 
                     51: #define        OC_SHIFT        4
                     52: #define        OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
                     53: #define        OC_AMEXT(x)     (((x) >> OC_SHIFT) & 0xF)
                     54: #define        OC_REGEXT(x)    ((x) & 0xF)
                     55: 
                     56: /*
                     57:  * Definitions for special instructions.
                     58:  */
                     59: #define        CASEB   0x8F
                     60: #define        CASEW   0xAF
                     61: #define        CASEL   0xCF
                     62: #define        CHMK    0xBC
                     63: 
                     64: /*
                     65:  * ioptab is a two level 1-based index by opcode into insttab.
                     66:  * The first level into ioptab is given by mapescbyte().
                     67:  * Since ioptab is 1-based, references would be expected to
                     68:  * be of the form
                     69:  *
                     70:  *     ptr = &insttab[ioptab[a][b] - 1];
                     71:  *
                     72:  * but the form
                     73:  *
                     74:  *     ptr = &(insttab - 1)[ioptab[a][b]]
                     75:  *
                     76:  * is equivalent and generates less code (!) (time to work on the
                     77:  * compiler again...).
                     78:  */
                     79: static short ioptab[3][256];
                     80: #define        mapescbyte(b)   ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0)
                     81: 
                     82: mkioptab()
                     83: {
                     84:        register struct insttab *p;
                     85:        register int mapchar;
                     86:        register short *iop;
                     87: 
                     88:        /*
                     89:         * The idea here is that whenever two opcodes have the same
                     90:         * codes, but different mnemonics, we want to prefer the one
                     91:         * with the `simpler' type.  Here lower numbers make simpler
                     92:         * types.  This seems (likely) to work reasonably well.
                     93:         *
                     94:         * At present, this affects the following opcodes:
                     95:         *
                     96:         *  7c  clrq   | clrd   | clrg
                     97:         *  7e  movaq  | movad  | movag
                     98:         *  7f  pushaq | pushad | pushag
                     99:         *  d4  clrl   | clrf
                    100:         *  de  moval  | movaf
                    101:         *  df  pushal | pushaf
                    102:         *
                    103:         * In each case, the leftmost mnemonics are preferred.
                    104:         */
                    105: #define PREFER(a, b) (A_TYPEXT((a)->argtype[0]) < A_TYPEXT((b)->argtype[0]))
                    106: 
                    107:        for (p = insttab; p->iname != NULL; p++) {
                    108:                mapchar = mapescbyte(p->eopcode);
                    109:                iop = &ioptab[mapchar][p->popcode];
                    110:                if (*iop == 0 || PREFER(p, &(insttab - 1)[*iop]))
                    111:                        *iop = p - (insttab - 1);
                    112:        }
                    113: #undef PREFER
                    114: }
                    115: 
                    116: /*
                    117:  * Global variables for communication between the minions and printins.
                    118:  */
                    119: static int idsp;               /* which space we are in (INSTR or DATA) */
                    120: static int argno;              /* which argument we are working on */
                    121: static int dotoff;             /* offset from dot for this arg */
                    122: static int vset[7];            /* set by savevar, cleared by clrvar */
                    123: 
                    124: #define        savevar(v)      (vset[argno] = 1, var[argno] = v)
                    125: #define        clrvar(v)       (vset[argno] = 0, var[argno] = 0x80000000)
                    126: 
                    127: /*
                    128:  * Read some bytes, checking for errors, and updating the offset.
                    129:  */
                    130: #define        getsomebytes(ptr, nbytes) \
                    131:        (void) adbread(idsp, inkdot(dotoff), ptr, nbytes); \
                    132:        checkerr(); \
                    133:        dotoff += (nbytes)
                    134: 
                    135: /*
                    136:  * Read one byte, and advance the offset.
                    137:  */
                    138: static int
                    139: getbyte()
                    140: {
                    141:        u_char c;
                    142: 
                    143:        getsomebytes(&c, sizeof(c));
                    144:        return (c);
                    145: }
                    146: 
                    147: /*
                    148:  * adb's view: printins() prints one instruction, and sets dotinc.
                    149:  */
                    150: printins(space)
                    151:        int space;
                    152: {
                    153:        register u_char *ap;
                    154:        register struct insttab *ip;
                    155:        int ins, mode, optype, mapchar, t;
                    156:        char *lastix, *ixreg;
                    157:        char *operandout();
                    158: 
                    159:        /*
                    160:         * Set up the module variables, pick up the instruction, and
                    161:         * find its table entry.
                    162:         */
                    163:        idsp = space;
                    164:        dotoff = 0;
                    165:        ins = idsp == SP_NONE ? (u_char)dot : getbyte();
                    166:        if ((mapchar = mapescbyte(ins)) != 0) {
                    167:                t = getbyte();
                    168:                if (ioptab[mapchar][t] == 0) {
                    169:                        /*
                    170:                         * Oops; not a defined instruction; back over this
                    171:                         * escape byte. 
                    172:                         */
                    173:                        dotoff--;
                    174:                        mapchar = 0;
                    175:                } else
                    176:                        ins = t;
                    177:        }
                    178:        if ((t = ioptab[mapchar][ins]) == 0) {
                    179:                adbprintf("<undefined operator byte>: %x", ins);
                    180:                dotinc = 1;
                    181:                return;
                    182:        }
                    183:        ip = &(insttab - 1)[t];
                    184:        adbprintf("%s%8t", ip->iname);
                    185: 
                    186:        /*
                    187:         * For each argument, decode that argument.
                    188:         * We set t if we notice something fishy.
                    189:         */
                    190:        t = 0;
                    191:        for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++) {
                    192:                optype = *ap++;
                    193:                clrvar();
                    194:                if (argno != 0)
                    195:                        printc(',');
                    196:                /*
                    197:                 * lastix and ixreg track the register indexed addressing
                    198:                 * mode, which is written as <stuff>[reg] but encoded as
                    199:                 * [reg]<stuff>.  Only one [reg] is legal.
                    200:                 */
                    201:                lastix = NULL;
                    202:                do {
                    203:                        /* check for special pc-relative (branch) */
                    204:                        if (A_ACCEXT(optype) & ACCB) {
                    205:                                switch (A_TYPEXT(optype)) {
                    206:                                case TYPB:
                    207:                                        mode = OC_CONS(OC_BDISP, R_PC);
                    208:                                        break;
                    209:                                case TYPW:
                    210:                                        mode = OC_CONS(OC_WDISP, R_PC);
                    211:                                        break;
                    212:                                }
                    213:                        } else
                    214:                                mode = getbyte();
                    215:                        ixreg = operandout(mode, optype, ins == CHMK);
                    216:                        if (lastix) {
                    217:                                adbprintf("[%s]", lastix);
                    218:                                if (ixreg)
                    219:                                        t = 1;
                    220:                        }
                    221:                } while ((lastix = ixreg) != NULL);
                    222:        }
                    223:        if (t)
                    224:                adbprintf("%4t# not code? illegal arguments detected  ");
                    225:        switch (ins) {
                    226:        case CASEB:
                    227:        case CASEW:
                    228:        case CASEL:
                    229:                if (mapchar == 0 && vset[1] && vset[2])
                    230:                        casebody(var[1], var[2]);
                    231:                else
                    232:                        adbprintf("\n%4t# not code? non-constant cases  ");
                    233:        }
                    234:        dotinc = dotoff;
                    235: }
                    236: 
                    237: /*
                    238:  * Print out the locations to which each of the cases branch.
                    239:  * This routine carefully allows expressions such as
                    240:  *
                    241:  *     casel   <val>,$<const>,$0x7fffffff
                    242:  *
                    243:  * even though they do not fit on a VAX.
                    244:  */
                    245: static
                    246: casebody(base, limit)
                    247:        register expr_t base, limit;
                    248: {
                    249:        register expr_t i = -1;
                    250:        register addr_t a, baseaddr = inkdot(dotoff);
                    251:        short displ;
                    252: 
                    253:        argno = 0;
                    254:        do {
                    255:                i++;
                    256:                adbprintf("\n    %R:  ", base++);
                    257:                getsomebytes(&displ, sizeof(displ));
                    258:                a = displ + baseaddr;
                    259:                psymoff("%R", a, SP_DATA, maxoff, "");
                    260:                savevar(a);
                    261:        } while (i != limit);
                    262: }
                    263: 
                    264: /*
                    265:  * Handle a normal operand.  Return pointer to register
                    266:  * name if this is an index instruction, else return NULL.
                    267:  */
                    268: static char *
                    269: operandout(mode, optype, ischmk)
                    270:        register int mode;
                    271:        int optype, ischmk;
                    272: {
                    273:        register char *r;
                    274:        register int regnumber, nbytes, n;
                    275:        union {
                    276:                char b;
                    277:                short w;
                    278:                int l;
                    279:        } displ;
                    280:        extern char *syscalls[];
                    281:        extern int nsys;
                    282: 
                    283:        regnumber = OC_REGEXT(mode);
                    284:        r = regname[regnumber];
                    285:        switch (OC_AMEXT(mode)) {
                    286: 
                    287:        case OC_IMM0: case OC_IMM1:
                    288:        case OC_IMM2: case OC_IMM3:
                    289:                savevar(mode);
                    290:                printc('$');
                    291: #ifdef notyet
                    292:                if (ty_float[A_TYPEXT(optype)])
                    293:                        prints(fltimm[mode]);
                    294:                else if (ischmk && (u_int)mode < nsys && syscalls[mode])
                    295:                        prints(syscalls[mode]);
                    296:                else
                    297:                        adbprintf("%V", mode);
                    298: #else
                    299:                switch (A_TYPEXT(optype)) {
                    300: 
                    301:                case TYPF:
                    302:                case TYPD:
                    303:                case TYPG:
                    304:                case TYPH:
                    305:                        prints(fltimm[mode]);
                    306:                        break;
                    307: 
                    308:                default:
                    309:                        if (ischmk && (u_int)mode < nsys && syscalls[mode])
                    310:                                prints(syscalls[mode]);
                    311:                        else
                    312:                                adbprintf("%V", mode);
                    313:                        break;
                    314:                }
                    315: #endif
                    316:                return (0);
                    317: 
                    318:        case OC_INDEX:
                    319:                return (r);     /* will be printed later */
                    320: 
                    321:        case OC_REG:
                    322:                adbprintf("%s", r);
                    323:                return (0);
                    324: 
                    325:        case OC_DREG:
                    326:                adbprintf("(%s)", r);
                    327:                return (0);
                    328: 
                    329:        case OC_ADREG:
                    330:                adbprintf("-(%s)", r);
                    331:                return (0);
                    332: 
                    333:        case OC_DAIREG:
                    334:                printc('*');
                    335:                /* FALLTHROUGH */
                    336: 
                    337:        case OC_AIREG:
                    338:                if (regnumber != R_PC) {
                    339:                        adbprintf("(%s)+", r);
                    340:                        return (0);
                    341:                }
                    342:                /* PC immediate */
                    343:                printc('$');
                    344:                if (mode == OC_CONS(OC_DAIREG, R_PC))
                    345:                        /* PC absolute, always 4 bytes */
                    346:                        nbytes = 4;
                    347:                else {
                    348:                        nbytes = ty_nbyte[A_TYPEXT(optype)];
                    349:                        if (ty_NORELOC[A_TYPEXT(optype)]) {
                    350:                                bignumprint(nbytes, optype);
                    351:                                return (0);
                    352:                        }
                    353:                }
                    354:                break;
                    355: 
                    356:        case OC_DBDISP:
                    357:                printc('*');
                    358:                /* FALLTHROUGH */
                    359: 
                    360:        case OC_BDISP:
                    361:                nbytes = 1;
                    362:                break;
                    363: 
                    364:        case OC_DWDISP:
                    365:                printc('*');
                    366:                /* FALLTHROUGH */
                    367: 
                    368:        case OC_WDISP:
                    369:                nbytes = 2;
                    370:                break;
                    371: 
                    372:        case OC_DLDISP:
                    373:                printc('*');
                    374:                /* FALLTHROUGH */
                    375: 
                    376:        case OC_LDISP:
                    377:                nbytes = 4;
                    378:                break;
                    379: 
                    380:        default:
                    381:                panic("operandout 1");
                    382:                /* NOTREACHED */
                    383:        }
                    384: 
                    385:        /*
                    386:         * Print a displacement format.
                    387:         */
                    388:        getsomebytes(&displ, nbytes);
                    389:        switch (nbytes) {
                    390:        case 1:
                    391:                n = displ.b;
                    392:                break;
                    393:        case 2:
                    394:                n = displ.w;
                    395:                break;
                    396:        case 4:
                    397:                n = displ.l;
                    398:                break;
                    399:        default:
                    400:                panic("operandout 2");
                    401:                /* NOTREACHED */
                    402:        }
                    403:        if (regnumber == R_PC) {
                    404:                switch (OC_AMEXT(mode)) {
                    405: 
                    406:                case OC_DAIREG:
                    407:                        if (ischmk && (u_int)n < nsys && syscalls[n]) {
                    408:                                prints(syscalls[n]);
                    409:                                return (0);
                    410:                        }
                    411:                        break;
                    412: 
                    413:                case OC_BDISP: case OC_DBDISP:
                    414:                case OC_WDISP: case OC_DWDISP:
                    415:                case OC_LDISP: case OC_DLDISP:
                    416:                        /* PC offset */
                    417:                        n += dot + dotoff;
                    418:                }
                    419:                psymoff("%V", (addr_t)n, SP_DATA, maxoff, "");
                    420:        } else
                    421:                adbprintf("%V(%s)", (expr_t)n, regname[regnumber]);
                    422:        savevar(n);
                    423:        return (0);
                    424: }
                    425: 
                    426: /*
                    427:  * Print an F-float, D-float, G-float, H-float, quadword, or octaword.
                    428:  * F- and D-floating values are printed as themselves, unless they are
                    429:  * reserved operand bit patterns; these, and the others, are printed
                    430:  * instead in hex, with leading zeroes suppressed.
                    431:  */
                    432: static
                    433: bignumprint(nbytes, optype)
                    434:        int nbytes, optype;
                    435: {
                    436:        register char *p;
                    437:        register int i;
                    438:        union {
                    439:                float   f;      /* if f-floating */
                    440:                double  d;      /* if d-floating */
                    441:                u_char  c[16];  /* if G, H, Q, or O */
                    442:        } n;
                    443:        char expbuf[4*8+1];     /* max 4 8-character hex ints */
                    444:        static char tohex[] = "0123456789abcdef";
                    445: 
                    446:        /*
                    447:         * Read in the number, then figure out how to print it.
                    448:         */
                    449:        getsomebytes(&n, nbytes);
                    450:        switch (A_TYPEXT(optype)) {
                    451: 
                    452:        case TYPF:
                    453:                if ((p = checkfloat((caddr_t)&n.f, 0)) == NULL) {
                    454:                        adbprintf("0f%f", n.f);
                    455:                        return;
                    456:                }
                    457:                adbprintf("%s 0f::", p);
                    458:                break;
                    459: 
                    460:        case TYPD:
                    461:                if ((p = checkfloat((caddr_t)&n.d, 1)) == NULL) {
                    462:                        adbprintf("0d%f", n.d);
                    463:                        return;
                    464:                }
                    465:                adbprintf("%s 0d::", p);
                    466:                break;
                    467: 
                    468:        case TYPG:
                    469:                adbprintf("0g::");
                    470:                break;
                    471: 
                    472:        case TYPH:
                    473:                adbprintf("0h::");
                    474:                break;
                    475: 
                    476:        case TYPQ:
                    477:        case TYPO:
                    478:                break;
                    479: 
                    480:        default:
                    481:                panic("bignumprint");
                    482:        }
                    483: 
                    484:        /*
                    485:         * Expand the number into expbuf, then skip leading zeroes.
                    486:         * Be careful not to skip the entire number.
                    487:         */
                    488:        for (p = expbuf, i = nbytes; --i >= 0;) {
                    489:                *p++ = tohex[n.c[i] >> 4];
                    490:                *p++ = tohex[n.c[i] & 15];
                    491:        }
                    492:        for (p = expbuf; *p == '0'; p++)
                    493:                /* void */;
                    494:        prints(*p ? p : p - 1);
                    495: }

unix.superglobalmegacorp.com

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