[Lldb-commits] [lldb] r256915 - [LLDB][MIPS32]Merge emulation of similar instructions
Bhushan D. Attarde via lldb-commits
lldb-commits at lists.llvm.org
Tue Jan 5 21:44:03 PST 2016
Author: bhushan.attarde
Date: Tue Jan 5 23:44:02 2016
New Revision: 256915
URL: http://llvm.org/viewvc/llvm-project?rev=256915&view=rev
Log:
[LLDB][MIPS32]Merge emulation of similar instructions
SUMMARY:
This patch merges emulation of similar instructions into a single function (wherever possible) to remove code duplication.
Reviewers: clayborg
Subscribers: mohit.bhakkad, sagar, jaydeep, lldb-commits
Differential Revision: http://reviews.llvm.org/D15886
Modified:
lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
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=256915&r1=256914&r2=256915&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp Tue Jan 5 23:44:02 2016
@@ -591,45 +591,45 @@ EmulateInstructionMIPS::GetOpcodeForInst
//----------------------------------------------------------------------
// 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" },
+ { "BEQ", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQ rs,rt,offset" },
+ { "BNE", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNE rs,rt,offset" },
+ { "BEQL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BEQL rs,rt,offset" },
+ { "BNEL", &EmulateInstructionMIPS::Emulate_BXX_3ops, "BNEL rs,rt,offset" },
+ { "BGEZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BGEZALL rt,offset" },
{ "BAL", &EmulateInstructionMIPS::Emulate_BAL, "BAL offset" },
- { "BGEZAL", &EmulateInstructionMIPS::Emulate_BGEZAL, "BGEZAL rs,offset" },
+ { "BGEZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "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" },
+ { "BGEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZ rs,offset" },
+ { "BLEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLEZALC rs,offset" },
+ { "BGEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGEZALC rs,offset" },
+ { "BLTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BLTZALC rs,offset" },
+ { "BGTZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BGTZALC rs,offset" },
+ { "BEQZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BEQZALC rs,offset" },
+ { "BNEZALC", &EmulateInstructionMIPS::Emulate_Bcond_Link_C,"BNEZALC rs,offset" },
+ { "BEQC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BEQC rs,rt,offset" },
+ { "BNEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNEC rs,rt,offset" },
+ { "BLTC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTC rs,rt,offset" },
+ { "BGEC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEC rs,rt,offset" },
+ { "BLTUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BLTUC rs,rt,offset" },
+ { "BGEUC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BGEUC rs,rt,offset" },
+ { "BLTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLTZC rt,offset" },
+ { "BLEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BLEZC rt,offset" },
+ { "BGEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGEZC rt,offset" },
+ { "BGTZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BGTZC rt,offset" },
+ { "BEQZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BEQZC rt,offset" },
+ { "BNEZC", &EmulateInstructionMIPS::Emulate_BXX_2ops_C, "BNEZC rt,offset" },
+ { "BGEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGEZL rt,offset" },
+ { "BGTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZ rt,offset" },
+ { "BGTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BGTZL rt,offset" },
+ { "BLEZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZ rt,offset" },
+ { "BLEZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLEZL rt,offset" },
+ { "BLTZ", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZ rt,offset" },
+ { "BLTZAL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZAL rt,offset" },
+ { "BLTZALL", &EmulateInstructionMIPS::Emulate_Bcond_Link, "BLTZALL rt,offset" },
+ { "BLTZL", &EmulateInstructionMIPS::Emulate_BXX_2ops, "BLTZL rt,offset" },
+ { "BOVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BOVC rs,rt,offset" },
+ { "BNVC", &EmulateInstructionMIPS::Emulate_BXX_3ops_C, "BNVC rs,rt,offset" },
{ "J", &EmulateInstructionMIPS::Emulate_J, "J target" },
{ "JAL", &EmulateInstructionMIPS::Emulate_JAL, "JAL target" },
{ "JALX", &EmulateInstructionMIPS::Emulate_JAL, "JALX target" },
@@ -639,16 +639,16 @@ EmulateInstructionMIPS::GetOpcodeForInst
{ "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" },
+ { "BC1F", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1F cc, offset" },
+ { "BC1T", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1T cc, offset" },
+ { "BC1FL", &EmulateInstructionMIPS::Emulate_FP_branch, "BC1FL cc, offset" },
+ { "BC1TL", &EmulateInstructionMIPS::Emulate_FP_branch, "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" },
+ { "BC1ANY2F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2F cc, offset" },
+ { "BC1ANY2T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY2T cc, offset" },
+ { "BC1ANY4F", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4F cc, offset" },
+ { "BC1ANY4T", &EmulateInstructionMIPS::Emulate_3D_branch, "BC1ANY4T cc, offset" },
{ "BNZ_B", &EmulateInstructionMIPS::Emulate_BNZB, "BNZ.b wt,s16" },
{ "BNZ_H", &EmulateInstructionMIPS::Emulate_BNZH, "BNZ.h wt,s16" },
{ "BNZ_W", &EmulateInstructionMIPS::Emulate_BNZW, "BNZ.w wt,s16" },
@@ -1387,19 +1387,26 @@ EmulateInstructionMIPS::Emulate_JRADDIUS
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);
+}
+
+/*
+ Emulate below MIPS branch instructions.
+ BEQ, BNE : Branch on condition
+ BEQL, BNEL : Branch likely
+*/
bool
-EmulateInstructionMIPS::Emulate_BEQ (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BXX_3ops (llvm::MCInst& insn)
{
bool success = false;
uint32_t rs, rt;
int32_t offset, pc, target, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
- /*
- * 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();
@@ -1416,459 +1423,342 @@ EmulateInstructionMIPS::Emulate_BEQ (llv
if (!success)
return false;
- if (rs_val == rt_val)
- target = pc + offset;
- else
- target = pc + 8;
+ if (!strcasecmp (op_name, "BEQ") ||
+ !strcasecmp (op_name, "BEQL"))
+ {
+ if (rs_val == rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BNE") ||
+ !strcasecmp (op_name, "BNEL"))
+ {
+ if (rs_val != rt_val)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
Context context;
context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate (offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
+ return false;
+
return true;
}
+/*
+ Emulate below MIPS branch instructions.
+ BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot
+*/
bool
-EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn)
{
bool success = false;
- int32_t offset, pc, target;
+ uint32_t rs, rt;
+ int32_t offset, pc, target, rs_val, rt_val;
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
-
- offset = insn.getOperand(0).getImm();
+
+ 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, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- // unconditional branch
- target = pc + offset;
+ rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
+
+ rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ if (!success)
+ return false;
+
+ if (!strcasecmp (op_name, "BEQC"))
+ {
+ if (rs_val == rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BNEC"))
+ {
+ if (rs_val != rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BLTC"))
+ {
+ if (rs_val < rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BGEC"))
+ {
+ if (rs_val >= rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BLTUC"))
+ {
+ if (rs_val < rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BGEUC"))
+ {
+ if ((uint32_t)rs_val >= (uint32_t)rt_val)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BOVC"))
+ {
+ if (IsAdd64bitOverflow (rs_val, rt_val))
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BNVC"))
+ {
+ if (!IsAdd64bitOverflow (rs_val, rt_val))
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
Context context;
context.type = eContextRelativeBranchImmediate;
context.SetImmediate (current_inst_size + offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
+ return false;
+
return true;
}
-/*
- BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
- BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
- BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
+/*
+ Emulate below MIPS conditional branch and link instructions.
+ BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches
*/
bool
-EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn)
{
bool success = false;
- int32_t target = 0;
- uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+ uint32_t rs;
+ int32_t offset, pc, target;
+ int32_t rs_val;
const char *op_name = m_insn_info->getName (insn.getOpcode ());
- bool update_ra = false;
- uint32_t ra_offset = 0;
-
- /*
- * BEQZ16 rs, offset
- * condition <- (GPR[rs] = 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BNEZ16 rs, offset
- * condition <- (GPR[rs] != 0)
- * if condition then
- * PC = PC + sign_ext (offset || 0)
- *
- * BEQZC rs, offset (compact instruction: No delay slot)
- * condition <- (GPR[rs] == 0)
- * if condition then
- * PC = PC + 4 + sign_ext (offset || 0)
- */
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- int32_t offset = insn.getOperand(1).getImm();
+ rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
if (!success)
return false;
- if (!strcasecmp (op_name, "BEQZ16_MM"))
+ if (!strcasecmp (op_name, "BLEZALC"))
{
- if (rs_val == 0)
+ if (rs_val <= 0)
target = pc + offset;
else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
+ target = pc + 4;
}
- else if (!strcasecmp (op_name, "BNEZ16_MM"))
+ else if (!strcasecmp (op_name, "BGEZALC"))
{
- if (rs_val != 0)
+ if (rs_val >= 0)
target = pc + offset;
else
- target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
+ target = pc + 4;
}
- else if (!strcasecmp (op_name, "BEQZC_MM"))
+ else if (!strcasecmp (op_name, "BLTZALC"))
{
- if (rs_val == 0)
- target = pc + 4 + offset;
+ if (rs_val < 0)
+ target = pc + offset;
else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
+ target = pc + 4;
}
- else if (!strcasecmp (op_name, "BNEZC_MM"))
+ else if (!strcasecmp (op_name, "BGTZALC"))
{
- if (rs_val != 0)
- target = pc + 4 + offset;
+ if (rs_val > 0)
+ target = pc + offset;
else
- target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
+ target = pc + 4;
}
- else if (!strcasecmp (op_name, "BGEZALS_MM"))
+ else if (!strcasecmp (op_name, "BEQZALC"))
{
- if (rs_val >= 0)
+ if (rs_val == 0)
target = pc + offset;
else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
+ target = pc + 4;
}
- else if (!strcasecmp (op_name, "BLTZALS_MM"))
+ else if (!strcasecmp (op_name, "BNEZALC"))
{
- if (rs_val >= 0)
+ if (rs_val != 0)
target = pc + offset;
else
- target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
-
- update_ra = true;
- ra_offset = 6;
+ target = pc + 4;
}
Context context;
- context.type = eContextRelativeBranchImmediate;
- context.SetImmediate (current_inst_size + offset);
-
+
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
- if (update_ra)
- {
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
- }
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
+ return false;
+
return true;
}
-/* Emulate micromips jump instructions.
- JALR16,JALRS16
+/*
+ Emulate below MIPS Non-Compact conditional branch and link instructions.
+ BLTZAL, BGEZAL :
+ BLTZALL, BGEZALL : Branch likely
*/
bool
-EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn)
{
bool success = false;
- uint32_t ra_offset = 0;
+ uint32_t rs;
+ int32_t offset, pc, target;
+ int32_t rs_val;
const char *op_name = m_insn_info->getName (insn.getOpcode ());
- uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
- uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
if (!success)
return false;
- if (!strcasecmp (op_name, "JALR16_MM"))
- ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
- else if (!strcasecmp (op_name, "JALRS16_MM"))
- ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
+ if (!strcasecmp (op_name, "BLTZAL") ||
+ !strcasecmp (op_name, "BLTZALL"))
+ {
+ if ((int32_t) rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BGEZAL") ||
+ !strcasecmp (op_name, "BGEZALL"))
+ {
+ if ((int32_t) rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
Context context;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
return false;
return true;
}
-/* Emulate JALS and JALX instructions.
- JALS 32 bit instruction with short (2-byte) delay slot.
- JALX 32 bit instruction with 4-byte delay slot.
+/*
+ Emulate below MIPS branch instructions.
+ BLTZL, BGEZL, BGTZL, BLEZL : Branch likely
+ BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches
*/
bool
-EmulateInstructionMIPS::Emulate_JALx (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn)
{
bool success = false;
- uint32_t offset=0, target=0, pc=0, ra_offset=0;
+ uint32_t rs;
+ int32_t offset, pc, target;
+ int32_t rs_val;
const char *op_name = m_insn_info->getName (insn.getOpcode ());
-
- /*
- * JALS target
- * RA = PC + 6
- * offset = sign_ext (offset << 1)
- * PC = PC[31-27] | offset
- * JALX target
- * RA = PC + 8
- * offset = sign_ext (offset << 2)
- * PC = PC[31-28] | offset
- */
- offset = insn.getOperand(0).getImm();
+
+ rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ offset = insn.getOperand(1).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- // These are PC-region branches and not PC-relative.
- if (!strcasecmp (op_name, "JALS_MM"))
+ rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ if (!success)
+ return false;
+
+ if (!strcasecmp (op_name, "BLTZL") ||
+ !strcasecmp (op_name, "BLTZ"))
{
- // target address is in the âcurrentâ 128 MB-aligned region
- target = (pc & 0xF8000000UL) | offset;
- ra_offset = 6;
+ if (rs_val < 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
}
- else if (!strcasecmp (op_name, "JALX_MM"))
+ else if (!strcasecmp (op_name, "BGEZL") ||
+ !strcasecmp (op_name, "BGEZ"))
{
- // target address is in the âcurrentâ 256 MB-aligned region
- target = (pc & 0xF0000000UL) | offset;
- ra_offset = 8;
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BGTZL") ||
+ !strcasecmp (op_name, "BGTZ"))
+ {
+ if (rs_val > 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BLEZL") ||
+ !strcasecmp (op_name, "BLEZ"))
+ {
+ if (rs_val <= 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
}
Context context;
+ context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate (offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
- return false;
-
return true;
}
+/*
+ Emulate below MIPS branch instructions.
+ BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches
+*/
bool
-EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn)
-{
- bool success = false;
- uint32_t rs=0, rt=0;
- int32_t pc=0, rs_val=0;
-
- /*
- JALRS rt, rs
- GPR[rt] <- PC + 6
- PC <- GPR[rs]
- */
-
- rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
- return false;
-
- // This is 4-byte instruction with 2-byte delay slot.
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6))
- 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- return true;
-}
-
-bool
-EmulateInstructionMIPS::Emulate_BLTZL (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn)
{
bool success = false;
uint32_t rs;
int32_t offset, pc, target;
int32_t rs_val;
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- /*
- * 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();
@@ -1880,13 +1770,52 @@ EmulateInstructionMIPS::Emulate_BLTZL (l
if (!success)
return false;
- if (rs_val < 0)
- target = pc + offset;
- else
- target = pc + 8; /* skip delay slot */
+ if (!strcasecmp (op_name, "BLTZC"))
+ {
+ if (rs_val < 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BLEZC"))
+ {
+ if (rs_val <= 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BGEZC"))
+ {
+ if (rs_val >= 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BGTZC"))
+ {
+ if (rs_val > 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BEQZC"))
+ {
+ if (rs_val == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
+ else if (!strcasecmp (op_name, "BNEZC"))
+ {
+ if (rs_val != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4;
+ }
Context context;
context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate (current_inst_size + offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
@@ -1895,37 +1824,24 @@ EmulateInstructionMIPS::Emulate_BLTZL (l
}
bool
-EmulateInstructionMIPS::Emulate_BGTZL (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn)
{
bool success = false;
- uint32_t rs;
int32_t offset, pc, target;
- int32_t rs_val;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
- /*
- * 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();
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- if (rs_val > 0)
- target = pc + offset;
- else
- target = pc + 8; /* skip delay slot */
+ // unconditional branch
+ target = pc + offset;
Context context;
context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate (current_inst_size + offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
@@ -1933,1301 +1849,319 @@ EmulateInstructionMIPS::Emulate_BGTZL (l
return true;
}
+/*
+ BEQZC, BNEZC are 32 bit compact instructions without a delay slot.
+ BEQZ16, BNEZ16 are 16 bit instructions with delay slot.
+ BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot.
+*/
bool
-EmulateInstructionMIPS::Emulate_BLEZL (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn)
{
bool success = false;
- uint32_t rs;
- int32_t offset, pc, target;
- int32_t rs_val;
+ int32_t target = 0;
+ uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize();
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
+ bool update_ra = false;
+ uint32_t ra_offset = 0;
/*
- * BLEZL rs, offset
- * condition <- (GPR[rs] <= 0)
+ * BEQZ16 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- target = pc + offset;
-
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- target = pc + 4 + offset;
-
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- target = pc + 4 + offset;
-
- Context context;
-
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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)
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BNEZ16 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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)
+ * PC = PC + sign_ext (offset || 0)
+ *
+ * BEQZC rs, offset (compact instruction: No delay slot)
+ * condition <- (GPR[rs] == 0)
* if condition then
- * PC = PC + sign_ext (offset << 2)
+ * PC = PC + 4 + sign_ext (offset || 0)
*/
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ int32_t offset = insn.getOperand(1).getImm();
+
+ int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
if (!success)
return false;
- if (rs_val <= 0)
- target = pc + 4 + offset;
- else
- target = pc + 4;
+ if (!strcasecmp (op_name, "BEQZ16_MM"))
+ {
+ if (rs_val == 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
+ }
+ else if (!strcasecmp (op_name, "BNEZ16_MM"))
+ {
+ if (rs_val != 0)
+ target = pc + offset;
+ else
+ target = pc + current_inst_size + m_next_inst_size; // Skip delay slot instruction.
+ }
+ else if (!strcasecmp (op_name, "BEQZC_MM"))
+ {
+ if (rs_val == 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
+ }
+ else if (!strcasecmp (op_name, "BNEZC_MM"))
+ {
+ if (rs_val != 0)
+ target = pc + 4 + offset;
+ else
+ target = pc + 4; // 32 bit instruction and does not have delay slot instruction.
+ }
+ else if (!strcasecmp (op_name, "BGEZALS_MM"))
+ {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
+
+ update_ra = true;
+ ra_offset = 6;
+ }
+ else if (!strcasecmp (op_name, "BLTZALS_MM"))
+ {
+ if (rs_val >= 0)
+ target = pc + offset;
+ else
+ target = pc + 6; // 32 bit instruction with short (2-byte) delay slot
+
+ update_ra = true;
+ ra_offset = 6;
+ }
Context context;
context.type = eContextRelativeBranchImmediate;
+ context.SetImmediate (current_inst_size + offset);
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
+ if (update_ra)
+ {
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
+ return false;
+ }
return true;
}
+/* Emulate micromips jump instructions.
+ JALR16,JALRS16
+*/
bool
-EmulateInstructionMIPS::Emulate_BGEZC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_JALRx16_MM (llvm::MCInst& insn)
{
bool success = false;
- uint32_t rs;
- int32_t offset, pc, target;
- int32_t rs_val;
+ uint32_t ra_offset = 0;
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
- /*
- * 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();
+ uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
if (!success)
return false;
- if (rs_val >= 0)
- target = pc + 4 + offset;
- else
- target = pc + 4;
+ if (!strcasecmp (op_name, "JALR16_MM"))
+ ra_offset = 6; // 2-byte instruction with 4-byte delay slot.
+ else if (!strcasecmp (op_name, "JALRS16_MM"))
+ ra_offset = 4; // 2-byte instruction with 2-byte delay slot.
Context context;
- context.type = eContextRelativeBranchImmediate;
- if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
+ return false;
+
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
return false;
return true;
}
+/* Emulate JALS and JALX instructions.
+ JALS 32 bit instruction with short (2-byte) delay slot.
+ JALX 32 bit instruction with 4-byte delay slot.
+*/
bool
-EmulateInstructionMIPS::Emulate_BGTZC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_JALx (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)
+ uint32_t offset=0, target=0, pc=0, ra_offset=0;
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
+
+ /*
+ * JALS target
+ * RA = PC + 6
+ * offset = sign_ext (offset << 1)
+ * PC = PC[31-27] | offset
+ * JALX target
+ * RA = PC + 8
+ * offset = sign_ext (offset << 2)
+ * PC = PC[31-28] | offset
*/
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- if (rs_val > 0)
- target = pc + 4 + offset;
- else
- target = pc + 4;
+ // These are PC-region branches and not PC-relative.
+ if (!strcasecmp (op_name, "JALS_MM"))
+ {
+ // target address is in the âcurrentâ 128 MB-aligned region
+ target = (pc & 0xF8000000UL) | offset;
+ ra_offset = 6;
+ }
+ else if (!strcasecmp (op_name, "JALX_MM"))
+ {
+ // target address is in the âcurrentâ 256 MB-aligned region
+ target = (pc & 0xF0000000UL) | offset;
+ ra_offset = 8;
+ }
Context context;
- context.type = eContextRelativeBranchImmediate;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset))
+ return false;
+
return true;
}
bool
-EmulateInstructionMIPS::Emulate_BEQZC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_JALRS (llvm::MCInst& insn)
{
bool success = false;
- uint32_t rs;
- int32_t offset, pc, target;
- uint32_t rs_val;
-
+ uint32_t rs=0, rt=0;
+ int32_t pc=0, rs_val=0;
+
/*
- * BEQZC rs, offset
- * condition <- (GPR[rs] = 0)
- * if condition then
- * PC = PC + sign_ext (offset << 2)
+ JALRS rt, rs
+ GPR[rt] <- PC + 6
+ PC <- GPR[rs]
*/
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
- pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
+ rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
+ rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
+
+ rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
if (!success)
return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 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, dwarf_pc_mips, target))
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val))
return false;
+ // This is 4-byte instruction with 2-byte delay slot.
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 6))
+ return false;
+
return true;
}
bool
-EmulateInstructionMIPS::Emulate_BNEZC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BAL (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)
+ * BAL offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 8
+ * PC = PC + offset
*/
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- offset = insn.getOperand(1).getImm();
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- if (rs_val != 0)
- target = pc + 4 + offset;
- else
- target = pc + 4;
+ target = pc + offset;
Context context;
- context.type = eContextRelativeBranchImmediate;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
- return true;
-}
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8))
+ return false;
-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);
+ return true;
}
bool
-EmulateInstructionMIPS::Emulate_BOVC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BALC (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)
+ /*
+ * BALC offset
+ * offset = sign_ext (offset << 2)
+ * RA = PC + 4
+ * PC = PC + 4 + offset
*/
- rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
- rt = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- offset = insn.getOperand(2).getImm();
+ offset = insn.getOperand(0).getImm();
pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
-
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
- if (!success)
- return false;
-
- if (IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
+ target = pc + 4 + offset;
Context context;
- context.type = eContextRelativeBranchImmediate;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
+ if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4))
+ return false;
+
return true;
}
bool
-EmulateInstructionMIPS::Emulate_BNVC (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_BC (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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
- rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success);
- if (!success)
- return false;
+ /*
+ * BC offset
+ * offset = sign_ext (offset << 2)
+ * PC = PC + 4 + offset
+ */
+ offset = insn.getOperand(0).getImm();
- rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success);
+ pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success);
if (!success)
return false;
- if (! IsAdd64bitOverflow (rs_val, rt_val))
- target = pc + offset;
- else
- target = pc + 4;
+ target = pc + 4 + offset;
Context context;
- context.type = eContextRelativeBranchImmediate;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
return false;
@@ -3419,102 +2353,19 @@ EmulateInstructionMIPS::Emulate_JR (llvm
return true;
}
+/*
+ Emulate Branch on FP True/False
+ BC1F, BC1FL : Branch on FP False (L stands for branch likely)
+ BC1T, BC1TL : Branch on FP True (L stands for branch likely)
+*/
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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- return true;
-}
-
-bool
-EmulateInstructionMIPS::Emulate_BC1T (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_FP_branch (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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- return true;
-}
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
-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();
@@ -3528,53 +2379,23 @@ EmulateInstructionMIPS::Emulate_BC1FL (l
/* 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, 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 */
-
+ if (!strcasecmp (op_name, "BC1F") ||
+ !strcasecmp (op_name, "BC1FL"))
+ {
+ if ((fcsr & (1 << cc)) == 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BC1T") ||
+ !strcasecmp (op_name, "BC1TL"))
+ {
+ if ((fcsr & (1 << cc)) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
Context context;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
@@ -3661,154 +2482,19 @@ EmulateInstructionMIPS::Emulate_BC1NEZ (
return true;
}
+/*
+ Emulate MIPS-3D Branch instructions
+ BC1ANY2F, BC1ANY2T : Branch on Any of Two Floating Point Condition Codes False/True
+ BC1ANY4F, BC1ANY4T : Branch on Any of Four Floating Point Condition Codes False/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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, 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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- return true;
-}
-
-bool
-EmulateInstructionMIPS::Emulate_BC1ANY4F (llvm::MCInst& insn)
+EmulateInstructionMIPS::Emulate_3D_branch (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, dwarf_pc_mips, 0, &success);
- if (!success)
- return false;
-
- fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, 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, dwarf_pc_mips, target))
- return false;
-
- return true;
-}
+ const char *op_name = m_insn_info->getName (insn.getOpcode ());
-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();
@@ -3823,12 +2509,38 @@ EmulateInstructionMIPS::Emulate_BC1ANY4T
/* 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;
-
+ if (!strcasecmp (op_name, "BC1ANY2F"))
+ {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 3) != 3)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BC1ANY2T"))
+ {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 3) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BC1ANY4F"))
+ {
+ /* if any one bit is 0 */
+ if (((fcsr >> cc) & 0xf) != 0xf)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
+ else if (!strcasecmp (op_name, "BC1ANY4T"))
+ {
+ /* if any one bit is 1 */
+ if (((fcsr >> cc) & 0xf) != 0)
+ target = pc + offset;
+ else
+ target = pc + 8;
+ }
Context context;
if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target))
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=256915&r1=256914&r2=256915&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h (original)
+++ lldb/trunk/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h Tue Jan 5 23:44:02 2016
@@ -160,121 +160,37 @@ protected:
Emulate_LDST_Reg (llvm::MCInst& insn);
bool
- Emulate_BEQ (llvm::MCInst& insn);
+ Emulate_BXX_3ops (llvm::MCInst& insn);
bool
- Emulate_BNE (llvm::MCInst& insn);
+ Emulate_BXX_3ops_C (llvm::MCInst& insn);
bool
- Emulate_BEQL (llvm::MCInst& insn);
+ Emulate_BXX_2ops (llvm::MCInst& insn);
bool
- Emulate_BNEL (llvm::MCInst& insn);
+ Emulate_BXX_2ops_C (llvm::MCInst& insn);
bool
- Emulate_BGEZALL (llvm::MCInst& insn);
+ Emulate_Bcond_Link_C (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);
+ Emulate_Bcond_Link (llvm::MCInst& insn);
bool
- Emulate_BGEZC (llvm::MCInst& insn);
+ Emulate_FP_branch (llvm::MCInst& insn);
bool
- Emulate_BGTZC (llvm::MCInst& insn);
+ Emulate_3D_branch (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);
+ Emulate_BAL (llvm::MCInst& insn);
bool
- Emulate_BOVC (llvm::MCInst& insn);
+ Emulate_BALC (llvm::MCInst& insn);
bool
- Emulate_BNVC (llvm::MCInst& insn);
+ Emulate_BC (llvm::MCInst& insn);
bool
Emulate_J (llvm::MCInst& insn);
@@ -295,36 +211,12 @@ protected:
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
Emulate_BNZB (llvm::MCInst& insn);
bool
More information about the lldb-commits
mailing list