Remove dup inftarg.o from NATDEPFILES.
[deliverable/binutils-gdb.git] / gdb / i386-pinsn.c
index 437d44d91b92962bafce95251319c86b36c5e717..bbc622f281d6cbad2e1c16c9d91dceffcfaa3421 100644 (file)
@@ -1,22 +1,21 @@
 /* Print i386 instructions for GDB, the GNU debugger.
-   Copyright (C) 1988 Free Software Foundation, Inc.
+   Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
 
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY.  No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
+This file is part of GDB.
 
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License.  A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities.  It
-should be in a file named COPYING.  Among other things, the copyright
-notice and this notice must be preserved on all copies.
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther.  Help stamp out software hoarding!
-*/
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 /*
  * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
@@ -32,9 +31,13 @@ anyone else from sharing it farther.  Help stamp out software hoarding!
  * the Intel manual for details.
  */
 
-#include <stdio.h>
+#include "defs.h"
+
 #include <ctype.h>
 
+/* For the GDB interface at the bottom of the file... */
+#include "gdbcore.h"
+
 #define Eb OP_E, b_mode
 #define indirEb OP_indirE, b_mode
 #define Gb OP_G, b_mode
@@ -101,6 +104,8 @@ 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();
 
+static void dofloat (), putop (), append_prefix (), set_op ();
+static int get16 (), get32 ();
 
 #define b_mode 1
 #define v_mode 2
@@ -633,6 +638,7 @@ static unsigned char *codep;
 static int mod;
 static int rm;
 static int reg;
+static void oappend ();
 
 static char *names32[]={
   "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
@@ -841,6 +847,7 @@ struct dis386 grps[][8] = {
 
 static int prefixes;
 
+static void
 ckprefix ()
 {
   prefixes = 0;
@@ -895,7 +902,9 @@ 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;
+extern void fputs_filtered ();
 
 /*
  * disassemble the first instruction in 'inbuf'.  You have to make
@@ -910,13 +919,14 @@ static int start_pc;
  *   100 bytes is certainly enough, unless symbol printing is added later
  * The function returns the length of this instruction in bytes.
  */
-i386dis (pc, inbuf, outbuf)
+
+int
+i386dis (pc, inbuf, stream)
      int pc;
      unsigned char *inbuf;
-     char *outbuf;
+     FILE *stream;
 {
   struct dis386 *dp;
-  char *p;
   int i;
   int enter_instruction;
   char *first, *second, *third;
@@ -926,6 +936,8 @@ i386dis (pc, inbuf, outbuf)
   op1out[0] = 0;
   op2out[0] = 0;
   op3out[0] = 0;
+
+  op_index[0] = op_index[1] = op_index[2] = -1;
   
   start_pc = pc;
   start_codep = inbuf;
@@ -951,8 +963,7 @@ i386dis (pc, inbuf, outbuf)
       && ((*codep < 0xd8) || (*codep > 0xdf)))
     {
       /* fwait not followed by floating point instruction */
-      oappend ("fwait");
-      strcpy (outbuf, obuf);
+      fputs_filtered ("fwait", stream);
       return (1);
     }
   
@@ -990,14 +1001,17 @@ i386dis (pc, inbuf, outbuf)
       putop (dp->name);
       
       obufp = op1out;
+      op_ad = 2;
       if (dp->op1)
        (*dp->op1)(dp->bytemode1);
       
       obufp = op2out;
+      op_ad = 1;
       if (dp->op2)
        (*dp->op2)(dp->bytemode2);
       
       obufp = op3out;
+      op_ad = 0;
       if (dp->op3)
        (*dp->op3)(dp->bytemode3);
     }
@@ -1006,6 +1020,7 @@ i386dis (pc, inbuf, outbuf)
   for (i = strlen (obuf); i < 6; i++)
     oappend (" ");
   oappend (" ");
+  fputs_filtered (obuf, stream);
   
   /* enter instruction is printed with operands in the
    * same order as the intel book; everything else
@@ -1016,6 +1031,9 @@ i386dis (pc, inbuf, outbuf)
       first = op1out;
       second = op2out;
       third = op3out;
+      op_ad = op_index[0];
+      op_index[0] = op_index[2];
+      op_index[2] = op_ad;
     }
   else
     {
@@ -1026,23 +1044,31 @@ i386dis (pc, inbuf, outbuf)
   needcomma = 0;
   if (*first)
     {
-      oappend (first);
+      if (op_index[0] != -1)
+       print_address (op_address[op_index[0]], stream);
+      else
+       fputs_filtered (first, stream);
       needcomma = 1;
     }
   if (*second)
     {
       if (needcomma)
-       oappend (",");
-      oappend (second);
+       fputs_filtered (",", stream);
+      if (op_index[1] != -1)
+       print_address (op_address[op_index[1]], stream);
+      else
+       fputs_filtered (second, stream);
       needcomma = 1;
     }
   if (*third)
     {
       if (needcomma)
-       oappend (",");
-      oappend (third);
+       fputs_filtered (",", stream);
+      if (op_index[2] != -1)
+       print_address (op_address[op_index[2]], stream);
+      else
+       fputs_filtered (third, stream);
     }
-  strcpy (outbuf, obuf);
   return (codep - inbuf);
 }
 
@@ -1275,7 +1301,7 @@ char *fgrps[][8] = {
   },
 };
 
-
+static void
 dofloat ()
 {
   struct dis386 *dp;
@@ -1313,20 +1339,27 @@ dofloat ()
 }
 
 /* ARGSUSED */
+int
 OP_ST (ignore)
+     int ignore;
 {
   oappend ("%st");
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_STi (ignore)
+     int ignore;
 {
   sprintf (scratchbuf, "%%st(%d)", rm);
   oappend (scratchbuf);
+  return (0);
 }
 
 
 /* capital letters in template are macros */
+static void
 putop (template)
      char *template;
 {
@@ -1359,14 +1392,16 @@ putop (template)
   *obufp = 0;
 }
 
+static void
 oappend (s)
-char *s;
+     char *s;
 {
   strcpy (obufp, s);
   obufp += strlen (s);
   *obufp = 0;
 }
 
+static void
 append_prefix ()
 {
   if (prefixes & PREFIX_CS)
@@ -1383,17 +1418,21 @@ append_prefix ()
     oappend ("%gs:");
 }
 
+int
 OP_indirE (bytemode)
+     int bytemode;
 {
   oappend ("*");
   OP_E (bytemode);
+  return (0);
 }
 
+int
 OP_E (bytemode)
+     int bytemode;
 {
   int disp;
   int havesib;
-  int didoutput = 0;
   int base;
   int index;
   int scale;
@@ -1426,7 +1465,7 @@ OP_E (bytemode)
          oappend ("<bad dis table>");
          break;
        }
-      return;
+      return (0);
     }
   
   append_prefix ();
@@ -1481,7 +1520,7 @@ OP_E (bytemode)
   
   if (mod != 0 || rm == 5 || (havesib && base == 5))
     {
-      sprintf (scratchbuf, "%d", disp);
+      sprintf (scratchbuf, "0x%x", disp);
       oappend (scratchbuf);
     }
   
@@ -1502,9 +1541,12 @@ OP_E (bytemode)
        }
       oappend (")");
     }
+  return (0);
 }
 
+int
 OP_G (bytemode)
+     int bytemode;
 {
   switch (bytemode) 
     {
@@ -1527,8 +1569,10 @@ OP_G (bytemode)
       oappend ("<internal disassembler error>");
       break;
     }
+  return (0);
 }
 
+static int
 get32 ()
 {
   int x = 0;
@@ -1540,6 +1584,7 @@ get32 ()
   return (x);
 }
 
+static int
 get16 ()
 {
   int x = 0;
@@ -1549,7 +1594,17 @@ get16 ()
   return (x);
 }
 
+static void
+set_op (op)
+     int op;
+{
+  op_index[op_ad] = op_ad;
+  op_address[op_ad] = op;
+}
+
+int
 OP_REG (code)
+     int code;
 {
   char *s;
   
@@ -1580,9 +1635,12 @@ OP_REG (code)
       break;
     }
   oappend (s);
+  return (0);
 }
 
+int
 OP_I (bytemode)
+     int bytemode;
 {
   int op;
   
@@ -1602,13 +1660,16 @@ OP_I (bytemode)
       break;
     default:
       oappend ("<internal disassembler error>");
-      return;
+      return (0);
     }
   sprintf (scratchbuf, "$0x%x", op);
   oappend (scratchbuf);
+  return (0);
 }
 
+int
 OP_sI (bytemode)
+     int bytemode;
 {
   int op;
   
@@ -1628,13 +1689,16 @@ OP_sI (bytemode)
       break;
     default:
       oappend ("<internal disassembler error>");
-      return;
+      return (0);
     }
   sprintf (scratchbuf, "$0x%x", op);
   oappend (scratchbuf);
+  return (0);
 }
 
+int
 OP_J (bytemode)
+     int bytemode;
 {
   int disp;
   int mask = -1;
@@ -1657,26 +1721,32 @@ OP_J (bytemode)
        }
       break;
     default:
-      oappend ("<internal disassembelr error>");
-      return;
+      oappend ("<internal disassembler error>");
+      return (0);
     }
-  
-  sprintf (scratchbuf, "0x%x",
-          (start_pc + codep - start_codep + disp) & mask);
+  disp = (start_pc + codep - start_codep + disp) & mask;
+  set_op (disp);
+  sprintf (scratchbuf, "0x%x", disp);
   oappend (scratchbuf);
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_SEG (dummy)
+     int dummy;
 {
   static char *sreg[] = {
     "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
   };
 
   oappend (sreg[reg]);
+  return (0);
 }
 
+int
 OP_DIR (size)
+     int size;
 {
   int seg, offset;
   
@@ -1702,18 +1772,22 @@ OP_DIR (size)
       else
        offset = (short)get16 ();
       
-      sprintf (scratchbuf, "0x%x",
-              start_pc + codep - start_codep + offset);
+      offset = start_pc + codep - start_codep + offset;
+      set_op (offset);
+      sprintf (scratchbuf, "0x%x", offset);
       oappend (scratchbuf);
       break;
     default:
       oappend ("<internal disassembler error>");
       break;
     }
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_OFF (bytemode)
+     int bytemode;
 {
   int off;
   
@@ -1724,55 +1798,76 @@ OP_OFF (bytemode)
   
   sprintf (scratchbuf, "0x%x", off);
   oappend (scratchbuf);
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_ESDI (dummy)
+    int dummy;
 {
   oappend ("%es:(");
   oappend (aflag ? "%edi" : "%di");
   oappend (")");
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_DSSI (dummy)
+    int dummy;
 {
   oappend ("%ds:(");
   oappend (aflag ? "%esi" : "%si");
   oappend (")");
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_ONE (dummy)
+    int dummy;
 {
   oappend ("1");
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_C (dummy)
+    int dummy;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%cr%d", reg);
   oappend (scratchbuf);
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_D (dummy)
+    int dummy;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%db%d", reg);
   oappend (scratchbuf);
+  return (0);
 }
 
 /* ARGSUSED */
+int
 OP_T (dummy)
+     int dummy;
 {
   codep++; /* skip mod/rm */
   sprintf (scratchbuf, "%%tr%d", reg);
   oappend (scratchbuf);
+  return (0);
 }
 
+int
 OP_rm (bytemode)
+     int bytemode;
 {
   switch (bytemode) 
     {
@@ -1783,31 +1878,20 @@ OP_rm (bytemode)
       oappend (names16[rm]);
       break;
     }
+  return (0);
 }
        
-/* GDB interface */
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "frame.h"
-#include "inferior.h"
-
 #define MAXLEN 20
+
+int
 print_insn (memaddr, stream)
      CORE_ADDR memaddr;
      FILE *stream;
 {
   unsigned char buffer[MAXLEN];
-  /* should be expanded if disassembler prints symbol names */
-  char outbuf[100];
-  int n;
-  
-  read_memory (memaddr, buffer, MAXLEN);
-  
-  n = i386dis ((int)memaddr, buffer, outbuf);
   
-  fputs (outbuf, stream);
+  read_memory (memaddr, (char *) buffer, MAXLEN);
   
-  return (n);
+  return (i386dis ((int)memaddr, buffer, stream));
 }
 
This page took 0.030234 seconds and 4 git commands to generate.