diff options
Diffstat (limited to 'lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp')
-rw-r--r-- | lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp | 4990 |
1 files changed, 2610 insertions, 2380 deletions
diff --git a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index 47b98ca85b7..21f57dbf7a8 100644 --- a/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -1,4 +1,5 @@ -//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++ -*-===// +//===-- EmulateInstructionMIPS.cpp -------------------------------*- C++ +//-*-===// // // The LLVM Compiler Infrastructure // @@ -11,30 +12,30 @@ #include <stdlib.h> -#include "llvm-c/Disassembler.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCDisassembler/MCDisassembler.h" -#include "llvm/MC/MCRegisterInfo.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCContext.h" #include "lldb/Core/Address.h" -#include "lldb/Core/Opcode.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/ConstString.h" -#include "lldb/Core/PluginManager.h" #include "lldb/Core/DataExtractor.h" +#include "lldb/Core/Opcode.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Target.h" +#include "llvm-c/Disassembler.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" +#include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/ADT/STLExtras.h" #include "Plugins/Process/Utility/InstructionUtils.h" -#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64 +#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64 using namespace lldb; using namespace lldb_private; @@ -42,7 +43,6 @@ using namespace lldb_private; #define UInt(x) ((uint64_t)x) #define integer int64_t - //---------------------------------------------------------------------- // // EmulateInstructionMIPS implementation @@ -51,1926 +51,2180 @@ using namespace lldb_private; #ifdef __mips__ extern "C" { - void LLVMInitializeMipsTargetInfo (); - void LLVMInitializeMipsTarget (); - void LLVMInitializeMipsAsmPrinter (); - void LLVMInitializeMipsTargetMC (); - void LLVMInitializeMipsDisassembler (); +void LLVMInitializeMipsTargetInfo(); +void LLVMInitializeMipsTarget(); +void LLVMInitializeMipsAsmPrinter(); +void LLVMInitializeMipsTargetMC(); +void LLVMInitializeMipsDisassembler(); } #endif -EmulateInstructionMIPS::EmulateInstructionMIPS (const lldb_private::ArchSpec &arch) : - EmulateInstruction (arch) -{ - /* Create instance of llvm::MCDisassembler */ - std::string Error; - llvm::Triple triple = arch.GetTriple(); - const llvm::Target *target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error); +EmulateInstructionMIPS::EmulateInstructionMIPS( + const lldb_private::ArchSpec &arch) + : EmulateInstruction(arch) { + /* Create instance of llvm::MCDisassembler */ + std::string Error; + llvm::Triple triple = arch.GetTriple(); + const llvm::Target *target = + llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error); - /* - * If we fail to get the target then we haven't registered it. The SystemInitializerCommon - * does not initialize targets, MCs and disassemblers. However we need the MCDisassembler - * to decode the instructions so that the decoding complexity stays with LLVM. - * Initialize the MIPS targets and disassemblers. - */ +/* + * If we fail to get the target then we haven't registered it. The + * SystemInitializerCommon + * does not initialize targets, MCs and disassemblers. However we need the + * MCDisassembler + * to decode the instructions so that the decoding complexity stays with LLVM. + * Initialize the MIPS targets and disassemblers. +*/ #ifdef __mips__ - if (!target) - { - LLVMInitializeMipsTargetInfo (); - LLVMInitializeMipsTarget (); - LLVMInitializeMipsAsmPrinter (); - LLVMInitializeMipsTargetMC (); - LLVMInitializeMipsDisassembler (); - target = llvm::TargetRegistry::lookupTarget (triple.getTriple(), Error); - } + if (!target) { + LLVMInitializeMipsTargetInfo(); + LLVMInitializeMipsTarget(); + LLVMInitializeMipsAsmPrinter(); + LLVMInitializeMipsTargetMC(); + LLVMInitializeMipsDisassembler(); + target = llvm::TargetRegistry::lookupTarget(triple.getTriple(), Error); + } #endif - assert (target); - - llvm::StringRef cpu; - - switch (arch.GetCore()) - { - case ArchSpec::eCore_mips32: - case ArchSpec::eCore_mips32el: - cpu = "mips32"; break; - case ArchSpec::eCore_mips32r2: - case ArchSpec::eCore_mips32r2el: - cpu = "mips32r2"; break; - case ArchSpec::eCore_mips32r3: - case ArchSpec::eCore_mips32r3el: - cpu = "mips32r3"; break; - case ArchSpec::eCore_mips32r5: - case ArchSpec::eCore_mips32r5el: - cpu = "mips32r5"; break; - case ArchSpec::eCore_mips32r6: - case ArchSpec::eCore_mips32r6el: - cpu = "mips32r6"; break; - case ArchSpec::eCore_mips64: - case ArchSpec::eCore_mips64el: - cpu = "mips64"; break; - case ArchSpec::eCore_mips64r2: - case ArchSpec::eCore_mips64r2el: - cpu = "mips64r2"; break; - case ArchSpec::eCore_mips64r3: - case ArchSpec::eCore_mips64r3el: - cpu = "mips64r3"; break; - case ArchSpec::eCore_mips64r5: - case ArchSpec::eCore_mips64r5el: - cpu = "mips64r5"; break; - case ArchSpec::eCore_mips64r6: - case ArchSpec::eCore_mips64r6el: - cpu = "mips64r6"; break; - default: - 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,"; - - m_reg_info.reset (target->createMCRegInfo (triple.getTriple())); - assert (m_reg_info.get()); - - m_insn_info.reset (target->createMCInstrInfo()); - 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, 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)); - assert (m_context.get()); - - m_disasm.reset (target->createMCDisassembler (*m_subtype_info, *m_context)); - assert (m_disasm.get()); - - /* Create alternate disassembler for microMIPS */ - if (arch_flags & ArchSpec::eMIPSAse_mips16) - features += "+mips16,"; - else if (arch_flags & ArchSpec::eMIPSAse_micromips) - features += "+micromips,"; - - m_alt_subtype_info.reset (target->createMCSubtargetInfo (triple.getTriple(), cpu, features)); - assert (m_alt_subtype_info.get()); - - m_alt_disasm.reset (target->createMCDisassembler (*m_alt_subtype_info, *m_context)); - assert (m_alt_disasm.get()); - - m_next_inst_size = 0; - m_use_alt_disaasm = false; + assert(target); + + llvm::StringRef cpu; + + switch (arch.GetCore()) { + case ArchSpec::eCore_mips32: + case ArchSpec::eCore_mips32el: + cpu = "mips32"; + break; + case ArchSpec::eCore_mips32r2: + case ArchSpec::eCore_mips32r2el: + cpu = "mips32r2"; + break; + case ArchSpec::eCore_mips32r3: + case ArchSpec::eCore_mips32r3el: + cpu = "mips32r3"; + break; + case ArchSpec::eCore_mips32r5: + case ArchSpec::eCore_mips32r5el: + cpu = "mips32r5"; + break; + case ArchSpec::eCore_mips32r6: + case ArchSpec::eCore_mips32r6el: + cpu = "mips32r6"; + break; + case ArchSpec::eCore_mips64: + case ArchSpec::eCore_mips64el: + cpu = "mips64"; + break; + case ArchSpec::eCore_mips64r2: + case ArchSpec::eCore_mips64r2el: + cpu = "mips64r2"; + break; + case ArchSpec::eCore_mips64r3: + case ArchSpec::eCore_mips64r3el: + cpu = "mips64r3"; + break; + case ArchSpec::eCore_mips64r5: + case ArchSpec::eCore_mips64r5el: + cpu = "mips64r5"; + break; + case ArchSpec::eCore_mips64r6: + case ArchSpec::eCore_mips64r6el: + cpu = "mips64r6"; + break; + default: + 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,"; + + m_reg_info.reset(target->createMCRegInfo(triple.getTriple())); + assert(m_reg_info.get()); + + m_insn_info.reset(target->createMCInstrInfo()); + 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, 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)); + assert(m_context.get()); + + m_disasm.reset(target->createMCDisassembler(*m_subtype_info, *m_context)); + assert(m_disasm.get()); + + /* Create alternate disassembler for microMIPS */ + if (arch_flags & ArchSpec::eMIPSAse_mips16) + features += "+mips16,"; + else if (arch_flags & ArchSpec::eMIPSAse_micromips) + features += "+micromips,"; + + m_alt_subtype_info.reset( + target->createMCSubtargetInfo(triple.getTriple(), cpu, features)); + assert(m_alt_subtype_info.get()); + + m_alt_disasm.reset( + target->createMCDisassembler(*m_alt_subtype_info, *m_context)); + assert(m_alt_disasm.get()); + + m_next_inst_size = 0; + m_use_alt_disaasm = false; +} + +void EmulateInstructionMIPS::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void EmulateInstructionMIPS::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString EmulateInstructionMIPS::GetPluginNameStatic() { + ConstString g_plugin_name("lldb.emulate-instruction.mips32"); + return g_plugin_name; +} + +lldb_private::ConstString EmulateInstructionMIPS::GetPluginName() { + static ConstString g_plugin_name("EmulateInstructionMIPS"); + return g_plugin_name; +} + +const char *EmulateInstructionMIPS::GetPluginDescriptionStatic() { + return "Emulate instructions for the MIPS32 architecture."; } -void -EmulateInstructionMIPS::Initialize () -{ - PluginManager::RegisterPlugin (GetPluginNameStatic (), - GetPluginDescriptionStatic (), - CreateInstance); -} - -void -EmulateInstructionMIPS::Terminate () -{ - PluginManager::UnregisterPlugin (CreateInstance); -} - -ConstString -EmulateInstructionMIPS::GetPluginNameStatic () -{ - ConstString g_plugin_name ("lldb.emulate-instruction.mips32"); - return g_plugin_name; -} - -lldb_private::ConstString -EmulateInstructionMIPS::GetPluginName() -{ - static ConstString g_plugin_name ("EmulateInstructionMIPS"); - return g_plugin_name; -} +EmulateInstruction * +EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch, + InstructionType inst_type) { + if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic( + inst_type)) { + if (arch.GetTriple().getArch() == llvm::Triple::mips || + arch.GetTriple().getArch() == llvm::Triple::mipsel) { + std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap( + new EmulateInstructionMIPS(arch)); + if (emulate_insn_ap.get()) + return emulate_insn_ap.release(); + } + } -const char * -EmulateInstructionMIPS::GetPluginDescriptionStatic () -{ - return "Emulate instructions for the MIPS32 architecture."; + return NULL; } -EmulateInstruction * -EmulateInstructionMIPS::CreateInstance (const ArchSpec &arch, InstructionType inst_type) -{ - if (EmulateInstructionMIPS::SupportsEmulatingInstructionsOfTypeStatic(inst_type)) - { - if (arch.GetTriple().getArch() == llvm::Triple::mips - || arch.GetTriple().getArch() == llvm::Triple::mipsel) - { - std::auto_ptr<EmulateInstructionMIPS> emulate_insn_ap (new EmulateInstructionMIPS (arch)); - if (emulate_insn_ap.get()) - return emulate_insn_ap.release(); - } +bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::mips || + arch.GetTriple().getArch() == llvm::Triple::mipsel) + return true; + return false; +} + +const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num, + bool alternate_name) { + if (alternate_name) { + switch (reg_num) { + case dwarf_sp_mips: + return "r29"; + case dwarf_r30_mips: + return "r30"; + case dwarf_ra_mips: + return "r31"; + case dwarf_f0_mips: + return "f0"; + case dwarf_f1_mips: + return "f1"; + case dwarf_f2_mips: + return "f2"; + case dwarf_f3_mips: + return "f3"; + case dwarf_f4_mips: + return "f4"; + case dwarf_f5_mips: + return "f5"; + case dwarf_f6_mips: + return "f6"; + case dwarf_f7_mips: + return "f7"; + case dwarf_f8_mips: + return "f8"; + case dwarf_f9_mips: + return "f9"; + case dwarf_f10_mips: + return "f10"; + case dwarf_f11_mips: + return "f11"; + case dwarf_f12_mips: + return "f12"; + case dwarf_f13_mips: + return "f13"; + case dwarf_f14_mips: + return "f14"; + case dwarf_f15_mips: + return "f15"; + case dwarf_f16_mips: + return "f16"; + case dwarf_f17_mips: + return "f17"; + case dwarf_f18_mips: + return "f18"; + case dwarf_f19_mips: + return "f19"; + case dwarf_f20_mips: + return "f20"; + case dwarf_f21_mips: + return "f21"; + case dwarf_f22_mips: + return "f22"; + case dwarf_f23_mips: + return "f23"; + case dwarf_f24_mips: + return "f24"; + case dwarf_f25_mips: + return "f25"; + case dwarf_f26_mips: + return "f26"; + case dwarf_f27_mips: + return "f27"; + case dwarf_f28_mips: + return "f28"; + case dwarf_f29_mips: + return "f29"; + case dwarf_f30_mips: + return "f30"; + case dwarf_f31_mips: + return "f31"; + case dwarf_w0_mips: + return "w0"; + case dwarf_w1_mips: + return "w1"; + case dwarf_w2_mips: + return "w2"; + case dwarf_w3_mips: + return "w3"; + case dwarf_w4_mips: + return "w4"; + case dwarf_w5_mips: + return "w5"; + case dwarf_w6_mips: + return "w6"; + case dwarf_w7_mips: + return "w7"; + case dwarf_w8_mips: + return "w8"; + case dwarf_w9_mips: + return "w9"; + case dwarf_w10_mips: + return "w10"; + case dwarf_w11_mips: + return "w11"; + case dwarf_w12_mips: + return "w12"; + case dwarf_w13_mips: + return "w13"; + case dwarf_w14_mips: + return "w14"; + case dwarf_w15_mips: + return "w15"; + case dwarf_w16_mips: + return "w16"; + case dwarf_w17_mips: + return "w17"; + case dwarf_w18_mips: + return "w18"; + case dwarf_w19_mips: + return "w19"; + case dwarf_w20_mips: + return "w20"; + case dwarf_w21_mips: + return "w21"; + case dwarf_w22_mips: + return "w22"; + case dwarf_w23_mips: + return "w23"; + case dwarf_w24_mips: + return "w24"; + case dwarf_w25_mips: + return "w25"; + case dwarf_w26_mips: + return "w26"; + case dwarf_w27_mips: + return "w27"; + case dwarf_w28_mips: + return "w28"; + case dwarf_w29_mips: + return "w29"; + case dwarf_w30_mips: + return "w30"; + case dwarf_w31_mips: + return "w31"; + case dwarf_mir_mips: + return "mir"; + case dwarf_mcsr_mips: + return "mcsr"; + case dwarf_config5_mips: + return "config5"; + default: + break; + } + return nullptr; + } + + switch (reg_num) { + case dwarf_zero_mips: + return "r0"; + case dwarf_r1_mips: + return "r1"; + case dwarf_r2_mips: + return "r2"; + case dwarf_r3_mips: + return "r3"; + case dwarf_r4_mips: + return "r4"; + case dwarf_r5_mips: + return "r5"; + case dwarf_r6_mips: + return "r6"; + case dwarf_r7_mips: + return "r7"; + case dwarf_r8_mips: + return "r8"; + case dwarf_r9_mips: + return "r9"; + case dwarf_r10_mips: + return "r10"; + case dwarf_r11_mips: + return "r11"; + case dwarf_r12_mips: + return "r12"; + case dwarf_r13_mips: + return "r13"; + case dwarf_r14_mips: + return "r14"; + case dwarf_r15_mips: + return "r15"; + case dwarf_r16_mips: + return "r16"; + case dwarf_r17_mips: + return "r17"; + case dwarf_r18_mips: + return "r18"; + case dwarf_r19_mips: + return "r19"; + case dwarf_r20_mips: + return "r20"; + case dwarf_r21_mips: + return "r21"; + case dwarf_r22_mips: + return "r22"; + case dwarf_r23_mips: + return "r23"; + case dwarf_r24_mips: + return "r24"; + case dwarf_r25_mips: + return "r25"; + case dwarf_r26_mips: + return "r26"; + case dwarf_r27_mips: + return "r27"; + case dwarf_gp_mips: + return "gp"; + case dwarf_sp_mips: + return "sp"; + case dwarf_r30_mips: + return "fp"; + case dwarf_ra_mips: + return "ra"; + case dwarf_sr_mips: + return "sr"; + case dwarf_lo_mips: + return "lo"; + case dwarf_hi_mips: + return "hi"; + case dwarf_bad_mips: + return "bad"; + case dwarf_cause_mips: + return "cause"; + case dwarf_pc_mips: + return "pc"; + case dwarf_f0_mips: + return "f0"; + case dwarf_f1_mips: + return "f1"; + case dwarf_f2_mips: + return "f2"; + case dwarf_f3_mips: + return "f3"; + case dwarf_f4_mips: + return "f4"; + case dwarf_f5_mips: + return "f5"; + case dwarf_f6_mips: + return "f6"; + case dwarf_f7_mips: + return "f7"; + case dwarf_f8_mips: + return "f8"; + case dwarf_f9_mips: + return "f9"; + case dwarf_f10_mips: + return "f10"; + case dwarf_f11_mips: + return "f11"; + case dwarf_f12_mips: + return "f12"; + case dwarf_f13_mips: + return "f13"; + case dwarf_f14_mips: + return "f14"; + case dwarf_f15_mips: + return "f15"; + case dwarf_f16_mips: + return "f16"; + case dwarf_f17_mips: + return "f17"; + case dwarf_f18_mips: + return "f18"; + case dwarf_f19_mips: + return "f19"; + case dwarf_f20_mips: + return "f20"; + case dwarf_f21_mips: + return "f21"; + case dwarf_f22_mips: + return "f22"; + case dwarf_f23_mips: + return "f23"; + case dwarf_f24_mips: + return "f24"; + case dwarf_f25_mips: + return "f25"; + case dwarf_f26_mips: + return "f26"; + case dwarf_f27_mips: + return "f27"; + case dwarf_f28_mips: + return "f28"; + case dwarf_f29_mips: + return "f29"; + case dwarf_f30_mips: + return "f30"; + case dwarf_f31_mips: + return "f31"; + case dwarf_fcsr_mips: + return "fcsr"; + case dwarf_fir_mips: + return "fir"; + case dwarf_w0_mips: + return "w0"; + case dwarf_w1_mips: + return "w1"; + case dwarf_w2_mips: + return "w2"; + case dwarf_w3_mips: + return "w3"; + case dwarf_w4_mips: + return "w4"; + case dwarf_w5_mips: + return "w5"; + case dwarf_w6_mips: + return "w6"; + case dwarf_w7_mips: + return "w7"; + case dwarf_w8_mips: + return "w8"; + case dwarf_w9_mips: + return "w9"; + case dwarf_w10_mips: + return "w10"; + case dwarf_w11_mips: + return "w11"; + case dwarf_w12_mips: + return "w12"; + case dwarf_w13_mips: + return "w13"; + case dwarf_w14_mips: + return "w14"; + case dwarf_w15_mips: + return "w15"; + case dwarf_w16_mips: + return "w16"; + case dwarf_w17_mips: + return "w17"; + case dwarf_w18_mips: + return "w18"; + case dwarf_w19_mips: + return "w19"; + case dwarf_w20_mips: + return "w20"; + case dwarf_w21_mips: + return "w21"; + case dwarf_w22_mips: + return "w22"; + case dwarf_w23_mips: + return "w23"; + case dwarf_w24_mips: + return "w24"; + case dwarf_w25_mips: + return "w25"; + case dwarf_w26_mips: + return "w26"; + case dwarf_w27_mips: + return "w27"; + case dwarf_w28_mips: + return "w28"; + case dwarf_w29_mips: + return "w29"; + case dwarf_w30_mips: + return "w30"; + case dwarf_w31_mips: + return "w31"; + case dwarf_mcsr_mips: + return "mcsr"; + case dwarf_mir_mips: + return "mir"; + case dwarf_config5_mips: + return "config5"; + } + return nullptr; +} + +bool EmulateInstructionMIPS::GetRegisterInfo(RegisterKind reg_kind, + uint32_t reg_num, + RegisterInfo ®_info) { + if (reg_kind == eRegisterKindGeneric) { + switch (reg_num) { + case LLDB_REGNUM_GENERIC_PC: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_pc_mips; + break; + case LLDB_REGNUM_GENERIC_SP: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_sp_mips; + break; + case LLDB_REGNUM_GENERIC_FP: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_r30_mips; + break; + case LLDB_REGNUM_GENERIC_RA: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_ra_mips; + break; + case LLDB_REGNUM_GENERIC_FLAGS: + reg_kind = eRegisterKindDWARF; + reg_num = dwarf_sr_mips; + break; + default: + return false; + } + } + + if (reg_kind == eRegisterKindDWARF) { + ::memset(®_info, 0, sizeof(RegisterInfo)); + ::memset(reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); + + if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || + reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || + reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) { + reg_info.byte_size = 4; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_zero_mips && + (int)reg_num <= dwarf_f31_mips) { + reg_info.byte_size = 4; + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if ((int)reg_num >= dwarf_w0_mips && + (int)reg_num <= dwarf_w31_mips) { + reg_info.byte_size = 16; + reg_info.format = eFormatVectorOfUInt8; + reg_info.encoding = eEncodingVector; + } else { + return false; + } + + reg_info.name = GetRegisterName(reg_num, false); + reg_info.alt_name = GetRegisterName(reg_num, true); + reg_info.kinds[eRegisterKindDWARF] = reg_num; + + switch (reg_num) { + case dwarf_r30_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; + break; + case dwarf_ra_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; + break; + case dwarf_sp_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; + break; + case dwarf_pc_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; + break; + case dwarf_sr_mips: + reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; + break; + default: + break; } - - return NULL; + return true; + } + return false; +} + +EmulateInstructionMIPS::MipsOpcode * +EmulateInstructionMIPS::GetOpcodeForInstruction(const char *op_name) { + static EmulateInstructionMIPS::MipsOpcode g_opcodes[] = { + //---------------------------------------------------------------------- + // Prologue/Epilogue instructions + //---------------------------------------------------------------------- + {"ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, + "ADDIU rt, rs, immediate"}, + {"SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)"}, + {"LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)"}, + {"SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt"}, + {"ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt"}, + {"LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate"}, + + //---------------------------------------------------------------------- + // MicroMIPS Prologue/Epilogue instructions + //---------------------------------------------------------------------- + {"ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, + "ADDIU immediate"}, + {"ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, + "ADDIUS5 rd,immediate"}, + {"SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)"}, + {"SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, + "SWM16 reglist,offset(sp)"}, + {"SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, + "SWM32 reglist,offset(base)"}, + {"SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, + "SWP rs1,offset(base)"}, + {"LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)"}, + {"LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, + "LWM16 reglist,offset(sp)"}, + {"LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, + "LWM32 reglist,offset(base)"}, + {"LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, + "LWP rd,offset(base)"}, + {"JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, + "JRADDIUSP immediate"}, + //---------------------------------------------------------------------- + + // 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)"}, + {"LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LLX rt, offset(base)"}, + {"LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LLXE rt, offset(base)"}, + {"LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LLDX rt, offset(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)"}, + {"SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SCX rt, offset(base)"}, + {"SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SCXE rt, offset(base)"}, + {"SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SCDX rt, offset(base)"}, + + //---------------------------------------------------------------------- + // MicroMIPS Load/Store instructions + //---------------------------------------------------------------------- + {"LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LBU16 rt, decoded_offset(base)"}, + {"LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LHU16 rt, left_shifted_offset(base)"}, + {"LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LW16 rt, left_shifted_offset(base)"}, + {"LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "LWGP rt, left_shifted_offset(gp)"}, + {"SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SH16 rt, left_shifted_offset(base)"}, + {"SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SW16 rt, left_shifted_offset(base)"}, + {"SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SWSP rt, left_shifted_offset(base)"}, + {"SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, + "SB16 rt, offset(base)"}, + + //---------------------------------------------------------------------- + // Branch instructions + //---------------------------------------------------------------------- + {"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_Bcond_Link, + "BGEZAL rs,offset"}, + {"BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset"}, + {"BC", &EmulateInstructionMIPS::Emulate_BC, "BC 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"}, + {"JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target"}, + {"JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target"}, + {"JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset"}, + {"JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset"}, + {"JR", &EmulateInstructionMIPS::Emulate_JR, "JR target"}, + {"JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target"}, + {"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_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"}, + {"BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16"}, + {"BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16"}, + {"BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16"}, + {"BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16"}, + {"BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16"}, + {"BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16"}, + {"BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16"}, + + //---------------------------------------------------------------------- + // MicroMIPS Branch instructions + //---------------------------------------------------------------------- + {"B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset"}, + {"BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BEQZ16 rs, offset"}, + {"BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BNEZ16 rs, offset"}, + {"BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BEQZC rs, offset"}, + {"BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BNEZC rs, offset"}, + {"BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BGEZALS rs, offset"}, + {"BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, + "BLTZALS rs, offset"}, + {"JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs"}, + {"JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs"}, + {"JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs"}, + {"JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs"}, + {"JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target"}, + {"JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target"}, + {"JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs"}, + }; + + static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); + + for (size_t i = 0; i < k_num_mips_opcodes; ++i) { + if (!strcasecmp(g_opcodes[i].op_name, op_name)) + return &g_opcodes[i]; + } + + return NULL; } -bool -EmulateInstructionMIPS::SetTargetTriple (const ArchSpec &arch) -{ - if (arch.GetTriple().getArch () == llvm::Triple::mips - || arch.GetTriple().getArch () == llvm::Triple::mipsel) - return true; +uint32_t +EmulateInstructionMIPS::GetSizeOfInstruction(lldb_private::DataExtractor &data, + uint64_t inst_addr) { + uint64_t next_inst_size = 0; + llvm::MCInst mc_insn; + llvm::MCDisassembler::DecodeStatus decode_status; + llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); + + if (m_use_alt_disaasm) + decode_status = + m_alt_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, + inst_addr, llvm::nulls(), llvm::nulls()); + else + decode_status = + m_disasm->getInstruction(mc_insn, next_inst_size, raw_insn, inst_addr, + llvm::nulls(), llvm::nulls()); + + if (decode_status != llvm::MCDisassembler::Success) return false; + + return m_insn_info->get(mc_insn.getOpcode()).getSize(); } -const char * -EmulateInstructionMIPS::GetRegisterName (unsigned reg_num, bool alternate_name) -{ - if (alternate_name) - { - switch (reg_num) - { - case dwarf_sp_mips: return "r29"; - case dwarf_r30_mips: return "r30"; - case dwarf_ra_mips: return "r31"; - case dwarf_f0_mips: return "f0"; - case dwarf_f1_mips: return "f1"; - case dwarf_f2_mips: return "f2"; - case dwarf_f3_mips: return "f3"; - case dwarf_f4_mips: return "f4"; - case dwarf_f5_mips: return "f5"; - case dwarf_f6_mips: return "f6"; - case dwarf_f7_mips: return "f7"; - case dwarf_f8_mips: return "f8"; - case dwarf_f9_mips: return "f9"; - case dwarf_f10_mips: return "f10"; - case dwarf_f11_mips: return "f11"; - case dwarf_f12_mips: return "f12"; - case dwarf_f13_mips: return "f13"; - case dwarf_f14_mips: return "f14"; - case dwarf_f15_mips: return "f15"; - case dwarf_f16_mips: return "f16"; - case dwarf_f17_mips: return "f17"; - case dwarf_f18_mips: return "f18"; - case dwarf_f19_mips: return "f19"; - case dwarf_f20_mips: return "f20"; - case dwarf_f21_mips: return "f21"; - case dwarf_f22_mips: return "f22"; - case dwarf_f23_mips: return "f23"; - case dwarf_f24_mips: return "f24"; - case dwarf_f25_mips: return "f25"; - case dwarf_f26_mips: return "f26"; - case dwarf_f27_mips: return "f27"; - case dwarf_f28_mips: return "f28"; - case dwarf_f29_mips: return "f29"; - case dwarf_f30_mips: return "f30"; - case dwarf_f31_mips: return "f31"; - case dwarf_w0_mips: return "w0"; - case dwarf_w1_mips: return "w1"; - case dwarf_w2_mips: return "w2"; - case dwarf_w3_mips: return "w3"; - case dwarf_w4_mips: return "w4"; - case dwarf_w5_mips: return "w5"; - case dwarf_w6_mips: return "w6"; - case dwarf_w7_mips: return "w7"; - case dwarf_w8_mips: return "w8"; - case dwarf_w9_mips: return "w9"; - case dwarf_w10_mips: return "w10"; - case dwarf_w11_mips: return "w11"; - case dwarf_w12_mips: return "w12"; - case dwarf_w13_mips: return "w13"; - case dwarf_w14_mips: return "w14"; - case dwarf_w15_mips: return "w15"; - case dwarf_w16_mips: return "w16"; - case dwarf_w17_mips: return "w17"; - case dwarf_w18_mips: return "w18"; - case dwarf_w19_mips: return "w19"; - case dwarf_w20_mips: return "w20"; - case dwarf_w21_mips: return "w21"; - case dwarf_w22_mips: return "w22"; - case dwarf_w23_mips: return "w23"; - case dwarf_w24_mips: return "w24"; - case dwarf_w25_mips: return "w25"; - case dwarf_w26_mips: return "w26"; - case dwarf_w27_mips: return "w27"; - case dwarf_w28_mips: return "w28"; - case dwarf_w29_mips: return "w29"; - case dwarf_w30_mips: return "w30"; - case dwarf_w31_mips: return "w31"; - case dwarf_mir_mips: return "mir"; - case dwarf_mcsr_mips: return "mcsr"; - case dwarf_config5_mips: return "config5"; - default: - break; - } - return nullptr; - } +bool EmulateInstructionMIPS::SetInstruction(const Opcode &insn_opcode, + const Address &inst_addr, + Target *target) { + m_use_alt_disaasm = false; - switch (reg_num) - { - case dwarf_zero_mips: return "r0"; - case dwarf_r1_mips: return "r1"; - case dwarf_r2_mips: return "r2"; - case dwarf_r3_mips: return "r3"; - case dwarf_r4_mips: return "r4"; - case dwarf_r5_mips: return "r5"; - case dwarf_r6_mips: return "r6"; - case dwarf_r7_mips: return "r7"; - case dwarf_r8_mips: return "r8"; - case dwarf_r9_mips: return "r9"; - case dwarf_r10_mips: return "r10"; - case dwarf_r11_mips: return "r11"; - case dwarf_r12_mips: return "r12"; - case dwarf_r13_mips: return "r13"; - case dwarf_r14_mips: return "r14"; - case dwarf_r15_mips: return "r15"; - case dwarf_r16_mips: return "r16"; - case dwarf_r17_mips: return "r17"; - case dwarf_r18_mips: return "r18"; - case dwarf_r19_mips: return "r19"; - case dwarf_r20_mips: return "r20"; - case dwarf_r21_mips: return "r21"; - case dwarf_r22_mips: return "r22"; - case dwarf_r23_mips: return "r23"; - case dwarf_r24_mips: return "r24"; - case dwarf_r25_mips: return "r25"; - case dwarf_r26_mips: return "r26"; - case dwarf_r27_mips: return "r27"; - case dwarf_gp_mips: return "gp"; - case dwarf_sp_mips: return "sp"; - case dwarf_r30_mips: return "fp"; - case dwarf_ra_mips: return "ra"; - case dwarf_sr_mips: return "sr"; - case dwarf_lo_mips: return "lo"; - case dwarf_hi_mips: return "hi"; - case dwarf_bad_mips: return "bad"; - case dwarf_cause_mips: return "cause"; - case dwarf_pc_mips: return "pc"; - case dwarf_f0_mips: return "f0"; - case dwarf_f1_mips: return "f1"; - case dwarf_f2_mips: return "f2"; - case dwarf_f3_mips: return "f3"; - case dwarf_f4_mips: return "f4"; - case dwarf_f5_mips: return "f5"; - case dwarf_f6_mips: return "f6"; - case dwarf_f7_mips: return "f7"; - case dwarf_f8_mips: return "f8"; - case dwarf_f9_mips: return "f9"; - case dwarf_f10_mips: return "f10"; - case dwarf_f11_mips: return "f11"; - case dwarf_f12_mips: return "f12"; - case dwarf_f13_mips: return "f13"; - case dwarf_f14_mips: return "f14"; - case dwarf_f15_mips: return "f15"; - case dwarf_f16_mips: return "f16"; - case dwarf_f17_mips: return "f17"; - case dwarf_f18_mips: return "f18"; - case dwarf_f19_mips: return "f19"; - case dwarf_f20_mips: return "f20"; - case dwarf_f21_mips: return "f21"; - case dwarf_f22_mips: return "f22"; - case dwarf_f23_mips: return "f23"; - case dwarf_f24_mips: return "f24"; - case dwarf_f25_mips: return "f25"; - case dwarf_f26_mips: return "f26"; - case dwarf_f27_mips: return "f27"; - case dwarf_f28_mips: return "f28"; - case dwarf_f29_mips: return "f29"; - case dwarf_f30_mips: return "f30"; - case dwarf_f31_mips: return "f31"; - case dwarf_fcsr_mips: return "fcsr"; - case dwarf_fir_mips: return "fir"; - case dwarf_w0_mips: return "w0"; - case dwarf_w1_mips: return "w1"; - case dwarf_w2_mips: return "w2"; - case dwarf_w3_mips: return "w3"; - case dwarf_w4_mips: return "w4"; - case dwarf_w5_mips: return "w5"; - case dwarf_w6_mips: return "w6"; - case dwarf_w7_mips: return "w7"; - case dwarf_w8_mips: return "w8"; - case dwarf_w9_mips: return "w9"; - case dwarf_w10_mips: return "w10"; - case dwarf_w11_mips: return "w11"; - case dwarf_w12_mips: return "w12"; - case dwarf_w13_mips: return "w13"; - case dwarf_w14_mips: return "w14"; - case dwarf_w15_mips: return "w15"; - case dwarf_w16_mips: return "w16"; - case dwarf_w17_mips: return "w17"; - case dwarf_w18_mips: return "w18"; - case dwarf_w19_mips: return "w19"; - case dwarf_w20_mips: return "w20"; - case dwarf_w21_mips: return "w21"; - case dwarf_w22_mips: return "w22"; - case dwarf_w23_mips: return "w23"; - case dwarf_w24_mips: return "w24"; - case dwarf_w25_mips: return "w25"; - case dwarf_w26_mips: return "w26"; - case dwarf_w27_mips: return "w27"; - case dwarf_w28_mips: return "w28"; - case dwarf_w29_mips: return "w29"; - case dwarf_w30_mips: return "w30"; - case dwarf_w31_mips: return "w31"; - case dwarf_mcsr_mips: return "mcsr"; - case dwarf_mir_mips: return "mir"; - case dwarf_config5_mips: return "config5"; - } - return nullptr; -} + if (EmulateInstruction::SetInstruction(insn_opcode, inst_addr, target)) { + if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) { + Error error; + lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; -bool -EmulateInstructionMIPS::GetRegisterInfo (RegisterKind reg_kind, uint32_t reg_num, RegisterInfo ®_info) -{ - if (reg_kind == eRegisterKindGeneric) - { - switch (reg_num) - { - case LLDB_REGNUM_GENERIC_PC: reg_kind = eRegisterKindDWARF; reg_num = dwarf_pc_mips; break; - case LLDB_REGNUM_GENERIC_SP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sp_mips; break; - case LLDB_REGNUM_GENERIC_FP: reg_kind = eRegisterKindDWARF; reg_num = dwarf_r30_mips; break; - case LLDB_REGNUM_GENERIC_RA: reg_kind = eRegisterKindDWARF; reg_num = dwarf_ra_mips; break; - case LLDB_REGNUM_GENERIC_FLAGS: reg_kind = eRegisterKindDWARF; reg_num = dwarf_sr_mips; break; - default: - return false; - } - } + /* + * The address belongs to microMIPS function. To find the size of + * next instruction use microMIPS disassembler. + */ + m_use_alt_disaasm = true; - if (reg_kind == eRegisterKindDWARF) - { - ::memset (®_info, 0, sizeof(RegisterInfo)); - ::memset (reg_info.kinds, LLDB_INVALID_REGNUM, sizeof(reg_info.kinds)); - - if (reg_num == dwarf_sr_mips || reg_num == dwarf_fcsr_mips || reg_num == dwarf_fir_mips || reg_num == dwarf_mcsr_mips || reg_num == dwarf_mir_mips || reg_num == dwarf_config5_mips) - { - reg_info.byte_size = 4; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } - else if ((int)reg_num >= dwarf_zero_mips && (int)reg_num <= dwarf_f31_mips) - { - reg_info.byte_size = 4; - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } - else if ((int)reg_num >= dwarf_w0_mips && (int)reg_num <= dwarf_w31_mips) - { - reg_info.byte_size = 16; - reg_info.format = eFormatVectorOfUInt8; - reg_info.encoding = eEncodingVector; - } - else - { - return false; - } - - reg_info.name = GetRegisterName (reg_num, false); - reg_info.alt_name = GetRegisterName (reg_num, true); - reg_info.kinds[eRegisterKindDWARF] = reg_num; - - switch (reg_num) - { - case dwarf_r30_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP; break; - case dwarf_ra_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA; break; - case dwarf_sp_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP; break; - case dwarf_pc_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC; break; - case dwarf_sr_mips: reg_info.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS; break; - default: break; - } - return true; - } - return false; -} + uint32_t current_inst_size = insn_opcode.GetByteSize(); + uint8_t buf[sizeof(uint32_t)]; + uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size; + Address next_addr(next_inst_addr); -EmulateInstructionMIPS::MipsOpcode* -EmulateInstructionMIPS::GetOpcodeForInstruction (const char *op_name) -{ - static EmulateInstructionMIPS::MipsOpcode - g_opcodes[] = - { - //---------------------------------------------------------------------- - // Prologue/Epilogue instructions - //---------------------------------------------------------------------- - { "ADDiu", &EmulateInstructionMIPS::Emulate_ADDiu, "ADDIU rt, rs, immediate" }, - { "SW", &EmulateInstructionMIPS::Emulate_SW, "SW rt, offset(rs)" }, - { "LW", &EmulateInstructionMIPS::Emulate_LW, "LW rt, offset(base)" }, - { "SUBU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "SUBU rd, rs, rt" }, - { "ADDU", &EmulateInstructionMIPS::Emulate_SUBU_ADDU, "ADDU rd, rs, rt" }, - { "LUI", &EmulateInstructionMIPS::Emulate_LUI, "LUI rt, immediate" }, - - //---------------------------------------------------------------------- - // MicroMIPS Prologue/Epilogue instructions - //---------------------------------------------------------------------- - { "ADDIUSP_MM", &EmulateInstructionMIPS::Emulate_ADDIUSP, "ADDIU immediate" }, - { "ADDIUS5_MM", &EmulateInstructionMIPS::Emulate_ADDIUS5, "ADDIUS5 rd,immediate" }, - { "SWSP_MM", &EmulateInstructionMIPS::Emulate_SWSP, "SWSP rt,offset(sp)" }, - { "SWM16_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM16 reglist,offset(sp)" }, - { "SWM32_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWM32 reglist,offset(base)" }, - { "SWP_MM", &EmulateInstructionMIPS::Emulate_SWM16_32, "SWP rs1,offset(base)" }, - { "LWSP_MM", &EmulateInstructionMIPS::Emulate_LWSP, "LWSP rt,offset(sp)" }, - { "LWM16_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM16 reglist,offset(sp)" }, - { "LWM32_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWM32 reglist,offset(base)" }, - { "LWP_MM", &EmulateInstructionMIPS::Emulate_LWM16_32, "LWP rd,offset(base)" }, - { "JRADDIUSP", &EmulateInstructionMIPS::Emulate_JRADDIUSP, "JRADDIUSP immediate" }, - //---------------------------------------------------------------------- - - // 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)" }, - { "LLX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLX rt, offset(base)" }, - { "LLXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLXE rt, offset(base)" }, - { "LLDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LLDX rt, offset(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)" }, - { "SCX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCX rt, offset(base)" }, - { "SCXE", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCXE rt, offset(base)" }, - { "SCDX", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SCDX rt, offset(base)" }, - - //---------------------------------------------------------------------- - // MicroMIPS Load/Store instructions - //---------------------------------------------------------------------- - { "LBU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LBU16 rt, decoded_offset(base)" }, - { "LHU16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LHU16 rt, left_shifted_offset(base)" }, - { "LW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LW16 rt, left_shifted_offset(base)" }, - { "LWGP_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "LWGP rt, left_shifted_offset(gp)" }, - { "SH16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SH16 rt, left_shifted_offset(base)" }, - { "SW16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SW16 rt, left_shifted_offset(base)" }, - { "SW_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SWSP rt, left_shifted_offset(base)" }, - { "SB16_MM", &EmulateInstructionMIPS::Emulate_LDST_Imm, "SB16 rt, offset(base)" }, - - //---------------------------------------------------------------------- - // Branch instructions - //---------------------------------------------------------------------- - { "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_Bcond_Link, "BGEZAL rs,offset" }, - { "BALC", &EmulateInstructionMIPS::Emulate_BALC, "BALC offset" }, - { "BC", &EmulateInstructionMIPS::Emulate_BC, "BC 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" }, - { "JALR", &EmulateInstructionMIPS::Emulate_JALR, "JALR target" }, - { "JALR_HB", &EmulateInstructionMIPS::Emulate_JALR, "JALR.HB target" }, - { "JIALC", &EmulateInstructionMIPS::Emulate_JIALC, "JIALC rt,offset" }, - { "JIC", &EmulateInstructionMIPS::Emulate_JIC, "JIC rt,offset" }, - { "JR", &EmulateInstructionMIPS::Emulate_JR, "JR target" }, - { "JR_HB", &EmulateInstructionMIPS::Emulate_JR, "JR.HB target" }, - { "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_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" }, - { "BNZ_D", &EmulateInstructionMIPS::Emulate_BNZD, "BNZ.d wt,s16" }, - { "BZ_B", &EmulateInstructionMIPS::Emulate_BZB, "BZ.b wt,s16" }, - { "BZ_H", &EmulateInstructionMIPS::Emulate_BZH, "BZ.h wt,s16" }, - { "BZ_W", &EmulateInstructionMIPS::Emulate_BZW, "BZ.w wt,s16" }, - { "BZ_D", &EmulateInstructionMIPS::Emulate_BZD, "BZ.d wt,s16" }, - { "BNZ_V", &EmulateInstructionMIPS::Emulate_BNZV, "BNZ.V wt,s16" }, - { "BZ_V", &EmulateInstructionMIPS::Emulate_BZV, "BZ.V wt,s16" }, - - //---------------------------------------------------------------------- - // MicroMIPS Branch instructions - //---------------------------------------------------------------------- - { "B16_MM", &EmulateInstructionMIPS::Emulate_B16_MM, "B16 offset" }, - { "BEQZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZ16 rs, offset" }, - { "BNEZ16_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZ16 rs, offset" }, - { "BEQZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BEQZC rs, offset" }, - { "BNEZC_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BNEZC rs, offset" }, - { "BGEZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BGEZALS rs, offset" }, - { "BLTZALS_MM", &EmulateInstructionMIPS::Emulate_Branch_MM, "BLTZALS rs, offset" }, - { "JALR16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALR16 rs" }, - { "JALRS16_MM", &EmulateInstructionMIPS::Emulate_JALRx16_MM, "JALRS16 rs" }, - { "JR16_MM", &EmulateInstructionMIPS::Emulate_JR, "JR16 rs rs" }, - { "JRC16_MM", &EmulateInstructionMIPS::Emulate_JR, "JRC16 rs rs" }, - { "JALS_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALS target" }, - { "JALX_MM", &EmulateInstructionMIPS::Emulate_JALx, "JALX target" }, - { "JALRS_MM", &EmulateInstructionMIPS::Emulate_JALRS, "JALRS rt, rs" }, - }; - - static const size_t k_num_mips_opcodes = llvm::array_lengthof(g_opcodes); - - for (size_t i = 0; i < k_num_mips_opcodes; ++i) - { - if (! strcasecmp (g_opcodes[i].op_name, op_name)) - return &g_opcodes[i]; - } + const size_t bytes_read = + target->ReadMemory(next_addr, /* Address of next instruction */ + true, /* prefer_file_cache */ + buf, sizeof(uint32_t), error, &load_addr); - return NULL; -} + if (bytes_read == 0) + return true; -uint32_t -EmulateInstructionMIPS::GetSizeOfInstruction (lldb_private::DataExtractor& data, uint64_t inst_addr) -{ - uint64_t next_inst_size = 0; - llvm::MCInst mc_insn; + DataExtractor data(buf, sizeof(uint32_t), GetByteOrder(), + GetAddressByteSize()); + m_next_inst_size = GetSizeOfInstruction(data, next_inst_addr); + return true; + } else { + /* + * If the address class is not eAddressClassCodeAlternateISA then + * the function is not microMIPS. In this case instruction size is + * always 4 bytes. + */ + m_next_inst_size = 4; + return true; + } + } + return false; +} + +bool EmulateInstructionMIPS::ReadInstruction() { + bool success = false; + m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, + LLDB_INVALID_ADDRESS, &success); + if (success) { + Context read_inst_context; + read_inst_context.type = eContextReadOpcode; + read_inst_context.SetNoArgs(); + m_opcode.SetOpcode32( + ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success), + GetByteOrder()); + } + if (!success) + m_addr = LLDB_INVALID_ADDRESS; + return success; +} + +bool EmulateInstructionMIPS::EvaluateInstruction(uint32_t evaluate_options) { + bool success = false; + llvm::MCInst mc_insn; + uint64_t insn_size; + DataExtractor data; + + /* Keep the complexity of the decode logic with the llvm::MCDisassembler + * class. */ + if (m_opcode.GetData(data)) { llvm::MCDisassembler::DecodeStatus decode_status; - llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize()); - + llvm::ArrayRef<uint8_t> raw_insn(data.GetDataStart(), data.GetByteSize()); if (m_use_alt_disaasm) - decode_status = m_alt_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls()); + decode_status = m_alt_disasm->getInstruction( + mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); else - decode_status = m_disasm->getInstruction (mc_insn, next_inst_size, raw_insn, inst_addr, llvm::nulls(), llvm::nulls()); + decode_status = m_disasm->getInstruction( + mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); if (decode_status != llvm::MCDisassembler::Success) - return false; - - return m_insn_info->get(mc_insn.getOpcode()).getSize(); -} - -bool -EmulateInstructionMIPS::SetInstruction (const Opcode &insn_opcode, const Address &inst_addr, Target *target) -{ - m_use_alt_disaasm = false; - - if (EmulateInstruction::SetInstruction (insn_opcode, inst_addr, target)) - { - if (inst_addr.GetAddressClass() == eAddressClassCodeAlternateISA) - { - Error error; - lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; - - /* - * The address belongs to microMIPS function. To find the size of - * next instruction use microMIPS disassembler. - */ - m_use_alt_disaasm = true; - - uint32_t current_inst_size = insn_opcode.GetByteSize(); - uint8_t buf[sizeof(uint32_t)]; - uint64_t next_inst_addr = (m_addr & (~1ull)) + current_inst_size; - Address next_addr (next_inst_addr); - - const size_t bytes_read = target->ReadMemory (next_addr, /* Address of next instruction */ - true, /* prefer_file_cache */ - buf, - sizeof(uint32_t), - error, - &load_addr); - - if (bytes_read == 0) - return true; - - DataExtractor data (buf, sizeof(uint32_t), GetByteOrder(), GetAddressByteSize()); - m_next_inst_size = GetSizeOfInstruction (data, next_inst_addr); - return true; - } - else - { - /* - * If the address class is not eAddressClassCodeAlternateISA then - * the function is not microMIPS. In this case instruction size is - * always 4 bytes. - */ - m_next_inst_size = 4; - return true; - } - } - return false; -} + return false; + } -bool -EmulateInstructionMIPS::ReadInstruction () -{ - bool success = false; - m_addr = ReadRegisterUnsigned (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_ADDRESS, &success); - if (success) - { - Context read_inst_context; - read_inst_context.type = eContextReadOpcode; - read_inst_context.SetNoArgs (); - m_opcode.SetOpcode32 (ReadMemoryUnsigned (read_inst_context, m_addr, 4, 0, &success), GetByteOrder()); - } - if (!success) - m_addr = LLDB_INVALID_ADDRESS; - return success; -} - -bool -EmulateInstructionMIPS::EvaluateInstruction (uint32_t evaluate_options) -{ - bool success = false; - llvm::MCInst mc_insn; - uint64_t insn_size; - DataExtractor data; - - /* Keep the complexity of the decode logic with the llvm::MCDisassembler class. */ - if (m_opcode.GetData (data)) - { - llvm::MCDisassembler::DecodeStatus decode_status; - llvm::ArrayRef<uint8_t> raw_insn (data.GetDataStart(), data.GetByteSize()); - if (m_use_alt_disaasm) - decode_status = m_alt_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); - else - decode_status = m_disasm->getInstruction (mc_insn, insn_size, raw_insn, m_addr, llvm::nulls(), llvm::nulls()); - - if (decode_status != llvm::MCDisassembler::Success) - return false; - } + /* + * mc_insn.getOpcode() returns decoded opcode. However to make use + * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". + */ + const char *op_name = m_insn_info->getName(mc_insn.getOpcode()); - /* - * mc_insn.getOpcode() returns decoded opcode. However to make use - * of llvm::Mips::<insn> we would need "MipsGenInstrInfo.inc". - */ - const char *op_name = m_insn_info->getName (mc_insn.getOpcode ()); + if (op_name == NULL) + return false; - if (op_name == NULL) - return false; + /* + * Decoding has been done already. Just get the call-back function + * and emulate the instruction. + */ + MipsOpcode *opcode_data = GetOpcodeForInstruction(op_name); - /* - * Decoding has been done already. Just get the call-back function - * and emulate the instruction. - */ - MipsOpcode *opcode_data = GetOpcodeForInstruction (op_name); + if (opcode_data == NULL) + return false; - if (opcode_data == NULL) - return false; + uint64_t old_pc = 0, new_pc = 0; + const bool auto_advance_pc = + evaluate_options & eEmulateInstructionOptionAutoAdvancePC; - uint64_t old_pc = 0, new_pc = 0; - const bool auto_advance_pc = evaluate_options & eEmulateInstructionOptionAutoAdvancePC; + if (auto_advance_pc) { + old_pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; + } - if (auto_advance_pc) - { - old_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; - } + /* emulate instruction */ + success = (this->*opcode_data->callback)(mc_insn); + if (!success) + return false; - /* emulate instruction */ - success = (this->*opcode_data->callback) (mc_insn); + if (auto_advance_pc) { + new_pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); if (!success) - return false; + return false; - if (auto_advance_pc) - { - new_pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; - - /* If we haven't changed the PC, change it here */ - if (old_pc == new_pc) - { - new_pc += 4; - Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, new_pc)) - return false; - } + /* If we haven't changed the PC, change it here */ + if (old_pc == new_pc) { + new_pc += 4; + Context context; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + new_pc)) + return false; } + } - return true; + return true; } -bool -EmulateInstructionMIPS::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan) -{ - unwind_plan.Clear(); - unwind_plan.SetRegisterKind (eRegisterKindDWARF); +bool EmulateInstructionMIPS::CreateFunctionEntryUnwind( + UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); - UnwindPlan::RowSP row(new UnwindPlan::Row); - const bool can_replace = false; + UnwindPlan::RowSP row(new UnwindPlan::Row); + const bool can_replace = false; - // Our previous Call Frame Address is the stack pointer - row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0); + // Our previous Call Frame Address is the stack pointer + row->GetCFAValue().SetIsRegisterPlusOffset(dwarf_sp_mips, 0); - // Our previous PC is in the RA - row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace); + // Our previous PC is in the RA + row->SetRegisterLocationToRegister(dwarf_pc_mips, dwarf_ra_mips, can_replace); - unwind_plan.AppendRow (row); + unwind_plan.AppendRow(row); - // All other registers are the same. - unwind_plan.SetSourceName ("EmulateInstructionMIPS"); - unwind_plan.SetSourcedFromCompiler (eLazyBoolNo); - unwind_plan.SetUnwindPlanValidAtAllInstructions (eLazyBoolYes); - unwind_plan.SetReturnAddressRegister (dwarf_ra_mips); + // All other registers are the same. + unwind_plan.SetSourceName("EmulateInstructionMIPS"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes); + unwind_plan.SetReturnAddressRegister(dwarf_ra_mips); - return true; + return true; } -bool -EmulateInstructionMIPS::nonvolatile_reg_p (uint32_t regnum) -{ - switch (regnum) - { - case dwarf_r16_mips: - case dwarf_r17_mips: - case dwarf_r18_mips: - case dwarf_r19_mips: - case dwarf_r20_mips: - case dwarf_r21_mips: - case dwarf_r22_mips: - case dwarf_r23_mips: - case dwarf_gp_mips: - case dwarf_sp_mips: - case dwarf_r30_mips: - case dwarf_ra_mips: - return true; - default: - return false; - } +bool EmulateInstructionMIPS::nonvolatile_reg_p(uint32_t regnum) { + switch (regnum) { + case dwarf_r16_mips: + case dwarf_r17_mips: + case dwarf_r18_mips: + case dwarf_r19_mips: + case dwarf_r20_mips: + case dwarf_r21_mips: + case dwarf_r22_mips: + case dwarf_r23_mips: + case dwarf_gp_mips: + case dwarf_sp_mips: + case dwarf_r30_mips: + case dwarf_ra_mips: + return true; + default: return false; -} - -bool -EmulateInstructionMIPS::Emulate_ADDiu (llvm::MCInst& insn) -{ - // ADDIU rt, rs, immediate - // GPR[rt] <- GPR[rs] + sign_extend(immediate) - - uint8_t dst, src; - bool success = false; - const uint32_t imm16 = insn.getOperand(2).getImm(); - int64_t imm = SignedBits(imm16, 15, 0); - - dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); - - // If immediate value is greater then 2^16 - 1 then clang generate - // LUI, ADDIU, SUBU instructions in prolog. - // Example - // lui $1, 0x2 - // addiu $1, $1, -0x5920 - // subu $sp, $sp, $1 - // In this case, ADDIU dst and src will be same and not equal to sp - if (dst == src) - { - Context context; + } + return false; +} + +bool EmulateInstructionMIPS::Emulate_ADDiu(llvm::MCInst &insn) { + // ADDIU rt, rs, immediate + // GPR[rt] <- GPR[rs] + sign_extend(immediate) + + uint8_t dst, src; + bool success = false; + const uint32_t imm16 = insn.getOperand(2).getImm(); + int64_t imm = SignedBits(imm16, 15, 0); + + dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); + + // If immediate value is greater then 2^16 - 1 then clang generate + // LUI, ADDIU, SUBU instructions in prolog. + // Example + // lui $1, 0x2 + // addiu $1, $1, -0x5920 + // subu $sp, $sp, $1 + // In this case, ADDIU dst and src will be same and not equal to sp + if (dst == src) { + Context context; - /* read <src> register */ - const int64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); - if (!success) - return false; + /* read <src> register */ + const int64_t src_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); + if (!success) + return false; - /* Check if this is daddiu sp, sp, imm16 */ - if (dst == dwarf_sp_mips) - { - uint64_t result = src_opd_val + imm; - RegisterInfo reg_info_sp; + /* Check if this is daddiu sp, sp, imm16 */ + if (dst == dwarf_sp_mips) { + uint64_t result = src_opd_val + imm; + RegisterInfo reg_info_sp; - if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) - context.SetRegisterPlusOffset (reg_info_sp, imm); + if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) + context.SetRegisterPlusOffset(reg_info_sp, imm); - /* We are allocating bytes on stack */ - context.type = eContextAdjustStackPointer; + /* We are allocating bytes on stack */ + context.type = eContextAdjustStackPointer; - WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); - return true; - } + WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); + return true; + } - imm += src_opd_val; - context.SetImmediateSigned (imm); - context.type = eContextImmediate; + imm += src_opd_val; + context.SetImmediateSigned(imm); + context.type = eContextImmediate; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, imm)) - return false; - } + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, + dwarf_zero_mips + dst, imm)) + return false; + } - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_SW (llvm::MCInst& insn) -{ - bool success = false; - 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; +bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) { + bool success = false; + 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; + RegisterInfo reg_info_base; - src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); + src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - /* read base register */ - address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + /* read base register */ + address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - /* destination address */ - address = address + imm; + /* 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, dwarf_bad_mips, address); + /* Set the bad_vaddr register with base address used in the instruction */ + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + address); - /* We look for sp based non-volatile register stores */ - if (nonvolatile_reg_p (src)) - { + /* We look for sp based non-volatile register stores */ + if (nonvolatile_reg_p(src)) { - RegisterInfo reg_info_src; + RegisterInfo reg_info_src; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, + reg_info_src)) + return false; - Context context; - RegisterValue data_src; - context.type = eContextPushRegisterOnStack; - context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); + Context context; + RegisterValue data_src; + context.type = eContextPushRegisterOnStack; + context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); - uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; - Error error; + uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + Error error; - if (!ReadRegister (®_info_base, data_src)) - return false; + if (!ReadRegister(®_info_base, data_src)) + return false; - if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) - return false; + if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, + eByteOrderLittle, error) == 0) + return false; - if (!WriteMemory (context, address, buffer, reg_info_src.byte_size)) - return false; + if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) + return false; - return true; - } + return true; + } - return false; + return false; } -bool -EmulateInstructionMIPS::Emulate_LW (llvm::MCInst& insn) -{ - bool success =false; - uint32_t src, base; - int32_t imm, address; - Context bad_vaddr_context; +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(); + 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, dwarf_zero_mips + base, reg_info_base)) - return false; + RegisterInfo reg_info_base; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - /* read base register */ - address = (int32_t)ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + /* read base register */ + address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - /* destination address */ - address = address + imm; + /* 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, dwarf_bad_mips, address); + /* Set the bad_vaddr register with base address used in the instruction */ + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + address); - if (nonvolatile_reg_p (src)) - { - RegisterValue data_src; - RegisterInfo reg_info_src; + if (nonvolatile_reg_p(src)) { + RegisterValue data_src; + RegisterInfo reg_info_src; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, + reg_info_src)) + return false; - Context context; - context.type = eContextPopRegisterOffStack; - context.SetAddress (address); + Context context; + context.type = eContextPopRegisterOffStack; + context.SetAddress(address); - if (!WriteRegister (context, ®_info_src, data_src)) - return false; + if (!WriteRegister(context, ®_info_src, data_src)) + return false; - return true; - } + return true; + } - return false; + return false; } -bool -EmulateInstructionMIPS::Emulate_SUBU_ADDU (llvm::MCInst& insn) -{ - // SUBU sp, <src>, <rt> - // ADDU sp, <src>, <rt> - // ADDU dst, sp, <rt> +bool EmulateInstructionMIPS::Emulate_SUBU_ADDU(llvm::MCInst &insn) { + // SUBU sp, <src>, <rt> + // ADDU sp, <src>, <rt> + // ADDU dst, sp, <rt> - bool success = false; - uint64_t result; - uint8_t src, dst, rt; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - dst = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - src = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); + bool success = false; + uint64_t result; + uint8_t src, dst, rt; + const char *op_name = m_insn_info->getName(insn.getOpcode()); - /* Check if sp is destination register */ - if (dst == dwarf_sp_mips) - { - rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg()); + dst = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + src = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); - /* read <src> register */ - uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); - if (!success) - return false; + /* Check if sp is destination register */ + if (dst == dwarf_sp_mips) { + rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); - /* read <rt > register */ - uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); - if (!success) - return false; + /* read <src> register */ + uint64_t src_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); + if (!success) + return false; - if (!strcasecmp (op_name, "SUBU")) - result = src_opd_val - rt_opd_val; - else - result = src_opd_val + rt_opd_val; + /* read <rt > register */ + uint64_t rt_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); + if (!success) + return false; - Context context; - RegisterInfo reg_info_sp; - if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) - context.SetRegisterPlusOffset (reg_info_sp, rt_opd_val); + if (!strcasecmp(op_name, "SUBU")) + result = src_opd_val - rt_opd_val; + else + result = src_opd_val + rt_opd_val; - /* We are allocating bytes on stack */ - context.type = eContextAdjustStackPointer; + Context context; + RegisterInfo reg_info_sp; + if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) + context.SetRegisterPlusOffset(reg_info_sp, rt_opd_val); - WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); + /* We are allocating bytes on stack */ + context.type = eContextAdjustStackPointer; - return true; - } - else if (src == dwarf_sp_mips) - { - rt = m_reg_info->getEncodingValue (insn.getOperand(2).getReg()); + WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); - /* read <src> register */ - uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); - if (!success) - return false; + return true; + } else if (src == dwarf_sp_mips) { + rt = m_reg_info->getEncodingValue(insn.getOperand(2).getReg()); - /* read <rt> register */ - uint64_t rt_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); - if (!success) - return false; + /* read <src> register */ + uint64_t src_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + src, 0, &success); + if (!success) + return false; - Context context; + /* read <rt> register */ + uint64_t rt_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); + if (!success) + return false; - if (!strcasecmp (op_name, "SUBU")) - result = src_opd_val - rt_opd_val; - else - result = src_opd_val + rt_opd_val; + Context context; - context.SetImmediateSigned (result); - context.type = eContextImmediate; + if (!strcasecmp(op_name, "SUBU")) + result = src_opd_val - rt_opd_val; + else + result = src_opd_val + rt_opd_val; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + dst, result)) - return false; - } + context.SetImmediateSigned(result); + context.type = eContextImmediate; - return true; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, + dwarf_zero_mips + dst, result)) + return false; + } + + return true; } -bool -EmulateInstructionMIPS::Emulate_LUI (llvm::MCInst& insn) -{ - // LUI rt, immediate - // GPR[rt] <- sign_extend(immediate << 16) +bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) { + // LUI rt, immediate + // GPR[rt] <- sign_extend(immediate << 16) - const uint32_t imm32 = insn.getOperand(1).getImm() << 16; - int64_t imm = SignedBits(imm32, 31, 0); - uint8_t rt; - Context context; - - rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - context.SetImmediateSigned (imm); - context.type = eContextImmediate; + const uint32_t imm32 = insn.getOperand(1).getImm() << 16; + int64_t imm = SignedBits(imm32, 31, 0); + uint8_t rt; + Context context; - if (WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, imm)) - return true; + rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + context.SetImmediateSigned(imm); + context.type = eContextImmediate; - return false; + if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, + imm)) + return true; + + return false; } -bool -EmulateInstructionMIPS::Emulate_ADDIUSP (llvm::MCInst& insn) -{ - bool success = false; - const uint32_t imm9 = insn.getOperand(0).getImm(); - uint64_t result; +bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) { + bool success = false; + const uint32_t imm9 = insn.getOperand(0).getImm(); + uint64_t result; - // This instruction operates implicitly on stack pointer, so read <sp> register. - uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success); - if (!success) - return false; + // This instruction operates implicitly on stack pointer, so read <sp> + // register. + uint64_t src_opd_val = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); + if (!success) + return false; - result = src_opd_val + imm9; + result = src_opd_val + imm9; - Context context; - RegisterInfo reg_info_sp; - if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) - context.SetRegisterPlusOffset (reg_info_sp, imm9); + Context context; + RegisterInfo reg_info_sp; + if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) + context.SetRegisterPlusOffset(reg_info_sp, imm9); - // We are adjusting the stack. - context.type = eContextAdjustStackPointer; + // We are adjusting the stack. + context.type = eContextAdjustStackPointer; - WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); - return true; + WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); + return true; } -bool -EmulateInstructionMIPS::Emulate_ADDIUS5 (llvm::MCInst& insn) -{ - bool success = false; - uint32_t base; - const uint32_t imm4 = insn.getOperand(2).getImm(); - uint64_t result; +bool EmulateInstructionMIPS::Emulate_ADDIUS5(llvm::MCInst &insn) { + bool success = false; + uint32_t base; + const uint32_t imm4 = insn.getOperand(2).getImm(); + uint64_t result; - // The source and destination register is same for this instruction. - base = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); + // The source and destination register is same for this instruction. + base = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); - // We are looking for stack adjustment only - if (base == dwarf_sp_mips) - { - // Read stack pointer register - uint64_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + // We are looking for stack adjustment only + if (base == dwarf_sp_mips) { + // Read stack pointer register + uint64_t src_opd_val = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - result = src_opd_val + imm4; + result = src_opd_val + imm4; - Context context; - RegisterInfo reg_info_sp; - if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) - context.SetRegisterPlusOffset (reg_info_sp, imm4); + Context context; + RegisterInfo reg_info_sp; + if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) + context.SetRegisterPlusOffset(reg_info_sp, imm4); - // We are adjusting the stack. - context.type = eContextAdjustStackPointer; + // We are adjusting the stack. + context.type = eContextAdjustStackPointer; - WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result); - } + WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, result); + } - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_SWSP (llvm::MCInst& insn) -{ - bool success = false; - uint32_t imm5 = insn.getOperand(2).getImm(); - uint32_t src, base; - Context bad_vaddr_context; - uint32_t address; +bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) { + bool success = false; + uint32_t imm5 = insn.getOperand(2).getImm(); + uint32_t src, base; + Context bad_vaddr_context; + uint32_t address; - src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); + src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); - RegisterInfo reg_info_base; + RegisterInfo reg_info_base; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - // read base register - address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + // read base register + address = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + base, 0, + &success); + if (!success) + return false; - // destination address - address = address + imm5; + // destination address + address = address + imm5; - // We use bad_vaddr_context to store base address which is used by H/W watchpoint - // Set the bad_vaddr register with base address used in the instruction - bad_vaddr_context.type = eContextInvalid; - WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, address); + // We use bad_vaddr_context to store base address which is used by H/W + // watchpoint + // Set the bad_vaddr register with base address used in the instruction + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + address); - // We look for sp based non-volatile register stores. - if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) - { - RegisterInfo reg_info_src = {}; - Context context; - RegisterValue data_src; - context.type = eContextPushRegisterOnStack; - context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); + // We look for sp based non-volatile register stores. + if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { + RegisterInfo reg_info_src = {}; + Context context; + RegisterValue data_src; + context.type = eContextPushRegisterOnStack; + context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); - uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; - Error error; + uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + Error error; - if (!ReadRegister (®_info_base, data_src)) - return false; + if (!ReadRegister(®_info_base, data_src)) + return false; - if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) - return false; + if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, + eByteOrderLittle, error) == 0) + return false; - if (!WriteMemory (context, address, buffer, reg_info_src.byte_size)) - return false; + if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) + return false; - return true; - } + return true; + } - return false; + return false; } /* Emulate SWM16,SWM32 and SWP instruction. - SWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand). + SWM16 always has stack pointer as a base register (but it is still available + in MCInst as an operand). SWM32 and SWP can have base register other than stack pointer. */ -bool -EmulateInstructionMIPS::Emulate_SWM16_32 (llvm::MCInst& insn) -{ - bool success = false; - uint32_t src, base; - uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store. - - // Base register is second last operand of the instruction. - base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); - - // We are looking for sp based stores so if base is not a stack pointer then don't proceed. - if (base != dwarf_sp_mips) - return false; +bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) { + bool success = false; + uint32_t src, base; + uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on + // no of regs to store. + + // Base register is second last operand of the instruction. + base = + m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); + + // We are looking for sp based stores so if base is not a stack pointer then + // don't proceed. + if (base != dwarf_sp_mips) + return false; - // offset is always the last operand. - uint32_t offset = insn.getOperand(num_operands-1).getImm(); + // offset is always the last operand. + uint32_t offset = insn.getOperand(num_operands - 1).getImm(); - RegisterInfo reg_info_base; - RegisterInfo reg_info_src; - - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) - return false; + RegisterInfo reg_info_base; + RegisterInfo reg_info_src; - // read SP - uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - // Resulting base addrss - base_address = base_address + offset; + // read SP + uint32_t base_address = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - // Total no of registers to be stored are num_operands-2. - for (uint32_t i = 0; i < num_operands - 2; i++) - { - // Get the register number to be stored. - src = m_reg_info->getEncodingValue (insn.getOperand(i).getReg()); + // Resulting base addrss + base_address = base_address + offset; - /* - Record only non-volatile stores. - This check is required for SWP instruction because source operand could be any register. - SWM16 and SWM32 instruction always has saved registers as source operands. - */ - if (!nonvolatile_reg_p (src)) - return false; + // Total no of registers to be stored are num_operands-2. + for (uint32_t i = 0; i < num_operands - 2; i++) { + // Get the register number to be stored. + src = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) - return false; + /* + Record only non-volatile stores. + This check is required for SWP instruction because source operand could + be any register. + SWM16 and SWM32 instruction always has saved registers as source + operands. + */ + if (!nonvolatile_reg_p(src)) + return false; - Context context; - RegisterValue data_src; - context.type = eContextPushRegisterOnStack; - context.SetRegisterToRegisterPlusOffset (reg_info_src, reg_info_base, 0); + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, + reg_info_src)) + return false; - uint8_t buffer [RegisterValue::kMaxRegisterByteSize]; - Error error; + Context context; + RegisterValue data_src; + context.type = eContextPushRegisterOnStack; + context.SetRegisterToRegisterPlusOffset(reg_info_src, reg_info_base, 0); - if (!ReadRegister (®_info_base, data_src)) - return false; + uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + Error error; - if (data_src.GetAsMemoryData (®_info_src, buffer, reg_info_src.byte_size, eByteOrderLittle, error) == 0) - return false; + if (!ReadRegister(®_info_base, data_src)) + return false; - if (!WriteMemory (context, base_address, buffer, reg_info_src.byte_size)) - return false; + if (data_src.GetAsMemoryData(®_info_src, buffer, reg_info_src.byte_size, + eByteOrderLittle, error) == 0) + return false; - // Stack address for next register - base_address = base_address + reg_info_src.byte_size; - } - return true; + if (!WriteMemory(context, base_address, buffer, reg_info_src.byte_size)) + return false; + + // Stack address for next register + base_address = base_address + reg_info_src.byte_size; + } + return true; } -bool -EmulateInstructionMIPS::Emulate_LWSP (llvm::MCInst& insn) -{ - bool success = false; - uint32_t src = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - uint32_t base = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); - uint32_t imm5 = insn.getOperand(2).getImm(); - Context bad_vaddr_context; +bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) { + bool success = false; + uint32_t src = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + uint32_t base = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); + uint32_t imm5 = insn.getOperand(2).getImm(); + Context bad_vaddr_context; - RegisterInfo reg_info_base; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + base, reg_info_base)) - return false; + RegisterInfo reg_info_base; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - // read base register - uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + // read base register + uint32_t base_address = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - base_address = base_address + imm5; + base_address = base_address + imm5; - // We use bad_vaddr_context to store base address which is used by H/W watchpoint - // Set the bad_vaddr register with base address used in the instruction - bad_vaddr_context.type = eContextInvalid; - WriteRegisterUnsigned (bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, base_address); + // We use bad_vaddr_context to store base address which is used by H/W + // watchpoint + // Set the bad_vaddr register with base address used in the instruction + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + base_address); - if (base == dwarf_sp_mips && nonvolatile_reg_p (src)) - { - RegisterValue data_src; - RegisterInfo reg_info_src; + if (base == dwarf_sp_mips && nonvolatile_reg_p(src)) { + RegisterValue data_src; + RegisterInfo reg_info_src; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + src, reg_info_src)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + src, + reg_info_src)) + return false; - Context context; - context.type = eContextPopRegisterOffStack; - context.SetAddress (base_address); + Context context; + context.type = eContextPopRegisterOffStack; + context.SetAddress(base_address); - if (!WriteRegister (context, ®_info_src, data_src)) - return false; + if (!WriteRegister(context, ®_info_src, data_src)) + return false; - return true; - } + return true; + } - return false; + return false; } /* Emulate LWM16, LWM32 and LWP instructions. - LWM16 always has stack pointer as a base register (but it is still available in MCInst as an operand). + LWM16 always has stack pointer as a base register (but it is still available + in MCInst as an operand). LWM32 and LWP can have base register other than stack pointer. */ -bool -EmulateInstructionMIPS::Emulate_LWM16_32 (llvm::MCInst& insn) -{ - bool success = false; - uint32_t dst, base; - uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on no of regs to store. - uint32_t imm = insn.getOperand(num_operands-1).getImm(); // imm is the last operand in the instruction. - - // Base register is second last operand of the instruction. - base = m_reg_info->getEncodingValue (insn.getOperand(num_operands-2).getReg()); - - // We are looking for sp based loads so if base is not a stack pointer then don't proceed. - if (base != dwarf_sp_mips) - return false; +bool EmulateInstructionMIPS::Emulate_LWM16_32(llvm::MCInst &insn) { + bool success = false; + uint32_t dst, base; + uint32_t num_operands = insn.getNumOperands(); // No of operands vary based on + // no of regs to store. + uint32_t imm = insn.getOperand(num_operands - 1) + .getImm(); // imm is the last operand in the instruction. + + // Base register is second last operand of the instruction. + base = + m_reg_info->getEncodingValue(insn.getOperand(num_operands - 2).getReg()); + + // We are looking for sp based loads so if base is not a stack pointer then + // don't proceed. + if (base != dwarf_sp_mips) + return false; - uint32_t base_address = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + uint32_t base_address = ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - base_address = base_address + imm; - - RegisterValue data_dst; - RegisterInfo reg_info_dst; - - // Total no of registers to be re-stored are num_operands-2. - for (uint32_t i = 0; i < num_operands - 2; i++) - { - // Get the register number to be re-stored. - dst = m_reg_info->getEncodingValue (insn.getOperand(i).getReg()); - - /* - Record only non-volatile loads. - This check is required for LWP instruction because destination operand could be any register. - LWM16 and LWM32 instruction always has saved registers as destination operands. - */ - if (!nonvolatile_reg_p (dst)) - return false; - - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + dst, reg_info_dst)) - return false; - - Context context; - context.type = eContextPopRegisterOffStack; - context.SetAddress (base_address + (i*4)); - - if (!WriteRegister (context, ®_info_dst, data_dst)) - return false; - } + base_address = base_address + imm; - return true; -} + RegisterValue data_dst; + RegisterInfo reg_info_dst; -bool -EmulateInstructionMIPS::Emulate_JRADDIUSP (llvm::MCInst& insn) -{ - bool success = false; - int32_t imm5 = insn.getOperand(0).getImm(); + // Total no of registers to be re-stored are num_operands-2. + for (uint32_t i = 0; i < num_operands - 2; i++) { + // Get the register number to be re-stored. + dst = m_reg_info->getEncodingValue(insn.getOperand(i).getReg()); - /* JRADDIUSP immediate - * PC <- RA - * SP <- SP + zero_extend(Immediate << 2) + /* + Record only non-volatile loads. + This check is required for LWP instruction because destination operand + could be any register. + LWM16 and LWM32 instruction always has saved registers as destination + operands. */ - - // This instruction operates implicitly on stack pointer, so read <sp> register. - int32_t src_opd_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_sp_mips, 0, &success); - if (!success) - return false; + if (!nonvolatile_reg_p(dst)) + return false; - int32_t ra_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_ra_mips, 0, &success); - if (!success) - return false; - - int32_t result = src_opd_val + imm5; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + dst, + reg_info_dst)) + return false; Context context; + context.type = eContextPopRegisterOffStack; + context.SetAddress(base_address + (i * 4)); - // Update the PC - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, ra_val)) - return false; - - RegisterInfo reg_info_sp; - if (GetRegisterInfo (eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) - context.SetRegisterPlusOffset (reg_info_sp, imm5); + if (!WriteRegister(context, ®_info_dst, data_dst)) + return false; + } - // We are adjusting stack - context.type = eContextAdjustStackPointer; + return true; +} - // update SP - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_sp_mips, result)) - return false; +bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) { + bool success = false; + int32_t imm5 = insn.getOperand(0).getImm(); - return true; + /* JRADDIUSP immediate + * PC <- RA + * SP <- SP + zero_extend(Immediate << 2) + */ + + // This instruction operates implicitly on stack pointer, so read <sp> + // register. + int32_t src_opd_val = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_sp_mips, 0, &success); + if (!success) + return false; + + int32_t ra_val = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_ra_mips, 0, &success); + if (!success) + return false; + + int32_t result = src_opd_val + imm5; + + Context context; + + // Update the PC + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + ra_val)) + return false; + + RegisterInfo reg_info_sp; + if (GetRegisterInfo(eRegisterKindDWARF, dwarf_sp_mips, reg_info_sp)) + context.SetRegisterPlusOffset(reg_info_sp, imm5); + + // We are adjusting stack + context.type = eContextAdjustStackPointer; + + // update SP + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, + result)) + return false; + + return true; } -static int -IsAdd64bitOverflow (int32_t a, int32_t b) -{ - int32_t r = (uint32_t) a + (uint32_t) b; +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_BXX_3ops (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs, rt; - int32_t offset, pc, target = 0, rs_val, rt_val; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { + bool success = false; + uint32_t rs, rt; + int32_t offset, pc, target = 0, rs_val, rt_val; + const char *op_name = m_insn_info->getName(insn.getOpcode()); + + 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; + 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; + rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rt, 0, &success); + if (!success) + return false; - 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; - } + 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); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; - - return true; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; + + return true; } -/* +/* Emulate below MIPS branch instructions. - BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch instructions with no delay slot + BEQC, BNEC, BLTC, BGEC, BLTUC, BGEUC, BOVC, BNVC: Compact branch + instructions with no delay slot */ -bool -EmulateInstructionMIPS::Emulate_BXX_3ops_C (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs, rt; - int32_t offset, pc, target = 0, 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(); - - 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; +bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { + bool success = false; + uint32_t rs, rt; + int32_t offset, pc, target = 0, 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(); + + 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; + 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; + 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 + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BNEC")) - { - if (rs_val != rt_val) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BLTC")) - { - if (rs_val < rt_val) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGEC")) - { - if (rs_val >= rt_val) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BLTUC")) - { - if (rs_val < rt_val) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGEUC")) - { - if ((uint32_t)rs_val >= (uint32_t)rt_val) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BOVC")) - { - if (IsAdd64bitOverflow (rs_val, rt_val)) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BNVC")) - { - if (!IsAdd64bitOverflow (rs_val, rt_val)) - target = pc + offset; - else - target = pc + 4; - } + if (!strcasecmp(op_name, "BEQC")) { + if (rs_val == rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BNEC")) { + if (rs_val != rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BLTC")) { + if (rs_val < rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGEC")) { + if (rs_val >= rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BLTUC")) { + if (rs_val < rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGEUC")) { + if ((uint32_t)rs_val >= (uint32_t)rt_val) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BOVC")) { + if (IsAdd64bitOverflow(rs_val, rt_val)) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BNVC")) { + if (!IsAdd64bitOverflow(rs_val, rt_val)) + target = pc + offset; + else + target = pc + 4; + } - Context context; - context.type = eContextRelativeBranchImmediate; - context.SetImmediate (current_inst_size + offset); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; - - return true; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; + + return true; } -/* +/* Emulate below MIPS conditional branch and link instructions. BLEZALC, BGEZALC, BLTZALC, BGTZALC, BEQZALC, BNEZALC : Compact branches */ -bool -EmulateInstructionMIPS::Emulate_Bcond_Link_C (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs; - int32_t offset, pc, target = 0; - int32_t rs_val; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_Bcond_Link_C(llvm::MCInst &insn) { + bool success = false; + uint32_t rs; + int32_t offset, pc, target = 0; + int32_t rs_val; + const char *op_name = m_insn_info->getName(insn.getOpcode()); + + 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; + rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rs, 0, &success); + if (!success) + return false; - if (!strcasecmp (op_name, "BLEZALC")) - { - if (rs_val <= 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGEZALC")) - { - if (rs_val >= 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BLTZALC")) - { - if (rs_val < 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGTZALC")) - { - if (rs_val > 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BEQZALC")) - { - if (rs_val == 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BNEZALC")) - { - if (rs_val != 0) - target = pc + offset; - else - target = pc + 4; - } + if (!strcasecmp(op_name, "BLEZALC")) { + if (rs_val <= 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGEZALC")) { + if (rs_val >= 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BLTZALC")) { + if (rs_val < 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGTZALC")) { + if (rs_val > 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BEQZALC")) { + if (rs_val == 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BNEZALC")) { + if (rs_val != 0) + target = pc + offset; + else + target = pc + 4; + } - Context context; - - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 4)) + return false; + + return true; } -/* +/* Emulate below MIPS Non-Compact conditional branch and link instructions. BLTZAL, BGEZAL : BLTZALL, BGEZALL : Branch likely */ -bool -EmulateInstructionMIPS::Emulate_Bcond_Link (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs; - int32_t offset, pc, target = 0; - int32_t rs_val; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_Bcond_Link(llvm::MCInst &insn) { + bool success = false; + uint32_t rs; + int32_t offset, pc, target = 0; + int32_t rs_val; + const char *op_name = m_insn_info->getName(insn.getOpcode()); + + 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; + rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rs, 0, &success); + if (!success) + return false; - 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; - } + 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; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 8)) + return false; - return true; + return true; } -/* +/* Emulate below MIPS branch instructions. BLTZL, BGEZL, BGTZL, BLEZL : Branch likely BLTZ, BGEZ, BGTZ, BLEZ : Non-compact branches */ -bool -EmulateInstructionMIPS::Emulate_BXX_2ops (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs; - int32_t offset, pc, target = 0; - int32_t rs_val; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { + bool success = false; + uint32_t rs; + int32_t offset, pc, target = 0; + int32_t rs_val; + const char *op_name = m_insn_info->getName(insn.getOpcode()); + + 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; + 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")) - { - if (rs_val < 0) - target = pc + offset; - else - target = pc + 8; - } - else if (!strcasecmp (op_name, "BGEZL") || - !strcasecmp (op_name, "BGEZ")) - { - 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; - } + if (!strcasecmp(op_name, "BLTZL") || !strcasecmp(op_name, "BLTZ")) { + if (rs_val < 0) + target = pc + offset; + else + target = pc + 8; + } else if (!strcasecmp(op_name, "BGEZL") || !strcasecmp(op_name, "BGEZ")) { + 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); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -/* +/* Emulate below MIPS branch instructions. BLTZC, BLEZC, BGEZC, BGTZC, BEQZC, BNEZC : Compact Branches */ -bool -EmulateInstructionMIPS::Emulate_BXX_2ops_C (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs; - int32_t offset, pc, target = 0; - 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(); - - 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; +bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { + bool success = false; + uint32_t rs; + int32_t offset, pc, target = 0; + 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(); + + 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; + rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rs, 0, &success); + if (!success) + return false; - if (!strcasecmp (op_name, "BLTZC")) - { - if (rs_val < 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BLEZC")) - { - if (rs_val <= 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGEZC")) - { - if (rs_val >= 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BGTZC")) - { - if (rs_val > 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BEQZC")) - { - if (rs_val == 0) - target = pc + offset; - else - target = pc + 4; - } - else if (!strcasecmp (op_name, "BNEZC")) - { - if (rs_val != 0) - target = pc + offset; - else - target = pc + 4; - } + if (!strcasecmp(op_name, "BLTZC")) { + if (rs_val < 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BLEZC")) { + if (rs_val <= 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGEZC")) { + if (rs_val >= 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BGTZC")) { + if (rs_val > 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BEQZC")) { + if (rs_val == 0) + target = pc + offset; + else + target = pc + 4; + } else if (!strcasecmp(op_name, "BNEZC")) { + if (rs_val != 0) + target = pc + offset; + else + target = pc + 4; + } - Context context; - context.type = eContextRelativeBranchImmediate; - context.SetImmediate (current_inst_size + offset); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn) -{ - bool success = false; - int32_t offset, pc, target; - uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); +bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { + bool success = false; + int32_t offset, pc, target; + uint32_t current_inst_size = m_insn_info->get(insn.getOpcode()).getSize(); - offset = insn.getOperand(0).getImm(); + offset = insn.getOperand(0).getImm(); - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - // unconditional branch - target = pc + offset; + // unconditional branch + target = pc + offset; - Context context; - context.type = eContextRelativeBranchImmediate; - context.SetImmediate (current_inst_size + offset); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } /* @@ -1978,503 +2232,498 @@ EmulateInstructionMIPS::Emulate_B16_MM (llvm::MCInst& insn) BEQZ16, BNEZ16 are 16 bit instructions with delay slot. BGEZALS, BLTZALS are 16 bit instructions with short (2-byte) delay slot. */ -bool -EmulateInstructionMIPS::Emulate_Branch_MM (llvm::MCInst& insn) -{ - bool success = false; - 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; - - /* - * 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) - */ +bool EmulateInstructionMIPS::Emulate_Branch_MM(llvm::MCInst &insn) { + bool success = false; + 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; + + /* + * 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(); + + int32_t pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - int32_t offset = insn.getOperand(1).getImm(); + int32_t rs_val = (int32_t)ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); + if (!success) + return false; - int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + 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 - int32_t rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); - if (!success) - return false; + 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 - 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; - } + update_ra = true; + ra_offset = 6; + } - Context context; - context.type = eContextRelativeBranchImmediate; - context.SetImmediate (current_inst_size + offset); + Context context; + context.type = eContextRelativeBranchImmediate; + context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + 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; + 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_JALRx16_MM (llvm::MCInst& insn) -{ - bool success = false; - uint32_t ra_offset = 0; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); +bool EmulateInstructionMIPS::Emulate_JALRx16_MM(llvm::MCInst &insn) { + bool success = false; + uint32_t ra_offset = 0; + const char *op_name = m_insn_info->getName(insn.getOpcode()); - uint32_t rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); + uint32_t rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); - uint32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + uint32_t pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - uint32_t rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); - if (!success) - return false; + uint32_t rs_val = 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, "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 context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + rs_val)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + ra_offset)) + return false; - return true; + 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_JALx (llvm::MCInst& insn) -{ - bool success = false; - 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 - */ - offset = insn.getOperand(0).getImm(); - - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; +bool EmulateInstructionMIPS::Emulate_JALx(llvm::MCInst &insn) { + bool success = false; + 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 + */ + offset = insn.getOperand(0).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")) - { - // 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; - } + // 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 context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + ra_offset)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + ra_offset)) + return false; - return true; + return true; } -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] - */ +bool EmulateInstructionMIPS::Emulate_JALRS(llvm::MCInst &insn) { + bool success = false; + uint32_t rs = 0, rt = 0; + int32_t pc = 0, rs_val = 0; - rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); + /* + JALRS rt, rs + GPR[rt] <- PC + 6 + PC <- GPR[rs] + */ - rs_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); - if (!success) - return false; + rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; - - Context context; + rs_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rs, 0, &success); + if (!success) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) - return false; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + 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; + 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_BAL (llvm::MCInst& insn) -{ - bool success = false; - int32_t offset, pc, target; +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(); + /* + * 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; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - target = pc + offset; + target = pc + offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 8)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_BALC (llvm::MCInst& insn) -{ - bool success = false; - int32_t offset, pc, target; +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(); + /* + * 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; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - target = pc + offset; + target = pc + offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 4)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_BC (llvm::MCInst& insn) -{ - bool success = false; - int32_t offset, pc, target; +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(); + /* + * 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; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - target = pc + offset; + target = pc + offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_J (llvm::MCInst& insn) -{ - bool success = false; - uint32_t offset, pc; +bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { + bool success = false; + uint32_t offset, pc; - /* - * J offset - * offset = sign_ext (offset << 2) - * PC = PC[63-28] | offset - */ - offset = insn.getOperand(0).getImm(); + /* + * J offset + * offset = sign_ext (offset << 2) + * PC = PC[63-28] | offset + */ + offset = insn.getOperand(0).getImm(); - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - /* This is a PC-region branch and not PC-relative */ - pc = (pc & 0xF0000000UL) | offset; + /* This is a PC-region branch and not PC-relative */ + pc = (pc & 0xF0000000UL) | offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, pc)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_JAL (llvm::MCInst& insn) -{ - bool success = false; - uint32_t offset, target, pc; +bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) { + bool success = false; + uint32_t offset, target, pc; - /* - * JAL offset - * offset = sign_ext (offset << 2) - * PC = PC[63-28] | offset - */ - offset = insn.getOperand(0).getImm(); + /* + * JAL offset + * offset = sign_ext (offset << 2) + * PC = PC[63-28] | offset + */ + offset = insn.getOperand(0).getImm(); - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - /* This is a PC-region branch and not PC-relative */ - target = (pc & 0xF0000000UL) | offset; + /* This is a PC-region branch and not PC-relative */ + target = (pc & 0xF0000000UL) | offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 8)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 8)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_JALR (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs, rt; - uint32_t pc, rs_val; +bool EmulateInstructionMIPS::Emulate_JALR(llvm::MCInst &insn) { + bool success = false; + uint32_t rs, rt; + uint32_t pc, rs_val; - /* - * JALR rt, rs - * GPR[rt] = PC + 8 - * PC = GPR[rs] - */ - rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - rs = m_reg_info->getEncodingValue (insn.getOperand(1).getReg()); + /* + * JALR rt, rs + * GPR[rt] = PC + 8 + * PC = GPR[rs] + */ + rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + rs = m_reg_info->getEncodingValue(insn.getOperand(1).getReg()); - pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + 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; + rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, + &success); + if (!success) + return false; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + rs_val)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_zero_mips + rt, pc + 8)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, + pc + 8)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_JIALC (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rt; - int32_t target, offset, pc, rt_val; +bool EmulateInstructionMIPS::Emulate_JIALC(llvm::MCInst &insn) { + bool success = false; + uint32_t rt; + int32_t target, offset, pc, rt_val; - /* - * JIALC rt, offset - * offset = sign_ext (offset) - * PC = GPR[rt] + offset - * RA = PC + 4 - */ - rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - offset = insn.getOperand(1).getImm(); + /* + * JIALC rt, offset + * offset = sign_ext (offset) + * PC = GPR[rt] + offset + * RA = PC + 4 + */ + rt = 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; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); - if (!success) - return false; + rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rt, 0, &success); + if (!success) + return false; - target = rt_val + offset; + target = rt_val + offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_ra_mips, pc + 4)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_ra_mips, + pc + 4)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_JIC (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rt; - int32_t target, offset, rt_val; +bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) { + bool success = false; + uint32_t rt; + int32_t target, offset, rt_val; - /* - * JIC rt, offset - * offset = sign_ext (offset) - * PC = GPR[rt] + offset - */ - rt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - offset = insn.getOperand(1).getImm(); + /* + * JIC rt, offset + * offset = sign_ext (offset) + * PC = GPR[rt] + offset + */ + rt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + offset = insn.getOperand(1).getImm(); - rt_val = (int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rt, 0, &success); - if (!success) - return false; + rt_val = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + rt, 0, &success); + if (!success) + return false; - target = rt_val + offset; + target = rt_val + offset; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn) -{ - bool success = false; - uint32_t rs; - uint32_t rs_val; +bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { + bool success = false; + uint32_t rs; + uint32_t rs_val; - /* - * JR rs - * PC = GPR[rs] - */ - rs = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); + /* + * JR rs + * PC = GPR[rs] + */ + rs = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); - rs_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + rs, 0, &success); - if (!success) - return false; + rs_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + rs, 0, + &success); + if (!success) + return false; - Context context; + Context context; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, rs_val)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + rs_val)) + return false; - return true; + return true; } /* @@ -2482,419 +2731,400 @@ EmulateInstructionMIPS::Emulate_JR (llvm::MCInst& insn) 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_FP_branch (llvm::MCInst& insn) -{ - bool success = false; - uint32_t cc, fcsr; - int32_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { + bool success = false; + uint32_t cc, fcsr; + int32_t pc, offset, target = 0; + const char *op_name = m_insn_info->getName(insn.getOpcode()); - fcsr = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); - if (!success) - return false; + cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + offset = insn.getOperand(1).getImm(); - /* fcsr[23], fcsr[25-31] are vaild condition bits */ - fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - 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; + fcsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); + if (!success) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + /* fcsr[23], fcsr[25-31] are vaild condition bits */ + fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - return true; + 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)) + return false; + + return true; } -bool -EmulateInstructionMIPS::Emulate_BC1EQZ (llvm::MCInst& insn) -{ - bool success = false; - uint32_t ft; - uint32_t ft_val; - int32_t target, pc, offset; - - /* - * BC1EQZ ft, offset - * condition <- (FPR[ft].bit0 == 0) - * if condition then - * offset = sign_ext (offset) - * PC = PC + 4 + offset - */ - ft = 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; +bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { + bool success = false; + uint32_t ft; + uint32_t ft_val; + int32_t target, pc, offset; - ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success); - if (!success) - return false; + /* + * BC1EQZ ft, offset + * condition <- (FPR[ft].bit0 == 0) + * if condition then + * offset = sign_ext (offset) + * PC = PC + 4 + offset + */ + ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + offset = insn.getOperand(1).getImm(); - if ((ft_val & 1) == 0) - target = pc + 4 + offset; - else - target = pc + 8; - - Context context; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, + &success); + if (!success) + return false; - return true; + if ((ft_val & 1) == 0) + target = pc + 4 + offset; + else + target = pc + 8; + + Context context; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; + + return true; } -bool -EmulateInstructionMIPS::Emulate_BC1NEZ (llvm::MCInst& insn) -{ - bool success = false; - uint32_t ft; - uint32_t ft_val; - int32_t target, pc, offset; - - /* - * BC1NEZ ft, offset - * condition <- (FPR[ft].bit0 != 0) - * if condition then - * offset = sign_ext (offset) - * PC = PC + 4 + offset - */ - ft = 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; +bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { + bool success = false; + uint32_t ft; + uint32_t ft_val; + int32_t target, pc, offset; - ft_val = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + ft, 0, &success); - if (!success) - return false; + /* + * BC1NEZ ft, offset + * condition <- (FPR[ft].bit0 != 0) + * if condition then + * offset = sign_ext (offset) + * PC = PC + 4 + offset + */ + ft = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + offset = insn.getOperand(1).getImm(); - if ((ft_val & 1) != 0) - target = pc + 4 + offset; - else - target = pc + 8; - - Context context; + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + ft_val = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_zero_mips + ft, 0, + &success); + if (!success) + return false; - return true; + if ((ft_val & 1) != 0) + target = pc + 4 + offset; + else + target = pc + 8; + + Context context; + + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; + + 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 + 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_3D_branch (llvm::MCInst& insn) -{ - bool success = false; - uint32_t cc, fcsr; - int32_t pc, offset, target = 0; - const char *op_name = m_insn_info->getName (insn.getOpcode ()); - - 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; +bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { + bool success = false; + uint32_t cc, fcsr; + int32_t pc, offset, target = 0; + const char *op_name = m_insn_info->getName(insn.getOpcode()); - fcsr = (uint32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_fcsr_mips, 0, &success); - if (!success) - return false; + cc = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + offset = insn.getOperand(1).getImm(); - /* fcsr[23], fcsr[25-31] are vaild condition bits */ - fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); + pc = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - 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; + fcsr = (uint32_t)ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_fcsr_mips, 0, + &success); + if (!success) + return false; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + /* fcsr[23], fcsr[25-31] are vaild condition bits */ + fcsr = ((fcsr >> 24) & 0xfe) | ((fcsr >> 23) & 0x01); - return true; -} + 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; -bool -EmulateInstructionMIPS::Emulate_BNZB (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 1, true); + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; + + return true; } -bool -EmulateInstructionMIPS::Emulate_BNZH (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 2, true); +bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 1, true); } -bool -EmulateInstructionMIPS::Emulate_BNZW (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 4, true); +bool EmulateInstructionMIPS::Emulate_BNZH(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 2, true); } -bool -EmulateInstructionMIPS::Emulate_BNZD (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 8, true); +bool EmulateInstructionMIPS::Emulate_BNZW(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 4, true); } -bool -EmulateInstructionMIPS::Emulate_BZB (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 1, false); +bool EmulateInstructionMIPS::Emulate_BNZD(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 8, true); } -bool -EmulateInstructionMIPS::Emulate_BZH (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 2, false); +bool EmulateInstructionMIPS::Emulate_BZB(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 1, false); } -bool -EmulateInstructionMIPS::Emulate_BZW (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 4, false); +bool EmulateInstructionMIPS::Emulate_BZH(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 2, false); } -bool -EmulateInstructionMIPS::Emulate_BZD (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_DF(insn, 8, false); +bool EmulateInstructionMIPS::Emulate_BZW(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 4, false); } -bool -EmulateInstructionMIPS::Emulate_MSA_Branch_DF (llvm::MCInst& insn, int element_byte_size, bool bnz) -{ - bool success = false, branch_hit = true; - int32_t target = 0; - RegisterValue reg_value; - const uint8_t *ptr = NULL; +bool EmulateInstructionMIPS::Emulate_BZD(llvm::MCInst &insn) { + return Emulate_MSA_Branch_DF(insn, 8, false); +} - uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - int32_t offset = insn.getOperand(1).getImm(); +bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn, + int element_byte_size, + bool bnz) { + bool success = false, branch_hit = true; + int32_t target = 0; + RegisterValue reg_value; + const uint8_t *ptr = NULL; - int32_t pc = ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_pc_mips, 0, &success); - if (!success) - return false; + uint32_t wt = m_reg_info->getEncodingValue(insn.getOperand(0).getReg()); + int32_t offset = insn.getOperand(1).getImm(); - if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) - ptr = (const uint8_t *)reg_value.GetBytes(); - else - return false; + int32_t pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - for(int i = 0; i < 16 / element_byte_size; i++) - { - switch(element_byte_size) - { - case 1: - if((*ptr == 0 && bnz) || (*ptr != 0 && !bnz) ) - branch_hit = false; - break; - case 2: - if ((*(const uint16_t *)ptr == 0 && bnz) || (*(const uint16_t *)ptr != 0 && !bnz)) - branch_hit = false; - break; - case 4: - if ((*(const uint32_t *)ptr == 0 && bnz) || (*(const uint32_t *)ptr != 0 && !bnz)) - branch_hit = false; - break; - case 8: - if ((*(const uint64_t *)ptr == 0 && bnz) || (*(const uint64_t *)ptr != 0 && !bnz)) - branch_hit = false; - break; - } - if(!branch_hit) - break; - ptr = ptr + element_byte_size; - } + if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) + ptr = (const uint8_t *)reg_value.GetBytes(); + else + return false; - if(branch_hit) - target = pc + offset; - else - target = pc + 8; + for (int i = 0; i < 16 / element_byte_size; i++) { + switch (element_byte_size) { + case 1: + if ((*ptr == 0 && bnz) || (*ptr != 0 && !bnz)) + branch_hit = false; + break; + case 2: + if ((*(const uint16_t *)ptr == 0 && bnz) || + (*(const uint16_t *)ptr != 0 && !bnz)) + branch_hit = false; + break; + case 4: + if ((*(const uint32_t *)ptr == 0 && bnz) || + (*(const uint32_t *)ptr != 0 && !bnz)) + branch_hit = false; + break; + case 8: + if ((*(const uint64_t *)ptr == 0 && bnz) || + (*(const uint64_t *)ptr != 0 && !bnz)) + branch_hit = false; + break; + } + if (!branch_hit) + break; + ptr = ptr + element_byte_size; + } + + if (branch_hit) + target = pc + offset; + else + target = pc + 8; - Context context; - context.type = eContextRelativeBranchImmediate; + Context context; + context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_BNZV (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_V (insn, true); +bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) { + return Emulate_MSA_Branch_V(insn, true); } -bool -EmulateInstructionMIPS::Emulate_BZV (llvm::MCInst& insn) -{ - return Emulate_MSA_Branch_V (insn, false); +bool EmulateInstructionMIPS::Emulate_BZV(llvm::MCInst &insn) { + return Emulate_MSA_Branch_V(insn, false); } -bool -EmulateInstructionMIPS::Emulate_MSA_Branch_V (llvm::MCInst& insn, bool bnz) -{ - bool success = false; - int32_t target = 0; - llvm::APInt wr_val = llvm::APInt::getNullValue(128); - llvm::APInt fail_value = llvm::APInt::getMaxValue(128); - llvm::APInt zero_value = llvm::APInt::getNullValue(128); - RegisterValue reg_value; +bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, + bool bnz) { + bool success = false; + int32_t target = 0; + llvm::APInt wr_val = llvm::APInt::getNullValue(128); + llvm::APInt fail_value = llvm::APInt::getMaxValue(128); + llvm::APInt zero_value = llvm::APInt::getNullValue(128); + RegisterValue reg_value; - uint32_t wt = m_reg_info->getEncodingValue (insn.getOperand(0).getReg()); - int32_t offset = insn.getOperand(1).getImm(); + uint32_t wt = 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; + int32_t pc = + ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_pc_mips, 0, &success); + if (!success) + return false; - if (ReadRegister (eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) - wr_val = reg_value.GetAsUInt128(fail_value); - else - return false; + if (ReadRegister(eRegisterKindDWARF, dwarf_w0_mips + wt, reg_value)) + wr_val = reg_value.GetAsUInt128(fail_value); + else + return false; - if((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) - target = pc + offset; - else - target = pc + 8; + if ((llvm::APInt::isSameValue(zero_value, wr_val) && !bnz) || + (!llvm::APInt::isSameValue(zero_value, wr_val) && bnz)) + target = pc + offset; + else + target = pc + 8; - Context context; - context.type = eContextRelativeBranchImmediate; + Context context; + context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned (context, eRegisterKindDWARF, dwarf_pc_mips, target)) - return false; + if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target)) + return false; - return true; + return true; } -bool -EmulateInstructionMIPS::Emulate_LDST_Imm (llvm::MCInst& insn) -{ - bool success = false; - uint32_t base; - int32_t imm, address; - Context bad_vaddr_context; +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(); + 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, dwarf_zero_mips + base, reg_info_base)) - return false; + RegisterInfo reg_info_base; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - /* read base register */ - address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + /* read base register */ + address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - /* destination address */ - address = address + imm; + /* 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, dwarf_bad_mips, address); + /* Set the bad_vaddr register with base address used in the instruction */ + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + address); - return true; + 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; +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()); + 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, dwarf_zero_mips + base, reg_info_base)) - return false; + RegisterInfo reg_info_base, reg_info_index; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + base, + reg_info_base)) + return false; - if (!GetRegisterInfo (eRegisterKindDWARF, dwarf_zero_mips + index, reg_info_index)) - return false; + if (!GetRegisterInfo(eRegisterKindDWARF, dwarf_zero_mips + index, + reg_info_index)) + return false; - /* read base register */ - address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + base, 0, &success); - if (!success) - return false; + /* read base register */ + address = (int32_t)ReadRegisterUnsigned(eRegisterKindDWARF, + dwarf_zero_mips + base, 0, &success); + if (!success) + return false; - /* read index register */ - index_address =(int32_t) ReadRegisterUnsigned (eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); - if (!success) - return false; + /* read index register */ + index_address = (int32_t)ReadRegisterUnsigned( + eRegisterKindDWARF, dwarf_zero_mips + index, 0, &success); + if (!success) + return false; - /* destination address */ - address = address + index_address; + /* 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, dwarf_bad_mips, address); + /* Set the bad_vaddr register with base address used in the instruction */ + bad_vaddr_context.type = eContextInvalid; + WriteRegisterUnsigned(bad_vaddr_context, eRegisterKindDWARF, dwarf_bad_mips, + address); - return true; + return true; } |