[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 (®_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