[RFA/alpha] Add handling of FP control insn in software-single step

Joel Brobecker brobecker@adacore.com
Tue May 17 02:50:00 GMT 2005


Hello,

We noticed that alpha-tdep.c:alpha_next_pc() did have any support for
FP control (branch) instructions. So single-steping over instructions
such as fbeq was not always working properly since the target address
was not always following the potential jump.

The attached patch should fix this.

2005-05-17  Joel Brobecker  <brobecker@adacore.com>

        * alpha-tdep.c (fp_register_zero_p): New function.
        (fp_register_sign_bit): New function.
        (alpha_next_pc): Add support for floating-point control instructions.

Tested on alpha-tru64 5.1a with no regression. It fixes a problem with
some code but I can't contribute it, as it has been given to us by a
customer.

OK to apply?

Thanks,
-- 
Joel
-------------- next part --------------
Index: alpha-tdep.c
===================================================================
RCS file: /nile.c/cvs/Dev/gdb/gdb-6.3/gdb/alpha-tdep.c,v
retrieving revision 1.3
diff -u -p -r1.3 alpha-tdep.c
--- alpha-tdep.c	1 Dec 2004 04:07:53 -0000	1.3
+++ alpha-tdep.c	17 May 2005 00:26:57 -0000
@@ -1357,6 +1357,26 @@ alpha_fill_fp_regs (int regno, void *f0_
 }
 
 
+
+/* Return nonzero if the given buffer holds a G_floating register
+   value of zero.  */
+   
+static int
+fp_register_zero_p (char *buf)
+{
+  return ((buf[1] & 0x0f) == 0 && buf[2] == 0 && buf[3] == 0
+          && buf[4] == 0 && buf[5] == 0 && buf[6] == 0 && buf[7] == 0);
+}
+
+/* Return the value of the sign bit for the G_floating register
+   value held in BUF.  */
+
+static int
+fp_register_sign_bit (char *buf)
+{
+  return (buf[0] & 0x80);
+}
+
 /* alpha_software_single_step() is called just before we want to resume
    the inferior, if we want to single-step it but there is no hardware
    or kernel single-step support (NetBSD on Alpha, for example).  We find
@@ -1372,6 +1392,7 @@ alpha_next_pc (CORE_ADDR pc)
   unsigned int op;
   int offset;
   LONGEST rav;
+  char reg[8];
 
   insn = alpha_read_insn (pc);
 
@@ -1400,8 +1421,9 @@ alpha_next_pc (CORE_ADDR pc)
 	  return (pc + 4 + offset);
 	}
 
+      regcache_cooked_read (current_regcache, (insn >> 21) & 0x1f, reg);
       /* Need to determine if branch is taken; read RA.  */
-      rav = (LONGEST) read_register ((insn >> 21) & 0x1f);
+      rav = extract_signed_integer (reg, 4);
       switch (op)
 	{
 	case 0x38:		/* BLBC */
@@ -1437,7 +1459,32 @@ alpha_next_pc (CORE_ADDR pc)
 	    goto branch_taken;
 	  break;
 
-	/* ??? Missing floating-point branches.  */
+        /* Floating point branches.  */
+        
+        case 0x31:              /* FBEQ */
+          if (fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
+        case 0x36:              /* FBGE */
+          if (fp_register_sign_bit (reg) == 0 || fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
+        case 0x37:              /* FBGT */
+          if (fp_register_sign_bit (reg) == 0 && ! fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
+        case 0x33:              /* FBLE */
+          if (fp_register_sign_bit (reg) == 1 || fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
+        case 0x32:              /* FBLT */
+          if (fp_register_sign_bit (reg) == 1 && ! fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
+        case 0x35:              /* FBNE */
+          if (! fp_register_zero_p (reg))
+            goto branch_taken;
+          break;
 	}
     }
 


More information about the Gdb-patches mailing list