* mips-tdep.c (mips_step_skips_delay), config/mips/tm-mips.h
authorJim Kingdon <jkingdon@engr.sgi.com>
Tue, 1 Mar 1994 00:15:07 +0000 (00:15 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Tue, 1 Mar 1994 00:15:07 +0000 (00:15 +0000)
(STEP_SKIPS_DELAY): Added.
* infrun.c (proceed) [STEP_SKIPS_DELAY]: Check for a breakpoint in
the delay slot.

gdb/ChangeLog
gdb/config/mips/tm-mips.h
gdb/infrun.c
gdb/mips-tdep.c

index d0c30b31245b28d8db01eb2eeca1799cead4c57c..c6e5b11c64a3635d45d2f2b41a9648d3360fd278 100644 (file)
@@ -1,5 +1,10 @@
 Mon Feb 28 12:40:46 1994  Jim Kingdon  (kingdon@deneb.cygnus.com)
 
+       * mips-tdep.c (mips_step_skips_delay), config/mips/tm-mips.h
+       (STEP_SKIPS_DELAY): Added.
+       * infrun.c (proceed) [STEP_SKIPS_DELAY]: Check for a breakpoint in
+       the delay slot.
+
        * valprint.c (val_print_string): If errcode is set, always print
        an error, regardless of force_ellipsis.  In the non-EIO case,
        just print the error message rather than calling error().  Don't
index a0d0c890474aae6d327a8051e2a0d27a0f5ec1e6..11326bf145b21ba2df6856466e2fcc5fe79652b4 100644 (file)
@@ -46,6 +46,10 @@ extern int mips_fpu;
 #define SKIP_PROLOGUE(pc)      pc = mips_skip_prologue (pc, 0)
 extern CORE_ADDR mips_skip_prologue PARAMS ((CORE_ADDR addr, int lenient));
 
+/* Return non-zero if PC points to an instruction which will cause a step
+   to execute both the instruction at PC and an instruction at PC+4.  */
+#define STEP_SKIPS_DELAY(pc) (mips_step_skips_delay (pc))
+
 /* Immediately after a function call, return the saved pc.
    Can't always go through the frames for this because on some machines
    the new frame is not set up until the new function executes
index ef9b82603a7d6cfad11a29e21d45475319669af9..146621c75b5d05f14af4c5753b7a6abea3811362 100644 (file)
@@ -280,6 +280,15 @@ proceed (addr, siggnal, step)
 
       if (breakpoint_here_p (read_pc ()))
        oneproc = 1;
+
+#ifdef STEP_SKIPS_DELAY
+      /* Check breakpoint_here_p first, because breakpoint_here_p is fast
+        (it just checks internal GDB data structures) and STEP_SKIPS_DELAY
+        is slow (it needs to read memory from the target).  */
+      if (breakpoint_here_p (read_pc () + 4)
+         && STEP_SKIPS_DELAY (read_pc ()))
+       oneproc = 1;
+#endif /* STEP_SKIPS_DELAY */
     }
   else
     write_pc (addr);
index 9a5d6b92d4569cc5b9ad03d88e6ad18e652384ee..faaeb6e1929cadcffccf4fa891fb3ce50473a899 100644 (file)
@@ -32,9 +32,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "objfiles.h"
 #include "gdbtypes.h"
 
-#if 0
 #include "opcode/mips.h"
-#endif
 
 #define VM_MIN_ADDRESS (unsigned)0x400000
 
@@ -921,8 +919,9 @@ mips_frame_num_args(fip)
        return -1;
 }
 \f
-#if 0
 /* Is this a branch with a delay slot?  */
+static int is_delayed PARAMS ((unsigned long));
+
 static int
 is_delayed (insn)
      unsigned long insn;
@@ -937,7 +936,18 @@ is_delayed (insn)
                                       | INSN_COND_BRANCH_DELAY
                                       | INSN_COND_BRANCH_LIKELY)));
 }
-#endif
+
+int
+mips_step_skips_delay (pc)
+     CORE_ADDR pc;
+{
+  char buf[4];
+
+  if (target_read_memory (pc, buf, 4) != 0)
+    /* If error reading memory, guess that it is not a delayed branch.  */
+    return 0;
+  return is_delayed (extract_unsigned_integer (buf, 4));
+}
 
 /* To skip prologues, I use this predicate.  Returns either PC itself
    if the code at PC does not look like a function prologue; otherwise