MIPS: Correct MUSTBE32 interpretation in delay slot handling
authorMaciej W. Rozycki <macro@codesourcery.com>
Sun, 5 Oct 2014 20:50:47 +0000 (21:50 +0100)
committerMaciej W. Rozycki <macro@codesourcery.com>
Sun, 5 Oct 2014 20:50:47 +0000 (21:50 +0100)
This change addresses `micromips_instruction_has_delay_slot' and
`mips16_instruction_has_delay_slot' that both incorrectly interpret
their MUSTBE32 argument.  Their callers assume that when the flag is
clear these functions will return 1 when any non-compact jump or branch
instruction is present at ADDR, while in fact they will only return 1
for 16-bit such instructions only.  This change makes the implementation
match the expectations.

* mips-tdep.c (micromips_instruction_has_delay_slot): When
!mustbe32 also return 1 for 32-bit instructions.
(mips16_instruction_has_delay_slot): Likewise.  Add an
explanatory comment.

gdb/ChangeLog
gdb/mips-tdep.c

index 6387550..ee1f934 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-05  Maciej W. Rozycki  <macro@codesourcery.com>
+
+       * mips-tdep.c (micromips_instruction_has_delay_slot): When
+       !mustbe32 also return 1 for 32-bit instructions.
+       (mips16_instruction_has_delay_slot): Likewise.  Add an
+       explanatory comment.
+
 2014-10-03  Maciej W. Rozycki  <macro@codesourcery.com>
 
        * elfread.c (elf_symtab_read): Also mark solib trampoline minimal
index 188580f..7e07673 100644 (file)
@@ -7035,17 +7035,18 @@ micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
   if (status)
     return 0;
 
-  if (!mustbe32)               /* 16-bit instructions.  */
-    return (micromips_op (insn) == 0x11
+                               /* 16-bit instructions.  */
+  if ((micromips_op (insn) == 0x11
                                /* POOL16C: bits 010001 */
-           && (b5s5_op (insn) == 0xc
+       && (b5s5_op (insn) == 0xc
                                /* JR16: bits 010001 01100 */
-               || (b5s5_op (insn) & 0x1e) == 0xe))
+          || (b5s5_op (insn) & 0x1e) == 0xe))
                                /* JALR16, JALRS16: bits 010001 0111x */
-          || (micromips_op (insn) & 0x37) == 0x23
+      || (micromips_op (insn) & 0x37) == 0x23
                                /* BEQZ16, BNEZ16: bits 10x011 */
-          || micromips_op (insn) == 0x33;
+      || micromips_op (insn) == 0x33)
                                /* B16: bits 110011 */
+    return !mustbe32;
 
                                /* 32-bit instructions.  */
   if (micromips_op (insn) == 0x0)
@@ -7091,6 +7092,10 @@ micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
                                /* JALX: bits 111100 */
 }
 
+/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay
+   slot (i.e. it is a non-compact jump instruction).  The instruction
+   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */
+
 static int
 mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
                                   int mustbe32)
@@ -7102,8 +7107,8 @@ mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
   if (status)
     return 0;
 
-  if (!mustbe32)
-    return (inst & 0xf89f) == 0xe800;  /* JR/JALR (16-bit instruction)  */
+  if ((inst & 0xf89f) == 0xe800)       /* JR/JALR (16-bit instruction)  */
+    return !mustbe32;
   return (inst & 0xf800) == 0x1800;    /* JAL/JALX (32-bit instruction)  */
 }