[committed] MIPS: Rewrite `add_offset_16' to match its name

Maciej W. Rozycki macro@codesourcery.com
Sun Oct 5 22:42:00 GMT 2014


Hi,

 We have a helper function called `add_offset_16' used by 
`extended_mips16_next_pc' to calculate branch destinations.  Weirdly 
enough the helper does not do what the name suggests and rather than doing 
its work for a 16-bit immediate branch offset it makes its calculations on 
a 26-bit immediate target used by JAL and JALX instructions.  Furthermore 
the JAL/JALX calculation is only needed once by `extended_mips16_next_pc' 
while a 16-bit branch offset calculation is made inline several times 
across `extended_mips16_next_pc'.

 This change therefore replaces the contents of `add_offset_16' with the 
16-bit branch offset calculation and updates `extended_mips16_next_pc' 
accordingly.

 No regression across the usual mips-linux-gnu multilibs.  Committed.

2014-10-05  Maciej W. Rozycki  <macro@codesourcery.com>

	gdb/
	* mips-tdep.c (add_offset_16): Rewrite to implement what the
	name implies.
	(extended_mips16_next_pc): Update accordingly.

  Maciej

gdb-mips16-jal-offset.diff
Index: gdb-fsf-trunk-quilt/gdb/mips-tdep.c
===================================================================
--- gdb-fsf-trunk-quilt.orig/gdb/mips-tdep.c	2014-10-03 20:24:53.000000000 +0100
+++ gdb-fsf-trunk-quilt/gdb/mips-tdep.c	2014-10-03 20:48:26.698978552 +0100
@@ -2178,10 +2178,13 @@ unpack_mips16 (struct gdbarch *gdbarch, 
 }
 
 
+/* Calculate the destination of a branch whose 16-bit opcode word is at PC,
+   and having a signed 16-bit OFFSET.  */
+
 static CORE_ADDR
 add_offset_16 (CORE_ADDR pc, int offset)
 {
-  return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)));
+  return pc + (offset << 1) + 2;
 }
 
 static CORE_ADDR
@@ -2196,7 +2199,7 @@ extended_mips16_next_pc (struct frame_in
       {
 	struct upk_mips16 upk;
 	unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
-	pc += (upk.offset << 1) + 2;
+	pc = add_offset_16 (pc, upk.offset);
 	break;
       }
     case 3:			/* JAL , JALX - Watch out, these are 32 bit
@@ -2204,7 +2207,7 @@ extended_mips16_next_pc (struct frame_in
       {
 	struct upk_mips16 upk;
 	unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
-	pc = add_offset_16 (pc, upk.offset);
+	pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
 	if ((insn >> 10) & 0x01)	/* Exchange mode */
 	  pc = pc & ~0x01;	/* Clear low bit, indicate 32 bit mode.  */
 	else
@@ -2218,7 +2221,7 @@ extended_mips16_next_pc (struct frame_in
 	unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
 	reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
 	if (reg == 0)
-	  pc += (upk.offset << 1) + 2;
+	  pc = add_offset_16 (pc, upk.offset);
 	else
 	  pc += 2;
 	break;
@@ -2230,7 +2233,7 @@ extended_mips16_next_pc (struct frame_in
 	unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
 	reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
 	if (reg != 0)
-	  pc += (upk.offset << 1) + 2;
+	  pc = add_offset_16 (pc, upk.offset);
 	else
 	  pc += 2;
 	break;
@@ -2244,8 +2247,7 @@ extended_mips16_next_pc (struct frame_in
 	reg = get_frame_register_signed (frame, 24);  /* Test register is 24 */
 	if (((upk.regx == 0) && (reg == 0))	/* BTEZ */
 	    || ((upk.regx == 1) && (reg != 0)))	/* BTNEZ */
-	  /* pc = add_offset_16(pc,upk.offset) ; */
-	  pc += (upk.offset << 1) + 2;
+	  pc = add_offset_16 (pc, upk.offset);
 	else
 	  pc += 2;
 	break;



More information about the Gdb-patches mailing list