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