Skip to content

Commit

Permalink
[LLDB][MIPS] MIPS load/store instruction emulation for hardware watch…
Browse files Browse the repository at this point in the history
…points

Reviewers: clayborg.
Subscribers: jaydeep, bhushan, sagar, nitesh.jain, lldb-commits.
Differential Revision: http://reviews.llvm.org/D12670

llvm-svn: 247129
  • Loading branch information
Mohit7 committed Sep 9, 2015
1 parent 2038747 commit a73239f
Show file tree
Hide file tree
Showing 4 changed files with 328 additions and 77 deletions.
181 changes: 169 additions & 12 deletions lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp
Expand Up @@ -410,6 +410,64 @@ EmulateInstructionMIPS::GetOpcodeForInstruction (const char *op_name)
{ "SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt,offset(rs)" },
{ "LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt,offset(base)" },

//----------------------------------------------------------------------
// Load/Store instructions
//----------------------------------------------------------------------
/* Following list of emulated instructions are required by implementation of hardware watchpoint
for MIPS in lldb. As we just need the address accessed by instructions, we have generalised
all these instructions in 2 functions depending on their addressing modes */

{ "LB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LB rt, offset(base)" },
{ "LBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBE rt, offset(base)" },
{ "LBU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU rt, offset(base)" },
{ "LBUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBUE rt, offset(base)" },
{ "LDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC1 ft, offset(base)" },
{ "LD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LD rt, offset(base)" },
{ "LDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDL rt, offset(base)" },
{ "LDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDR rt, offset(base)" },
{ "LLD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLD rt, offset(base)" },
{ "LDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LDC2 rt, offset(base)" },
{ "LDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LDXC1 fd, index (base)" },
{ "LH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LH rt, offset(base)" },
{ "LHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHE rt, offset(base)" },
{ "LHU", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU rt, offset(base)" },
{ "LHUE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHUE rt, offset(base)" },
{ "LL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LL rt, offset(base)" },
{ "LLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLE rt, offset(base)" },
{ "LUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LUXC1 fd, index (base)" },
{ "LW", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW rt, offset(base)" },
{ "LWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC1 ft, offset(base)" },
{ "LWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWC2 rt, offset(base)" },
{ "LWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWE rt, offset(base)" },
{ "LWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWL rt, offset(base)" },
{ "LWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWLE rt, offset(base)" },
{ "LWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWR rt, offset(base)" },
{ "LWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWRE rt, offset(base)" },
{ "LWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "LWXC1 fd, index (base)" },

{ "SB", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB rt, offset(base)" },
{ "SBE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SBE rt, offset(base)" },
{ "SC", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SC rt, offset(base)" },
{ "SCE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCE rt, offset(base)" },
{ "SCD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCD rt, offset(base)" },
{ "SD", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SD rt, offset(base)" },
{ "SDL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDL rt, offset(base)" },
{ "SDR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDR rt, offset(base)" },
{ "SDC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC1 ft, offset(base)" },
{ "SDC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SDC2 rt, offset(base)" },
{ "SDXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SDXC1 fs, index(base)" },
{ "SH", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH rt, offset(base)" },
{ "SHE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SHE rt, offset(base)" },
{ "SUXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SUXC1 fs, index (base)" },
{ "SWC1", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC1 ft, offset(base)" },
{ "SWC2", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWC2 rt, offset(base)" },
{ "SWE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWE rt, offset(base)" },
{ "SWL", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWL rt, offset(base)" },
{ "SWLE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWLE rt, offset(base)" },
{ "SWR", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWR rt, offset(base)" },
{ "SWRE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWRE rt, offset(base)" },
{ "SWXC1", &EmulateInstructionMIPS::Emulate_LDST_Reg, "SWXC1 fs, index (base)" },

//----------------------------------------------------------------------
// Branch instructions
//----------------------------------------------------------------------
Expand Down Expand Up @@ -663,29 +721,38 @@ EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn)
uint32_t imm16 = insn.getOperand(2).getImm();
uint32_t imm = SignedBits(imm16, 15, 0);
uint32_t src, base;
int32_t address;
Context bad_vaddr_context;

RegisterInfo reg_info_base;

src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());

if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, reg_info_base))
return false;

/* read base register */
address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, 0, &success);
if (!success)
return false;

/* destination address */
address = address + imm;

/* Set the bad_vaddr register with base address used in the instruction */
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, gcc_dwarf_bad_mips64, address);

/* We look for sp based non-volatile register stores */
if (base == gcc_dwarf_sp_mips && nonvolatile_reg_p (src))
{
uint32_t address;
RegisterInfo reg_info_base;
RegisterInfo reg_info_src;

if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, reg_info_base)
|| !GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + src, reg_info_src))
return false;
RegisterInfo reg_info_src;

/* read SP */
address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, 0, &success);
if (!success)
if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + src, reg_info_src))
return false;

/* destination address */
address = address + imm;

Context context;
RegisterValue data_src;
context.type = eContextPushRegisterOnStack;
Expand All @@ -712,10 +779,30 @@ EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn)
bool
EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn)
{
bool success =false;
uint32_t src, base;
int32_t imm, address;
Context bad_vaddr_context;

src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
imm = insn.getOperand(2).getImm();

RegisterInfo reg_info_base;
if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, reg_info_base))
return false;

/* read base register */
address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, 0, &success);
if (!success)
return false;

/* destination address */
address = address + imm;

/* Set the bad_vaddr register with base address used in the instruction */
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, gcc_dwarf_bad_mips64, address);

if (base == gcc_dwarf_sp_mips && nonvolatile_reg_p (src))
{
Expand Down Expand Up @@ -2929,3 +3016,73 @@ EmulateInstructionMIPS::Emulate_BC1ANY4T (llvm::MCInst& insn)

return true;
}

bool
EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn)
{
bool success = false;
uint32_t base;
int32_t imm, address;
Context bad_vaddr_context;

uint32_t num_operands = insn.getNumOperands();
base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
imm = insn.getOperand(num_operands-1).getImm();

RegisterInfo reg_info_base;
if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, reg_info_base))
return false;

/* read base register */
address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, 0, &success);
if (!success)
return false;

/* destination address */
address = address + imm;

/* Set the bad_vaddr register with base address used in the instruction */
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, gcc_dwarf_bad_mips, address);

return true;
}

bool
EmulateInstructionMIPS::Emulate_LDST_Reg (llvm::MCInst& insn)
{
bool success = false;
uint32_t base, index;
int32_t address, index_address;
Context bad_vaddr_context;

uint32_t num_operands = insn.getNumOperands();
base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg());
index = m_reg_info->getEncodingValue (insn.getOperand(num_operands-1).getReg());

RegisterInfo reg_info_base, reg_info_index;
if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, reg_info_base))
return false;

if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips + index, reg_info_index))
return false;

/* read base register */
address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + base, 0, &success);
if (!success)
return false;

/* read index register */
index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips + index, 0, &success);
if (!success)
return false;

/* destination address */
address = address + index_address;

/* Set the bad_vaddr register with base address used in the instruction */
bad_vaddr_context.type = eContextInvalid;
WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, gcc_dwarf_bad_mips, address);

return true;
}
6 changes: 6 additions & 0 deletions lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h
Expand Up @@ -130,6 +130,12 @@ class EmulateInstructionMIPS : public lldb_private::EmulateInstruction
bool
Emulate_LW (llvm::MCInst& insn);

bool
Emulate_LDST_Imm (llvm::MCInst& insn);

bool
Emulate_LDST_Reg (llvm::MCInst& insn);

bool
Emulate_BEQ (llvm::MCInst& insn);

Expand Down

0 comments on commit a73239f

Please sign in to comment.