1 //===-- EmulateInstructionMIPS.h ------------------------------------*- C++
2 //-*-===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
11 #define LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
12 
13 namespace llvm {
14 class MCDisassembler;
15 class MCSubtargetInfo;
16 class MCRegisterInfo;
17 class MCAsmInfo;
18 class MCContext;
19 class MCInstrInfo;
20 class MCInst;
21 }
22 
23 namespace lldb_private {
24   class OptionValueDictionary;
25 }
26 
27 #include "lldb/Core/EmulateInstruction.h"
28 #include "lldb/Utility/Status.h"
29 #include <optional>
30 
31 class EmulateInstructionMIPS : public lldb_private::EmulateInstruction {
32 public:
33   static void Initialize();
34 
35   static void Terminate();
36 
37   static llvm::StringRef GetPluginNameStatic() { return "mips32"; }
38 
39   static llvm::StringRef GetPluginDescriptionStatic();
40 
41   static lldb_private::EmulateInstruction *
42   CreateInstance(const lldb_private::ArchSpec &arch,
43                  lldb_private::InstructionType inst_type);
44 
45   static bool SupportsEmulatingInstructionsOfTypeStatic(
46       lldb_private::InstructionType inst_type) {
47     switch (inst_type) {
48     case lldb_private::eInstructionTypeAny:
49     case lldb_private::eInstructionTypePrologueEpilogue:
50     case lldb_private::eInstructionTypePCModifying:
51       return true;
52 
53     case lldb_private::eInstructionTypeAll:
54       return false;
55     }
56     return false;
57   }
58 
59   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
60 
61   bool SetTargetTriple(const lldb_private::ArchSpec &arch) override;
62 
63   EmulateInstructionMIPS(const lldb_private::ArchSpec &arch);
64 
65   bool SupportsEmulatingInstructionsOfType(
66       lldb_private::InstructionType inst_type) override {
67     return SupportsEmulatingInstructionsOfTypeStatic(inst_type);
68   }
69 
70   bool ReadInstruction() override;
71 
72   bool EvaluateInstruction(uint32_t evaluate_options) override;
73 
74   bool SetInstruction(const lldb_private::Opcode &insn_opcode,
75                       const lldb_private::Address &inst_addr,
76                       lldb_private::Target *target) override;
77 
78   bool TestEmulation(lldb_private::Stream &out_stream,
79                      lldb_private::ArchSpec &arch,
80                      lldb_private::OptionValueDictionary *test_data) override {
81     return false;
82   }
83 
84   std::optional<lldb_private::RegisterInfo>
85   GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override;
86 
87   bool
88   CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override;
89 
90 protected:
91   typedef struct {
92     const char *op_name;
93     bool (EmulateInstructionMIPS::*callback)(llvm::MCInst &insn);
94     const char *insn_name;
95   } MipsOpcode;
96 
97   static MipsOpcode *GetOpcodeForInstruction(llvm::StringRef name);
98 
99   uint32_t GetSizeOfInstruction(lldb_private::DataExtractor &data,
100                                 uint64_t inst_addr);
101 
102   bool Emulate_ADDiu(llvm::MCInst &insn);
103 
104   bool Emulate_SUBU_ADDU(llvm::MCInst &insn);
105 
106   bool Emulate_LUI(llvm::MCInst &insn);
107 
108   bool Emulate_SW(llvm::MCInst &insn);
109 
110   bool Emulate_LW(llvm::MCInst &insn);
111 
112   bool Emulate_ADDIUSP(llvm::MCInst &insn);
113 
114   bool Emulate_ADDIUS5(llvm::MCInst &insn);
115 
116   bool Emulate_SWSP(llvm::MCInst &insn);
117 
118   bool Emulate_SWM16_32(llvm::MCInst &insn);
119 
120   bool Emulate_LWSP(llvm::MCInst &insn);
121 
122   bool Emulate_LWM16_32(llvm::MCInst &insn);
123 
124   bool Emulate_JRADDIUSP(llvm::MCInst &insn);
125 
126   bool Emulate_LDST_Imm(llvm::MCInst &insn);
127 
128   bool Emulate_LDST_Reg(llvm::MCInst &insn);
129 
130   bool Emulate_BXX_3ops(llvm::MCInst &insn);
131 
132   bool Emulate_BXX_3ops_C(llvm::MCInst &insn);
133 
134   bool Emulate_BXX_2ops(llvm::MCInst &insn);
135 
136   bool Emulate_BXX_2ops_C(llvm::MCInst &insn);
137 
138   bool Emulate_Bcond_Link_C(llvm::MCInst &insn);
139 
140   bool Emulate_Bcond_Link(llvm::MCInst &insn);
141 
142   bool Emulate_FP_branch(llvm::MCInst &insn);
143 
144   bool Emulate_3D_branch(llvm::MCInst &insn);
145 
146   bool Emulate_BAL(llvm::MCInst &insn);
147 
148   bool Emulate_BALC(llvm::MCInst &insn);
149 
150   bool Emulate_BC(llvm::MCInst &insn);
151 
152   bool Emulate_J(llvm::MCInst &insn);
153 
154   bool Emulate_JAL(llvm::MCInst &insn);
155 
156   bool Emulate_JALR(llvm::MCInst &insn);
157 
158   bool Emulate_JIALC(llvm::MCInst &insn);
159 
160   bool Emulate_JIC(llvm::MCInst &insn);
161 
162   bool Emulate_JR(llvm::MCInst &insn);
163 
164   bool Emulate_BC1EQZ(llvm::MCInst &insn);
165 
166   bool Emulate_BC1NEZ(llvm::MCInst &insn);
167 
168   bool Emulate_BNZB(llvm::MCInst &insn);
169 
170   bool Emulate_BNZH(llvm::MCInst &insn);
171 
172   bool Emulate_BNZW(llvm::MCInst &insn);
173 
174   bool Emulate_BNZD(llvm::MCInst &insn);
175 
176   bool Emulate_BZB(llvm::MCInst &insn);
177 
178   bool Emulate_BZH(llvm::MCInst &insn);
179 
180   bool Emulate_BZW(llvm::MCInst &insn);
181 
182   bool Emulate_BZD(llvm::MCInst &insn);
183 
184   bool Emulate_MSA_Branch_DF(llvm::MCInst &insn, int element_byte_size,
185                              bool bnz);
186 
187   bool Emulate_BNZV(llvm::MCInst &insn);
188 
189   bool Emulate_BZV(llvm::MCInst &insn);
190 
191   bool Emulate_MSA_Branch_V(llvm::MCInst &insn, bool bnz);
192 
193   bool Emulate_B16_MM(llvm::MCInst &insn);
194 
195   bool Emulate_Branch_MM(llvm::MCInst &insn);
196 
197   bool Emulate_JALRx16_MM(llvm::MCInst &insn);
198 
199   bool Emulate_JALx(llvm::MCInst &insn);
200 
201   bool Emulate_JALRS(llvm::MCInst &insn);
202 
203   bool nonvolatile_reg_p(uint32_t regnum);
204 
205   const char *GetRegisterName(unsigned reg_num, bool alternate_name);
206 
207 private:
208   std::unique_ptr<llvm::MCDisassembler> m_disasm;
209   std::unique_ptr<llvm::MCDisassembler> m_alt_disasm;
210   std::unique_ptr<llvm::MCSubtargetInfo> m_subtype_info;
211   std::unique_ptr<llvm::MCSubtargetInfo> m_alt_subtype_info;
212   std::unique_ptr<llvm::MCRegisterInfo> m_reg_info;
213   std::unique_ptr<llvm::MCAsmInfo> m_asm_info;
214   std::unique_ptr<llvm::MCContext> m_context;
215   std::unique_ptr<llvm::MCInstrInfo> m_insn_info;
216   uint32_t m_next_inst_size;
217   bool m_use_alt_disaasm;
218 };
219 
220 #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_MIPS_EMULATEINSTRUCTIONMIPS_H
221