[PATCH/MIPS] Add support Octeon's bbit instructions

Andrew Pinski
2012-04-14T23:35:20Z

[-- Attachment #1: Type: text/plain, Size: 528 bytes --]

Hi,
Currently gdb does not support stepping over Octeon's bbit
instructions. These instructions are branch instructions with a delay
slot but in the cop2 instruction area.

This adds the support to both mips32_next_pc and
mips32_instruction_has_delay_slot.

OK? Built and tested on mips64-linux-gnu on an Octeon2.

Thanks,
Andrew Pinski

ChangeLog:
* mips-tdep.c (is_octeon): New function.
(isocteonbitinsn): New function.
(mips32_next_pc): Handle Octeon's bbit insturctions.
(mips32_instruction_has_delay_slot): Likewise.

[-- Attachment #2: addgdbbbit.diff.txt --]
[-- Type: text/plain, Size: 2523 bytes --]

Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.539
diff -u -p -r1.539 mips-tdep.c
--- mips-tdep.c 10 Apr 2012 23:06:57 -0000 1.539
+++ mips-tdep.c 14 Apr 2012 23:33:02 -0000
@@ -219,6 +219,18 @@ mips_abi (struct gdbarch *gdbarch)
return gdbarch_tdep (gdbarch)->mips_abi;
}

+static int
+is_octeon (struct gdbarch *gdbarch, const struct bfd_arch_info *info)
+{
+ if (!info)
+ info = gdbarch_bfd_arch_info (gdbarch);
+
+ return (info->mach == bfd_mach_mips_octeon
+ || info->mach == bfd_mach_mips_octeonp
+ || info->mach == bfd_mach_mips_octeon2);
+}
+
+
int
mips_isa_regsize (struct gdbarch *gdbarch)
{
@@ -1162,6 +1174,23 @@ mips32_bc1_pc (struct gdbarch *gdbarch,
return pc;
}

+/* Return true if the INST is the Octeon's BBIT instruction. */
+static int
+isocteonbitinsn (int inst, struct gdbarch *gdbarch)
+{
+ int op;
+ if (!is_octeon (gdbarch, NULL))
+ return 0;
+ op = itype_op (inst);
+ /* BBIT0 is encoded as LWC2: 110 010. */
+ /* BBIT032 is encoded as LDC2: 110 110. */
+ /* BBIT1 is encoded as SWC2: 111 010. */
+ /* BBIT132 is encoded as SDC2: 111 110. */
+ if (op == 50 || op == 54 || op == 58 || op == 62)
+ return 1;
+ return 0;
+}
+
/* Determine where to set a single step breakpoint while considering
branch prediction. */
static CORE_ADDR
@@ -1213,6 +1242,21 @@ mips32_next_pc (struct frame_info *frame
/* Add 1 to indicate 16-bit mode -- invert ISA mode. */
pc = ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + reg + 1;
}
+ else if (isocteonbitinsn (inst, gdbarch))
+ {
+ int bit, branch_if;
+ int op = itype_op (inst);
+ branch_if = op == 58 || op == 62;
+ bit = itype_rt (inst);
+ if (op == 54 || op == 62)
+ bit += 32;
+ if (((get_frame_register_signed (frame,
+ itype_rs (inst)) >> bit) & 1)
+ == branch_if)
+ pc += mips32_relative_offset (inst) + 4;
+ else
+ pc += 8; /* after the delay slot */
+ }
else
pc += 4; /* Not a branch, next instruction is easy. */
}
@@ -5397,6 +5441,8 @@ mips32_instruction_has_delay_slot (struc
op = itype_op (inst);
if ((inst & 0xe0000000) != 0)
{
+ if (isocteonbitinsn (inst, gdbarch))
+ return 1;
rs = itype_rs (inst);
rt = itype_rt (inst);
return (op >> 2 == 5 /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */