Skip to content

Commit 80e7fe8

Browse files
authored
[lldb][RISCV] Fix float load and stores in RISC-V emulator (#167490)
This patch fixes 2 fundamental problems in emulating `FLW`, `FSW`, `FLD` and `FSD` instructions. 1. Instructions immediate wasn't sign extended 2. Store instructions always wrote for 64 bits to memory Also this patch fixes 2 lldb tests for RISC-V: TestThreadJump.py and TestBreakpointHitCount.py
1 parent eb614cd commit 80e7fe8

File tree

1 file changed

+18
-12
lines changed

1 file changed

+18
-12
lines changed

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

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,32 +1328,36 @@ class Executor {
13281328
m_emu, inst, 8, ZextD,
13291329
[](uint64_t a, uint64_t b) { return std::max(a, b); });
13301330
}
1331-
template <typename T>
1332-
bool F_Load(T inst, const fltSemantics &(*semantics)(),
1333-
unsigned int numBits) {
1331+
template <typename I, typename T>
1332+
bool F_Load(I inst, const fltSemantics &(*semantics)()) {
13341333
return transformOptional(inst.rs1.Read(m_emu),
13351334
[&](auto &&rs1) {
1336-
uint64_t addr = rs1 + uint64_t(inst.imm);
1337-
uint64_t bits = *m_emu.ReadMem<uint64_t>(addr);
1335+
uint64_t addr =
1336+
rs1 + uint64_t(SignExt(inst.imm));
1337+
uint64_t bits = *m_emu.ReadMem<T>(addr);
1338+
unsigned numBits = sizeof(T) * 8;
13381339
APFloat f(semantics(), APInt(numBits, bits));
13391340
return inst.rd.WriteAPFloat(m_emu, f);
13401341
})
13411342
.value_or(false);
13421343
}
1343-
bool operator()(FLW inst) { return F_Load(inst, &APFloat::IEEEsingle, 32); }
1344-
template <typename T> bool F_Store(T inst, bool isDouble) {
1344+
bool operator()(FLW inst) {
1345+
return F_Load<FLW, uint32_t>(inst, &APFloat::IEEEsingle);
1346+
}
1347+
template <typename I, typename T> bool F_Store(I inst, bool isDouble) {
13451348
return transformOptional(zipOpt(inst.rs1.Read(m_emu),
13461349
inst.rs2.ReadAPFloat(m_emu, isDouble)),
13471350
[&](auto &&tup) {
13481351
auto [rs1, rs2] = tup;
1349-
uint64_t addr = rs1 + uint64_t(inst.imm);
1352+
uint64_t addr =
1353+
rs1 + uint64_t(SignExt(inst.imm));
13501354
uint64_t bits =
13511355
rs2.bitcastToAPInt().getZExtValue();
1352-
return m_emu.WriteMem<uint64_t>(addr, bits);
1356+
return m_emu.WriteMem<T>(addr, bits);
13531357
})
13541358
.value_or(false);
13551359
}
1356-
bool operator()(FSW inst) { return F_Store(inst, false); }
1360+
bool operator()(FSW inst) { return F_Store<FSW, uint32_t>(inst, false); }
13571361
std::tuple<bool, APFloat> FusedMultiplyAdd(APFloat rs1, APFloat rs2,
13581362
APFloat rs3) {
13591363
auto opStatus = rs1.fusedMultiplyAdd(rs2, rs3, m_emu.GetRoundingMode());
@@ -1616,8 +1620,10 @@ class Executor {
16161620
bool operator()(FCVT_S_LU inst) {
16171621
return FCVT_f2i(inst, &Rs::Read, APFloat::IEEEsingle());
16181622
}
1619-
bool operator()(FLD inst) { return F_Load(inst, &APFloat::IEEEdouble, 64); }
1620-
bool operator()(FSD inst) { return F_Store(inst, true); }
1623+
bool operator()(FLD inst) {
1624+
return F_Load<FLD, uint64_t>(inst, &APFloat::IEEEdouble);
1625+
}
1626+
bool operator()(FSD inst) { return F_Store<FSD, uint64_t>(inst, true); }
16211627
bool operator()(FMADD_D inst) { return FMA(inst, true, 1.0f, 1.0f); }
16221628
bool operator()(FMSUB_D inst) { return FMA(inst, true, 1.0f, -1.0f); }
16231629
bool operator()(FNMSUB_D inst) { return FMA(inst, true, -1.0f, 1.0f); }

0 commit comments

Comments
 (0)