BSD 4_4 release
[unix-history] / usr / src / old / adb / adb.vax / opset.c
index 3771f7d..5289a3d 100644 (file)
@@ -1,56 +1,61 @@
+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This module is believed to contain source code proprietary to AT&T.
+ * Use and redistribution is subject to the Berkeley Software License
+ * Agreement and your Software Agreement with AT&T (Western Electric).
+ */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)opset.c 4.5 %G%";
-#endif lint
+static char sccsid[] = "@(#)opset.c    4.9 (Berkeley) 4/4/91";
+#endif /* not lint */
+
 /*
 /*
- *     UNIX debugger
- *     Instruction printing routines.
- *     MACHINE DEPENDENT
+ * adb - instruction printing routines: VAX version
  */
 
  */
 
-#ifdef ADB
 #include "defs.h"
 #include "defs.h"
-#endif ADB
-#ifdef SDB
-#include "head.h"
-#endif SDB
-
-L_INT          dot;
-INT            dotinc;
-L_INT          insoutvar[36];
-#ifdef ADB
-L_INT          var[36];
-#endif ADB
 
 
+/*
+ * Get assembler definitions; declare tables that appear in optab.c.
+ */
+#define        ADB
 #undef INSTTAB
 #include "instrs.h"
 
 #undef INSTTAB
 #include "instrs.h"
 
-STRING regname[];
-STRING fltimm[];
-POS    type, space, incp;
+extern struct insttab insttab[];
+extern char *regname[];
+extern char *fltimm[];
+
+/* these are shared with the assembler: */
+extern int ty_NORELOC[];
+extern int ty_nbyte[];
+#ifdef notyet
+extern int ty_float[];         /* must update assizetab.c */
+#endif
+
 /*
 /*
- *     Definitions for registers and for operand classes
+ * Definitions for registers and for operand classes.
  */
  */
-char   *insregname();  /* how to print a register */
-
 #define        R_PC            0xF
 
 #define        R_PC            0xF
 
-#define        OC_IMM0         0x0
+#define        OC_IMM0         0x0             /* literal, aka immediate */
 #define        OC_IMM1         0x1
 #define        OC_IMM2         0x2
 #define        OC_IMM3         0x3
 #define        OC_IMM1         0x1
 #define        OC_IMM2         0x2
 #define        OC_IMM3         0x3
-#define        OC_INDEX        0x4
-#define        OC_REG          0x5
-#define        OC_DREG         0x6
-#define        OC_ADREG        0x7
-#define        OC_AIREG        0x8
-#define        OC_DAIREG       0x9
-
-#define        OC_BDISP        0xA
-#define        OC_DBDISP       0xB
-#define        OC_WDISP        0xC
-#define        OC_DWDISP       0xD
-#define        OC_LDISP        0xE
-#define        OC_DLDISP       0xF
+#define        OC_INDEX        0x4             /*   [rN]  */
+#define        OC_REG          0x5             /*    rN   */
+#define        OC_DREG         0x6             /*   (rN)  */
+#define        OC_ADREG        0x7             /*  -(rN)  */
+#define        OC_AIREG        0x8             /*   (rN)+ */
+#define        OC_DAIREG       0x9             /*  *(rN)+ */
+#define        OC_BDISP        0xA             /*  b(rN)  */
+#define        OC_DBDISP       0xB             /* *b(rN)  */
+#define        OC_WDISP        0xC             /*  w(rN)  */
+#define        OC_DWDISP       0xD             /* *w(rN)  */
+#define        OC_LDISP        0xE             /*  l(rN)  */
+#define        OC_DLDISP       0xF             /* *l(rN)  */
 
 #define        OC_SHIFT        4
 #define        OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
 
 #define        OC_SHIFT        4
 #define        OC_CONS(oc,reg) (((oc & 0xF) << OC_SHIFT) | (reg & 0xF))
@@ -58,140 +63,155 @@ char      *insregname();  /* how to print a register */
 #define        OC_REGEXT(x)    ((x) & 0xF)
 
 /*
 #define        OC_REGEXT(x)    ((x) & 0xF)
 
 /*
- *     Definitions for large numbers
- */
-#include "asnumber.h"
-typedef        struct  as_number       *numberp;
-numberp snarf();
-numberp snarfreloc();
-/*
- *     Definitions for special instructions
+ * Definitions for special instructions.
  */
 #define        CASEB   0x8F
 #define        CASEW   0xAF
 #define        CASEL   0xCF
  */
 #define        CASEB   0x8F
 #define        CASEW   0xAF
 #define        CASEL   0xCF
+#define        CHMK    0xBC
+
 /*
 /*
- *     Definitions for converting TYP's into numbers, booleans, etc.
- *     These are shared with the assembler.
+ * ioptab is a two level 1-based index by opcode into insttab.
+ * The first level into ioptab is given by mapescbyte().
+ * Since ioptab is 1-based, references would be expected to
+ * be of the form
+ *
+ *     ptr = &insttab[ioptab[a][b] - 1];
+ *
+ * but the form
+ *
+ *     ptr = &(insttab - 1)[ioptab[a][b]]
+ *
+ * is equivalent and generates less code (!) (time to work on the
+ * compiler again...).
  */
  */
-extern int     ty_NORELOC[];
-extern int     ty_float[];
-extern int     ty_nbyte[];
-extern int     ty_nlg[];
-extern char    *ty_string[];
-
-short ioptab[3][256];  /* two level 1-based index by opcode into insttab */
-
-int mapescbyte(byte)
-       u_char  byte;
-{
-       switch(byte){
-       default:        return(0);
-       case ESCD:      return(1);
-       case ESCF:      return(2);
-       }
-}
+static short ioptab[3][256];
+#define        mapescbyte(b)   ((b) == ESCD ? 1 : (b) == ESCF ? 2 : 0)
 
 mkioptab()
 {
 
 mkioptab()
 {
-       REG     struct insttab *p;
-               int     mapchar;
+       register struct insttab *p;
+       register int mapchar;
+       register short *iop;
 
 
-       for(p = insttab; p->iname; p++){
+       /*
+        * The idea here is that whenever two opcodes have the same
+        * codes, but different mnemonics, we want to prefer the one
+        * with the `simpler' type.  Here lower numbers make simpler
+        * types.  This seems (likely) to work reasonably well.
+        *
+        * At present, this affects the following opcodes:
+        *
+        *  7c  clrq   | clrd   | clrg
+        *  7e  movaq  | movad  | movag
+        *  7f  pushaq | pushad | pushag
+        *  d4  clrl   | clrf
+        *  de  moval  | movaf
+        *  df  pushal | pushaf
+        *
+        * In each case, the leftmost mnemonics are preferred.
+        */
+#define PREFER(a, b) (A_TYPEXT((a)->argtype[0]) < A_TYPEXT((b)->argtype[0]))
+
+       for (p = insttab; p->iname != NULL; p++) {
                mapchar = mapescbyte(p->eopcode);
                mapchar = mapescbyte(p->eopcode);
-               if (ioptab[mapchar][p->popcode])
-                       continue;
-               ioptab[mapchar][p->popcode] = (p - insttab) + 1;
+               iop = &ioptab[mapchar][p->popcode];
+               if (*iop == 0 || PREFER(p, &(insttab - 1)[*iop]))
+                       *iop = p - (insttab - 1);
        }
        }
+#undef PREFER
 }
 
 }
 
-u_char snarfuchar();
 /*
 /*
- *     Global variables for communicating with the minions and printins
+ * Global variables for communication between the minions and printins.
+ */
+static int idsp;               /* which space we are in (INSTR or DATA) */
+static int argno;              /* which argument we are working on */
+static int dotoff;             /* offset from dot for this arg */
+static int vset[7];            /* set by savevar, cleared by clrvar */
+
+#define        savevar(v)      (vset[argno] = 1, var[argno] = v)
+#define        clrvar(v)       (vset[argno] = 0, var[argno] = 0x80000000)
+
+/*
+ * Read some bytes, checking for errors, and updating the offset.
+ */
+#define        getsomebytes(ptr, nbytes) \
+       (void) adbread(idsp, inkdot(dotoff), ptr, nbytes); \
+       checkerr(); \
+       dotoff += (nbytes)
+
+/*
+ * Read one byte, and advance the offset.
  */
  */
-static int     idsp;
-static short   argno;          /* which argument one is working on */
-static char    insoutfmt[2];   /* how to format the relocated symbols */
-#ifdef SDB
-static struct  proct   *procp;
-#endif SDB
-
-static savevar(val)
-       long    val;
+static int
+getbyte()
 {
 {
-       var[argno] = val;
-       insoutvar[argno] = val;
+       u_char c;
+
+       getsomebytes(&c, sizeof(c));
+       return (c);
 }
 
 }
 
-printins(fmt, Idsp, ins)
-       char    fmt;
-#ifndef vax
-       u_char  ins;
-#else
-       u_char  ins;
-#endif
-       int     Idsp;
+/*
+ * adb's view: printins() prints one instruction, and sets dotinc.
+ */
+printins(space)
+       int space;
 {
 {
-               u_char  mode;           /* mode */
-               u_char  ins2;
-               char    *indexreg;      /* print of which register indexes */
-               char    *indexed;       /* we indexed */
-               char    *operandout();
-       REG     u_char  *ap;
-       REG     struct insttab *ip;
-               u_char  optype;
-               int     mapchar;
-
-       idsp = Idsp;
-       type = DSYM;
-       space = idsp;
-#ifdef SDB
-       procp = adrtoprocp(dot);
-       if (procp->paddr == dot){
-               printf("0x%04.4x", ins);
-               incp = 2;
-               goto ret;
-       }
-#endif SDB
-
-#ifdef ADB
-       insoutfmt[0] = 0;
-#endif ADB
-#ifdef SDB
-       insoutfmt[0] = fmt;
-#endif SDB
-
-       incp = 1;
-       if ((mapchar = mapescbyte(ins)) != 0){
-               ins2 = snarfuchar();
-               if (ioptab[mapchar][ins2] == 0){
+       register u_char *ap;
+       register struct insttab *ip;
+       int ins, mode, optype, mapchar, t;
+       char *lastix, *ixreg;
+       char *operandout();
+
+       /*
+        * Set up the module variables, pick up the instruction, and
+        * find its table entry.
+        */
+       idsp = space;
+       dotoff = 0;
+       ins = idsp == SP_NONE ? (u_char)dot : getbyte();
+       if ((mapchar = mapescbyte(ins)) != 0) {
+               t = getbyte();
+               if (ioptab[mapchar][t] == 0) {
                        /*
                        /*
-                        *      Oops; not a defined instruction;
-                        *      back over this escape byte.
+                        * Oops; not a defined instruction; back over this
+                        * escape byte. 
                         */
                         */
-                       incp -= 1;
+                       dotoff--;
                        mapchar = 0;
                        mapchar = 0;
-               } else {
-                       ins = ins2;
-               }
+               } else
+                       ins = t;
        }
        }
-       if (ioptab[mapchar][ins] == 0){
-               printf("<undefined operator byte>: %x", ins);
-               goto ret;
+       if ((t = ioptab[mapchar][ins]) == 0) {
+               adbprintf("<undefined operator byte>: %x", ins);
+               dotinc = 1;
+               return;
        }
        }
-       ip = &insttab[ioptab[mapchar][ins] - 1];
-       printf("%s\t", ip->iname);
+       ip = &(insttab - 1)[t];
+       adbprintf("%s%8t", ip->iname);
 
 
-       for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++, ap++) {
-               savevar(0x80000000);    /* an illegal symbol */
-               optype = *ap;
+       /*
+        * For each argument, decode that argument.
+        * We set t if we notice something fishy.
+        */
+       t = 0;
+       for (ap = ip->argtype, argno = 0; argno < ip->nargs; argno++) {
+               optype = *ap++;
+               clrvar();
                if (argno != 0)
                        printc(',');
                if (argno != 0)
                        printc(',');
-               indexreg = 0;
-               indexed = 0;
-               do{
-                       if (A_ACCEXT(optype) & ACCB){
-                               switch(A_TYPEXT(optype)){
+               /*
+                * lastix and ixreg track the register indexed addressing
+                * mode, which is written as <stuff>[reg] but encoded as
+                * [reg]<stuff>.  Only one [reg] is legal.
+                */
+               lastix = NULL;
+               do {
+                       /* check for special pc-relative (branch) */
+                       if (A_ACCEXT(optype) & ACCB) {
+                               switch (A_TYPEXT(optype)) {
                                case TYPB:
                                        mode = OC_CONS(OC_BDISP, R_PC);
                                        break;
                                case TYPB:
                                        mode = OC_CONS(OC_BDISP, R_PC);
                                        break;
@@ -199,376 +219,286 @@ printins(fmt, Idsp, ins)
                                        mode = OC_CONS(OC_WDISP, R_PC);
                                        break;
                                }
                                        mode = OC_CONS(OC_WDISP, R_PC);
                                        break;
                                }
-                       } else {
-                               mode = snarfuchar();
+                       } else
+                               mode = getbyte();
+                       ixreg = operandout(mode, optype, ins == CHMK);
+                       if (lastix) {
+                               adbprintf("[%s]", lastix);
+                               if (ixreg)
+                                       t = 1;
                        }
                        }
-                       indexreg = operandout(mode, optype);
-                       if (indexed)
-                               printf("[%s]", indexed);
-                       indexed = indexreg;
-               } while(indexed);
+               } while ((lastix = ixreg) != NULL);
        }
        }
-       if (mapchar == 0){
-               switch(ins){
-               case CASEB:
-               case CASEW:
-               case CASEL:
-                       casebody(insoutvar[1], insoutvar[2]);
-                       break;
-               default:
-                       break;
-               }
+       if (t)
+               adbprintf("%4t# not code? illegal arguments detected  ");
+       switch (ins) {
+       case CASEB:
+       case CASEW:
+       case CASEL:
+               if (mapchar == 0 && vset[1] && vset[2])
+                       casebody(var[1], var[2]);
+               else
+                       adbprintf("\n%4t# not code? non-constant cases  ");
        }
        }
-   ret: ;
-
-#ifdef SDB
-       oincr = incp;
-#endif SDB
-#ifdef ADB
-       dotinc = incp;
-#endif ADB
+       dotinc = dotoff;
 }
 
 }
 
+/*
+ * Print out the locations to which each of the cases branch.
+ * This routine carefully allows expressions such as
+ *
+ *     casel   <val>,$<const>,$0x7fffffff
+ *
+ * even though they do not fit on a VAX.
+ */
+static
 casebody(base, limit)
 casebody(base, limit)
-       long    base;
-       long    limit;
+       register expr_t base, limit;
 {
 {
-       int     i;
-       POS     baseincp;
-       POS     advincp;
-       struct  as_number       *valuep;
-#define        OSIZE (sizeof(short))
+       register expr_t i = -1;
+       register addr_t a, baseaddr = inkdot(dotoff);
+       short displ;
+
        argno = 0;
        argno = 0;
-       baseincp = incp;
-       for (i = 0; i <= limit; i++) {
-               printc(EOR);
-#ifdef SDB
-               printf("    %d:  ", i + base);
-#endif SDB
-#ifdef ADB
-               printf("    %R:  ", i + base);
-#endif ADB
-               valuep = snarfreloc(OSIZE, 0);
-               advincp = incp;
-               incp = baseincp;
-               dispaddress(valuep, OC_CONS(OC_WDISP, R_PC));
-               incp = advincp;
-       }
+       do {
+               i++;
+               adbprintf("\n    %R:  ", base++);
+               getsomebytes(&displ, sizeof(displ));
+               a = displ + baseaddr;
+               psymoff("%R", a, SP_DATA, maxoff, "");
+               savevar(a);
+       } while (i != limit);
 }
 
 /*
 }
 
 /*
- *     magic values to mung an offset to a register into
- *     something that psymoff can understand.. all magic
- */
-                             /* 0      1       2       3       4 */
-static long magic_masks[5] =   {0,     0x80,   0x8000, 0,      0};     
-static long magic_compl[5] =   {0,     0x100,  0x10000,0,      0};
-/*
- *     Snarf up some bytes, and put in the magic relocation flags
+ * Handle a normal operand.  Return pointer to register
+ * name if this is an index instruction, else return NULL.
  */
  */
-numberp snarfreloc(nbytes)
-       int     nbytes;
+static char *
+operandout(mode, optype, ischmk)
+       register int mode;
+       int optype, ischmk;
 {
 {
-       numberp back;
-       back = snarf(nbytes);
-       if (back->num_ulong[0] & magic_masks[nbytes])
-               back->num_ulong[0] -= magic_compl[nbytes];
-       return(back);
-}
-/*
- *     The following code is NOT portable from the PDP 11 to the VAX
- *     because of the byte ordering problem.
- */
-numberp snarf(nbytes)
-       int     nbytes;
-{
-       REG     int     i;
+       register char *r;
+       register int regnumber, nbytes, n;
+       union {
+               char b;
+               short w;
+               int l;
+       } displ;
+       extern char *syscalls[];
+       extern int nsys;
 
 
-       static  struct  as_number       backnumber;
-       static  struct  as_number       znumber;        /* init'ed to 0 */
+       regnumber = OC_REGEXT(mode);
+       r = regname[regnumber];
+       switch (OC_AMEXT(mode)) {
+
+       case OC_IMM0: case OC_IMM1:
+       case OC_IMM2: case OC_IMM3:
+               savevar(mode);
+               printc('$');
+#ifdef notyet
+               if (ty_float[A_TYPEXT(optype)])
+                       prints(fltimm[mode]);
+               else if (ischmk && (u_int)mode < nsys && syscalls[mode])
+                       prints(syscalls[mode]);
+               else
+                       adbprintf("%V", mode);
+#else
+               switch (A_TYPEXT(optype)) {
 
 
-       backnumber = znumber;
-       for (i = 0; i < nbytes; i++)
-               backnumber.num_uchar[i] = snarfuchar();
-       return(&backnumber);
-}
-/*
- *     Read one single character, and advance the dot
- */
-u_char snarfuchar()
-{
-       u_char  back;
-       /*
-        *      assert: bchkget and inkdot don't have side effects
-        */
-       back = (u_char)bchkget(inkdot(incp), idsp);
-       incp += 1;
-       return(back);
-}
-/*
- *     normal operand; return non zero pointer to register
- *     name if this is an index instruction.
- */
-char *operandout(mode, optype)
-       u_char  mode;
-       u_char  optype;
-{
-       char    *r;
-       int     regnumber;
-       int     nbytes;
+               case TYPF:
+               case TYPD:
+               case TYPG:
+               case TYPH:
+                       prints(fltimm[mode]);
+                       break;
+
+               default:
+                       if (ischmk && (u_int)mode < nsys && syscalls[mode])
+                               prints(syscalls[mode]);
+                       else
+                               adbprintf("%V", mode);
+                       break;
+               }
+#endif
+               return (0);
 
 
-       regnumber = OC_REGEXT(mode);
-       r = insregname(regnumber);
-       switch (OC_AMEXT(mode)){
-       case OC_IMM0:
-       case OC_IMM1:
-       case OC_IMM2:
-       case OC_IMM3:
-               shortliteral(mode, optype);
-               return(0);
        case OC_INDEX:
        case OC_INDEX:
-               return(r);              /* will be printed later */
+               return (r);     /* will be printed later */
+
        case OC_REG:
        case OC_REG:
-               printf("%s", r);
-               return(0);
+               adbprintf("%s", r);
+               return (0);
+
        case OC_DREG:
        case OC_DREG:
-               printf("(%s)", r);
-               return(0);
+               adbprintf("(%s)", r);
+               return (0);
+
        case OC_ADREG:
        case OC_ADREG:
-               printf("-(%s)", r);
-               return(0);
+               adbprintf("-(%s)", r);
+               return (0);
+
        case OC_DAIREG:
                printc('*');
        case OC_DAIREG:
                printc('*');
+               /* FALLTHROUGH */
+
        case OC_AIREG:
        case OC_AIREG:
-               if (regnumber == R_PC){
-                       pcimmediate(mode, optype);
-               } else {
-                       printf("(%s)+", r);
+               if (regnumber != R_PC) {
+                       adbprintf("(%s)+", r);
+                       return (0);
                }
                }
-               return(0);
+               /* PC immediate */
+               printc('$');
+               if (mode == OC_CONS(OC_DAIREG, R_PC))
+                       /* PC absolute, always 4 bytes */
+                       nbytes = 4;
+               else {
+                       nbytes = ty_nbyte[A_TYPEXT(optype)];
+                       if (ty_NORELOC[A_TYPEXT(optype)]) {
+                               bignumprint(nbytes, optype);
+                               return (0);
+                       }
+               }
+               break;
+
        case OC_DBDISP:
                printc('*');
        case OC_DBDISP:
                printc('*');
+               /* FALLTHROUGH */
+
        case OC_BDISP:
                nbytes = 1;
                break;
        case OC_BDISP:
                nbytes = 1;
                break;
+
        case OC_DWDISP:
                printc('*');
        case OC_DWDISP:
                printc('*');
+               /* FALLTHROUGH */
+
        case OC_WDISP:
                nbytes = 2;
                break;
        case OC_WDISP:
                nbytes = 2;
                break;
+
        case OC_DLDISP:
                printc('*');
        case OC_DLDISP:
                printc('*');
+               /* FALLTHROUGH */
+
        case OC_LDISP:
                nbytes = 4;
                break;
        case OC_LDISP:
                nbytes = 4;
                break;
-       }
-       dispaddress(snarfreloc(nbytes), mode);
-       return(0);
-}
 
 
-dispaddress(valuep, mode)
-       numberp valuep;
-       u_char  mode;
-{
-       int     regnumber = OC_REGEXT(mode);
-
-       switch(OC_AMEXT(mode)){
-       case OC_BDISP:
-       case OC_DBDISP:
-       case OC_WDISP:
-       case OC_DWDISP:
-       case OC_LDISP:
-       case OC_DLDISP:
-               if (regnumber == R_PC){
-                       /* PC offset addressing */
-                       valuep->num_ulong[0] += inkdot(incp);
-               }
-       }
-#ifdef ADB
-       if (regnumber == R_PC)
-               psymoff(valuep->num_ulong[0], type, &insoutfmt[0]);
-       else {                          /* } */
-               printf(LPRMODE, valuep->num_ulong[0]);
-               printf(insoutfmt);
-#endif ADB
-#ifdef SDB
-       if(psymoff(valuep->num_ulong[0], regnumber, &insoutfmt[0])
-          && (regnumber != R_PC)){
-#endif SDB
-               printf("(%s)", insregname(regnumber));
-       }
-       savevar((long)valuep->num_ulong[0]);
-}
-/*
- *     get a register name
- */
-char *insregname(regnumber)
-       int     regnumber;
-{
-       char    *r;
-       r = regname[regnumber];
-#ifdef SDB
-       if (   (insoutfmt[0] == 'i')
-           && (regnumber >= 6)
-           && (regnumber <= 11)
-           && (adrtoregvar(regnumber, procp) != -1)) {
-               r = sl_name;
+       default:
+               panic("operandout 1");
+               /* NOTREACHED */
        }
        }
-#endif SDB
-       return(r);
-}
-/*
- *     print out a short literal
- */
-shortliteral(mode, optype)
-       u_char  mode;
-       u_char  optype;
-{
-       savevar((long)mode);
-       switch(A_TYPEXT(optype)){
-       case TYPF:
-       case TYPD:
-       case TYPG:
-       case TYPH:
-               printf("$%s", fltimm[mode]);
+
+       /*
+        * Print a displacement format.
+        */
+       getsomebytes(&displ, nbytes);
+       switch (nbytes) {
+       case 1:
+               n = displ.b;
                break;
                break;
-       default:
-#ifdef ADB
-               printf("$%r", mode);
-#endif ADB
-#ifdef SDB
-               printf("$%d", mode);
-#endif SDB
+       case 2:
+               n = displ.w;
+               break;
+       case 4:
+               n = displ.l;
                break;
                break;
+       default:
+               panic("operandout 2");
+               /* NOTREACHED */
        }
        }
-}
+       if (regnumber == R_PC) {
+               switch (OC_AMEXT(mode)) {
 
 
-pcimmediate(mode, optype)
-       u_char  mode;
-       u_char  optype;
-{
-       int     nbytes;
+               case OC_DAIREG:
+                       if (ischmk && (u_int)n < nsys && syscalls[n]) {
+                               prints(syscalls[n]);
+                               return (0);
+                       }
+                       break;
 
 
-       printc('$');
-       if (mode == OC_CONS(OC_DAIREG, R_PC)){  /* PC absolute, always 4 bytes*/
-               dispaddress(snarfreloc(4), mode);
-               return;
-       }
-       nbytes = ty_nbyte[A_TYPEXT(optype)];
-       if (! ty_NORELOC[A_TYPEXT(optype)]){
-               dispaddress(snarfreloc(nbytes), mode);
-               return;
-       }
-       bignumprint(nbytes, optype);
+               case OC_BDISP: case OC_DBDISP:
+               case OC_WDISP: case OC_DWDISP:
+               case OC_LDISP: case OC_DLDISP:
+                       /* PC offset */
+                       n += dot + dotoff;
+               }
+               psymoff("%V", (addr_t)n, SP_DATA, maxoff, "");
+       } else
+               adbprintf("%V(%s)", (expr_t)n, regname[regnumber]);
+       savevar(n);
+       return (0);
 }
 
 }
 
+/*
+ * Print an F-float, D-float, G-float, H-float, quadword, or octaword.
+ * F- and D-floating values are printed as themselves, unless they are
+ * reserved operand bit patterns; these, and the others, are printed
+ * instead in hex, with leading zeroes suppressed.
+ */
+static
 bignumprint(nbytes, optype)
 bignumprint(nbytes, optype)
-       int     nbytes;
-       u_char  optype;
+       int nbytes, optype;
 {
 {
-       numberp valuep;
-       int     leading_zero = 1;
-       REG     int     bindex;
-       REG     int     nindex;
-       REG     int     ch;
-
-       valuep = snarf(nbytes);
-       switch(A_TYPEXT(optype)){
-       case TYPF:      
-               printf("0f%f", valuep->num_num.numFf_float.Ff_value);
+       register char *p;
+       register int i;
+       union {
+               float   f;      /* if f-floating */
+               double  d;      /* if d-floating */
+               u_char  c[16];  /* if G, H, Q, or O */
+       } n;
+       char expbuf[4*8+1];     /* max 4 8-character hex ints */
+       static char tohex[] = "0123456789abcdef";
+
+       /*
+        * Read in the number, then figure out how to print it.
+        */
+       getsomebytes(&n, nbytes);
+       switch (A_TYPEXT(optype)) {
+
+       case TYPF:
+               if ((p = checkfloat((caddr_t)&n.f, 0)) == NULL) {
+                       adbprintf("0f%f", n.f);
+                       return;
+               }
+               adbprintf("%s 0f::", p);
                break;
                break;
+
        case TYPD:
        case TYPD:
-               printf("0d%f", valuep->num_num.numFd_float.Fd_value);
+               if ((p = checkfloat((caddr_t)&n.d, 1)) == NULL) {
+                       adbprintf("0d%f", n.d);
+                       return;
+               }
+               adbprintf("%s 0d::", p);
                break;
                break;
+
        case TYPG:
        case TYPG:
-               printf("0g::"); goto qprint;
+               adbprintf("0g::");
+               break;
+
        case TYPH:
        case TYPH:
-               printf("0h::"); goto qprint;
+               adbprintf("0h::");
+               break;
+
        case TYPQ:
        case TYPO:
        case TYPQ:
        case TYPO:
-       qprint:
-               for (bindex = nbytes - 1; bindex >= 0; --bindex){
-                       for (nindex = 4; nindex >= 0; nindex -= 4){
-                               ch = (valuep->num_uchar[bindex] >> nindex);
-                               ch &= 0x0F;
-                               if ( ! (leading_zero &= (ch == 0) ) ){
-                                       if (ch <= 0x09)
-                                               printc(ch + '0');
-                                       else
-                                               printc(ch - 0x0A + 'a');
-                               }
-                       }
-               }
                break;
                break;
-       }
-}
-#ifdef SDB
 
 
-L_INT inkdot(incr)
-       int     incr;
-{
-       L_INT           newdot;
-
-       newdot = dot + incr;
-       return(newdot);
-}
-
-printc(c)
-       char c;
-{
-       printf("%c", c);
-}
-
-psymoff(v, regnumber, fmt)
-       L_INT   v;
-       char    *fmt;
-{
-       struct  proct   *procp;
-       REG     int diff;
-       if (fmt[0] == 'i') {
-               switch(regnumber){
-               case 12:        /* parameter */
-                       if ((diff = adrtoparam((ADDR) v, adrtoprocp(dot)))
-                                       != -1) {
-                               printf("%s", sl_name);
-                               prdiff(diff);
-                               return(0);
-                       }
-                       break;
-               case 13:        /* local */
-                       if ((diff = adrtolocal((ADDR) -v, adrtoprocp(dot))
-                                       ) != -1) {
-                               printf("%s", sl_name);
-                               prdiff(diff);
-                               return(0);
-                       }
-                       break;
-               default:
-                       break;
-               }
-               if (v < firstdata) {
-                       if ((procp = adrtoprocp((ADDR) v)) != badproc) {
-                               prlnoff(procp, v);
-                               return(0);
-                       }
-               } else {
-                       if ((diff = adrtoext((ADDR) v)) != -1) {
-                               printf("%s", sl_name);
-                               prdiff(diff);
-                               return(0);
-                       }
-               }
+       default:
+               panic("bignumprint");
        }
        }
-       prhex(v);
-       return(1);
-}
 
 
-prdiff(diff)
-{
-       if (diff) {
-               printf("+");
-               prhex(diff);
+       /*
+        * Expand the number into expbuf, then skip leading zeroes.
+        * Be careful not to skip the entire number.
+        */
+       for (p = expbuf, i = nbytes; --i >= 0;) {
+               *p++ = tohex[n.c[i] >> 4];
+               *p++ = tohex[n.c[i] & 15];
        }
        }
+       for (p = expbuf; *p == '0'; p++)
+               /* void */;
+       prints(*p ? p : p - 1);
 }
 }
-
-#endif SDB