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