summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp184
1 files changed, 131 insertions, 53 deletions
diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
index 7abf687..a574e7d 100644
--- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
+++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp
@@ -33,7 +33,7 @@
#include "llvm/ADT/STLExtras.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
-#include "Plugins/Process/Utility/RegisterContext_mips64.h"
+#include "Plugins/Process/Utility/RegisterContext_mips.h"
using namespace lldb;
using namespace lldb_private;
@@ -124,6 +124,19 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64 (const lldb_private::ArchSpec
cpu = "generic"; break;
}
+ std::string features = "";
+ uint32_t arch_flags = arch.GetFlags ();
+ if (arch_flags & ArchSpec::eMIPSAse_msa)
+ features += "+msa,";
+ if (arch_flags & ArchSpec::eMIPSAse_dsp)
+ features += "+dsp,";
+ if (arch_flags & ArchSpec::eMIPSAse_dspr2)
+ features += "+dspr2,";
+ if (arch_flags & ArchSpec::eMIPSAse_mips16)
+ features += "+mips16,";
+ if (arch_flags & ArchSpec::eMIPSAse_micromips)
+ features += "+micromips,";
+
m_reg_info.reset (target->createMCRegInfo (triple.getTriple()));
assert (m_reg_info.get());
@@ -131,7 +144,7 @@ EmulateInstructionMIPS64::EmulateInstructionMIPS64 (const lldb_private::ArchSpec
assert (m_insn_info.get());
m_asm_info.reset (target->createMCAsmInfo (*m_reg_info, triple.getTriple()));
- m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, ""));
+ m_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features));
assert (m_asm_info.get() && m_subtype_info.get());
m_context.reset (new llvm::MCContext (m_asm_info.get(), m_reg_info.get(), nullptr));
@@ -289,38 +302,38 @@ EmulateInstructionMIPS64::GetRegisterName (unsigned reg_num, bool alternate_name
case gcc_dwarf_bad_mips64: return "bad";
case gcc_dwarf_cause_mips64: return "cause";
case gcc_dwarf_pc_mips64: return "pc";
- case gcc_dwarf_f0_mips64: return "fp_reg[0]";
- case gcc_dwarf_f1_mips64: return "fp_reg[1]";
- case gcc_dwarf_f2_mips64: return "fp_reg[2]";
- case gcc_dwarf_f3_mips64: return "fp_reg[3]";
- case gcc_dwarf_f4_mips64: return "fp_reg[4]";
- case gcc_dwarf_f5_mips64: return "fp_reg[5]";
- case gcc_dwarf_f6_mips64: return "fp_reg[6]";
- case gcc_dwarf_f7_mips64: return "fp_reg[7]";
- case gcc_dwarf_f8_mips64: return "fp_reg[8]";
- case gcc_dwarf_f9_mips64: return "fp_reg[9]";
- case gcc_dwarf_f10_mips64: return "fp_reg[10]";
- case gcc_dwarf_f11_mips64: return "fp_reg[11]";
- case gcc_dwarf_f12_mips64: return "fp_reg[12]";
- case gcc_dwarf_f13_mips64: return "fp_reg[13]";
- case gcc_dwarf_f14_mips64: return "fp_reg[14]";
- case gcc_dwarf_f15_mips64: return "fp_reg[15]";
- case gcc_dwarf_f16_mips64: return "fp_reg[16]";
- case gcc_dwarf_f17_mips64: return "fp_reg[17]";
- case gcc_dwarf_f18_mips64: return "fp_reg[18]";
- case gcc_dwarf_f19_mips64: return "fp_reg[19]";
- case gcc_dwarf_f20_mips64: return "fp_reg[20]";
- case gcc_dwarf_f21_mips64: return "fp_reg[21]";
- case gcc_dwarf_f22_mips64: return "fp_reg[22]";
- case gcc_dwarf_f23_mips64: return "fp_reg[23]";
- case gcc_dwarf_f24_mips64: return "fp_reg[24]";
- case gcc_dwarf_f25_mips64: return "fp_reg[25]";
- case gcc_dwarf_f26_mips64: return "fp_reg[26]";
- case gcc_dwarf_f27_mips64: return "fp_reg[27]";
- case gcc_dwarf_f28_mips64: return "fp_reg[28]";
- case gcc_dwarf_f29_mips64: return "fp_reg[29]";
- case gcc_dwarf_f30_mips64: return "fp_reg[30]";
- case gcc_dwarf_f31_mips64: return "fp_reg[31]";
+ case gcc_dwarf_f0_mips64: return "f0";
+ case gcc_dwarf_f1_mips64: return "f1";
+ case gcc_dwarf_f2_mips64: return "f2";
+ case gcc_dwarf_f3_mips64: return "f3";
+ case gcc_dwarf_f4_mips64: return "f4";
+ case gcc_dwarf_f5_mips64: return "f5";
+ case gcc_dwarf_f6_mips64: return "f6";
+ case gcc_dwarf_f7_mips64: return "f7";
+ case gcc_dwarf_f8_mips64: return "f8";
+ case gcc_dwarf_f9_mips64: return "f9";
+ case gcc_dwarf_f10_mips64: return "f10";
+ case gcc_dwarf_f11_mips64: return "f11";
+ case gcc_dwarf_f12_mips64: return "f12";
+ case gcc_dwarf_f13_mips64: return "f13";
+ case gcc_dwarf_f14_mips64: return "f14";
+ case gcc_dwarf_f15_mips64: return "f15";
+ case gcc_dwarf_f16_mips64: return "f16";
+ case gcc_dwarf_f17_mips64: return "f17";
+ case gcc_dwarf_f18_mips64: return "f18";
+ case gcc_dwarf_f19_mips64: return "f19";
+ case gcc_dwarf_f20_mips64: return "f20";
+ case gcc_dwarf_f21_mips64: return "f21";
+ case gcc_dwarf_f22_mips64: return "f22";
+ case gcc_dwarf_f23_mips64: return "f23";
+ case gcc_dwarf_f24_mips64: return "f24";
+ case gcc_dwarf_f25_mips64: return "f25";
+ case gcc_dwarf_f26_mips64: return "f26";
+ case gcc_dwarf_f27_mips64: return "f27";
+ case gcc_dwarf_f28_mips64: return "f28";
+ case gcc_dwarf_f29_mips64: return "f29";
+ case gcc_dwarf_f30_mips64: return "f30";
+ case gcc_dwarf_f31_mips64: return "f31";
case gcc_dwarf_fcsr_mips64: return "fcsr";
case gcc_dwarf_fir_mips64: return "fir";
}
@@ -397,6 +410,9 @@ EmulateInstructionMIPS64::GetOpcodeForInstruction (const char *op_name)
{ "SD", &EmulateInstructionMIPS64::Emulate_SD, "SD rt,offset(rs)" },
{ "LD", &EmulateInstructionMIPS64::Emulate_LD, "LD rt,offset(base)" },
+ { "SW", &EmulateInstructionMIPS64::Emulate_SW, "SW rt,offset(rs)" },
+ { "LW", &EmulateInstructionMIPS64::Emulate_LW, "LW rt,offset(rs)" },
+
//----------------------------------------------------------------------
// Branch instructions
//----------------------------------------------------------------------
@@ -644,35 +660,95 @@ EmulateInstructionMIPS64::Emulate_DADDiu (llvm::MCInst& insn)
}
bool
+EmulateInstructionMIPS64::Emulate_SW (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
+
+ 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 = 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);
+
+ return true;
+}
+
+bool
+EmulateInstructionMIPS64::Emulate_LW (llvm::MCInst& insn)
+{
+ bool success = false;
+ uint32_t base;
+ int64_t imm, address;
+ Context bad_vaddr_context;
+
+ 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 = 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);
+
+ return true;
+}
+
+bool
EmulateInstructionMIPS64::Emulate_SD (llvm::MCInst& insn)
{
+ uint64_t address;
+ RegisterInfo reg_info_base;
+ RegisterInfo reg_info_src;
bool success = false;
uint32_t imm16 = insn.getOperand(2).getImm();
uint64_t imm = SignedBits(imm16, 15, 0);
uint32_t src, base;
+ Context bad_vaddr_context;
src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg());
base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg());
- /* We look for sp based non-volatile register stores */
- if (base == gcc_dwarf_sp_mips64 && nonvolatile_reg_p (src))
- {
- uint64_t address;
- RegisterInfo reg_info_base;
- RegisterInfo reg_info_src;
-
- if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, reg_info_base)
- || !GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + src, reg_info_src))
- return false;
+ if (!GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, reg_info_base)
+ || !GetRegisterInfo (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + src, reg_info_src))
+ return false;
- /* read SP */
- address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, 0, &success);
- if (!success)
- return false;
+ /* read SP */
+ address = ReadRegisterUnsigned (eRegisterKindDWARF, gcc_dwarf_zero_mips64 + base, 0, &success);
+ if (!success)
+ return false;
- /* destination address */
- address = address + imm;
+ /* destination address */
+ address = address + imm;
+ /* We look for sp based non-volatile register stores */
+ if (base == gcc_dwarf_sp_mips64 && nonvolatile_reg_p (src))
+ {
Context context;
RegisterValue data_src;
context.type = eContextPushRegisterOnStack;
@@ -689,11 +765,13 @@ EmulateInstructionMIPS64::Emulate_SD (llvm::MCInst& insn)
if (!WriteMemory (context, address, buffer, reg_info_src.byte_size))
return false;
-
- return true;
}
- return false;
+ /* 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);
+
+ return true;
}
bool
OpenPOWER on IntegriCloud