mips64: implement Cavium BBIT0 and BBIT1 instructions

Implement Cavium specific instructions:
- BBIT0 (Branch on bit clear)
- BBIT1 (Branch on bit set)

This should fix the hang issue reported in:
https://bugs.kde.org/show_bug.cgi?id=336139


git-svn-id: svn://svn.valgrind.org/vex/trunk@2942 8f6e269a-dfd6-0310-a8e1-e2731360e62c
diff --git a/priv/guest_mips_toIR.c b/priv/guest_mips_toIR.c
index db04ad4..908f2c8 100644
--- a/priv/guest_mips_toIR.c
+++ b/priv/guest_mips_toIR.c
@@ -774,6 +774,11 @@
       return True;
    }
 
+   /* Cavium Specific instructions. */
+   if (opcode == 0x32 || opcode == 0x3A) {  /* BBIT0, BBIT1 */
+      return True;
+   }
+
    return False;
 }
 
@@ -17086,6 +17091,47 @@
       store(mkexpr(t1), getIReg(rt));
       break;
 
+   case 0x32:  /* Branch on Bit Clear - BBIT0; Cavium OCTEON */
+      /* Cavium Specific instructions. */
+      if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+         DIP("bbit0 r%d, 0x%x, %x", rs, rt, imm);
+         t0 = newTemp(Ity_I32);
+         t1 = newTemp(Ity_I32);
+         assign(t0, mkU32(0x1));
+         assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
+         dis_branch(False, binop(Iop_CmpEQ32,
+                                 binop(Iop_And32,
+                                       mkexpr(t1),
+                                       mkNarrowTo32(ty, getIReg(rs))),
+                                 mkU32(0x0)),
+                    imm, &bstmt);
+         break;
+      } else {
+         goto decode_failure;
+      }
+
+   case 0x3A:  /* Branch on Bit Set - BBIT1; Cavium OCTEON */
+      /* Cavium Specific instructions. */
+      if (VEX_MIPS_COMP_ID(archinfo->hwcaps) == VEX_PRID_COMP_CAVIUM) {
+         DIP("bbit1 r%d, 0x%x, %x", rs, rt, imm);
+         t0 = newTemp(Ity_I32);
+         t1 = newTemp(Ity_I32);
+         assign(t0, mkU32(0x1));
+         assign(t1, binop(Iop_Shl32, mkexpr(t0), mkU8(rt)));
+         dis_branch(False, binop(Iop_CmpNE32,
+                                 binop(Iop_And32,
+                                       mkexpr(t1),
+                                       mkNarrowTo32(ty, getIReg(rs))),
+                                 mkU32(0x0)),
+                    imm, &bstmt);
+         break;
+      } else {
+         goto decode_failure;
+      }
+
+   default:
+      goto decode_failure;
+
    decode_failure_dsp:
       vex_printf("Error occured while trying to decode MIPS32 DSP "
                  "instruction.\nYour platform probably doesn't support "