Skip to content

Commit 05ae747

Browse files
author
Emmmer
committed
[LLDB][RISCV] Add RV64C instruction support for EmulateInstructionRISCV
Add: - RV64C instructions sets. - corresponding unittests. - `c.break` code for lldb and lldb-server Fix: - wrong decoding of imm in `DecodeSType` Reviewed By: DavidSpickett Differential Revision: https://reviews.llvm.org/D136362
1 parent 0284148 commit 05ae747

File tree

6 files changed

+467
-46
lines changed

6 files changed

+467
-46
lines changed

lldb/source/Host/common/NativeProcessProtocol.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,10 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
503503
static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
504504
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
505505
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
506-
static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
506+
static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
507507
static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
508508
static const uint8_t g_riscv_opcode[] = {0x73, 0x00, 0x10, 0x00}; // ebreak
509+
static const uint8_t g_riscv_opcode_c[] = {0x02, 0x90}; // c.ebreak
509510

510511
switch (GetArchitecture().GetMachine()) {
511512
case llvm::Triple::aarch64:
@@ -535,8 +536,10 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
535536
return llvm::makeArrayRef(g_ppcle_opcode);
536537

537538
case llvm::Triple::riscv32:
538-
case llvm::Triple::riscv64:
539-
return llvm::makeArrayRef(g_riscv_opcode);
539+
case llvm::Triple::riscv64: {
540+
return size_hint == 2 ? llvm::makeArrayRef(g_riscv_opcode_c)
541+
: llvm::makeArrayRef(g_riscv_opcode);
542+
}
540543

541544
default:
542545
return llvm::createStringError(llvm::inconvertibleErrorCode(),

lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include <cstdlib>
10-
119
#include "EmulateInstructionRISCV.h"
1210
#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h"
1311
#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
12+
#include "RISCVCInstructions.h"
1413
#include "RISCVInstructions.h"
1514

1615
#include "lldb/Core/Address.h"
@@ -86,8 +85,8 @@ constexpr uint32_t DecodeBImm(uint32_t inst) {
8685
}
8786

8887
constexpr uint32_t DecodeSImm(uint32_t inst) {
89-
return (uint64_t(int64_t(int32_t(inst & 0xFE00000)) >> 20)) // imm[11:5]
90-
| ((inst & 0xF80) >> 7); // imm[4:0]
88+
return (uint64_t(int64_t(int32_t(inst & 0xFE000000)) >> 20)) // imm[11:5]
89+
| ((inst & 0xF80) >> 7); // imm[4:0]
9190
}
9291

9392
constexpr uint32_t DecodeUImm(uint32_t inst) {
@@ -194,14 +193,14 @@ LoadStoreAddr(EmulateInstructionRISCV &emulator, I inst) {
194193
}
195194

196195
// Read T from memory, then load its sign-extended value m_emu to register.
197-
template <typename I, typename T, typename m_emu>
196+
template <typename I, typename T, typename E>
198197
static std::enable_if_t<is_load<I>, bool>
199-
Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(m_emu)) {
198+
Load(EmulateInstructionRISCV &emulator, I inst, uint64_t (*extend)(E)) {
200199
auto addr = LoadStoreAddr(emulator, inst);
201200
if (!addr)
202201
return false;
203202
return emulator.ReadMem<T>(*addr)
204-
.transform([&](T t) { return inst.rd.Write(emulator, extend(m_emu(t))); })
203+
.transform([&](T t) { return inst.rd.Write(emulator, extend(E(t))); })
205204
.value_or(false);
206205
}
207206

@@ -461,6 +460,38 @@ static const InstrPattern PATTERNS[] = {
461460
{"AMOMAX_D", 0xF800707F, 0xA000302F, DecodeRType<AMOMAX_D>},
462461
{"AMOMINU_D", 0xF800707F, 0xC000302F, DecodeRType<AMOMINU_D>},
463462
{"AMOMAXU_D", 0xF800707F, 0xE000302F, DecodeRType<AMOMAXU_D>},
463+
464+
// RVC (Compressed Instructions) //
465+
{"C_LWSP", 0xE003, 0x4002, DecodeC_LWSP},
466+
{"C_LDSP", 0xE003, 0x6002, DecodeC_LDSP},
467+
{"C_SWSP", 0xE003, 0xC002, DecodeC_SWSP},
468+
{"C_SDSP", 0xE003, 0xE002, DecodeC_SDSP},
469+
{"C_LW", 0xE003, 0x4000, DecodeC_LW},
470+
{"C_LD", 0xE003, 0x6000, DecodeC_LD},
471+
{"C_SW", 0xE003, 0xC000, DecodeC_SW},
472+
{"C_SD", 0xE003, 0xE000, DecodeC_SD},
473+
{"C_J", 0xE003, 0xA001, DecodeC_J},
474+
{"C_JR", 0xF07F, 0x8002, DecodeC_JR},
475+
{"C_JALR", 0xF07F, 0x9002, DecodeC_JALR},
476+
{"C_BNEZ", 0xE003, 0xE001, DecodeC_BNEZ},
477+
{"C_BEQZ", 0xE003, 0xC001, DecodeC_BEQZ},
478+
{"C_LI", 0xE003, 0x4001, DecodeC_LI},
479+
{"C_LUI_ADDI16SP", 0xE003, 0x6001, DecodeC_LUI_ADDI16SP},
480+
{"C_ADDI", 0xE003, 0x1, DecodeC_ADDI},
481+
{"C_ADDIW", 0xE003, 0x2001, DecodeC_ADDIW},
482+
{"C_ADDI4SPN", 0xE003, 0x0, DecodeC_ADDI4SPN},
483+
{"C_SLLI", 0xE003, 0x2, DecodeC_SLLI},
484+
{"C_SRLI", 0xEC03, 0x8001, DecodeC_SRLI},
485+
{"C_SRAI", 0xEC03, 0x8401, DecodeC_SRAI},
486+
{"C_ANDI", 0xEC03, 0x8801, DecodeC_ANDI},
487+
{"C_MV", 0xF003, 0x8002, DecodeC_MV},
488+
{"C_ADD", 0xF003, 0x9002, DecodeC_ADD},
489+
{"C_AND", 0xFC63, 0x8C61, DecodeC_AND},
490+
{"C_OR", 0xFC63, 0x8C41, DecodeC_OR},
491+
{"C_XOR", 0xFC63, 0x8C21, DecodeC_XOR},
492+
{"C_SUB", 0xFC63, 0x8C01, DecodeC_SUB},
493+
{"C_SUBW", 0xFC63, 0x9C01, DecodeC_SUBW},
494+
{"C_ADDW", 0xFC63, 0x9C21, DecodeC_ADDW},
464495
};
465496

466497
llvm::Optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) {
@@ -473,9 +504,9 @@ llvm::Optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) {
473504

474505
for (const InstrPattern &pat : PATTERNS) {
475506
if ((inst & pat.type_mask) == pat.eigen) {
476-
LLDB_LOGF(log, "EmulateInstructionRISCV::%s: inst(%x) was decoded to %s",
477-
__FUNCTION__, inst, pat.name);
478-
auto decoded = pat.decode(inst);
507+
LLDB_LOGF(log, "EmulateInstructionRISCV::%s: inst(%x at %lx) was decoded to %s",
508+
__FUNCTION__, inst, m_addr, pat.name);
509+
auto decoded = is_rvc ? pat.decode(try_rvc) : pat.decode(inst);
479510
return DecodeResult{decoded, inst, is_rvc, pat};
480511
}
481512
}
@@ -1017,6 +1048,11 @@ class Executor {
10171048
m_emu, inst, 8, ZextD,
10181049
[](uint64_t a, uint64_t b) { return std::max(a, b); });
10191050
}
1051+
bool operator()(INVALID inst) { return false; }
1052+
bool operator()(RESERVED inst) { return false; }
1053+
bool operator()(EBREAK inst) { return false; }
1054+
bool operator()(HINT inst) { return true; }
1055+
bool operator()(NOP inst) { return true; }
10201056
};
10211057

10221058
bool EmulateInstructionRISCV::Execute(DecodeResult inst, bool ignore_cond) {

0 commit comments

Comments
 (0)