[Lldb-commits] [lldb] r240373 - [LLDB][MIPS] MIPS32 branch emulation and single-stepping

Jaydeep Patil jaydeep.patil at imgtec.com
Mon Jun 22 20:37:08 PDT 2015


Author: jaydeep
Date: Mon Jun 22 22:37:08 2015
New Revision: 240373

URL: http://llvm.org/viewvc/llvm-project?rev=240373&view=rev
Log:
[LLDB][MIPS] MIPS32 branch emulation and single-stepping
    
    SUMMARY:
    This patch implements
      1. Emulation of MIPS32 branch instructions
      2. Enable single-stepping for MIPS32 instructions
      3. Correction in emulation of MIPS64 branch instructions with delay slot
      4. Adjust breakpoint address when breakpoint is hit in a forbidden slot of compact branch instruction
    
    Reviewers: clayborg
    Subscribers: mohit.bhakkad, sagar, bhushan, lldb-commits, emaste, nitesh.jain
    Differential Revision: http://reviews.llvm.org/D10596

Modified:
    lldb/trunk/include/lldb/Host/common/NativeRegisterContext.h
    lldb/trunk/source/Host/common/NativeRegisterContext.cpp
    lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
    lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
    lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h

Modified: lldb/trunk/include/lldb/Host/common/NativeRegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/common/NativeRegisterContext.h?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/common/NativeRegisterContext.h (original)
+++ lldb/trunk/include/lldb/Host/common/NativeRegisterContext.h Mon Jun 22 22:37:08 2015
@@ -141,6 +141,9 @@ public:
     lldb::addr_t
     GetPC (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
 
+    virtual lldb::addr_t
+    GetPCfromBreakpointLocation (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS);
+
     Error
     SetPC (lldb::addr_t pc);
 

Modified: lldb/trunk/source/Host/common/NativeRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/NativeRegisterContext.cpp?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/NativeRegisterContext.cpp (original)
+++ lldb/trunk/source/Host/common/NativeRegisterContext.cpp Mon Jun 22 22:37:08 2015
@@ -143,6 +143,12 @@ NativeRegisterContext::GetPC (lldb::addr
     return retval;
 }
 
+lldb::addr_t
+NativeRegisterContext::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
+{
+    return GetPC (fail_value);
+}
+
 Error
 NativeRegisterContext::SetPC (lldb::addr_t pc)
 {

Modified: lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp Mon Jun 22 22:37:08 2015
@@ -208,9 +208,41 @@ EmulateInstructionMIPS::GetRegisterName
     {
         switch (reg_num)
         {
-            case gcc_dwarf_sp_mips64: return "r29"; 
-            case gcc_dwarf_r30_mips64: return "r30"; 
-            case gcc_dwarf_ra_mips64: return "r31";
+            case gcc_dwarf_sp_mips:  return "r29"; 
+            case gcc_dwarf_r30_mips: return "r30"; 
+            case gcc_dwarf_ra_mips:  return "r31";
+            case gcc_dwarf_f0_mips:  return "f0";
+            case gcc_dwarf_f1_mips:  return "f1";
+            case gcc_dwarf_f2_mips:  return "f2";
+            case gcc_dwarf_f3_mips:  return "f3";
+            case gcc_dwarf_f4_mips:  return "f4";
+            case gcc_dwarf_f5_mips:  return "f5";
+            case gcc_dwarf_f6_mips:  return "f6";
+            case gcc_dwarf_f7_mips:  return "f7";
+            case gcc_dwarf_f8_mips:  return "f8";
+            case gcc_dwarf_f9_mips:  return "f9";
+            case gcc_dwarf_f10_mips: return "f10";
+            case gcc_dwarf_f11_mips: return "f11";
+            case gcc_dwarf_f12_mips: return "f12";
+            case gcc_dwarf_f13_mips: return "f13";
+            case gcc_dwarf_f14_mips: return "f14";
+            case gcc_dwarf_f15_mips: return "f15";
+            case gcc_dwarf_f16_mips: return "f16";
+            case gcc_dwarf_f17_mips: return "f17";
+            case gcc_dwarf_f18_mips: return "f18";
+            case gcc_dwarf_f19_mips: return "f19";
+            case gcc_dwarf_f20_mips: return "f20";
+            case gcc_dwarf_f21_mips: return "f21";
+            case gcc_dwarf_f22_mips: return "f22";
+            case gcc_dwarf_f23_mips: return "f23";
+            case gcc_dwarf_f24_mips: return "f24";
+            case gcc_dwarf_f25_mips: return "f25";
+            case gcc_dwarf_f26_mips: return "f26";
+            case gcc_dwarf_f27_mips: return "f27";
+            case gcc_dwarf_f28_mips: return "f28";
+            case gcc_dwarf_f29_mips: return "f29";
+            case gcc_dwarf_f30_mips: return "f30";
+            case gcc_dwarf_f31_mips: return "f31";
             default:
                 break;
         }
@@ -219,45 +251,78 @@ EmulateInstructionMIPS::GetRegisterName
 
     switch (reg_num)
     {
-        case gcc_dwarf_zero_mips64:     return "r0";
-        case gcc_dwarf_r1_mips64:       return "r1";
-        case gcc_dwarf_r2_mips64:       return "r2";
-        case gcc_dwarf_r3_mips64:       return "r3";
-        case gcc_dwarf_r4_mips64:       return "r4";
-        case gcc_dwarf_r5_mips64:       return "r5";
-        case gcc_dwarf_r6_mips64:       return "r6";
-        case gcc_dwarf_r7_mips64:       return "r7";
-        case gcc_dwarf_r8_mips64:       return "r8";
-        case gcc_dwarf_r9_mips64:       return "r9";
-        case gcc_dwarf_r10_mips64:      return "r10";
-        case gcc_dwarf_r11_mips64:      return "r11";
-        case gcc_dwarf_r12_mips64:      return "r12";
-        case gcc_dwarf_r13_mips64:      return "r13";
-        case gcc_dwarf_r14_mips64:      return "r14";
-        case gcc_dwarf_r15_mips64:      return "r15";
-        case gcc_dwarf_r16_mips64:      return "r16";
-        case gcc_dwarf_r17_mips64:      return "r17";
-        case gcc_dwarf_r18_mips64:      return "r18";
-        case gcc_dwarf_r19_mips64:      return "r19";
-        case gcc_dwarf_r20_mips64:      return "r20";
-        case gcc_dwarf_r21_mips64:      return "r21";
-        case gcc_dwarf_r22_mips64:      return "r22";
-        case gcc_dwarf_r23_mips64:      return "r23";
-        case gcc_dwarf_r24_mips64:      return "r24";
-        case gcc_dwarf_r25_mips64:      return "r25";
-        case gcc_dwarf_r26_mips64:      return "r26";
-        case gcc_dwarf_r27_mips64:      return "r27";
-        case gcc_dwarf_gp_mips64:       return "gp";
-        case gcc_dwarf_sp_mips64:       return "sp";
-        case gcc_dwarf_r30_mips64:      return "fp";
-        case gcc_dwarf_ra_mips64:       return "ra";
-        case gcc_dwarf_sr_mips64:       return "sr";
-        case gcc_dwarf_lo_mips64:       return "lo";
-        case gcc_dwarf_hi_mips64:       return "hi";
-        case gcc_dwarf_bad_mips64:      return "bad";
-        case gcc_dwarf_cause_mips64:    return "cause";
-        case gcc_dwarf_pc_mips64:       return "pc";
-
+        case gcc_dwarf_zero_mips:     return "r0";
+        case gcc_dwarf_r1_mips:       return "r1";
+        case gcc_dwarf_r2_mips:       return "r2";
+        case gcc_dwarf_r3_mips:       return "r3";
+        case gcc_dwarf_r4_mips:       return "r4";
+        case gcc_dwarf_r5_mips:       return "r5";
+        case gcc_dwarf_r6_mips:       return "r6";
+        case gcc_dwarf_r7_mips:       return "r7";
+        case gcc_dwarf_r8_mips:       return "r8";
+        case gcc_dwarf_r9_mips:       return "r9";
+        case gcc_dwarf_r10_mips:      return "r10";
+        case gcc_dwarf_r11_mips:      return "r11";
+        case gcc_dwarf_r12_mips:      return "r12";
+        case gcc_dwarf_r13_mips:      return "r13";
+        case gcc_dwarf_r14_mips:      return "r14";
+        case gcc_dwarf_r15_mips:      return "r15";
+        case gcc_dwarf_r16_mips:      return "r16";
+        case gcc_dwarf_r17_mips:      return "r17";
+        case gcc_dwarf_r18_mips:      return "r18";
+        case gcc_dwarf_r19_mips:      return "r19";
+        case gcc_dwarf_r20_mips:      return "r20";
+        case gcc_dwarf_r21_mips:      return "r21";
+        case gcc_dwarf_r22_mips:      return "r22";
+        case gcc_dwarf_r23_mips:      return "r23";
+        case gcc_dwarf_r24_mips:      return "r24";
+        case gcc_dwarf_r25_mips:      return "r25";
+        case gcc_dwarf_r26_mips:      return "r26";
+        case gcc_dwarf_r27_mips:      return "r27";
+        case gcc_dwarf_gp_mips:       return "gp";
+        case gcc_dwarf_sp_mips:       return "sp";
+        case gcc_dwarf_r30_mips:      return "fp";
+        case gcc_dwarf_ra_mips:       return "ra";
+        case gcc_dwarf_sr_mips:       return "sr";
+        case gcc_dwarf_lo_mips:       return "lo";
+        case gcc_dwarf_hi_mips:       return "hi";
+        case gcc_dwarf_bad_mips:      return "bad";
+        case gcc_dwarf_cause_mips:    return "cause";
+        case gcc_dwarf_pc_mips:       return "pc";
+        case gcc_dwarf_f0_mips:       return "fp_reg[0]";
+        case gcc_dwarf_f1_mips:       return "fp_reg[1]";
+        case gcc_dwarf_f2_mips:       return "fp_reg[2]";
+        case gcc_dwarf_f3_mips:       return "fp_reg[3]";
+        case gcc_dwarf_f4_mips:       return "fp_reg[4]";
+        case gcc_dwarf_f5_mips:       return "fp_reg[5]";
+        case gcc_dwarf_f6_mips:       return "fp_reg[6]";
+        case gcc_dwarf_f7_mips:       return "fp_reg[7]";
+        case gcc_dwarf_f8_mips:       return "fp_reg[8]";
+        case gcc_dwarf_f9_mips:       return "fp_reg[9]";
+        case gcc_dwarf_f10_mips:      return "fp_reg[10]";
+        case gcc_dwarf_f11_mips:      return "fp_reg[11]";
+        case gcc_dwarf_f12_mips:      return "fp_reg[12]";
+        case gcc_dwarf_f13_mips:      return "fp_reg[13]";
+        case gcc_dwarf_f14_mips:      return "fp_reg[14]";
+        case gcc_dwarf_f15_mips:      return "fp_reg[15]";
+        case gcc_dwarf_f16_mips:      return "fp_reg[16]";
+        case gcc_dwarf_f17_mips:      return "fp_reg[17]";
+        case gcc_dwarf_f18_mips:      return "fp_reg[18]";
+        case gcc_dwarf_f19_mips:      return "fp_reg[19]";
+        case gcc_dwarf_f20_mips:      return "fp_reg[20]";
+        case gcc_dwarf_f21_mips:      return "fp_reg[21]";
+        case gcc_dwarf_f22_mips:      return "fp_reg[22]";
+        case gcc_dwarf_f23_mips:      return "fp_reg[23]";
+        case gcc_dwarf_f24_mips:      return "fp_reg[24]";
+        case gcc_dwarf_f25_mips:      return "fp_reg[25]";
+        case gcc_dwarf_f26_mips:      return "fp_reg[26]";
+        case gcc_dwarf_f27_mips:      return "fp_reg[27]";
+        case gcc_dwarf_f28_mips:      return "fp_reg[28]";
+        case gcc_dwarf_f29_mips:      return "fp_reg[29]";
+        case gcc_dwarf_f30_mips:      return "fp_reg[30]";
+        case gcc_dwarf_f31_mips:      return "fp_reg[31]";
+        case gcc_dwarf_fcsr_mips:     return "fcsr";
+        case gcc_dwarf_fir_mips:      return "fir";
     }
     return nullptr;
 }
@@ -269,11 +334,11 @@ EmulateInstructionMIPS::GetRegisterInfo
     {
         switch (reg_num)
         {
-            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_pc_mips64; break;
-            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sp_mips64; break;
-            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_r30_mips64; break;
-            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_ra_mips64; break;
-            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sr_mips64; break;
+            case LLDB_REGNUM_GENERIC_PC:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_pc_mips; break;
+            case LLDB_REGNUM_GENERIC_SP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sp_mips; break;
+            case LLDB_REGNUM_GENERIC_FP:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_r30_mips; break;
+            case LLDB_REGNUM_GENERIC_RA:    reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_ra_mips; break;
+            case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = gcc_dwarf_sr_mips; break;
             default:
                 return false;
         }
@@ -284,27 +349,34 @@ EmulateInstructionMIPS::GetRegisterInfo
        ::memset (&reg_info, 0, sizeof(RegisterInfo));
        ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds));
 
-       if ((int)reg_num >= gcc_dwarf_zero_mips64 && (int)reg_num <= gcc_dwarf_pc_mips64)
+       if (reg_num == gcc_dwarf_sr_mips || reg_num == gcc_dwarf_fcsr_mips || reg_num == gcc_dwarf_fir_mips)
+       {
+           reg_info.byte_size = 4;
+           reg_info.format = eFormatHex;
+           reg_info.encoding = eEncodingUint;
+       }
+       else if ((int)reg_num >= gcc_dwarf_zero_mips && (int)reg_num <= gcc_dwarf_f31_mips)
        {
            reg_info.byte_size = 4;
            reg_info.format = eFormatHex;
            reg_info.encoding = eEncodingUint;
-           reg_info.name = GetRegisterName (reg_num, false);
-           reg_info.alt_name = GetRegisterName (reg_num, true);
-           reg_info.kinds[eRegisterKindDWARF] = reg_num;
        }
        else
        {
            return false;
        }
 
+       reg_info.name = GetRegisterName (reg_num, false);
+       reg_info.alt_name = GetRegisterName (reg_num, true);
+       reg_info.kinds[eRegisterKindDWARF] = reg_num;
+
        switch (reg_num)
        {
-           case gcc_dwarf_r30_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
-           case gcc_dwarf_ra_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
-           case gcc_dwarf_sp_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
-           case gcc_dwarf_pc_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
-           case gcc_dwarf_sr_mips64: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
+           case gcc_dwarf_r30_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break;
+           case gcc_dwarf_ra_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break;
+           case gcc_dwarf_sp_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break;
+           case gcc_dwarf_pc_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break;
+           case gcc_dwarf_sr_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break;
            default: break;
        }
        return true;
@@ -324,6 +396,68 @@ EmulateInstructionMIPS::GetOpcodeForInst
         { "ADDiu",      &EmulateInstructionMIPS::Emulate_ADDiu,       "ADDIU rt,rs,immediate"    },
         { "SW",         &EmulateInstructionMIPS::Emulate_SW,          "SW rt,offset(rs)"         },
         { "LW",         &EmulateInstructionMIPS::Emulate_LW,          "LW rt,offset(base)"       },
+
+        //----------------------------------------------------------------------
+        // Branch instructions
+        //----------------------------------------------------------------------
+        { "BEQ",        &EmulateInstructionMIPS::Emulate_BEQ,         "BEQ rs,rt,offset"          },
+        { "BNE",        &EmulateInstructionMIPS::Emulate_BNE,         "BNE rs,rt,offset"          },
+        { "BEQL",       &EmulateInstructionMIPS::Emulate_BEQL,        "BEQL rs,rt,offset"         },
+        { "BNEL",       &EmulateInstructionMIPS::Emulate_BNEL,        "BNEL rs,rt,offset"         },
+        { "BGEZALL",    &EmulateInstructionMIPS::Emulate_BGEZALL,     "BGEZALL rt,offset"         },
+        { "BAL",        &EmulateInstructionMIPS::Emulate_BAL,         "BAL offset"                },
+        { "BGEZAL",     &EmulateInstructionMIPS::Emulate_BGEZAL,      "BGEZAL rs,offset"          },
+        { "BALC",       &EmulateInstructionMIPS::Emulate_BALC,        "BALC offset"               },
+        { "BC",         &EmulateInstructionMIPS::Emulate_BC,          "BC offset"                 },
+        { "BGEZ",       &EmulateInstructionMIPS::Emulate_BGEZ,        "BGEZ rs,offset"            },
+        { "BLEZALC",    &EmulateInstructionMIPS::Emulate_BLEZALC,     "BLEZALC rs,offset"         },
+        { "BGEZALC",    &EmulateInstructionMIPS::Emulate_BGEZALC,     "BGEZALC rs,offset"         },
+        { "BLTZALC",    &EmulateInstructionMIPS::Emulate_BLTZALC,     "BLTZALC rs,offset"         },
+        { "BGTZALC",    &EmulateInstructionMIPS::Emulate_BGTZALC,     "BGTZALC rs,offset"         },
+        { "BEQZALC",    &EmulateInstructionMIPS::Emulate_BEQZALC,     "BEQZALC rs,offset"         },
+        { "BNEZALC",    &EmulateInstructionMIPS::Emulate_BNEZALC,     "BNEZALC rs,offset"         },
+        { "BEQC",       &EmulateInstructionMIPS::Emulate_BEQC,        "BEQC rs,rt,offset"         },
+        { "BNEC",       &EmulateInstructionMIPS::Emulate_BNEC,        "BNEC rs,rt,offset"         },
+        { "BLTC",       &EmulateInstructionMIPS::Emulate_BLTC,        "BLTC rs,rt,offset"         },
+        { "BGEC",       &EmulateInstructionMIPS::Emulate_BGEC,        "BGEC rs,rt,offset"         },
+        { "BLTUC",      &EmulateInstructionMIPS::Emulate_BLTUC,       "BLTUC rs,rt,offset"        },
+        { "BGEUC",      &EmulateInstructionMIPS::Emulate_BGEUC,       "BGEUC rs,rt,offset"        },
+        { "BLTZC",      &EmulateInstructionMIPS::Emulate_BLTZC,       "BLTZC rt,offset"           },
+        { "BLEZC",      &EmulateInstructionMIPS::Emulate_BLEZC,       "BLEZC rt,offset"           },
+        { "BGEZC",      &EmulateInstructionMIPS::Emulate_BGEZC,       "BGEZC rt,offset"           },
+        { "BGTZC",      &EmulateInstructionMIPS::Emulate_BGTZC,       "BGTZC rt,offset"           },
+        { "BEQZC",      &EmulateInstructionMIPS::Emulate_BEQZC,       "BEQZC rt,offset"           },
+        { "BNEZC",      &EmulateInstructionMIPS::Emulate_BNEZC,       "BNEZC rt,offset"           },
+        { "BGEZL",      &EmulateInstructionMIPS::Emulate_BGEZL,       "BGEZL rt,offset"           },
+        { "BGTZ",       &EmulateInstructionMIPS::Emulate_BGTZ,        "BGTZ rt,offset"            },
+        { "BGTZL",      &EmulateInstructionMIPS::Emulate_BGTZL,       "BGTZL rt,offset"           },
+        { "BLEZ",       &EmulateInstructionMIPS::Emulate_BLEZ,        "BLEZ rt,offset"            },
+        { "BLEZL",      &EmulateInstructionMIPS::Emulate_BLEZL,       "BLEZL rt,offset"           },
+        { "BLTZ",       &EmulateInstructionMIPS::Emulate_BLTZ,        "BLTZ rt,offset"            },
+        { "BLTZAL",     &EmulateInstructionMIPS::Emulate_BLTZAL,      "BLTZAL rt,offset"          },
+        { "BLTZALL",    &EmulateInstructionMIPS::Emulate_BLTZALL,     "BLTZALL rt,offset"         },
+        { "BLTZL",      &EmulateInstructionMIPS::Emulate_BLTZL,       "BLTZL rt,offset"           },
+        { "BOVC",       &EmulateInstructionMIPS::Emulate_BOVC,        "BOVC rs,rt,offset"         },
+        { "BNVC",       &EmulateInstructionMIPS::Emulate_BNVC,        "BNVC rs,rt,offset"         },
+        { "J",          &EmulateInstructionMIPS::Emulate_J,           "J target"                  },
+        { "JAL",        &EmulateInstructionMIPS::Emulate_JAL,         "JAL target"                },
+        { "JALX",       &EmulateInstructionMIPS::Emulate_JAL,         "JALX target"               },
+        { "JALR",       &EmulateInstructionMIPS::Emulate_JALR,        "JALR target"               },
+        { "JALR_HB",    &EmulateInstructionMIPS::Emulate_JALR,        "JALR.HB target"            },
+        { "JIALC",      &EmulateInstructionMIPS::Emulate_JIALC,       "JIALC rt,offset"           },
+        { "JIC",        &EmulateInstructionMIPS::Emulate_JIC,         "JIC rt,offset"             },
+        { "JR",         &EmulateInstructionMIPS::Emulate_JR,          "JR target"                 },
+        { "JR_HB",      &EmulateInstructionMIPS::Emulate_JR,          "JR.HB target"              },
+        { "BC1F",       &EmulateInstructionMIPS::Emulate_BC1F,        "BC1F cc, offset"           },
+        { "BC1T",       &EmulateInstructionMIPS::Emulate_BC1T,        "BC1T cc, offset"           },
+        { "BC1FL",      &EmulateInstructionMIPS::Emulate_BC1FL,       "BC1FL cc, offset"          },
+        { "BC1TL",      &EmulateInstructionMIPS::Emulate_BC1TL,       "BC1TL cc, offset"          },
+        { "BC1EQZ",     &EmulateInstructionMIPS::Emulate_BC1EQZ,      "BC1EQZ ft, offset"         },
+        { "BC1NEZ",     &EmulateInstructionMIPS::Emulate_BC1NEZ,      "BC1NEZ ft, offset"         },
+        { "BC1ANY2F",   &EmulateInstructionMIPS::Emulate_BC1ANY2F,    "BC1ANY2F cc, offset"       },
+        { "BC1ANY2T",   &EmulateInstructionMIPS::Emulate_BC1ANY2T,    "BC1ANY2T cc, offset"       },
+        { "BC1ANY4F",   &EmulateInstructionMIPS::Emulate_BC1ANY4F,    "BC1ANY4F cc, offset"       },
+        { "BC1ANY4T",   &EmulateInstructionMIPS::Emulate_BC1ANY4T,    "BC1ANY4T cc, offset"       },
     };
 
     static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
@@ -395,7 +529,7 @@ EmulateInstructionMIPS::EvaluateInstruct
 
     if (auto_advance_pc)
     {
-        old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+        old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
         if (!success)
             return false;
     }
@@ -407,7 +541,7 @@ EmulateInstructionMIPS::EvaluateInstruct
 
     if (auto_advance_pc)
     {
-        new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+        new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
         if (!success)
             return false;
 
@@ -416,7 +550,7 @@ EmulateInstructionMIPS::EvaluateInstruct
         {
             new_pc += 4;
             Context context;
-            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, new_pc))
+            if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, new_pc))
                 return false;
         }
     }
@@ -434,10 +568,10 @@ EmulateInstructionMIPS::CreateFunctionEn
     const bool can_replace = false;
 
     // Our previous Call Frame Address is the stack pointer
-    row->GetCFAValue().SetIsRegisterPlusOffset(gcc_dwarf_sp_mips64, 0);
+    row->GetCFAValue().SetIsRegisterPlusOffset(gcc_dwarf_sp_mips, 0);
 
     // Our previous PC is in the RA
-    row->SetRegisterLocationToRegister(gcc_dwarf_pc_mips64, gcc_dwarf_ra_mips64, can_replace);
+    row->SetRegisterLocationToRegister(gcc_dwarf_pc_mips, gcc_dwarf_ra_mips, can_replace);
 
     unwind_plan.AppendRow (row);
 
@@ -454,18 +588,18 @@ EmulateInstructionMIPS::nonvolatile_reg_
 {
     switch (regnum)
     {
-        case gcc_dwarf_r16_mips64:
-        case gcc_dwarf_r17_mips64:
-        case gcc_dwarf_r18_mips64:
-        case gcc_dwarf_r19_mips64:
-        case gcc_dwarf_r20_mips64:
-        case gcc_dwarf_r21_mips64:
-        case gcc_dwarf_r22_mips64:
-        case gcc_dwarf_r23_mips64:
-        case gcc_dwarf_gp_mips64:
-        case gcc_dwarf_sp_mips64:
-        case gcc_dwarf_r30_mips64:
-        case gcc_dwarf_ra_mips64:
+        case gcc_dwarf_r16_mips:
+        case gcc_dwarf_r17_mips:
+        case gcc_dwarf_r18_mips:
+        case gcc_dwarf_r19_mips:
+        case gcc_dwarf_r20_mips:
+        case gcc_dwarf_r21_mips:
+        case gcc_dwarf_r22_mips:
+        case gcc_dwarf_r23_mips:
+        case gcc_dwarf_gp_mips:
+        case gcc_dwarf_sp_mips:
+        case gcc_dwarf_r30_mips:
+        case gcc_dwarf_ra_mips:
             return true;
         default:
             return false;
@@ -486,10 +620,10 @@ EmulateInstructionMIPS::Emulate_ADDiu (l
     src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
 
     /* Check if this is addiu sp,<src>,imm16 */
-    if (dst == gcc_dwarf_sp_mips64)
+    if (dst == gcc_dwarf_sp_mips)
     {
         /* read <src> register */
-        uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + src, 0, &success);
+        uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + src, 0, &success);
         if (!success)
             return false;
 
@@ -497,13 +631,13 @@ EmulateInstructionMIPS::Emulate_ADDiu (l
 
         Context context;
         RegisterInfo reg_info_sp;
-        if (GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_sp_mips64, reg_info_sp))
+        if (GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_sp_mips, reg_info_sp))
             context.SetRegisterPlusOffset (reg_info_sp, imm);
 
         /* We are allocating bytes on stack */
         context.type = eContextAdjustStackPointer;
 
-        WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_sp_mips64, result);
+        WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_sp_mips, result);
     }
     
     return true;
@@ -521,18 +655,18 @@ EmulateInstructionMIPS::Emulate_SW (llvm
     base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
 
     /* We look for sp based non-volatile register stores */
-    if (base == gcc_dwarf_sp_mips64 && nonvolatile_reg_p (src))
+    if (base == gcc_dwarf_sp_mips && nonvolatile_reg_p (src))
     {
         uint32_t address;
         RegisterInfo reg_info_base;
         RegisterInfo reg_info_src;
 
-        if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, reg_info_base)
-            || !GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + src, reg_info_src))
+        if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, reg_info_base)
+            || !GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + src, reg_info_src))
             return false;
 
         /* read SP */
-        address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, 0, &success);
+        address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, 0, &success);
         if (!success)
             return false;
 
@@ -570,12 +704,12 @@ EmulateInstructionMIPS::Emulate_LW (llvm
     src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
     base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
 
-    if (base == gcc_dwarf_sp_mips64 && nonvolatile_reg_p (src))
+    if (base == gcc_dwarf_sp_mips && nonvolatile_reg_p (src))
     {
         RegisterValue data_src;
         RegisterInfo reg_info_src;
 
-        if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + src, reg_info_src))
+        if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + src, reg_info_src))
             return false;
 
         Context context;
@@ -589,3 +723,2196 @@ EmulateInstructionMIPS::Emulate_LW (llvm
 
     return false;
 }
+
+bool
+EmulateInstructionMIPS::Emulate_BEQ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BEQ rs, rt, offset
+     *      condition <- (GPR[rs] = GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val == rt_val)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNE (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BNE rs, rt, offset
+     *      condition <- (GPR[rs] != GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val != rt_val)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BEQL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BEQL rs, rt, offset
+     *      condition <- (GPR[rs] = GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val == rt_val)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNEL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BNEL rs, rt, offset
+     *      condition <- (GPR[rs] != GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val != rt_val)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target; 
+    int32_t rs_val;
+
+    /*
+     * BGEZL rs, offset
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val >= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZL rs, offset
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val < 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGTZL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGTZL rs, offset
+     *      condition <- (GPR[rs] > 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val > 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLEZL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLEZL rs, offset
+     *      condition <- (GPR[rs] <= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val <= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGTZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGTZ rs, offset
+     *      condition <- (GPR[rs] > 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val > 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLEZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target; 
+    int32_t rs_val;
+
+    /*
+     * BLEZ rs, offset
+     *      condition <- (GPR[rs] <= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val <= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZ rs, offset
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val < 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZALL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGEZALL rt, offset
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val >= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BAL (llvm::MCInst& insn)
+{
+    bool success = false;
+    int32_t offset, pc, target;
+
+    /*
+     * BAL offset
+     *      offset = sign_ext (offset << 2)
+     *      RA = PC + 8
+     *      PC = PC + offset
+    */
+    offset = insn.getOperand(0).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    target = pc + offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    int32_t offset, pc, target;
+
+    /* 
+     * BALC offset
+     *      offset = sign_ext (offset << 2)
+     *      RA = PC + 4
+     *      PC = PC + 4 + offset
+    */
+    offset = insn.getOperand(0).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    target = pc + 4 + offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZAL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGEZAL rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then     
+     *          RA = PC + 8
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if ((int32_t) rs_val >= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZAL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZAL rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then     
+     *          RA = PC + 8
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if ((int32_t) rs_val < 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZALL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZALL rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then     
+     *          RA = PC + 8
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val < 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+
+bool
+EmulateInstructionMIPS::Emulate_BLEZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLEZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] <= 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val <= 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGEZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val >= 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val < 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGTZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGTZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] > 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val > 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BEQZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target, rs_val;
+
+    /*
+     * BEQZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] == 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val == 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNEZALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target, rs_val;
+
+    /*
+     * BNEZALC rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] != 0)
+     *      if condition then     
+     *          RA = PC + 4
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val != 0)
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target, rs_val;
+
+    /*
+     * BGEZ rs,offset
+     *      offset = sign_ext (offset << 2)
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then     
+     *          PC = PC + offset
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (rs_val >= 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn)
+{
+    bool success = false;
+    int32_t offset, pc, target;
+
+    /* 
+     * BC offset
+     *      offset = sign_ext (offset << 2)
+     *      PC = PC + 4 + offset
+    */
+    offset = insn.getOperand(0).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    target = pc + 4 + offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BEQC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BEQC rs, rt, offset
+     *      condition <- (GPR[rs] = GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val == rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNEC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target, rs_val, rt_val;
+
+    /*
+     * BNEC rs, rt, offset
+     *      condition <- (GPR[rs] != GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val != rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    int32_t rs_val, rt_val;
+
+    /*
+     * BLTC rs, rt, offset
+     *      condition <- (GPR[rs] < GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val < rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    int32_t rs_val, rt_val;
+
+    /*
+     * BGEC rs, rt, offset
+     *      condition <- (GPR[rs] > GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val > rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTUC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    uint32_t rs_val, rt_val;
+
+    /*
+     * BLTUC rs, rt, offset
+     *      condition <- (GPR[rs] < GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val < rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEUC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    uint32_t rs_val, rt_val;
+
+    /*
+     * BGEUC rs, rt, offset
+     *      condition <- (GPR[rs] > GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val > rt_val)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLTZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLTZC rs, offset
+     *      condition <- (GPR[rs] < 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val < 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BLEZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BLEZC rs, offset
+     *      condition <- (GPR[rs] <= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val <= 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGEZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGEZC rs, offset
+     *      condition <- (GPR[rs] >= 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val >= 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BGTZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    int32_t rs_val;
+
+    /*
+     * BGTZC rs, offset
+     *      condition <- (GPR[rs] > 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val > 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BEQZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    uint32_t rs_val;
+
+    /*
+     * BEQZC rs, offset
+     *      condition <- (GPR[rs] = 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val == 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNEZC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    int32_t offset, pc, target;
+    uint32_t rs_val;
+
+    /*
+     * BNEZC rs, offset
+     *      condition <- (GPR[rs] != 0)
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    if (rs_val != 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+static int
+IsAdd64bitOverflow (int32_t a, int32_t b)
+{
+  int32_t r = (uint32_t) a + (uint32_t) b;
+  return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BOVC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    int32_t rs_val, rt_val;
+
+    /*
+     * BOVC rs, rt, offset
+     *      condition <- overflow(GPR[rs] + GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (IsAdd64bitOverflow (rs_val, rt_val))
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BNVC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    int32_t offset, pc, target;
+    int32_t rs_val, rt_val;
+
+    /*
+     * BNVC rs, rt, offset
+     *      condition <- overflow(GPR[rs] + GPR[rt])
+     *      if condition then
+     *          PC = PC + sign_ext (offset << 2)
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+    offset = insn.getOperand(2).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    if (! IsAdd64bitOverflow (rs_val, rt_val))
+        target = pc + offset;
+    else
+        target = pc + 4;
+
+    Context context;
+    context.type = eContextRelativeBranchImmediate;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t offset, pc;
+
+    /* 
+     * J offset
+     *      offset = sign_ext (offset << 2)
+     *      PC = PC[63-28] | offset
+    */
+    offset = insn.getOperand(0).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* This is a PC-region branch and not PC-relative */
+    pc = (pc & 0xF0000000UL) | offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, pc))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t offset, target, pc;
+
+    /* 
+     * JAL offset
+     *      offset = sign_ext (offset << 2)
+     *      PC = PC[63-28] | offset
+    */
+    offset = insn.getOperand(0).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* This is a PC-region branch and not PC-relative */
+    target = (pc & 0xF0000000UL) | offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs, rt;
+    uint32_t pc, rs_val;
+
+    /* 
+     * JALR rt, rs
+     *      GPR[rt] = PC + 8
+     *      PC = GPR[rs]
+    */
+    rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, rs_val))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, pc + 8))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rt;
+    int32_t target, offset, pc, rt_val;
+
+    /* 
+     * JIALC rt, offset
+     *      offset = sign_ext (offset)
+     *      PC = GPR[rt] + offset
+     *      RA = PC + 4
+    */
+    rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    target = rt_val + offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips, pc + 4))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rt;
+    int32_t target, offset, rt_val;
+
+    /* 
+     * JIC rt, offset
+     *      offset = sign_ext (offset)
+     *      PC = GPR[rt] + offset
+    */
+    rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+
+    rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rt, 0, &success);
+    if (!success)
+        return false;
+
+    target = rt_val + offset;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t rs;
+    uint32_t rs_val;
+
+    /* 
+     * JR rs
+     *      PC = GPR[rs]
+    */
+    rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+
+    rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + rs, 0, &success);
+    if (!success)
+        return false;
+
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, rs_val))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1F (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1F cc, offset
+     *  condition <- (FPConditionCode(cc) == 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+    
+    if ((fcsr & (1 << cc)) == 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1T (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1T cc, offset
+     *  condition <- (FPConditionCode(cc) != 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+    
+    if ((fcsr & (1 << cc)) != 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1FL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1F cc, offset
+     *  condition <- (FPConditionCode(cc) == 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+    
+    if ((fcsr & (1 << cc)) == 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1TL (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1T cc, offset
+     *  condition <- (FPConditionCode(cc) != 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+    
+    if ((fcsr & (1 << cc)) != 0)
+        target = pc + offset;
+    else
+        target = pc + 8;    /* skip delay slot */
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t ft;
+    uint32_t ft_val;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1EQZ ft, offset
+     *  condition <- (FPR[ft].bit0 == 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + 4 + offset
+    */
+    ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + ft, 0, &success);
+    if (!success)
+        return false;
+
+    if ((ft_val & 1) == 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t ft;
+    uint32_t ft_val;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1NEZ ft, offset
+     *  condition <- (FPR[ft].bit0 != 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + 4 + offset
+    */
+    ft = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + ft, 0, &success);
+    if (!success)
+        return false;
+
+    if ((ft_val & 1) != 0)
+        target = pc + 4 + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1ANY2F (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1ANY2F cc, offset
+     *  condition <- (FPConditionCode(cc) == 0 
+     *                  || FPConditionCode(cc+1) == 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+
+    /* if any one bit is 0 */
+    if (((fcsr >> cc) & 3) != 3)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1ANY2T (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1ANY2T cc, offset
+     *  condition <- (FPConditionCode(cc) == 1 
+     *                  || FPConditionCode(cc+1) == 1)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+
+    /* if any one bit is 1 */
+    if (((fcsr >> cc) & 3) != 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1ANY4F (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1ANY4F cc, offset
+     *  condition <- (FPConditionCode(cc) == 0 
+     *                  || FPConditionCode(cc+1) == 0)
+     *                  || FPConditionCode(cc+2) == 0)
+     *                  || FPConditionCode(cc+3) == 0)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+
+    /* if any one bit is 0 */
+    if (((fcsr >> cc) & 0xf) != 0xf)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}
+
+bool
+EmulateInstructionMIPS::Emulate_BC1ANY4T (llvm::MCInst& insn)
+{
+    bool success = false;
+    uint32_t cc, fcsr;
+    int32_t target, pc, offset;
+    
+    /*
+     * BC1ANY4T cc, offset
+     *  condition <- (FPConditionCode(cc) == 1 
+     *                  || FPConditionCode(cc+1) == 1)
+     *                  || FPConditionCode(cc+2) == 1)
+     *                  || FPConditionCode(cc+3) == 1)
+     *      if condition then
+     *          offset = sign_ext (offset)
+     *          PC = PC + offset
+    */
+    cc = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+    offset = insn.getOperand(1).getImm();
+    
+    pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips, 0, &success);
+    if (!success)
+        return false;
+
+    fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_fcsr_mips, 0, &success);
+    if (!success)
+        return false;
+
+    /* fcsr[23], fcsr[25-31] are vaild condition bits */
+    fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01);
+
+    /* if any one bit is 1 */
+    if (((fcsr >> cc) & 0xf) != 0)
+        target = pc + offset;
+    else
+        target = pc + 8;
+    
+    Context context;
+
+    if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips, target))
+        return false;
+
+    return true;
+}

Modified: lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h Mon Jun 22 22:37:08 2015
@@ -131,6 +131,171 @@ protected:
     Emulate_LW (llvm::MCInst& insn);
 
     bool
+    Emulate_BEQ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNE (llvm::MCInst& insn);
+
+    bool
+    Emulate_BEQL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNEL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZALL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BAL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZAL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLEZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGTZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BEQZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNEZALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BEQC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNEC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTUC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEUC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLEZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGTZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BEQZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNEZC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGEZL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGTZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BGTZL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLEZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLEZL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZAL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZALL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BLTZL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BOVC (llvm::MCInst& insn);
+
+    bool
+    Emulate_BNVC (llvm::MCInst& insn);
+
+    bool
+    Emulate_J (llvm::MCInst& insn);
+
+    bool
+    Emulate_JAL (llvm::MCInst& insn);
+
+    bool
+    Emulate_JALR (llvm::MCInst& insn);
+
+    bool
+    Emulate_JIALC (llvm::MCInst& insn);
+
+    bool
+    Emulate_JIC (llvm::MCInst& insn);
+
+    bool
+    Emulate_JR (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1F (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1T (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1FL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1TL (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1EQZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1NEZ (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1ANY2F  (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1ANY2T  (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1ANY4F  (llvm::MCInst& insn);
+
+    bool
+    Emulate_BC1ANY4T  (llvm::MCInst& insn);
+
+    bool
     nonvolatile_reg_p (uint32_t regnum);
 
     const char *

Modified: lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp Mon Jun 22 22:37:08 2015
@@ -758,7 +758,7 @@ EmulateInstructionMIPS64::Emulate_BEQ (l
     if (rs_val == rt_val)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     Context context;
     context.type = eContextRelativeBranchImmediate;
@@ -801,7 +801,7 @@ EmulateInstructionMIPS64::Emulate_BNE (l
     if (rs_val != rt_val)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     Context context;
     context.type = eContextRelativeBranchImmediate;
@@ -913,7 +913,7 @@ EmulateInstructionMIPS64::Emulate_BGEZL
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -952,7 +952,7 @@ EmulateInstructionMIPS64::Emulate_BLTZL
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -991,7 +991,7 @@ EmulateInstructionMIPS64::Emulate_BGTZL
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -1030,7 +1030,7 @@ EmulateInstructionMIPS64::Emulate_BLEZL
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -1069,7 +1069,7 @@ EmulateInstructionMIPS64::Emulate_BGTZ (
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -1082,7 +1082,7 @@ EmulateInstructionMIPS64::Emulate_BGTZ (
     if (rs_val > 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     Context context;
     context.type = eContextRelativeBranchImmediate;
@@ -1108,7 +1108,7 @@ EmulateInstructionMIPS64::Emulate_BLEZ (
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -1121,7 +1121,7 @@ EmulateInstructionMIPS64::Emulate_BLEZ (
     if (rs_val <= 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     Context context;
     context.type = eContextRelativeBranchImmediate;
@@ -1147,7 +1147,7 @@ EmulateInstructionMIPS64::Emulate_BLTZ (
      *          PC = PC + sign_ext (offset << 2)
     */
     rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
-    offset = insn.getOperand(2).getImm();
+    offset = insn.getOperand(1).getImm();
 
     pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
     if (!success)
@@ -1160,7 +1160,7 @@ EmulateInstructionMIPS64::Emulate_BLTZ (
     if (rs_val < 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     Context context;
     context.type = eContextRelativeBranchImmediate;
@@ -1307,7 +1307,7 @@ EmulateInstructionMIPS64::Emulate_BGEZAL
     if ((int64_t) rs_val >= 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
         return false;
@@ -1350,7 +1350,7 @@ EmulateInstructionMIPS64::Emulate_BLTZAL
     if ((int64_t) rs_val < 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
         return false;
@@ -1691,7 +1691,7 @@ EmulateInstructionMIPS64::Emulate_BGEZ (
     if (rs_val >= 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
 
     if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
         return false;
@@ -2532,7 +2532,7 @@ EmulateInstructionMIPS64::Emulate_BC1F (
     if ((fcsr & (1 << cc)) == 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2573,7 +2573,7 @@ EmulateInstructionMIPS64::Emulate_BC1T (
     if ((fcsr & (1 << cc)) != 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2694,7 +2694,7 @@ EmulateInstructionMIPS64::Emulate_BC1EQZ
     if ((ft_val & 1) == 0)
         target = pc + 4 + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2733,7 +2733,7 @@ EmulateInstructionMIPS64::Emulate_BC1NEZ
     if ((ft_val & 1) != 0)
         target = pc + 4 + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2776,7 +2776,7 @@ EmulateInstructionMIPS64::Emulate_BC1ANY
     if (((fcsr >> cc) & 3) != 3)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2819,7 +2819,7 @@ EmulateInstructionMIPS64::Emulate_BC1ANY
     if (((fcsr >> cc) & 3) != 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2864,7 +2864,7 @@ EmulateInstructionMIPS64::Emulate_BC1ANY
     if (((fcsr >> cc) & 0xf) != 0xf)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 
@@ -2909,7 +2909,7 @@ EmulateInstructionMIPS64::Emulate_BC1ANY
     if (((fcsr >> cc) & 0xf) != 0)
         target = pc + offset;
     else
-        target = pc + 4;
+        target = pc + 8;
     
     Context context;
 

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Mon Jun 22 22:37:08 2015
@@ -2018,7 +2018,7 @@ NativeProcessLinux::MonitorSIGTRAP(const
         {
             // If a watchpoint was hit, report it
             uint32_t wp_index;
-            Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, NULL);
+            Error error = thread_sp->GetRegisterContext()->GetWatchpointHitIndex(wp_index, LLDB_INVALID_ADDRESS);
             if (error.Fail() && log)
                 log->Printf("NativeProcessLinux::%s() "
                             "received error while checking for watchpoint hits, "
@@ -2442,7 +2442,9 @@ NativeProcessLinux::SetupSoftwareSingleS
         }
     }
     else if (m_arch.GetMachine() == llvm::Triple::mips64
-            || m_arch.GetMachine() == llvm::Triple::mips64el)
+            || m_arch.GetMachine() == llvm::Triple::mips64el
+            || m_arch.GetMachine() == llvm::Triple::mips
+            || m_arch.GetMachine() == llvm::Triple::mipsel)
         error = SetSoftwareBreakpoint(next_pc, 4);
     else
     {
@@ -2462,7 +2464,8 @@ bool
 NativeProcessLinux::SupportHardwareSingleStepping() const
 {
     if (m_arch.GetMachine() == llvm::Triple::arm
-        || m_arch.GetMachine() == llvm::Triple::mips64 || m_arch.GetMachine() == llvm::Triple::mips64el)
+        || m_arch.GetMachine() == llvm::Triple::mips64 || m_arch.GetMachine() == llvm::Triple::mips64el
+        || m_arch.GetMachine() == llvm::Triple::mips || m_arch.GetMachine() == llvm::Triple::mipsel)
         return false;
     return true;
 }
@@ -3028,7 +3031,6 @@ NativeProcessLinux::GetSoftwareBreakpoin
     // set per architecture.  Need ARM, MIPS support here.
     static const uint8_t g_aarch64_opcode[] = { 0x00, 0x00, 0x20, 0xd4 };
     static const uint8_t g_i386_opcode [] = { 0xCC };
-    static const uint8_t g_mips64_opcode[] = { 0x00, 0x00, 0x00, 0x0d };
 
     switch (m_arch.GetMachine ())
     {
@@ -3049,7 +3051,7 @@ NativeProcessLinux::GetSoftwareBreakpoin
         case llvm::Triple::mips64el:
         case llvm::Triple::mips:
         case llvm::Triple::mipsel:
-            actual_opcode_size = static_cast<uint32_t> (sizeof(g_mips64_opcode));
+            actual_opcode_size = 0;
             return Error ();
         
         default:
@@ -3553,7 +3555,7 @@ NativeProcessLinux::FixupBreakpointPCAsN
     }
 
     // First try probing for a breakpoint at a software breakpoint location: PC - breakpoint size.
-    const lldb::addr_t initial_pc_addr = context_sp->GetPC ();
+    const lldb::addr_t initial_pc_addr = context_sp->GetPCfromBreakpointLocation ();
     lldb::addr_t breakpoint_addr = initial_pc_addr;
     if (breakpoint_size > 0)
     {

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp Mon Jun 22 22:37:08 2015
@@ -485,6 +485,58 @@ NativeRegisterContextLinux_mips64::GetRe
     return k_num_register_sets;
 }
 
+lldb::addr_t
+NativeRegisterContextLinux_mips64::GetPCfromBreakpointLocation (lldb::addr_t fail_value)
+{
+    Error error;
+    RegisterValue pc_value;
+    lldb::addr_t pc = fail_value;
+    Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+    
+    if (log)
+        log->Printf ("NativeRegisterContextLinux_mips64::%s Reading PC from breakpoint location", __FUNCTION__);
+
+    // PC register is at index 34 of the register array
+    const RegisterInfo *const pc_info_p = GetRegisterInfoAtIndex (34);
+        
+    error = ReadRegister (pc_info_p, pc_value);
+    if (error.Success ())
+    {
+        pc = pc_value.GetAsUInt64 ();
+        
+        // CAUSE register is at index 37 of the register array
+        const RegisterInfo *const cause_info_p = GetRegisterInfoAtIndex (37);
+        RegisterValue cause_value;
+
+        ReadRegister (cause_info_p, cause_value);
+
+        uint64_t cause = cause_value.GetAsUInt64 ();
+        
+        if (log)
+            log->Printf ("NativeRegisterContextLinux_mips64::%s PC 0x%" PRIx64 " Cause 0x%" PRIx64, __FUNCTION__, pc, cause);
+
+        /*
+         * The breakpoint might be in a delay slot. In this case PC points
+         * to the delayed branch instruction rather then the instruction
+         * in the delay slot. If the CAUSE.BD flag is set then adjust the 
+         * PC based on the size of the branch instruction.
+        */
+        if ((cause & (1 << 31)) != 0)
+        {
+            lldb::addr_t branch_delay = 0;
+            branch_delay = 4;   // FIXME - Adjust according to size of branch instruction at PC
+            pc = pc + branch_delay;
+            pc_value.SetUInt64 (pc);
+            WriteRegister (pc_info_p, pc_value);
+            
+            if (log)
+                log->Printf ("NativeRegisterContextLinux_mips64::%s New PC 0x%" PRIx64, __FUNCTION__, pc);
+        }
+    }
+
+    return pc;
+}
+
 const RegisterSet *
 NativeRegisterContextLinux_mips64::GetRegisterSet (uint32_t set_index) const
 {

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h?rev=240373&r1=240372&r2=240373&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h Mon Jun 22 22:37:08 2015
@@ -33,6 +33,9 @@ namespace process_linux {
         uint32_t
         GetRegisterSetCount () const override;
 
+        lldb::addr_t
+        GetPCfromBreakpointLocation (lldb::addr_t fail_value = LLDB_INVALID_ADDRESS) override;
+
         const RegisterSet *
         GetRegisterSet (uint32_t set_index) const override;
 





More information about the lldb-commits mailing list