20 #define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
33 void EmulateInstructionPPC64::Initialize() {
34 PluginManager::RegisterPlugin(GetPluginNameStatic(),
35 GetPluginDescriptionStatic(), CreateInstance);
38 void EmulateInstructionPPC64::Terminate() {
39 PluginManager::UnregisterPlugin(CreateInstance);
42 llvm::StringRef EmulateInstructionPPC64::GetPluginDescriptionStatic() {
43 return "Emulate instructions for the PPC64 architecture.";
47 EmulateInstructionPPC64::CreateInstance(
const ArchSpec &arch,
49 if (EmulateInstructionPPC64::SupportsEmulatingInstructionsOfTypeStatic(
57 bool EmulateInstructionPPC64::SetTargetTriple(
const ArchSpec &arch) {
62 if (reg_num >= llvm::array_lengthof(g_register_infos_ppc64le))
64 reg_info = g_register_infos_ppc64le[reg_num];
68 bool EmulateInstructionPPC64::GetRegisterInfo(
RegisterKind reg_kind,
70 RegisterInfo ®_info) {
100 bool EmulateInstructionPPC64::ReadInstruction() {
101 bool success =
false;
106 ctx.
type = eContextReadOpcode;
108 m_opcode.SetOpcode32(ReadMemoryUnsigned(ctx, m_addr, 4, 0, &success),
116 bool EmulateInstructionPPC64::CreateFunctionEntryUnwind(
136 EmulateInstructionPPC64::GetOpcodeForInstruction(
uint32_t opcode) {
138 {0xfc0007ff, 0x7c0002a6, &EmulateInstructionPPC64::EmulateMFSPR,
140 {0xfc000003, 0xf8000000, &EmulateInstructionPPC64::EmulateSTD,
142 {0xfc000003, 0xf8000001, &EmulateInstructionPPC64::EmulateSTD,
144 {0xfc0007fe, 0x7c000378, &EmulateInstructionPPC64::EmulateOR,
146 {0xfc000000, 0x38000000, &EmulateInstructionPPC64::EmulateADDI,
148 {0xfc000003, 0xe8000000, &EmulateInstructionPPC64::EmulateLD,
150 static const size_t k_num_ppc_opcodes = llvm::array_lengthof(g_opcodes);
152 for (
size_t i = 0; i < k_num_ppc_opcodes; ++i) {
153 if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
154 return &g_opcodes[i];
159 bool EmulateInstructionPPC64::EvaluateInstruction(
uint32_t evaluate_options) {
160 const uint32_t opcode = m_opcode.GetOpcode32();
162 Opcode *opcode_data = GetOpcodeForInstruction(opcode);
167 const bool auto_advance_pc =
168 evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
170 bool success =
false;
173 if (auto_advance_pc) {
181 success = (this->*opcode_data->
callback)(opcode);
185 if (auto_advance_pc) {
191 if (new_pc_value == orig_pc_value) {
193 context.
type = eContextAdvancePC;
203 bool EmulateInstructionPPC64::EmulateMFSPR(
uint32_t opcode) {
207 enum { SPR_LR = 0x100 };
214 LLDB_LOG(log,
"EmulateMFSPR: {0:X+8}: mfspr r0, lr", m_addr);
222 context.
type = eContextWriteRegisterRandomBits;
224 LLDB_LOG(log,
"EmulateMFSPR: success!");
228 bool EmulateInstructionPPC64::EmulateLD(
uint32_t opcode) {
233 int32_t ids = llvm::SignExtend32<16>(ds << 2);
241 LLDB_LOG(log,
"EmulateLD: {0:X+8}: ld r{1}, {2}(r{3})", m_addr, rt, ids,
ra);
243 RegisterInfo r1_info;
249 ctx.
type = eContextRestoreStackPointer;
253 LLDB_LOG(log,
"EmulateLD: success!");
257 bool EmulateInstructionPPC64::EmulateSTD(
uint32_t opcode) {
276 int32_t ids = llvm::SignExtend32<16>(ds << 2);
278 LLDB_LOG(log,
"EmulateSTD: {0:X+8}: std{1} r{2}, {3}(r{4})", m_addr,
279 u ?
"u" :
"", rs, ids,
ra);
287 if (!success ||
lr != rs_val)
293 RegisterInfo rs_info;
296 RegisterInfo ra_info;
301 ctx.
type = eContextPushRegisterOnStack;
310 WriteMemory(ctx, addr, &rs_val,
sizeof(rs_val));
316 ctx.
type = eContextAdjustStackPointer;
320 LLDB_LOG(log,
"EmulateSTD: success!");
324 bool EmulateInstructionPPC64::EmulateOR(
uint32_t opcode) {
335 LLDB_LOG(log,
"EmulateOR: {0:X+8}: mr r{1}, r{2}", m_addr,
ra, rb);
338 RegisterInfo ra_info;
343 ctx.
type = eContextSetFramePointer;
353 LLDB_LOG(log,
"EmulateOR: success!");
357 bool EmulateInstructionPPC64::EmulateADDI(
uint32_t opcode) {
368 int32_t si_val = llvm::SignExtend32<16>(si);
370 LLDB_LOG(log,
"EmulateADDI: {0:X+8}: addi r1, r1, {1}", m_addr, si_val);
373 RegisterInfo r1_info;
378 ctx.
type = eContextRestoreStackPointer;
388 LLDB_LOG(log,
"EmulateADDI: success!");