xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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