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
4 changes: 3 additions & 1 deletion sim/simx/alu_unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,9 @@ void AluUnit::execute(instr_trace_t* trace) {
if (!tmask.test(t)) continue;
rd_data[t].i = link_pc;
}
warp.PC = rs1_data[thread_last].i + offset;
// JALR clears bit 0 of the computed target (RISC-V ISA); the RTL
// release build drops it implicitly via from_fullPC() truncation.
warp.PC = (rs1_data[thread_last].u + offset) & ~Word(1);
core_->perf_stats().branches += 1;
} break;
case BrType::SYS:
Expand Down
4 changes: 3 additions & 1 deletion tests/kernel/conform/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ int main() {
errors += test_shfl();
errors += test_qshfl();

errors += test_jalr();

if (0 == errors) {
PRINTF("Passed!\n");
} else {
PRINTF("Failed!\n");
}

return errors;
}
}
58 changes: 57 additions & 1 deletion tests/kernel/conform/tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,4 +448,60 @@ int test_qshfl() {
errors += check_error(qshfl_buffer, 0, QSHFL_GROUP_SZ);

return errors;
}
}

///////////////////////////////////////////////////////////////////////////////

#define JALR_PASS_VALUE 0x13579bdf

uint32_t __attribute__((noinline)) do_jalr_misaligned() {
uint32_t value = 0;
asm volatile(
// x1 is prepared so that the misaligned decode path can immediately
// execute a valid JALR to label 3 and produce a deterministic failure
// value instead of aborting in the decoder.
"la x1, 3f\n"
// 1744 matches the immediate embedded in the overlapped misaligned
// instruction below: jalr x0, -1744(x1).
"addi x1, x1, 1744\n"
"la t0, 1f\n"
// Add 1 on purpose. A correct JALR implementation must clear bit 0 and
// land at 1f. An incorrect implementation enters at 1f + 1 instead.
"addi t0, t0, 1\n"
"jalr x0, t0, 0\n"
".balign 4\n"
"1:\n"
// 0x00806713 is a hand-picked overlapped instruction word:
// - from the aligned entry at 1f it decodes as: ori x14, x0, 8
// - from the misaligned entry at 1f + 1 it decodes as:
// jalr x0, -1744(x1)
// That lets both fixed and unfixed builds decode valid instructions
// while still producing different results.
".4byte 0x00806713\n"
// next aligned instruction after the pass-path overlap word
".4byte 0x00000093\n"
"j 4f\n"
"3:\n"
// fail signature: JALR did not clear bit 0
"li %[value], 0x2468ace0\n"
"j 5f\n"
"4:\n"
// pass signature: JALR correctly cleared bit 0
"li %[value], 0x13579bdf\n"
"5:\n"
: [value] "=r" (value)
:
: "x1", "t0", "x14");
return value;
}

int test_jalr() {
PRINTF("JALR Test\n");
vx_tmc_one();
uint32_t value = do_jalr_misaligned();
if (value != JALR_PASS_VALUE) {
PRINTF("*** error: jalr value=0x%x, expected=0x%x\n", value, JALR_PASS_VALUE);
return 1;
}
return 0;
}
2 changes: 2 additions & 0 deletions tests/kernel/conform/tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ int test_vote();
int test_shfl();
int test_qshfl();

int test_jalr();

#endif
Loading