#include "EmulateInstructionRISCV.h"
#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h"
#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
#include "RISCVCInstructions.h"
#include "RISCVInstructions.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/Stream.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MathExtras.h"
#include <optional>
usingnamespacellvm;
usingnamespacelldb;
usingnamespacelldb_private;
LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionRISCV, InstructionRISCV)
namespace lldb_private {
template <typename... Ts>
static std::optional<std::tuple<Ts...>> zipOpt(std::optional<Ts> &&...ts) { … }
constexpr uint32_t BEQ = …;
constexpr uint32_t BNE = …;
constexpr uint32_t BLT = …;
constexpr uint32_t BGE = …;
constexpr uint32_t BLTU = …;
constexpr uint32_t BGEU = …;
constexpr int32_t SignExt(uint32_t imm) { … }
template <typename T>
constexpr std::enable_if_t<sizeof(T) <= 4, uint64_t> SextW(T value) { … }
template <typename T> constexpr uint64_t ZextD(T value) { … }
constexpr uint32_t DecodeJImm(uint32_t inst) { … }
constexpr uint32_t DecodeIImm(uint32_t inst) { … }
constexpr uint32_t DecodeBImm(uint32_t inst) { … }
constexpr uint32_t DecodeSImm(uint32_t inst) { … }
constexpr uint32_t DecodeUImm(uint32_t inst) { … }
static uint32_t GPREncodingToLLDB(uint32_t reg_encode) { … }
static uint32_t FPREncodingToLLDB(uint32_t reg_encode) { … }
bool Rd::Write(EmulateInstructionRISCV &emulator, uint64_t value) { … }
bool Rd::WriteAPFloat(EmulateInstructionRISCV &emulator, APFloat value) { … }
std::optional<uint64_t> Rs::Read(EmulateInstructionRISCV &emulator) { … }
std::optional<int32_t> Rs::ReadI32(EmulateInstructionRISCV &emulator) { … }
std::optional<int64_t> Rs::ReadI64(EmulateInstructionRISCV &emulator) { … }
std::optional<uint32_t> Rs::ReadU32(EmulateInstructionRISCV &emulator) { … }
std::optional<APFloat> Rs::ReadAPFloat(EmulateInstructionRISCV &emulator,
bool isDouble) { … }
static bool CompareB(uint64_t rs1, uint64_t rs2, uint32_t funct3) { … }
is_load;
is_store;
is_amo_add;
is_amo_bit_op;
is_amo_swap;
is_amo_cmp;
template <typename I>
static std::enable_if_t<is_load<I> || is_store<I>, std::optional<uint64_t>>
LoadStoreAddr(EmulateInstructionRISCV &emulator, I inst) { … }
template <typename I, typename T, typename E>
static std::enable_if_t<is_load<I>, bool>
Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) { … }
template <typename I, typename T>
static std::enable_if_t<is_store<I>, bool>
Store(EmulateInstructionRISCV &emulator, I inst) { … }
template <typename I>
static std::enable_if_t<is_amo_add<I> || is_amo_bit_op<I> || is_amo_swap<I> ||
is_amo_cmp<I>,
std::optional<uint64_t>>
AtomicAddr(EmulateInstructionRISCV &emulator, I inst, unsigned int align) { … }
template <typename I, typename T>
static std::enable_if_t<is_amo_swap<I>, bool>
AtomicSwap(EmulateInstructionRISCV &emulator, I inst, int align,
uint64_t (*extend)(T)) { … }
template <typename I, typename T>
static std::enable_if_t<is_amo_add<I>, bool>
AtomicADD(EmulateInstructionRISCV &emulator, I inst, int align,
uint64_t (*extend)(T)) { … }
template <typename I, typename T>
static std::enable_if_t<is_amo_bit_op<I>, bool>
AtomicBitOperate(EmulateInstructionRISCV &emulator, I inst, int align,
uint64_t (*extend)(T), T (*operate)(T, T)) { … }
template <typename I, typename T>
static std::enable_if_t<is_amo_cmp<I>, bool>
AtomicCmp(EmulateInstructionRISCV &emulator, I inst, int align,
uint64_t (*extend)(T), T (*cmp)(T, T)) { … }
bool AtomicSequence(EmulateInstructionRISCV &emulator) { … }
template <typename T> static RISCVInst DecodeUType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeJType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeIType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeBType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeSType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeRType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeRShamtType(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeRRS1Type(uint32_t inst) { … }
template <typename T> static RISCVInst DecodeR4Type(uint32_t inst) { … }
static const InstrPattern PATTERNS[] = …;
std::optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) { … }
class Executor { … };
bool EmulateInstructionRISCV::Execute(DecodeResult inst, bool ignore_cond) { … }
bool EmulateInstructionRISCV::EvaluateInstruction(uint32_t options) { … }
std::optional<DecodeResult>
EmulateInstructionRISCV::ReadInstructionAt(addr_t addr) { … }
bool EmulateInstructionRISCV::ReadInstruction() { … }
std::optional<addr_t> EmulateInstructionRISCV::ReadPC() { … }
bool EmulateInstructionRISCV::WritePC(addr_t pc) { … }
RoundingMode EmulateInstructionRISCV::GetRoundingMode() { … }
bool EmulateInstructionRISCV::SetAccruedExceptions(
APFloatBase::opStatus opStatus) { … }
std::optional<RegisterInfo>
EmulateInstructionRISCV::GetRegisterInfo(RegisterKind reg_kind,
uint32_t reg_index) { … }
bool EmulateInstructionRISCV::SetTargetTriple(const ArchSpec &arch) { … }
bool EmulateInstructionRISCV::TestEmulation(Stream &out_stream, ArchSpec &arch,
OptionValueDictionary *test_data) { … }
void EmulateInstructionRISCV::Initialize() { … }
void EmulateInstructionRISCV::Terminate() { … }
lldb_private::EmulateInstruction *
EmulateInstructionRISCV::CreateInstance(const ArchSpec &arch,
InstructionType inst_type) { … }
bool EmulateInstructionRISCV::SupportsThisArch(const ArchSpec &arch) { … }
}