This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gdb 5.0: mips-tdep.c (mips32_next_pc): branches get misdecoded (fwd)


---------- Forwarded message ----------
Message-ID: <Pine.GSO.3.96.1000619190736.10348R-100000@delta.ds2.pg.gda.pl>
Date: Mon, 19 Jun 2000 19:17:39 +0200 (MET DST)
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
To: bug-gdb@gnu.org
Subject: gdb 5.0: mips-tdep.c (mips32_next_pc): branches get misdecoded

Hi,

 Due to a number of bugs mips32_next_pc () does not get many of the
branches right.  As a result breakpoints get inserted in wrong places thus
single-stepping does not work as expected.  The following patch fixes the
problem for me.  It also cleans up comments a bit.

 I was only able to test it on a MIPS I CPU so likely branches are not
runtime tested.  All of them were verified with MIPS documentation.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

diff -u --recursive --new-file gdb-5.0.macro/gdb/mips-tdep.c gdb-5.0/gdb/mips-tdep.c
--- gdb-5.0.macro/gdb/mips-tdep.c	Sun Apr  9 14:35:35 2000
+++ gdb-5.0/gdb/mips-tdep.c	Sat Jun 17 15:29:42 2000
@@ -596,21 +596,21 @@
   unsigned long inst;
   int op;
   inst = mips_fetch_instruction (pc);
-  if ((inst & 0xe0000000) != 0)	/* Not a special, junp or branch instruction */
+  if ((inst & 0xe0000000) != 0)	/* Not a special, jump or branch instruction */
     {
-      if ((inst >> 27) == 5)	/* BEQL BNEZ BLEZL BGTZE , bits 0101xx */
+      if ((inst >> 28) == 5)	/* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
 	{
-	  op = ((inst >> 25) & 0x03);
+	  op = ((inst >> 26) & 0x03);
 	  switch (op)
 	    {
-	    case 0:
-	      goto equal_branch;	/* BEQL   */
-	    case 1:
-	      goto neq_branch;	/* BNEZ   */
-	    case 2:
-	      goto less_branch;	/* BLEZ   */
-	    case 3:
-	      goto greater_branch;	/* BGTZ */
+	    case 0:		/* BEQL */
+	      goto equal_branch;
+	    case 1:		/* BNEL */
+	      goto neq_branch;
+	    case 2:		/* BLEZL */
+	      goto less_branch;
+	    case 3:		/* BGTZ */
+	      goto greater_branch;
 	    default:
 	      pc += 4;
 	    }
@@ -636,45 +636,45 @@
 	      pc += 4;
 	    }
 
-	  break;		/* end special */
+	  break;	/* end SPECIAL */
 	case 1:		/* REGIMM */
 	  {
 	    op = jtype_op (inst);	/* branch condition */
 	    switch (jtype_op (inst))
 	      {
 	      case 0:		/* BLTZ */
-	      case 2:		/* BLTXL */
-	      case 16:		/* BLTZALL */
+	      case 2:		/* BLTZL */
+	      case 16:		/* BLTZAL */
 	      case 18:		/* BLTZALL */
 	      less_branch:
-		if (read_register (itype_rs (inst)) < 0)
+		if ((LONGEST) read_register (itype_rs (inst)) < 0)
 		  pc += mips32_relative_offset (inst) + 4;
 		else
 		  pc += 8;	/* after the delay slot */
 		break;
-	      case 1:		/* GEZ */
+	      case 1:		/* BGEZ */
 	      case 3:		/* BGEZL */
 	      case 17:		/* BGEZAL */
 	      case 19:		/* BGEZALL */
 	      greater_equal_branch:
-		if (read_register (itype_rs (inst)) >= 0)
+		if ((LONGEST) read_register (itype_rs (inst)) >= 0)
 		  pc += mips32_relative_offset (inst) + 4;
 		else
 		  pc += 8;	/* after the delay slot */
 		break;
-		/* All of the other intructions in the REGIMM catagory */
+		/* All of the other instructions in the REGIMM category */
 	      default:
 		pc += 4;
 	      }
 	  }
-	  break;		/* end REGIMM */
+	  break;	/* end REGIMM */
 	case 2:		/* J */
 	case 3:		/* JAL */
 	  {
 	    unsigned long reg;
 	    reg = jtype_target (inst) << 2;
+	    /* Upper four bits never changed... */
 	    pc = reg + ((pc + 4) & 0xf0000000);
-	    /* Whats this mysterious 0xf000000 adjustment ??? */
 	  }
 	  break;
 	  /* FIXME case JALX : */
@@ -685,38 +685,37 @@
 	    /* Add 1 to indicate 16 bit mode - Invert ISA mode */
 	  }
 	  break;		/* The new PC will be alternate mode */
-	case 4:		/* BEQ , BEQL */
+	case 4:		/* BEQ, BEQL */
 	equal_branch:
-	  if (read_register (itype_rs (inst)) ==
-	      read_register (itype_rt (inst)))
+	  if ((LONGEST) read_register (itype_rs (inst)) ==
+	      (LONGEST) read_register (itype_rt (inst)))
 	    pc += mips32_relative_offset (inst) + 4;
 	  else
 	    pc += 8;
 	  break;
-	case 5:		/* BNE , BNEL */
+	case 5:		/* BNE, BNEL */
 	neq_branch:
-	  if (read_register (itype_rs (inst)) !=
-	      read_register (itype_rs (inst)))
+	  if ((LONGEST) read_register (itype_rs (inst)) !=
+	      (LONGEST) read_register (itype_rt (inst)))
 	    pc += mips32_relative_offset (inst) + 4;
 	  else
 	    pc += 8;
 	  break;
-	case 6:		/* BLEZ , BLEZL */
+	case 6:		/* BLEZ, BLEZL */
 	less_zero_branch:
-	  if (read_register (itype_rs (inst) <= 0))
+	  if ((LONGEST) read_register (itype_rs (inst)) <= 0)
 	    pc += mips32_relative_offset (inst) + 4;
 	  else
 	    pc += 8;
 	  break;
 	case 7:
-	greater_branch:	/* BGTZ BGTZL */
-	  if (read_register (itype_rs (inst) > 0))
+	default:
+	greater_branch:	/* BGTZ, BGTZL */
+	  if ((LONGEST) read_register (itype_rs (inst)) > 0)
 	    pc += mips32_relative_offset (inst) + 4;
 	  else
 	    pc += 8;
 	  break;
-	default:
-	  pc += 8;
 	}			/* switch */
     }				/* else */
   return pc;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]