fix stabs.texinfo xref bugs
[deliverable/binutils-gdb.git] / gdb / hppa-pinsn.c
index 5d8df98d18905636292590b2470c8021fa8b0775..87d5e7a6fe124a82c1d109653f4a914745a1c089 100644 (file)
@@ -1,58 +1,67 @@
 /* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
-   Copyright (C) 1989, 1990 Free Software Foundation, Inc.
+   Copyright 1989, 1990, 1992 Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
    University of Utah (pa-gdb-bugs@cs.utah.edu).
 
-This file is part of GDB, the GNU disassembler.
+This file is part of GDB.
 
-GDB is free software; you can redistribute it and/or modify
+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 1, or (at your option)
-any later version.
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
 
-GDB is distributed in the hope that it will be useful,
+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 GDB; see the file COPYING.  If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include <stdio.h>
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
 #include "opcode/hppa.h"
 
-char *control_reg[] = {"rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
-                      "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
-                      "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
-                      "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
-                      "tr4", "tr5", "tr6", "tr7"
-                      };
-
-char *compare_cond_names[] = {"", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
-                             ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
-                             ",>>", ",nsv", ",ev"
-                             };
-char *add_cond_names[] = {"", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
-                         ",od", ",tr", ",<>", ",>=", ",>", ",uv",
-                         ",vnz", ",nsv", ",ev"
-                         };
-char *logical_cond_names[] = {"", ",=", ",<", ",<=", 0, 0, 0, ",od",
-                             ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
-char *unit_cond_names[] = {"", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
-                          ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
-                          };
-char *shift_cond_names[] = {"", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"};
-
-char *index_compl_names[] = {"", ",m", ",s", ",sm"};
-char *short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
-char *short_bytes_compl_names[] = {"", ",b,m", ",e", ",e,m"};
-char *float_format_names[] = {",sgl", ",dbl", ",quad"};
-char *float_comp_names[] =
+static char *control_reg[] =
+{  "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
+   "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
+   "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
+   "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
+   "tr4", "tr5", "tr6", "tr7"
+   };
+
+static char *compare_cond_names[] =
+{  "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv",
+   ",od", ",tr", ",<>", ",>=", ",>", ",>>=",
+   ",>>", ",nsv", ",ev"
+   };
+
+static char *add_cond_names[] =
+{  "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv",
+   ",od", ",tr", ",<>", ",>=", ",>", ",uv",
+   ",vnz", ",nsv", ",ev"
+   };
+
+static char *logical_cond_names[] =
+{  "", ",=", ",<", ",<=", 0, 0, 0, ",od",
+   ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"
+   };
+
+static char *unit_cond_names[] =
+{  "", 0, ",sbz", ",shz", ",sdc", 0, ",sbc", ",shc",
+   ",tr", 0, ",nbz", ",nhz", ",ndc", 0, ",nbc", ",nhc"
+   };
+
+static char *shift_cond_names[] =
+{"", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"};
+
+static char *index_compl_names[] = {"", ",m", ",s", ",sm"};
+static char *short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
+static char *short_bytes_compl_names[] = {"", ",b,m", ",e", ",e,m"};
+static char *float_format_names[] = {",sgl", ",dbl", ",quad"};
+static char *float_comp_names[] =
 {",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
  ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
  ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
@@ -67,7 +76,10 @@ char *float_comp_names[] =
 #define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
                        (GET_FIELD ((insn), 19, 19) ? 8 : 0))
 
-void fput_reg (), fput_const ();
+static void fput_reg PARAMS ((unsigned reg, FILE *stream));
+static void fput_const PARAMS ((unsigned num, FILE *stream));
+static void fput_reg_r PARAMS ((unsigned reg, FILE *stream));
+static void fput_creg PARAMS ((unsigned reg, FILE *stream));
 
 /* Print one instruction from MEMADDR on STREAM.  */
 int
@@ -75,9 +87,10 @@ print_insn (memaddr, stream)
      CORE_ADDR memaddr;
      FILE *stream;
 {
-  unsigned int insn, i, op;
+  long insn;
+  unsigned int i, op;
 
-  read_memory (memaddr, &insn, sizeof (insn));
+  insn = read_memory_integer (memaddr, sizeof (insn));
 
   for (i = 0; i < NUMOPCODES; ++i)
     {
@@ -221,13 +234,13 @@ print_insn (memaddr, stream)
                  print_address (memaddr + 8 + extract_12 (insn), stream);
                  break;
                case 'W':
-                 /* don't interpret an address if it's an external branch
-                    instruction. */
                  op = GET_FIELD (insn, 0, 5);
-                 if (op != 0x38 /* be */ && op != 0x39 /* ble */)
-                   print_address (memaddr + 8 + extract_17 (insn), stream);
-                 else
+
+                 if (op == 0x38 /* be */ || op == 0x39 /* ble */)
                    fput_const (extract_17 (insn), stream);
+                 else
+                   print_address (memaddr + 8 + extract_17 (insn), stream);
+
                  break;
                case 'B':
                  {
@@ -245,6 +258,10 @@ print_insn (memaddr, stream)
                  fprintf_filtered (stream, "%d",
                                    GET_FIELD (insn, 22, 26));
                  break;
+               case 'Q':
+                 fprintf_filtered (stream, "%d",
+                                   GET_FIELD (insn, 11, 15));
+                 break;
                case 'T':
                  fprintf_filtered (stream, "%d",
                                    32 - GET_FIELD (insn, 27, 31));
@@ -328,6 +345,35 @@ print_insn (memaddr, stream)
                  break;
                }
            }
+
+/* If this is an external branch, examine the previous instruction and see if
+   it was an ldil that loaded something into the same base reg.  If so, then
+   calculate the branch target from the constants in both instructions, and
+   print it out. */
+
+         op = GET_FIELD (insn, 0, 5);
+         if (op == 0x38 /* be */ || op == 0x39 /* ble */)
+           {
+             CORE_ADDR target_address;
+             long prev_insn;
+             int basereg, basereg_prev;
+
+             target_address = extract_17 (insn);
+             basereg = GET_FIELD (insn, 6, 10);
+             if (basereg != 0)
+               {
+                 prev_insn = read_memory_integer (memaddr - 4,
+                                                  sizeof(prev_insn));
+                 basereg_prev = GET_FIELD (prev_insn, 6, 10);
+
+                 if ((prev_insn & 0xfc000000) == 0x20000000 /* ldil */
+                     && basereg == basereg_prev)
+                   target_address += extract_21 (prev_insn);
+               }
+             fprintf_filtered (stream, "\t! ");
+             print_address (target_address, stream);
+           }
+
          return sizeof(insn);
        }
     }
@@ -337,7 +383,7 @@ print_insn (memaddr, stream)
   
 /* Utility function to print registers */
 
-void
+static void
 fput_reg (reg, stream)
      unsigned reg;
      FILE *stream;
This page took 0.025841 seconds and 4 git commands to generate.