Files
TheRock/compiler/amd-llvm/lldb/unittests/Instruction/RISCV/TestRiscvInstEmulation.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

189 lines
7.3 KiB
C++

//===-- TestRiscvInstEmulation.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 "gtest/gtest.h"
#include "Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h"
#include "lldb/Core/AddressRange.h"
#include "lldb/Symbol/UnwindPlan.h"
#include "lldb/Utility/ArchSpec.h"
#include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h"
#include "Plugins/Instruction/RISCV/EmulateInstructionRISCV.h"
#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
#include "llvm/Support/TargetSelect.h"
using namespace lldb;
using namespace lldb_private;
class TestRiscvInstEmulation : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
protected:
};
void TestRiscvInstEmulation::SetUpTestCase() {
llvm::InitializeAllTargets();
llvm::InitializeAllAsmPrinters();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers();
DisassemblerLLVMC::Initialize();
EmulateInstructionRISCV::Initialize();
}
void TestRiscvInstEmulation::TearDownTestCase() {
DisassemblerLLVMC::Terminate();
EmulateInstructionRISCV::Terminate();
}
TEST_F(TestRiscvInstEmulation, TestSimpleRiscvFunction) {
ArchSpec arch("riscv64-unknown-linux-gnu");
// Enable compressed instruction support (RVC extension).
arch.SetFlags(ArchSpec::eRISCV_rvc);
std::unique_ptr<UnwindAssemblyInstEmulation> engine(
static_cast<UnwindAssemblyInstEmulation *>(
UnwindAssemblyInstEmulation::CreateInstance(arch)));
ASSERT_NE(nullptr, engine);
// RISC-V function with compressed and uncompressed instructions
// 0x0000: 1141 addi sp, sp, -0x10
// 0x0002: e406 sd ra, 0x8(sp)
// 0x0004: e022 sd s0, 0x0(sp)
// 0x0006: 0800 addi s0, sp, 0x10
// 0x0008: 00000537 lui a0, 0x0
// 0x000C: 00050513 mv a0, a0
// 0x0010: 00000097 auipc ra, 0x0
// 0x0014: 000080e7 jalr ra <main+0x10>
// 0x0018: 4501 li a0, 0x0
// 0x001A: ff040113 addi sp, s0, -0x10
// 0x001E: 60a2 ld ra, 0x8(sp)
// 0x0020: 6402 ld s0, 0x0(sp)
// 0x0022: 0141 addi sp, sp, 0x10
// 0x0024: 8082 ret
uint8_t data[] = {// 0x0000: 1141 addi sp, sp, -0x10
0x41, 0x11,
// 0x0002: e406 sd ra, 0x8(sp)
0x06, 0xE4,
// 0x0004: e022 sd s0, 0x0(sp)
0x22, 0xE0,
// 0x0006: 0800 addi s0, sp, 0x10
0x00, 0x08,
// 0x0008: 00000537 lui a0, 0x0
0x37, 0x05, 0x00, 0x00,
// 0x000C: 00050513 mv a0, a0
0x13, 0x05, 0x05, 0x00,
// 0x0010: 00000097 auipc ra, 0x0
0x97, 0x00, 0x00, 0x00,
// 0x0014: 000080e7 jalr ra <main+0x10>
0xE7, 0x80, 0x00, 0x00,
// 0x0018: 4501 li a0, 0x0
0x01, 0x45,
// 0x001A: ff040113 addi sp, s0, -0x10
0x13, 0x01, 0x04, 0xFF,
// 0x001E: 60a2 ld ra, 0x8(sp)
0xA2, 0x60,
// 0x0020: 6402 ld s0, 0x0(sp)
0x02, 0x64,
// 0x0022: 0141 addi sp, sp, 0x10
0x41, 0x01,
// 0x0024: 8082 ret
0x82, 0x80};
// Expected UnwindPlan (prologue only - emulation stops after frame setup):
// row[0]: 0: CFA=sp+0 => fp= <same> ra= <same>
// row[1]: 2: CFA=sp+16 => fp= <same> ra= <same> (after stack
// allocation) row[2]: 4: CFA=sp+16 => fp= <same> ra=[CFA-8]
// (after saving ra) row[3]: 6: CFA=sp+16 => fp=[CFA-16] ra=[CFA-8]
// (after saving s0/fp) row[4]: 8: CFA=s0+0 => fp=[CFA-16] ra=[CFA-8]
// (after setting frame pointer: s0=sp+16)
const UnwindPlan::Row *row;
AddressRange sample_range;
UnwindPlan unwind_plan(eRegisterKindLLDB);
UnwindPlan::Row::AbstractRegisterLocation regloc;
sample_range = AddressRange(0x1000, sizeof(data));
EXPECT_TRUE(engine->GetNonCallSiteUnwindPlanFromAssembly(
sample_range, data, sizeof(data), unwind_plan));
// CFA=sp+0 => fp=<same> ra=<same>.
row = unwind_plan.GetRowForFunctionOffset(0);
EXPECT_EQ(0, row->GetOffset());
EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);
EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row->GetCFAValue().GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));
EXPECT_TRUE(regloc.IsSame());
EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));
EXPECT_TRUE(regloc.IsSame());
// CFA=sp+16 => fp=<same> ra=<same>.
row = unwind_plan.GetRowForFunctionOffset(2);
EXPECT_EQ(2, row->GetOffset());
EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);
EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row->GetCFAValue().GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));
EXPECT_TRUE(regloc.IsSame());
EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));
EXPECT_TRUE(regloc.IsSame());
// CFA=sp+16 => fp=<same> ra=[CFA-8].
row = unwind_plan.GetRowForFunctionOffset(4);
EXPECT_EQ(4, row->GetOffset());
EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);
EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row->GetCFAValue().GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));
EXPECT_TRUE(regloc.IsSame());
EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
// CFA=sp+16 => fp=[CFA-16] ra=[CFA-8]
row = unwind_plan.GetRowForFunctionOffset(6);
EXPECT_EQ(6, row->GetOffset());
EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_sp_riscv);
EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(16, row->GetCFAValue().GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
// CFA=s0+0 => fp=[CFA-16] ra=[CFA-8]
// s0 = sp + 16, so switching CFA to s0 does not change the effective
// locations.
row = unwind_plan.GetRowForFunctionOffset(8);
EXPECT_EQ(8, row->GetOffset());
EXPECT_TRUE(row->GetCFAValue().GetRegisterNumber() == gpr_fp_riscv);
EXPECT_TRUE(row->GetCFAValue().IsRegisterPlusOffset() == true);
EXPECT_EQ(0, row->GetCFAValue().GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_fp_riscv, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-16, regloc.GetOffset());
EXPECT_TRUE(row->GetRegisterInfo(gpr_ra_riscv, regloc));
EXPECT_TRUE(regloc.IsAtCFAPlusOffset());
EXPECT_EQ(-8, regloc.GetOffset());
}