[Lldb-commits] [lldb] r238820 - [LLDB][MIPS] MIPS64 Branch instruction emulation for SW single stepping
Mohit K. Bhakkad
mohit.bhakkad at gmail.com
Tue Jun 2 04:22:29 PDT 2015
Author: mohit.bhakkad
Date: Tue Jun 2 06:22:29 2015
New Revision: 238820
URL: http://llvm.org/viewvc/llvm-project?rev=238820&view=rev
Log:
[LLDB][MIPS] MIPS64 Branch instruction emulation for SW single stepping
Patch by Jaydeep Patil
Reviewers: clayborg, jasonmolenda
Subscribers: bhushan, mohit.bhakkad, sagar, lldb-commits.
Differential Revision: http://reviews.llvm.org/D10155
Modified:
lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
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=238820&r1=238819&r2=238820&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp Tue Jun 2 06:22:29 2015
@@ -335,9 +335,54 @@ EmulateInstructionMIPS64::GetOpcodeForIn
//----------------------------------------------------------------------
// Branch instructions
//----------------------------------------------------------------------
- { "B", &EmulateInstructionMIPS64::Emulate_B, "B offset" },
+ { "BEQ", &EmulateInstructionMIPS64::Emulate_BEQ, "BEQ rs,rt,offset" },
+ { "BNE", &EmulateInstructionMIPS64::Emulate_BNE, "BNE rs,rt,offset" },
+ { "BEQL", &EmulateInstructionMIPS64::Emulate_BEQL, "BEQL rs,rt,offset" },
+ { "BNEL", &EmulateInstructionMIPS64::Emulate_BNEL, "BNEL rs,rt,offset" },
+ { "BGEZALL", &EmulateInstructionMIPS64::Emulate_BGEZALL, "BGEZALL rt,offset" },
{ "BAL", &EmulateInstructionMIPS64::Emulate_BAL, "BAL offset" },
+ { "BGEZAL", &EmulateInstructionMIPS64::Emulate_BGEZAL, "BGEZAL rs,offset" },
{ "BALC", &EmulateInstructionMIPS64::Emulate_BALC, "BALC offset" },
+ { "BC", &EmulateInstructionMIPS64::Emulate_BC, "BC offset" },
+ { "BGEZ", &EmulateInstructionMIPS64::Emulate_BGEZ, "BGEZ rs,offset" },
+ { "BLEZALC", &EmulateInstructionMIPS64::Emulate_BLEZALC, "BLEZALC rs,offset" },
+ { "BGEZALC", &EmulateInstructionMIPS64::Emulate_BGEZALC, "BGEZALC rs,offset" },
+ { "BLTZALC", &EmulateInstructionMIPS64::Emulate_BLTZALC, "BLTZALC rs,offset" },
+ { "BGTZALC", &EmulateInstructionMIPS64::Emulate_BGTZALC, "BGTZALC rs,offset" },
+ { "BEQZALC", &EmulateInstructionMIPS64::Emulate_BEQZALC, "BEQZALC rs,offset" },
+ { "BNEZALC", &EmulateInstructionMIPS64::Emulate_BNEZALC, "BNEZALC rs,offset" },
+ { "BEQC", &EmulateInstructionMIPS64::Emulate_BEQC, "BEQC rs,rt,offset" },
+ { "BNEC", &EmulateInstructionMIPS64::Emulate_BNEC, "BNEC rs,rt,offset" },
+ { "BLTC", &EmulateInstructionMIPS64::Emulate_BLTC, "BLTC rs,rt,offset" },
+ { "BGEC", &EmulateInstructionMIPS64::Emulate_BGEC, "BGEC rs,rt,offset" },
+ { "BLTUC", &EmulateInstructionMIPS64::Emulate_BLTUC, "BLTUC rs,rt,offset" },
+ { "BGEUC", &EmulateInstructionMIPS64::Emulate_BGEUC, "BGEUC rs,rt,offset" },
+ { "BLTZC", &EmulateInstructionMIPS64::Emulate_BLTZC, "BLTZC rt,offset" },
+ { "BLEZC", &EmulateInstructionMIPS64::Emulate_BLEZC, "BLEZC rt,offset" },
+ { "BGEZC", &EmulateInstructionMIPS64::Emulate_BGEZC, "BGEZC rt,offset" },
+ { "BGTZC", &EmulateInstructionMIPS64::Emulate_BGTZC, "BGTZC rt,offset" },
+ { "BEQZC", &EmulateInstructionMIPS64::Emulate_BEQZC, "BEQZC rt,offset" },
+ { "BNEZC", &EmulateInstructionMIPS64::Emulate_BNEZC, "BNEZC rt,offset" },
+ { "BGEZL", &EmulateInstructionMIPS64::Emulate_BGEZL, "BGEZL rt,offset" },
+ { "BGTZ", &EmulateInstructionMIPS64::Emulate_BGTZ, "BGTZ rt,offset" },
+ { "BGTZL", &EmulateInstructionMIPS64::Emulate_BGTZL, "BGTZL rt,offset" },
+ { "BLEZ", &EmulateInstructionMIPS64::Emulate_BLEZ, "BLEZ rt,offset" },
+ { "BLEZL", &EmulateInstructionMIPS64::Emulate_BLEZL, "BLEZL rt,offset" },
+ { "BLTZ", &EmulateInstructionMIPS64::Emulate_BLTZ, "BLTZ rt,offset" },
+ { "BLTZAL", &EmulateInstructionMIPS64::Emulate_BLTZAL, "BLTZAL rt,offset" },
+ { "BLTZALL", &EmulateInstructionMIPS64::Emulate_BLTZALL, "BLTZALL rt,offset" },
+ { "BLTZL", &EmulateInstructionMIPS64::Emulate_BLTZL, "BLTZL rt,offset" },
+ { "BOVC", &EmulateInstructionMIPS64::Emulate_BOVC, "BOVC rs,rt,offset" },
+ { "BNVC", &EmulateInstructionMIPS64::Emulate_BNVC, "BNVC rs,rt,offset" },
+ { "J", &EmulateInstructionMIPS64::Emulate_J, "J target" },
+ { "JAL", &EmulateInstructionMIPS64::Emulate_JAL, "JAL target" },
+ { "JALX", &EmulateInstructionMIPS64::Emulate_JAL, "JALX target" },
+ { "JALR", &EmulateInstructionMIPS64::Emulate_JALR, "JALR target" },
+ { "JALR_HB", &EmulateInstructionMIPS64::Emulate_JALR, "JALR.HB target" },
+ { "JIALC", &EmulateInstructionMIPS64::Emulate_JIALC, "JIALC rt,offset" },
+ { "JIC", &EmulateInstructionMIPS64::Emulate_JIC, "JIC rt,offset" },
+ { "JR", &EmulateInstructionMIPS64::Emulate_JR, "JR target" },
+ { "JR_HB", &EmulateInstructionMIPS64::Emulate_JR, "JR.HB target" },
};
static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes);
@@ -605,17 +650,505 @@ EmulateInstructionMIPS64::Emulate_LD (ll
}
bool
-EmulateInstructionMIPS64::Emulate_B (llvm::MCInst& insn)
+EmulateInstructionMIPS64::Emulate_BEQ (llvm::MCInst& insn)
{
bool success = false;
- uint64_t offset, pc, target;
+ uint32_t rs, rt;
+ int64_t offset, pc, target, rs_val, rt_val;
/*
- * B offset
- * PC = PC + sign_ext (offset << 2)
+ * BEQ rs, rt, offset
+ * condition <- (GPR[rs] = GPR[rt])
+ * if condition then
+ * PC = PC + sign_ext (offset << 2)
*/
- offset = insn.getOperand(0).getImm() << 2;
- offset = SignedBits (offset, 17, 0);
+ 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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNE (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BEQL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNEL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEZL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGTZL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLEZL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGTZ (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLEZ (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZ (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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(2).getImm();
+
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ Context context;
+ context.type = eContextRelativeBranchImmediate;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEZALL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 8))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BAL (llvm::MCInst& insn)
+{
+ bool success = false;
+ int64_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_mips64, 0, &success);
if (!success)
@@ -624,6 +1157,830 @@ EmulateInstructionMIPS64::Emulate_B (llv
target = pc + offset;
Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 8))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ target = pc + 4 + offset;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEZAL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if ((int64_t) rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 8))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZAL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if ((int64_t) rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 4;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 8))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZALL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 8))
+ return false;
+
+ return true;
+}
+
+
+bool
+EmulateInstructionMIPS64::Emulate_BLEZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGTZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BEQZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_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 = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNEZALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_ra_mips64, pc + 4))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEZ (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BC (llvm::MCInst& insn)
+{
+ bool success = false;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ target = pc + 4 + offset;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BEQC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNEC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTUC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ uint64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGEUC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ uint64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLTZC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BLEZC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
@@ -633,25 +1990,303 @@ EmulateInstructionMIPS64::Emulate_B (llv
}
bool
-EmulateInstructionMIPS64::Emulate_BAL (llvm::MCInst& insn)
+EmulateInstructionMIPS64::Emulate_BGEZC (llvm::MCInst& insn)
{
bool success = false;
- uint64_t offset, pc, target;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_t rs_val;
/*
- * BAL offset
+ * 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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BGTZC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BEQZC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ uint64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNEZC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ int64_t offset, pc, target;
+ uint64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+static int
+IsAdd64bitOverflow (int64_t a, int64_t b)
+{
+ int64_t r = (uint64_t) a + (uint64_t) b;
+ return (a < 0 && b < 0 && r >= 0) || (a >= 0 && b >= 0 && r < 0);
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BOVC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_BNVC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs, rt;
+ int64_t offset, pc, target;
+ int64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + 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_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_J (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint64_t offset, pc;
+
+ /*
+ * J offset
* offset = sign_ext (offset << 2)
- * RA = PC + 8
- * PC = PC + offset
+ * PC = PC[63-28] | offset
*/
- offset = insn.getOperand(0).getImm() << 2;
- offset = SignedBits (offset, 17, 0);
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
if (!success)
return false;
- target = pc + offset;
+ /* This is a PC-region branch and not PC-relative */
+ pc = (pc & 0xFFFFFFFFF0000000ULL) | offset;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, pc))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_JAL (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint64_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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ /* This is a PC-region branch and not PC-relative */
+ target = (pc & 0xFFFFFFFFF0000000ULL) | offset;
Context context;
@@ -665,25 +2300,64 @@ EmulateInstructionMIPS64::Emulate_BAL (l
}
bool
-EmulateInstructionMIPS64::Emulate_BALC (llvm::MCInst& insn)
+EmulateInstructionMIPS64::Emulate_JALR (llvm::MCInst& insn)
{
bool success = false;
- uint64_t offset, pc, target;
+ uint32_t rs, rt;
+ uint64_t pc, rs_val;
/*
- * BALC offset
- * offset = sign_ext (offset << 2)
+ * 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_mips64, 0, &success);
+ if (!success)
+ return false;
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, rs_val))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rt, pc + 8))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_JIALC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rt;
+ int64_t target, offset, pc, rt_val;
+
+ /*
+ * JIALC rt, offset
+ * offset = sign_ext (offset)
+ * PC = GPR[rt] + offset
* RA = PC + 4
- * PC = PC + 4 + offset
*/
- offset = insn.getOperand(0).getImm() << 2;
- offset = SignedBits (offset, 17, 0);
+ rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_pc_mips64, 0, &success);
if (!success)
return false;
- target = pc + 4 + offset;
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ target = rt_val + offset;
Context context;
@@ -694,4 +2368,58 @@ EmulateInstructionMIPS64::Emulate_BALC (
return false;
return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_JIC (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rt;
+ int64_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(0).getImm();
+
+ rt_val = (int64_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rt, 0, &success);
+ if (!success)
+ return false;
+
+ target = rt_val + offset;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, target))
+ return false;
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_JR (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t rs;
+ uint64_t rs_val;
+
+ /*
+ * JR rs
+ * PC = GPR[rs]
+ */
+ rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+
+ rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + rs, 0, &success);
+ if (!success)
+ return false;
+
+ Context context;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, gcc_dwarf_pc_mips64, rs_val))
+ return false;
+
+ return true;
}
Modified: lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h?rev=238820&r1=238819&r2=238820&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h Tue Jun 2 06:22:29 2015
@@ -131,15 +131,141 @@ protected:
Emulate_LD (llvm::MCInst& insn);
bool
- Emulate_B (llvm::MCInst& insn);
-
+ 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
nonvolatile_reg_p (uint64_t regnum);
const char *
More information about the lldb-commits
mailing list