lh03061238 updated this revision to Diff 480297.
lh03061238 edited the summary of this revision.
lh03061238 added a comment.

(1) Use sort alphabetically in the following file
lldb/source/Plugins/Instruction/CMakeLists.txt
lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
lldb/tools/lldb-server/CMakeLists.txt
lldb/tools/lldb-server/SystemInitializerLLGS.cpp

(2) Use ALL_CAPS for include guard symbol

(3) Modify the following functions
SupportsThisInstructionType(InstructionType inst_type)
GetOpcodeForInstruction(uint32_t inst)
EvaluateInstruction(uint32_t options)
CreateInstance(const ArchSpec &arch,InstructionType inst_type)

(4) Added TODO description in GetOpcodeForInstruction(uint32_t inst)

(5) Use #if defined(__loongarch__) in 
lldb/tools/lldb-server/SystemInitializerLLGS.cpp

(6) Remove the example from commit message


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D139158/new/

https://reviews.llvm.org/D139158

Files:
  lldb/source/Plugins/Instruction/CMakeLists.txt
  lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
  lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
  lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
  lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
  lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
  lldb/tools/lldb-server/CMakeLists.txt
  lldb/tools/lldb-server/SystemInitializerLLGS.cpp

Index: lldb/tools/lldb-server/SystemInitializerLLGS.cpp
===================================================================
--- lldb/tools/lldb-server/SystemInitializerLLGS.cpp
+++ lldb/tools/lldb-server/SystemInitializerLLGS.cpp
@@ -29,6 +29,11 @@
 #include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
 #endif
 
+#if defined(__loongarch__)
+#define LLDB_TARGET_LoongArch
+#include "Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h"
+#endif
+
 #if defined(__mips64__) || defined(mips64) || defined(__mips64) ||             \
     defined(__MIPS64__) || defined(_M_MIPS64)
 #define LLDB_TARGET_MIPS64
@@ -57,6 +62,9 @@
 #if defined(LLDB_TARGET_ARM) || defined(LLDB_TARGET_ARM64)
   EmulateInstructionARM::Initialize();
 #endif
+#if defined(LLDB_TARGET_LoongArch)
+  EmulateInstructionLoongArch::Initialize();
+#endif
 #if defined(LLDB_TARGET_MIPS) || defined(LLDB_TARGET_MIPS64)
   EmulateInstructionMIPS::Initialize();
 #endif
@@ -76,6 +84,9 @@
 #if defined(LLDB_TARGET_ARM) || defined(LLDB_TARGET_ARM64)
   EmulateInstructionARM::Terminate();
 #endif
+#if defined(LLDB_TARGET_LoongArch)
+  EmulateInstructionLoongArch::Terminate();
+#endif
 #if defined(LLDB_TARGET_MIPS) || defined(LLDB_TARGET_MIPS64)
   EmulateInstructionMIPS::Terminate();
 #endif
Index: lldb/tools/lldb-server/CMakeLists.txt
===================================================================
--- lldb/tools/lldb-server/CMakeLists.txt
+++ lldb/tools/lldb-server/CMakeLists.txt
@@ -51,6 +51,7 @@
       lldbVersion
       ${LLDB_PLUGINS}
       lldbPluginInstructionARM
+      lldbPluginInstructionLoongArch
       lldbPluginInstructionMIPS
       lldbPluginInstructionMIPS64
       lldbPluginInstructionRISCV
Index: lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
+++ lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
@@ -168,7 +168,7 @@
       size_hint = 4;
     }
   } else if (arch.IsMIPS() || arch.GetTriple().isPPC64() ||
-             arch.GetTriple().isRISCV())
+             arch.GetTriple().isRISCV() || arch.GetTriple().isLoongArch())
     size_hint = 4;
   error = process.SetBreakpoint(next_pc, size_hint, /*hardware=*/false);
 
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -883,7 +883,7 @@
 
 bool NativeProcessLinux::SupportHardwareSingleStepping() const {
   if (m_arch.IsMIPS() || m_arch.GetMachine() == llvm::Triple::arm ||
-      m_arch.GetTriple().isRISCV())
+      m_arch.GetTriple().isRISCV() || m_arch.GetTriple().isLoongArch())
     return false;
   return true;
 }
Index: lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
@@ -0,0 +1,76 @@
+//===---EmulateInstructionLoongArch.h--------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+
+namespace lldb_private {
+
+class EmulateInstructionLoongArch : public EmulateInstruction {
+public:
+  static llvm::StringRef GetPluginNameStatic() { return "LoongArch"; }
+
+  static llvm::StringRef GetPluginDescriptionStatic() {
+    return "Emulate instructions for the LoongArch architecture.";
+  }
+
+  static bool SupportsThisInstructionType(InstructionType inst_type) {
+    return inst_type == eInstructionTypePCModifying;
+  }
+
+  static bool SupportsThisArch(const ArchSpec &arch);
+
+  static lldb_private::EmulateInstruction *
+  CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);
+
+  static void Initialize();
+
+  static void Terminate();
+
+public:
+  EmulateInstructionLoongArch(const ArchSpec &arch)
+      : EmulateInstruction(arch) {}
+
+  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+  bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
+    return SupportsThisInstructionType(inst_type);
+  }
+
+  bool SetTargetTriple(const ArchSpec &arch) override;
+  bool ReadInstruction() override;
+  bool EvaluateInstruction(uint32_t options) override;
+  bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+                     OptionValueDictionary *test_data) override;
+
+  llvm::Optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind,
+                                               uint32_t reg_num) override;
+  lldb::addr_t ReadPC(bool *success);
+  bool WritePC(lldb::addr_t pc);
+
+private:
+  struct Opcode {
+    uint32_t mask;
+    uint32_t value;
+    bool (EmulateInstructionLoongArch::*callback)(uint32_t opcode);
+    const char *name;
+  };
+
+  Opcode *GetOpcodeForInstruction(uint32_t inst);
+
+  bool EmulateNonJMP(uint32_t inst);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
Index: lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
@@ -0,0 +1,181 @@
+//===---EmulateInstructionLoongArch.cpp------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstdlib>
+
+#include "EmulateInstructionLoongArch.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h"
+#include "Plugins/Process/Utility/lldb-loongarch-register-enums.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/OptionValueArray.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionLoongArch, InstructionLoongArch)
+
+namespace lldb_private {
+
+EmulateInstructionLoongArch::Opcode *
+EmulateInstructionLoongArch::GetOpcodeForInstruction(uint32_t inst) {
+  // TODO: Add the mask of jump instruction.
+  static EmulateInstructionLoongArch::Opcode g_opcodes[] = {
+      {0x00000000, 0x00000000, &EmulateInstructionLoongArch::EmulateNonJMP,
+       "NonJMP"}};
+  static const size_t num_loongarch_opcodes = std::size(g_opcodes);
+
+  for (size_t i = 0; i < num_loongarch_opcodes; ++i)
+    if ((g_opcodes[i].mask & inst) == g_opcodes[i].value)
+      return &g_opcodes[i];
+  return nullptr;
+}
+
+bool EmulateInstructionLoongArch::EvaluateInstruction(uint32_t options) {
+  uint32_t inst_size = m_opcode.GetByteSize();
+  uint32_t inst = m_opcode.GetOpcode32();
+  bool increase_pc = options & eEmulateInstructionOptionAutoAdvancePC;
+  bool success = false;
+
+  Opcode *opcode_data = GetOpcodeForInstruction(inst);
+  if (!opcode_data)
+    return false;
+
+  lldb::addr_t old_pc = 0;
+  if (increase_pc) {
+    old_pc = ReadPC(&success);
+    if (!success)
+      return false;
+  }
+
+  // Call the Emulate... function.
+  if (!(this->*opcode_data->callback)(inst))
+    return false;
+
+  if (increase_pc) {
+    lldb::addr_t new_pc = ReadPC(&success);
+    if (!success)
+      return false;
+
+    if (new_pc == old_pc && !WritePC(old_pc + inst_size))
+      return false;
+  }
+  return true;
+}
+
+bool EmulateInstructionLoongArch::ReadInstruction() {
+  bool success = false;
+  m_addr = ReadPC(&success);
+  if (!success) {
+    m_addr = LLDB_INVALID_ADDRESS;
+    return false;
+  }
+
+  Context ctx;
+  ctx.type = eContextReadOpcode;
+  ctx.SetNoArgs();
+  uint32_t inst = (uint32_t)ReadMemoryUnsigned(ctx, m_addr, 4, 0, &success);
+  m_opcode.SetOpcode32(inst, GetByteOrder());
+
+  return true;
+}
+
+lldb::addr_t EmulateInstructionLoongArch::ReadPC(bool *success) {
+  return ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+                              LLDB_INVALID_ADDRESS, success);
+}
+
+bool EmulateInstructionLoongArch::WritePC(lldb::addr_t pc) {
+  EmulateInstruction::Context ctx;
+  ctx.type = eContextAdvancePC;
+  ctx.SetNoArgs();
+  return WriteRegisterUnsigned(ctx, eRegisterKindGeneric,
+                               LLDB_REGNUM_GENERIC_PC, pc);
+}
+
+llvm::Optional<RegisterInfo>
+EmulateInstructionLoongArch::GetRegisterInfo(lldb::RegisterKind reg_kind,
+                                             uint32_t reg_index) {
+  if (reg_kind == eRegisterKindGeneric) {
+    switch (reg_index) {
+    case LLDB_REGNUM_GENERIC_PC:
+      reg_kind = eRegisterKindLLDB;
+      reg_index = gpr_pc_loongarch;
+      break;
+    case LLDB_REGNUM_GENERIC_SP:
+      reg_kind = eRegisterKindLLDB;
+      reg_index = gpr_sp_loongarch;
+      break;
+    case LLDB_REGNUM_GENERIC_FP:
+      reg_kind = eRegisterKindLLDB;
+      reg_index = gpr_fp_loongarch;
+      break;
+    case LLDB_REGNUM_GENERIC_RA:
+      reg_kind = eRegisterKindLLDB;
+      reg_index = gpr_ra_loongarch;
+      break;
+    // We may handle LLDB_REGNUM_GENERIC_ARGx when more instructions are
+    // supported.
+    default:
+      llvm_unreachable("unsupported register");
+    }
+  }
+
+  const RegisterInfo *array =
+      RegisterInfoPOSIX_loongarch64::GetRegisterInfoPtr(m_arch);
+  const uint32_t length =
+      RegisterInfoPOSIX_loongarch64::GetRegisterInfoCount(m_arch);
+
+  if (reg_index >= length || reg_kind != eRegisterKindLLDB)
+    return {};
+  return array[reg_index];
+}
+
+bool EmulateInstructionLoongArch::SetTargetTriple(const ArchSpec &arch) {
+  return SupportsThisArch(arch);
+}
+
+bool EmulateInstructionLoongArch::TestEmulation(
+    Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) {
+  return false;
+}
+
+void EmulateInstructionLoongArch::Initialize() {
+  PluginManager::RegisterPlugin(GetPluginNameStatic(),
+                                GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void EmulateInstructionLoongArch::Terminate() {
+  PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::EmulateInstruction *
+EmulateInstructionLoongArch::CreateInstance(const ArchSpec &arch,
+                                            InstructionType inst_type) {
+  if (EmulateInstructionLoongArch::SupportsThisInstructionType(inst_type) &&
+      SupportsThisArch(arch))
+    return new EmulateInstructionLoongArch(arch);
+  return nullptr;
+}
+
+bool EmulateInstructionLoongArch::SupportsThisArch(const ArchSpec &arch) {
+  return arch.GetTriple().isLoongArch();
+}
+
+bool EmulateInstructionLoongArch::EmulateNonJMP(uint32_t inst) { return false; }
+
+} // namespace lldb_private
Index: lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginInstructionLoongArch PLUGIN
+  EmulateInstructionLoongArch.cpp
+
+  LINK_LIBS
+    lldbCore
+    lldbInterpreter
+    lldbPluginProcessUtility
+    lldbSymbol
+  LINK_COMPONENTS
+    Support
+  )
Index: lldb/source/Plugins/Instruction/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Instruction/CMakeLists.txt
+++ lldb/source/Plugins/Instruction/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_subdirectory(ARM)
 add_subdirectory(ARM64)
+add_subdirectory(LoongArch)
 add_subdirectory(MIPS)
 add_subdirectory(MIPS64)
 add_subdirectory(PPC64)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to