Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions src/emulator/reference_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void PushQueue(std::array<std::uint64_t, kLinxQueueCount> &queue, std::uint64_t
queue[0] = value;
}

void WriteHlLuiDest(LinxState &state, std::uint64_t idx, std::uint64_t value) {
void WriteHlImmediateDest(LinxState &state, std::uint64_t idx, std::uint64_t value) {
if (idx == 31) {
PushQueue(state.tq, value);
} else if (idx == 30) {
Expand Down Expand Up @@ -252,10 +252,23 @@ void ReferenceExecutor::Execute(isa::Minst &inst) {
state.pc = inst.next_pc;
} else if (inst.mnemonic == "HL.LUI") {
const auto rd = inst.dsts.empty() ? 0 : inst.dsts.front().value;
const auto imm = GetUnsignedAny(inst, {"imm", "simm22", "simm"}).value_or(0);
const auto value = static_cast<std::uint64_t>(
static_cast<std::int64_t>(static_cast<std::int32_t>(static_cast<std::uint32_t>(imm))));
WriteHlLuiDest(state, rd, value);
const auto imm = GetUnsignedAny(inst, {"imm32", "imm"}).value_or(0);
const auto value = (imm & UINT64_C(0xffffffff)) << 32U;
WriteHlImmediateDest(state, rd, value);
commit_record.dst0.data = value;
state.pc = inst.next_pc;
} else if (inst.mnemonic == "HL.LIU") {
const auto rd = inst.dsts.empty() ? 0 : inst.dsts.front().value;
const auto imm = GetUnsignedAny(inst, {"uimm32", "imm"}).value_or(0);
const auto value = imm & UINT64_C(0xffffffff);
WriteHlImmediateDest(state, rd, value);
commit_record.dst0.data = value;
state.pc = inst.next_pc;
} else if (inst.mnemonic == "HL.LIS") {
const auto rd = inst.dsts.empty() ? 0 : inst.dsts.front().value;
const auto imm = GetSignedAny(inst, {"simm32", "imm"}).value_or(0);
const auto value = static_cast<std::uint64_t>(imm);
WriteHlImmediateDest(state, rd, value);
commit_record.dst0.data = value;
state.pc = inst.next_pc;
} else if (inst.mnemonic == "ADDI") {
Expand Down
23 changes: 12 additions & 11 deletions tests/unit/emulator_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,8 @@ int TestMinstRecordAdapter() {
int TestReferenceExecutorExit() {
const std::vector<std::uint8_t> program = {
0x00, 0x08, // C.BSTART.STD
0x0e, 0x00, 0x17, 0x51, 0x55, 0x05, // hl.lui 0x5555, ->a0
0x0e, 0x10, 0x97, 0x0f, 0x00, 0x09, // hl.lui 0x10009000, ->t
0x0e, 0x00, 0x1d, 0x51, 0x55, 0x05, // hl.liu 0x5555, ->a0
0x0e, 0x10, 0x9d, 0x0f, 0x00, 0x09, // hl.liu 0x10009000, ->t
0x59, 0x20, 0x81, 0x01, // swi a0, [t#1, 0]
0x00, 0x00, // C.BSTOP
};
Expand All @@ -313,8 +313,8 @@ int TestReferenceExecutorExit() {
int TestReferenceExecutorImmediateContracts() {
const std::vector<std::uint8_t> program = {
0xfe, 0xff, 0x17, 0xf1, 0xff, 0xff, // hl.lui 0xffffffff, ->a0
0x1e, 0x11, 0x97, 0x1f, 0x11, 0x11, // hl.lui 0x11111111, ->t
0x2e, 0x22, 0x17, 0x2f, 0x22, 0x22, // hl.lui 0x22222222, ->u
0xfe, 0xff, 0x9d, 0xff, 0xff, 0xff, // hl.liu 0xffffffff, ->t
0xfe, 0xff, 0x0d, 0xff, 0xff, 0xff, // hl.lis -1, ->u
0x19, 0xa2, 0x11, 0x00, // lwi [a1, 4], ->a2
0xd9, 0xaf, 0x32, 0xfe, // swi a3, [a1, -4]
};
Expand All @@ -328,20 +328,21 @@ int TestReferenceExecutorImmediateContracts() {
ctx->Write32(0, 0x89abcdef);

ReferenceExecutor executor(ctx);
if (!executor.Step() || ctx->State().gpr[2] != UINT64_MAX || !ctx->LastCommitted().has_value() ||
ctx->LastCommitted()->dst0.data != UINT64_MAX) {
if (!executor.Step() || ctx->State().gpr[2] != 0xffffffff00000000ULL ||
!ctx->LastCommitted().has_value() ||
ctx->LastCommitted()->dst0.data != 0xffffffff00000000ULL) {
return 18;
}
if (!executor.Step() ||
ctx->State().tq != std::array<std::uint64_t, 4>{0x11111111, 0x10, 0x11, 0x12} ||
ctx->State().tq != std::array<std::uint64_t, 4>{0xffffffff, 0x10, 0x11, 0x12} ||
ctx->State().uq != std::array<std::uint64_t, 4>{0x20, 0x21, 0x22, 0x23} ||
!ctx->LastCommitted().has_value() || ctx->LastCommitted()->dst0.data != 0x11111111) {
!ctx->LastCommitted().has_value() || ctx->LastCommitted()->dst0.data != 0xffffffff) {
return 19;
}
if (!executor.Step() ||
ctx->State().uq != std::array<std::uint64_t, 4>{0x22222222, 0x20, 0x21, 0x22} ||
ctx->State().tq != std::array<std::uint64_t, 4>{0x11111111, 0x10, 0x11, 0x12} ||
!ctx->LastCommitted().has_value() || ctx->LastCommitted()->dst0.data != 0x22222222) {
ctx->State().uq != std::array<std::uint64_t, 4>{UINT64_MAX, 0x20, 0x21, 0x22} ||
ctx->State().tq != std::array<std::uint64_t, 4>{0xffffffff, 0x10, 0x11, 0x12} ||
!ctx->LastCommitted().has_value() || ctx->LastCommitted()->dst0.data != UINT64_MAX) {
return 20;
}
if (!executor.Step() || ctx->State().gpr[4] != 0xffffffff89abcdefULL ||
Expand Down
Loading