From 6edfbfae8b6b89a5b3a4b376e2c59933e0170a72 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Sat, 11 Dec 2021 11:17:24 +0000 Subject: [PATCH] Add ebreak size/alignment test --- test/sim/sw_testcases/ebreak.c | 48 ++++++++++++++++++++ test/sim/sw_testcases/ebreak.expected_output | 10 ++++ 2 files changed, 58 insertions(+) create mode 100644 test/sim/sw_testcases/ebreak.c create mode 100644 test/sim/sw_testcases/ebreak.expected_output diff --git a/test/sim/sw_testcases/ebreak.c b/test/sim/sw_testcases/ebreak.c new file mode 100644 index 0000000..a742fe0 --- /dev/null +++ b/test/sim/sw_testcases/ebreak.c @@ -0,0 +1,48 @@ +#include "tb_cxxrtl_io.h" +#include "hazard3_csr.h" + +// This is naked so we can take its address and get accurate offsets for the +// breakpoints, which we can then check. Otherwise, we would have issues with +// the size of the prologue potentially varying between builds etc. +// +// There is also a GCC extension for taking the address of a label, but GCC +// takes artistic liberty in deciding where that label actually "is". + +void __attribute__((naked)) test() { + asm volatile ( + // Word-aligned word-sized + ".option norvc\n" + "ebreak\n" + ".option rvc\n" + // Word-aligned halfword-sized + "c.ebreak\n" + // Halfword-aligned word-sized + ".option norvc\n" + "ebreak\n" + ".option rvc\n" + // Halfword-aligned halfword-sized + "c.ebreak\n" + + "ret\n" + ); +} + +int main() { + tb_puts("Entering test section\n"); + test(); + tb_puts("Done\n"); +} + +void __attribute__((interrupt)) handle_exception() { + tb_printf("mcause = %u\n", read_csr(mcause)); + tb_printf("Offset into test: %u, ", read_csr(mepc) - (uintptr_t)&test); + if (*(uint16_t*)read_csr(mepc) & 0x3 == 0x3) { + tb_puts("32-bit ebreak\n"); + write_csr(mepc, read_csr(mepc) + 4); + } + else { + tb_puts("16-bit ebreak\n"); + write_csr(mepc, read_csr(mepc) + 2); + } + write_csr(mcause, 0); +} diff --git a/test/sim/sw_testcases/ebreak.expected_output b/test/sim/sw_testcases/ebreak.expected_output new file mode 100644 index 0000000..ac8d45d --- /dev/null +++ b/test/sim/sw_testcases/ebreak.expected_output @@ -0,0 +1,10 @@ +Entering test section +mcause = 3 +Offset into test: 0, 32-bit ebreak +mcause = 3 +Offset into test: 4, 16-bit ebreak +mcause = 3 +Offset into test: 6, 32-bit ebreak +mcause = 3 +Offset into test: 10, 16-bit ebreak +Done