Annotation of 43BSDReno/bin/adb/adb.vax/opset.c, revision 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.