10b57cec5SDimitry Andric //===-- EmulateInstructionMIPS.h ------------------------------------*- C++ 20b57cec5SDimitry Andric //-*-===// 30b57cec5SDimitry Andric // 40b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric 105ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H 115ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric namespace llvm { 140b57cec5SDimitry Andric class MCDisassembler; 150b57cec5SDimitry Andric class MCSubtargetInfo; 160b57cec5SDimitry Andric class MCRegisterInfo; 170b57cec5SDimitry Andric class MCAsmInfo; 180b57cec5SDimitry Andric class MCContext; 190b57cec5SDimitry Andric class MCInstrInfo; 200b57cec5SDimitry Andric class MCInst; 210b57cec5SDimitry Andric } 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace lldb_private { 240b57cec5SDimitry Andric class OptionValueDictionary; 250b57cec5SDimitry Andric } 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric #include "lldb/Core/EmulateInstruction.h" 280b57cec5SDimitry Andric #include "lldb/Utility/Status.h" 29bdd1243dSDimitry Andric #include <optional> 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric class EmulateInstructionMIPS : public lldb_private::EmulateInstruction { 320b57cec5SDimitry Andric public: 330b57cec5SDimitry Andric static void Initialize(); 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric static void Terminate(); 360b57cec5SDimitry Andric GetPluginNameStatic()37349cc55cSDimitry Andric static llvm::StringRef GetPluginNameStatic() { return "mips32"; } 380b57cec5SDimitry Andric 39349cc55cSDimitry Andric static llvm::StringRef GetPluginDescriptionStatic(); 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric static lldb_private::EmulateInstruction * 420b57cec5SDimitry Andric CreateInstance(const lldb_private::ArchSpec &arch, 430b57cec5SDimitry Andric lldb_private::InstructionType inst_type); 440b57cec5SDimitry Andric SupportsEmulatingInstructionsOfTypeStatic(lldb_private::InstructionType inst_type)450b57cec5SDimitry Andric static bool SupportsEmulatingInstructionsOfTypeStatic( 460b57cec5SDimitry Andric lldb_private::InstructionType inst_type) { 470b57cec5SDimitry Andric switch (inst_type) { 480b57cec5SDimitry Andric case lldb_private::eInstructionTypeAny: 490b57cec5SDimitry Andric case lldb_private::eInstructionTypePrologueEpilogue: 500b57cec5SDimitry Andric case lldb_private::eInstructionTypePCModifying: 510b57cec5SDimitry Andric return true; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric case lldb_private::eInstructionTypeAll: 540b57cec5SDimitry Andric return false; 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric return false; 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric GetPluginName()59349cc55cSDimitry Andric llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric bool SetTargetTriple(const lldb_private::ArchSpec &arch) override; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric EmulateInstructionMIPS(const lldb_private::ArchSpec &arch); 640b57cec5SDimitry Andric SupportsEmulatingInstructionsOfType(lldb_private::InstructionType inst_type)650b57cec5SDimitry Andric bool SupportsEmulatingInstructionsOfType( 660b57cec5SDimitry Andric lldb_private::InstructionType inst_type) override { 670b57cec5SDimitry Andric return SupportsEmulatingInstructionsOfTypeStatic(inst_type); 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric bool ReadInstruction() override; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric bool EvaluateInstruction(uint32_t evaluate_options) override; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric bool SetInstruction(const lldb_private::Opcode &insn_opcode, 750b57cec5SDimitry Andric const lldb_private::Address &inst_addr, 760b57cec5SDimitry Andric lldb_private::Target *target) override; 770b57cec5SDimitry Andric TestEmulation(lldb_private::Stream & out_stream,lldb_private::ArchSpec & arch,lldb_private::OptionValueDictionary * test_data)78*06c3fb27SDimitry Andric bool TestEmulation(lldb_private::Stream &out_stream, 790b57cec5SDimitry Andric lldb_private::ArchSpec &arch, 800b57cec5SDimitry Andric lldb_private::OptionValueDictionary *test_data) override { 810b57cec5SDimitry Andric return false; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 84bdd1243dSDimitry Andric std::optional<lldb_private::RegisterInfo> 85bdd1243dSDimitry Andric GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric bool 880b57cec5SDimitry Andric CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric protected: 910b57cec5SDimitry Andric typedef struct { 920b57cec5SDimitry Andric const char *op_name; 930b57cec5SDimitry Andric bool (EmulateInstructionMIPS::*callback)(llvm::MCInst &insn); 940b57cec5SDimitry Andric const char *insn_name; 950b57cec5SDimitry Andric } MipsOpcode; 960b57cec5SDimitry Andric 9781ad6265SDimitry Andric static MipsOpcode *GetOpcodeForInstruction(llvm::StringRef name); 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data, 1000b57cec5SDimitry Andric uint64_t inst_addr); 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric bool Emulate_ADDiu(llvm::MCInst &insn); 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric bool Emulate_SUBU_ADDU(llvm::MCInst &insn); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric bool Emulate_LUI(llvm::MCInst &insn); 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric bool Emulate_SW(llvm::MCInst &insn); 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric bool Emulate_LW(llvm::MCInst &insn); 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric bool Emulate_ADDIUSP(llvm::MCInst &insn); 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool Emulate_ADDIUS5(llvm::MCInst &insn); 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric bool Emulate_SWSP(llvm::MCInst &insn); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric bool Emulate_SWM16_32(llvm::MCInst &insn); 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric bool Emulate_LWSP(llvm::MCInst &insn); 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric bool Emulate_LWM16_32(llvm::MCInst &insn); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric bool Emulate_JRADDIUSP(llvm::MCInst &insn); 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric bool Emulate_LDST_Imm(llvm::MCInst &insn); 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric bool Emulate_LDST_Reg(llvm::MCInst &insn); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric bool Emulate_BXX_3ops(llvm::MCInst &insn); 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric bool Emulate_BXX_3ops_C(llvm::MCInst &insn); 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric bool Emulate_BXX_2ops(llvm::MCInst &insn); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric bool Emulate_BXX_2ops_C(llvm::MCInst &insn); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric bool Emulate_Bcond_Link_C(llvm::MCInst &insn); 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric bool Emulate_Bcond_Link(llvm::MCInst &insn); 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric bool Emulate_FP_branch(llvm::MCInst &insn); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric bool Emulate_3D_branch(llvm::MCInst &insn); 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric bool Emulate_BAL(llvm::MCInst &insn); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric bool Emulate_BALC(llvm::MCInst &insn); 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric bool Emulate_BC(llvm::MCInst &insn); 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric bool Emulate_J(llvm::MCInst &insn); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric bool Emulate_JAL(llvm::MCInst &insn); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric bool Emulate_JALR(llvm::MCInst &insn); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric bool Emulate_JIALC(llvm::MCInst &insn); 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric bool Emulate_JIC(llvm::MCInst &insn); 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric bool Emulate_JR(llvm::MCInst &insn); 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric bool Emulate_BC1EQZ(llvm::MCInst &insn); 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric bool Emulate_BC1NEZ(llvm::MCInst &insn); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric bool Emulate_BNZB(llvm::MCInst &insn); 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric bool Emulate_BNZH(llvm::MCInst &insn); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric bool Emulate_BNZW(llvm::MCInst &insn); 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric bool Emulate_BNZD(llvm::MCInst &insn); 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric bool Emulate_BZB(llvm::MCInst &insn); 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric bool Emulate_BZH(llvm::MCInst &insn); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric bool Emulate_BZW(llvm::MCInst &insn); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric bool Emulate_BZD(llvm::MCInst &insn); 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size, 1850b57cec5SDimitry Andric bool bnz); 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric bool Emulate_BNZV(llvm::MCInst &insn); 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric bool Emulate_BZV(llvm::MCInst &insn); 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz); 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric bool Emulate_B16_MM(llvm::MCInst &insn); 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric bool Emulate_Branch_MM(llvm::MCInst &insn); 1960b57cec5SDimitry Andric 1970b57cec5SDimitry Andric bool Emulate_JALRx16_MM(llvm::MCInst &insn); 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric bool Emulate_JALx(llvm::MCInst &insn); 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric bool Emulate_JALRS(llvm::MCInst &insn); 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andric bool nonvolatile_reg_p(uint32_t regnum); 2040b57cec5SDimitry Andric 2055ffd83dbSDimitry Andric const char *GetRegisterName(unsigned reg_num, bool alternate_name); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric private: 2080b57cec5SDimitry Andric std::unique_ptr<llvm::MCDisassembler> m_disasm; 2090b57cec5SDimitry Andric std::unique_ptr<llvm::MCDisassembler> m_alt_disasm; 2100b57cec5SDimitry Andric std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info; 2110b57cec5SDimitry Andric std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info; 2120b57cec5SDimitry Andric std::unique_ptr<llvm::MCRegisterInfo> m_reg_info; 2130b57cec5SDimitry Andric std::unique_ptr<llvm::MCAsmInfo> m_asm_info; 2140b57cec5SDimitry Andric std::unique_ptr<llvm::MCContext> m_context; 2150b57cec5SDimitry Andric std::unique_ptr<llvm::MCInstrInfo> m_insn_info; 2160b57cec5SDimitry Andric uint32_t m_next_inst_size; 2170b57cec5SDimitry Andric bool m_use_alt_disaasm; 2180b57cec5SDimitry Andric }; 2190b57cec5SDimitry Andric 2205ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H 221