* i386-dis.c (print_insn_i8086): New routine to disassemble using
authorStu Grossman <grossman@cygnus>
Fri, 12 Jul 1996 17:15:38 +0000 (17:15 +0000)
committerStu Grossman <grossman@cygnus>
Fri, 12 Jul 1996 17:15:38 +0000 (17:15 +0000)
the 8086 instruction set.
* i386-dis.c:  General cleanups.  Make most things static.  Add
prototypes.  Get rid of static variables aflags and dflags.  Pass
them as args (to almost everything).

opcodes/ChangeLog
opcodes/i386-dis.c

index f1561ff8d4ab92cae54e65e7f2da9743e5e4a4b4..21b2f34b9a6484dc56b6997facdd037f056a3253 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jul 12 10:12:01 1996  Stu Grossman  (grossman@critters.cygnus.com)
+
+       * i386-dis.c (print_insn_i8086):  New routine to disassemble using
+       the 8086 instruction set.
+       * i386-dis.c:  General cleanups.  Make most things static.  Add
+       prototypes.  Get rid of static variables aflags and dflags.  Pass
+       them as args (to almost everything).
+
 Thu Jul 11 11:58:44 1996  Jeffrey A Law  (law@cygnus.com)
 
        * h8300-dis.c (bfd_h8_disassemble): Handle macregs in ldmac insns.
index b21e27622df2867cd802a41d51a434099e5a01dc..6fcc724a8fdd32f60b0b5bfb357aad4f11dc62ef 100644 (file)
@@ -1,5 +1,5 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988, 1989, 1991, 1993, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1988, 89, 91, 93, 94, 95, 1996 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -139,13 +139,19 @@ fetch_data (info, addr)
 #define fs OP_REG, fs_reg
 #define gs OP_REG, gs_reg
 
-int OP_E(), OP_indirE(), OP_G(), OP_I(), OP_sI(), OP_REG();
-int OP_J(), OP_SEG();
-int OP_DIR(), OP_OFF(), OP_DSSI(), OP_ESDI(), OP_ONE(), OP_C();
-int OP_D(), OP_T(), OP_rm();
+typedef int op_rtn PARAMS ((int bytemode, int aflag, int dflag));
 
-static void dofloat (), putop (), append_prefix (), set_op ();
-static int get16 (), get32 ();
+static op_rtn OP_E, OP_G, OP_I, OP_indirE, OP_sI, OP_REG, OP_J, OP_DIR, OP_OFF;
+static op_rtn OP_ESDI, OP_DSSI, OP_SEG, OP_ONE, OP_C, OP_D, OP_T, OP_rm, OP_ST;
+static op_rtn OP_STi;
+
+static void append_prefix PARAMS ((void));
+static void set_op PARAMS ((int op));
+static void putop PARAMS ((char *template, int aflag, int dflag));
+static void dofloat PARAMS ((int aflag, int dflag));
+static int get16 PARAMS ((void));
+static int get32 PARAMS ((void));
+static void ckprefix PARAMS ((void));
 
 #define b_mode 1
 #define v_mode 2
@@ -212,15 +218,15 @@ static int get16 (), get32 ();
 
 struct dis386 {
   char *name;
-  int (*op1)();
+  op_rtn *op1;
   int bytemode1;
-  int (*op2)();
+  op_rtn *op2;
   int bytemode2;
-  int (*op3)();
+  op_rtn *op3;
   int bytemode3;
 };
 
-struct dis386 dis386[] = {
+static struct dis386 dis386[] = {
   /* 00 */
   { "addb",    Eb, Gb },
   { "addS",    Ev, Gv },
@@ -511,7 +517,7 @@ struct dis386 dis386[] = {
   { GRP5 },
 };
 
-struct dis386 dis386_twobyte[] = {
+static struct dis386 dis386_twobyte[] = {
   /* 00 */
   { GRP6 },
   { GRP7 },
@@ -732,7 +738,7 @@ static disassemble_info *the_info;
 static int mod;
 static int rm;
 static int reg;
-static void oappend ();
+static void oappend PARAMS ((char *s));
 
 static char *names32[]={
   "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
@@ -746,8 +752,11 @@ static char *names8[] = {
 static char *names_seg[] = {
   "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
 };
+static char *index16[] = {
+  "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
+};
 
-struct dis386 grps[][8] = {
+static struct dis386 grps[][8] = {
   /* GRP1b */
   {
     { "addb",  Eb, Ib },
@@ -1004,9 +1013,6 @@ ckprefix ()
     }
 }
 
-static int dflag;
-static int aflag;              
-
 static char op1out[100], op2out[100], op3out[100];
 static int op_address[3], op_ad, op_index[3];
 static int start_pc;
@@ -1021,10 +1027,28 @@ static int start_pc;
  * The function returns the length of this instruction in bytes.
  */
 
+int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
+                           int dflag));
 int
 print_insn_i386 (pc, info)
      bfd_vma pc;
      disassemble_info *info;
+{
+  print_insn_x86 (pc, info, 1, 1);
+}
+
+int
+print_insn_i8086 (pc, info)
+     bfd_vma pc;
+     disassemble_info *info;
+{
+  print_insn_x86 (pc, info, 0, 0);
+}
+
+int
+print_insn_x86 (pc, info, aflag, dflag)
+     bfd_vma pc;
+     disassemble_info *info;
 {
   struct dis386 *dp;
   int i;
@@ -1080,10 +1104,6 @@ print_insn_i386 (pc, info)
       return (1);
     }
   
-  /* these would be initialized to 0 if disassembling for 8086 or 286 */
-  dflag = 1;
-  aflag = 1;
-  
   if (prefixes & PREFIX_DATA)
     dflag ^= 1;
   
@@ -1116,29 +1136,29 @@ print_insn_i386 (pc, info)
 
   if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
     {
-      dofloat ();
+      dofloat (aflag, dflag);
     }
   else
     {
       if (dp->name == NULL)
        dp = &grps[dp->bytemode1][reg];
       
-      putop (dp->name);
+      putop (dp->name, aflag, dflag);
       
       obufp = op1out;
       op_ad = 2;
       if (dp->op1)
-       (*dp->op1)(dp->bytemode1);
+       (*dp->op1)(dp->bytemode1, aflag, dflag);
       
       obufp = op2out;
       op_ad = 1;
       if (dp->op2)
-       (*dp->op2)(dp->bytemode2);
+       (*dp->op2)(dp->bytemode2, aflag, dflag);
       
       obufp = op3out;
       op_ad = 0;
       if (dp->op3)
-       (*dp->op3)(dp->bytemode3);
+       (*dp->op3)(dp->bytemode3, aflag, dflag);
     }
   
   obufp = obuf + strlen (obuf);
@@ -1197,7 +1217,7 @@ print_insn_i386 (pc, info)
   return (codep - inbuf);
 }
 
-char *float_mem[] = {
+static char *float_mem[] = {
   /* d8 */
   "fadds",
   "fmuls",
@@ -1274,7 +1294,6 @@ char *float_mem[] = {
 
 #define ST OP_ST, 0
 #define STi OP_STi, 0
-int OP_ST(), OP_STi();
 
 #define FGRPd9_2 NULL, NULL, 0
 #define FGRPd9_4 NULL, NULL, 1
@@ -1286,7 +1305,7 @@ int OP_ST(), OP_STi();
 #define FGRPde_3 NULL, NULL, 7
 #define FGRPdf_4 NULL, NULL, 8
 
-struct dis386 float_reg[][8] = {
+static struct dis386 float_reg[][8] = {
   /* d8 */
   {
     { "fadd",  ST, STi },
@@ -1378,7 +1397,7 @@ struct dis386 float_reg[][8] = {
 };
 
 
-char *fgrps[][8] = {
+static char *fgrps[][8] = {
   /* d9_2  0 */
   {
     "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
@@ -1427,7 +1446,9 @@ char *fgrps[][8] = {
 };
 
 static void
-dofloat ()
+dofloat (aflag, dflag)
+     int aflag;
+     int dflag;
 {
   struct dis386 *dp;
   unsigned char floatop;
@@ -1436,9 +1457,9 @@ dofloat ()
   
   if (mod != 3)
     {
-      putop (float_mem[(floatop - 0xd8) * 8 + reg]);
+      putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
       obufp = op1out;
-      OP_E (v_mode);
+      OP_E (v_mode, aflag, dflag);
       return;
     }
   codep++;
@@ -1446,7 +1467,7 @@ dofloat ()
   dp = &float_reg[floatop - 0xd8][reg];
   if (dp->name == NULL)
     {
-      putop (fgrps[dp->bytemode1][rm]);
+      putop (fgrps[dp->bytemode1][rm], aflag, dflag);
       /* instruction fnstsw is only one with strange arg */
       if (floatop == 0xdf
          && FETCH_DATA (the_info, codep + 1)
@@ -1455,29 +1476,33 @@ dofloat ()
     }
   else
     {
-      putop (dp->name);
+      putop (dp->name, aflag, dflag);
       obufp = op1out;
       if (dp->op1)
-       (*dp->op1)(dp->bytemode1);
+       (*dp->op1)(dp->bytemode1, aflag, dflag);
       obufp = op2out;
       if (dp->op2)
-       (*dp->op2)(dp->bytemode2);
+       (*dp->op2)(dp->bytemode2, aflag, dflag);
     }
 }
 
 /* ARGSUSED */
-int
-OP_ST (ignore)
+static int
+OP_ST (ignore, aflag, dflag)
      int ignore;
+     int aflag;
+     int dflag;
 {
   oappend ("%st");
   return (0);
 }
 
 /* ARGSUSED */
-int
-OP_STi (ignore)
+static int
+OP_STi (ignore, aflag, dflag)
      int ignore;
+     int aflag;
+     int dflag;
 {
   sprintf (scratchbuf, "%%st(%d)", rm);
   oappend (scratchbuf);
@@ -1487,8 +1512,10 @@ OP_STi (ignore)
 
 /* capital letters in template are macros */
 static void
-putop (template)
+putop (template, aflag, dflag)
      char *template;
+     int aflag;
+     int dflag;
 {
   char *p;
   
@@ -1500,7 +1527,7 @@ putop (template)
          *obufp++ = *p;
          break;
        case 'C':               /* For jcxz/jecxz */
-         if (aflag == 0)
+         if (aflag)
            *obufp++ = 'e';
          break;
        case 'N':
@@ -1545,33 +1572,27 @@ append_prefix ()
     oappend ("%gs:");
 }
 
-int
-OP_indirE (bytemode)
+static int
+OP_indirE (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   oappend ("*");
-  OP_E (bytemode);
-  return (0);
+  return OP_E (bytemode, aflag, dflag);
 }
 
-int
-OP_E (bytemode)
+static int
+OP_E (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   int disp;
-  int havesib;
-  int base;
-  int index;
-  int scale;
-  int havebase;
-  
+
   /* skip mod/rm byte */
   codep++;
-  
-  havesib = 0;
-  havebase = 0;
-  disp = 0;
-  
+
   if (mod == 3)
     {
       switch (bytemode)
@@ -1592,90 +1613,114 @@ OP_E (bytemode)
          oappend ("<bad dis table>");
          break;
        }
-      return (0);
+      return 0;
     }
-  
+
+  disp = 0;
   append_prefix ();
-  if (rm == 4)
+
+  if (aflag) /* 32 bit address mode */
     {
-      havesib = 1;
+      int havesib;
+      int havebase;
+      int base;
+      int index;
+      int scale;
+
+      havesib = 0;
       havebase = 1;
-      FETCH_DATA (the_info, codep + 1);
-      scale = (*codep >> 6) & 3;
-      index = (*codep >> 3) & 7;
-      base = *codep & 7;
-      codep++;
-    }
-  
-  switch (mod)
-    {
-    case 0:
-      switch (rm)
+      base = rm;
+
+      if (base == 4)
+       {
+         havesib = 1;
+         FETCH_DATA (the_info, codep + 1);
+         scale = (*codep >> 6) & 3;
+         index = (*codep >> 3) & 7;
+         base = *codep & 7;
+         codep++;
+       }
+
+      switch (mod)
        {
-       case 4:
-         /* implies havesib and havebase */
-         if (base == 5) {
-           havebase = 0;
-           disp = get32 ();
-         }
+       case 0:
+         if (base == 5)
+           {
+             havebase = 0;
+             disp = get32 ();
+           }
          break;
-       case 5:
-         disp = get32 ();
+       case 1:
+         FETCH_DATA (the_info, codep + 1);
+         disp = *(char *)codep++;
          break;
-       default:
-         havebase = 1;
-         base = rm;
+       case 2:
+         disp = get32 ();
          break;
        }
-      break;
-    case 1:
-      FETCH_DATA (the_info, codep + 1);
-      disp = *(char *)codep++;
-      if (rm != 4)
-       {
-         havebase = 1;
-         base = rm;
-       }
-      break;
-    case 2:
-      disp = get32 ();
-      if (rm != 4)
+
+      if (mod != 0 || base == 5)
        {
-         havebase = 1;
-         base = rm;
+         sprintf (scratchbuf, "0x%x", disp);
+         oappend (scratchbuf);
        }
-      break;
-    }
-  
-  if (mod != 0 || rm == 5 || (havesib && base == 5))
-    {
-      sprintf (scratchbuf, "0x%x", disp);
-      oappend (scratchbuf);
-    }
-  
-  if (havebase || havesib) 
-    {
-      oappend ("(");
-      if (havebase)
-       oappend (names32[base]);
-      if (havesib) 
+
+      if (havebase || (havesib && (index != 4 || scale != 0)))
        {
-         if (index != 4) 
+         oappend ("(");
+         if (havebase)
+           oappend (names32[base]);
+         if (havesib)
            {
-             sprintf (scratchbuf, ",%s", names32[index]);
+             if (index != 4)
+               {
+                 sprintf (scratchbuf, ",%s", names32[index]);
+                 oappend (scratchbuf);
+               }
+             sprintf (scratchbuf, ",%d", 1 << scale);
              oappend (scratchbuf);
            }
-         sprintf (scratchbuf, ",%d", 1 << scale);
+         oappend (")");
+       }
+    }
+  else
+    { /* 16 bit address mode */
+      switch (mod)
+       {
+       case 0:
+         if (rm == 6)
+           disp = (short) get16 ();
+         break;
+       case 1:
+         FETCH_DATA (the_info, codep + 1);
+         disp = *(char *)codep++;
+         break;
+       case 2:
+         disp = (short) get16 ();
+         break;
+       }
+
+      if (mod != 0 || rm == 6)
+       {
+         sprintf (scratchbuf, "0x%x", disp);
          oappend (scratchbuf);
        }
-      oappend (")");
+
+      if (mod != 0 || rm != 6)
+       {
+         oappend ("(");
+         oappend (index16[rm]);
+         oappend (")");
+       }
     }
-  return (0);
+  return 0;
 }
 
-int
-OP_G (bytemode)
+static int
+OP_G (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   switch (bytemode) 
     {
@@ -1733,9 +1778,11 @@ set_op (op)
   op_address[op_ad] = op;
 }
 
-int
-OP_REG (code)
+static int
+OP_REG (code, aflag, dflag)
      int code;
+     int aflag;
+     int dflag;
 {
   char *s;
   
@@ -1769,9 +1816,11 @@ OP_REG (code)
   return (0);
 }
 
-int
-OP_I (bytemode)
+static int
+OP_I (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   int op;
   
@@ -1799,9 +1848,11 @@ OP_I (bytemode)
   return (0);
 }
 
-int
-OP_sI (bytemode)
+static int
+OP_sI (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   int op;
   
@@ -1829,9 +1880,11 @@ OP_sI (bytemode)
   return (0);
 }
 
-int
-OP_J (bytemode)
+static int
+OP_J (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   int disp;
   int mask = -1;
@@ -1866,9 +1919,11 @@ OP_J (bytemode)
 }
 
 /* ARGSUSED */
-int
-OP_SEG (dummy)
+static int
+OP_SEG (dummy, aflag, dflag)
      int dummy;
+     int aflag;
+     int dflag;
 {
   static char *sreg[] = {
     "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
@@ -1878,9 +1933,11 @@ OP_SEG (dummy)
   return (0);
 }
 
-int
-OP_DIR (size)
+static int
+OP_DIR (size, aflag, dflag)
      int size;
+     int aflag;
+     int dflag;
 {
   int seg, offset;
   
@@ -1919,12 +1976,16 @@ OP_DIR (size)
 }
 
 /* ARGSUSED */
-int
-OP_OFF (bytemode)
+static int
+OP_OFF (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   int off;
-  
+
+  append_prefix ();
+
   if (aflag)
     off = get32 ();
   else
@@ -1936,9 +1997,11 @@ OP_OFF (bytemode)
 }
 
 /* ARGSUSED */
-int
-OP_ESDI (dummy)
-    int dummy;
+static int
+OP_ESDI (dummy, aflag, dflag)
+     int dummy;
+     int aflag;
+     int dflag;
 {
   oappend ("%es:(");
   oappend (aflag ? "%edi" : "%di");
@@ -1947,9 +2010,11 @@ OP_ESDI (dummy)
 }
 
 /* ARGSUSED */
-int
-OP_DSSI (dummy)
-    int dummy;
+static int
+OP_DSSI (dummy, aflag, dflag)
+     int dummy;
+     int aflag;
+     int dflag;
 {
   oappend ("%ds:(");
   oappend (aflag ? "%esi" : "%si");
@@ -1958,18 +2023,22 @@ OP_DSSI (dummy)
 }
 
 /* ARGSUSED */
-int
-OP_ONE (dummy)
-    int dummy;
+static int
+OP_ONE (dummy, aflag, dflag)
+     int dummy;
+     int aflag;
+     int dflag;
 {
   oappend ("1");
   return (0);
 }
 
 /* ARGSUSED */
-int
-OP_C (dummy)
-    int dummy;
+static int
+OP_C (dummy, aflag, dflag)
+     int dummy;
+     int aflag;
+     int dflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%cr%d", reg);
@@ -1978,9 +2047,11 @@ OP_C (dummy)
 }
 
 /* ARGSUSED */
-int
-OP_D (dummy)
-    int dummy;
+static int
+OP_D (dummy, aflag, dflag)
+     int dummy;
+     int aflag;
+     int dflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%db%d", reg);
@@ -1989,9 +2060,11 @@ OP_D (dummy)
 }
 
 /* ARGSUSED */
-int
-OP_T (dummy)
+static int
+OP_T (dummy, aflag, dflag)
      int dummy;
+     int aflag;
+     int dflag;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%tr%d", reg);
@@ -1999,9 +2072,11 @@ OP_T (dummy)
   return (0);
 }
 
-int
-OP_rm (bytemode)
+static int
+OP_rm (bytemode, aflag, dflag)
      int bytemode;
+     int aflag;
+     int dflag;
 {
   switch (bytemode) 
     {