1bdd1243dSDimitry Andric //===---EmulateInstructionLoongArch.h--------------------------------------===//
2bdd1243dSDimitry Andric //
3bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6bdd1243dSDimitry Andric //
7bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8bdd1243dSDimitry Andric 
9bdd1243dSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
10bdd1243dSDimitry Andric #define LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
11bdd1243dSDimitry Andric 
12bdd1243dSDimitry Andric #include "lldb/Core/EmulateInstruction.h"
13bdd1243dSDimitry Andric #include "lldb/Interpreter/OptionValue.h"
14bdd1243dSDimitry Andric #include "lldb/Utility/Log.h"
15bdd1243dSDimitry Andric #include "lldb/Utility/Status.h"
16bdd1243dSDimitry Andric #include <optional>
17bdd1243dSDimitry Andric 
18bdd1243dSDimitry Andric namespace lldb_private {
19bdd1243dSDimitry Andric 
20bdd1243dSDimitry Andric class EmulateInstructionLoongArch : public EmulateInstruction {
21bdd1243dSDimitry Andric public:
GetPluginNameStatic()22bdd1243dSDimitry Andric   static llvm::StringRef GetPluginNameStatic() { return "LoongArch"; }
23bdd1243dSDimitry Andric 
GetPluginDescriptionStatic()24bdd1243dSDimitry Andric   static llvm::StringRef GetPluginDescriptionStatic() {
25bdd1243dSDimitry Andric     return "Emulate instructions for the LoongArch architecture.";
26bdd1243dSDimitry Andric   }
27bdd1243dSDimitry Andric 
SupportsThisInstructionType(InstructionType inst_type)28bdd1243dSDimitry Andric   static bool SupportsThisInstructionType(InstructionType inst_type) {
29bdd1243dSDimitry Andric     return inst_type == eInstructionTypePCModifying;
30bdd1243dSDimitry Andric   }
31bdd1243dSDimitry Andric 
32bdd1243dSDimitry Andric   static bool SupportsThisArch(const ArchSpec &arch);
33bdd1243dSDimitry Andric 
34bdd1243dSDimitry Andric   static lldb_private::EmulateInstruction *
35bdd1243dSDimitry Andric   CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);
36bdd1243dSDimitry Andric 
37bdd1243dSDimitry Andric   static void Initialize();
38bdd1243dSDimitry Andric 
39bdd1243dSDimitry Andric   static void Terminate();
40bdd1243dSDimitry Andric 
41bdd1243dSDimitry Andric public:
EmulateInstructionLoongArch(const ArchSpec & arch)42bdd1243dSDimitry Andric   EmulateInstructionLoongArch(const ArchSpec &arch) : EmulateInstruction(arch) {
43bdd1243dSDimitry Andric     m_arch_subtype = arch.GetMachine();
44bdd1243dSDimitry Andric   }
45bdd1243dSDimitry Andric 
GetPluginName()46bdd1243dSDimitry Andric   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
47bdd1243dSDimitry Andric 
SupportsEmulatingInstructionsOfType(InstructionType inst_type)48bdd1243dSDimitry Andric   bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
49bdd1243dSDimitry Andric     return SupportsThisInstructionType(inst_type);
50bdd1243dSDimitry Andric   }
51bdd1243dSDimitry Andric 
52bdd1243dSDimitry Andric   bool SetTargetTriple(const ArchSpec &arch) override;
53bdd1243dSDimitry Andric   bool ReadInstruction() override;
54bdd1243dSDimitry Andric   bool EvaluateInstruction(uint32_t options) override;
55*06c3fb27SDimitry Andric   bool TestEmulation(Stream &out_stream, ArchSpec &arch,
56bdd1243dSDimitry Andric                      OptionValueDictionary *test_data) override;
57bdd1243dSDimitry Andric 
58bdd1243dSDimitry Andric   std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind,
59bdd1243dSDimitry Andric                                               uint32_t reg_num) override;
60bdd1243dSDimitry Andric   lldb::addr_t ReadPC(bool *success);
61bdd1243dSDimitry Andric   bool WritePC(lldb::addr_t pc);
IsLoongArch64()62bdd1243dSDimitry Andric   bool IsLoongArch64() { return m_arch_subtype == llvm::Triple::loongarch64; }
63bdd1243dSDimitry Andric   bool TestExecute(uint32_t inst);
64bdd1243dSDimitry Andric 
65bdd1243dSDimitry Andric private:
66bdd1243dSDimitry Andric   struct Opcode {
67bdd1243dSDimitry Andric     uint32_t mask;
68bdd1243dSDimitry Andric     uint32_t value;
69bdd1243dSDimitry Andric     bool (EmulateInstructionLoongArch::*callback)(uint32_t opcode);
70bdd1243dSDimitry Andric     const char *name;
71bdd1243dSDimitry Andric   };
72bdd1243dSDimitry Andric 
73bdd1243dSDimitry Andric   llvm::Triple::ArchType m_arch_subtype;
74bdd1243dSDimitry Andric   Opcode *GetOpcodeForInstruction(uint32_t inst);
75bdd1243dSDimitry Andric 
76bdd1243dSDimitry Andric   bool EmulateBEQZ(uint32_t inst);
77bdd1243dSDimitry Andric   bool EmulateBNEZ(uint32_t inst);
78bdd1243dSDimitry Andric   bool EmulateBCEQZ(uint32_t inst);
79bdd1243dSDimitry Andric   bool EmulateBCNEZ(uint32_t inst);
80bdd1243dSDimitry Andric   bool EmulateJIRL(uint32_t inst);
81bdd1243dSDimitry Andric   bool EmulateB(uint32_t inst);
82bdd1243dSDimitry Andric   bool EmulateBL(uint32_t inst);
83bdd1243dSDimitry Andric   bool EmulateBEQ(uint32_t inst);
84bdd1243dSDimitry Andric   bool EmulateBNE(uint32_t inst);
85bdd1243dSDimitry Andric   bool EmulateBLT(uint32_t inst);
86bdd1243dSDimitry Andric   bool EmulateBGE(uint32_t inst);
87bdd1243dSDimitry Andric   bool EmulateBLTU(uint32_t inst);
88bdd1243dSDimitry Andric   bool EmulateBGEU(uint32_t inst);
89bdd1243dSDimitry Andric   bool EmulateNonJMP(uint32_t inst);
90bdd1243dSDimitry Andric 
91bdd1243dSDimitry Andric   bool EmulateBEQZ64(uint32_t inst);
92bdd1243dSDimitry Andric   bool EmulateBNEZ64(uint32_t inst);
93bdd1243dSDimitry Andric   bool EmulateBCEQZ64(uint32_t inst);
94bdd1243dSDimitry Andric   bool EmulateBCNEZ64(uint32_t inst);
95bdd1243dSDimitry Andric   bool EmulateJIRL64(uint32_t inst);
96bdd1243dSDimitry Andric   bool EmulateB64(uint32_t inst);
97bdd1243dSDimitry Andric   bool EmulateBL64(uint32_t inst);
98bdd1243dSDimitry Andric   bool EmulateBEQ64(uint32_t inst);
99bdd1243dSDimitry Andric   bool EmulateBNE64(uint32_t inst);
100bdd1243dSDimitry Andric   bool EmulateBLT64(uint32_t inst);
101bdd1243dSDimitry Andric   bool EmulateBGE64(uint32_t inst);
102bdd1243dSDimitry Andric   bool EmulateBLTU64(uint32_t inst);
103bdd1243dSDimitry Andric   bool EmulateBGEU64(uint32_t inst);
104bdd1243dSDimitry Andric };
105bdd1243dSDimitry Andric 
106bdd1243dSDimitry Andric } // namespace lldb_private
107bdd1243dSDimitry Andric 
108bdd1243dSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
109