diff --git a/test/sim/sw_testcases/load_misalign_halfword.c b/test/sim/sw_testcases/load_misalign_halfword.c new file mode 100644 index 0000000..2cea954 --- /dev/null +++ b/test/sim/sw_testcases/load_misalign_halfword.c @@ -0,0 +1,45 @@ +#include "tb_cxxrtl_io.h" +#include "hazard3_csr.h" + +int main() { + volatile uint32_t target_word = 0x1234cdefu; + volatile uint32_t result_word = 0; + tb_puts("Load halfword signed, 1 byte offset\n"); + asm volatile("lh %0, 1(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load halfword signed, 3 byte offset\n"); + asm volatile("lh %0, 3(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load halfword signed aligned (sanity check)\n"); + asm volatile("lh %0, 0(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + asm volatile("lh %0, 2(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + + result_word = 0; + tb_puts("Load halfword unsigned, 1 byte offset\n"); + asm volatile("lhu %0, 1(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load halfword unsigned, 3 byte offset\n"); + asm volatile("lhu %0, 3(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load halfword unsigned aligned (sanity check)\n"); + asm volatile("lhu %0, 0(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + asm volatile("lhu %0, 2(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + + return 0; +} + +void __attribute__((interrupt)) handle_exception() { + tb_printf("-> exception, mcause = %u\n", read_csr(mcause)); + write_csr(mcause, 0); + if (*(uint16_t*)read_csr(mepc) & 0x3 == 0x3) { + write_csr(mepc, read_csr(mepc) + 4); + } + else { + write_csr(mepc, read_csr(mepc) + 2); + } +} + diff --git a/test/sim/sw_testcases/load_misalign_halfword.expected_output b/test/sim/sw_testcases/load_misalign_halfword.expected_output new file mode 100644 index 0000000..d9a1a7a --- /dev/null +++ b/test/sim/sw_testcases/load_misalign_halfword.expected_output @@ -0,0 +1,18 @@ +Load halfword signed, 1 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load halfword signed, 3 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load halfword signed aligned (sanity check) +Result: ffffcdef +Result: 00001234 +Load halfword unsigned, 1 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load halfword unsigned, 3 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load halfword unsigned aligned (sanity check) +Result: 0000cdef +Result: 00001234 diff --git a/test/sim/sw_testcases/load_misalign_word.c b/test/sim/sw_testcases/load_misalign_word.c new file mode 100644 index 0000000..59039a2 --- /dev/null +++ b/test/sim/sw_testcases/load_misalign_word.c @@ -0,0 +1,31 @@ +#include "tb_cxxrtl_io.h" +#include "hazard3_csr.h" + +int main() { + volatile uint32_t target_word = -1u; + volatile uint32_t result_word = 0; + tb_puts("Load word, 1 byte offset\n"); + asm volatile("lw %0, 1(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load word, 2 byte offset\n"); + asm volatile("lw %0, 2(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load word, 3 byte offset\n"); + asm volatile("lw %0, 3(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); + tb_puts("Load word aligned (sanity check)\n"); + asm volatile("lw %0, 0(%1)" : "+r" (result_word) : "r" (&target_word)); + tb_printf("Result: %08x\n", result_word); +} + +void __attribute__((interrupt)) handle_exception() { + tb_printf("-> exception, mcause = %u\n", read_csr(mcause)); + write_csr(mcause, 0); + if (*(uint16_t*)read_csr(mepc) & 0x3 == 0x3) { + write_csr(mepc, read_csr(mepc) + 4); + } + else { + write_csr(mepc, read_csr(mepc) + 2); + } +} + diff --git a/test/sim/sw_testcases/load_misalign_word.expected_output b/test/sim/sw_testcases/load_misalign_word.expected_output new file mode 100644 index 0000000..4d652d3 --- /dev/null +++ b/test/sim/sw_testcases/load_misalign_word.expected_output @@ -0,0 +1,11 @@ +Load word, 1 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load word, 2 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load word, 3 byte offset +-> exception, mcause = 4 +Result: 00000000 +Load word aligned (sanity check) +Result: ffffffff diff --git a/test/sim/sw_testcases/store_misalign_halfword.c b/test/sim/sw_testcases/store_misalign_halfword.c new file mode 100644 index 0000000..e51029d --- /dev/null +++ b/test/sim/sw_testcases/store_misalign_halfword.c @@ -0,0 +1,31 @@ +#include "tb_cxxrtl_io.h" +#include "hazard3_csr.h" + +int main() { + volatile uint32_t target_word = -1u; + tb_puts("Store halfword, 1 byte offset\n"); + asm volatile ("sh zero, 1(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + tb_puts("Store halfword, 3 byte offset\n"); + asm volatile ("sh zero, 3(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + tb_puts("Aligned store halfword, sanity check\n"); + asm volatile ("sh zero, 0(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + asm volatile ("sh zero, 2(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + + return 0; +} + +void __attribute__((interrupt)) handle_exception() { + tb_printf("-> exception, mcause = %u\n", read_csr(mcause)); + write_csr(mcause, 0); + if (*(uint16_t*)read_csr(mepc) & 0x3 == 0x3) { + write_csr(mepc, read_csr(mepc) + 4); + } + else { + write_csr(mepc, read_csr(mepc) + 2); + } +} + diff --git a/test/sim/sw_testcases/store_misalign_halfword.expected_output b/test/sim/sw_testcases/store_misalign_halfword.expected_output new file mode 100644 index 0000000..dcbf772 --- /dev/null +++ b/test/sim/sw_testcases/store_misalign_halfword.expected_output @@ -0,0 +1,9 @@ +Store halfword, 1 byte offset +-> exception, mcause = 6 +Target value: ffffffff +Store halfword, 3 byte offset +-> exception, mcause = 6 +Target value: ffffffff +Aligned store halfword, sanity check +Target value: ffff0000 +Target value: 00000000 diff --git a/test/sim/sw_testcases/store_misalign_word.c b/test/sim/sw_testcases/store_misalign_word.c new file mode 100644 index 0000000..e23db15 --- /dev/null +++ b/test/sim/sw_testcases/store_misalign_word.c @@ -0,0 +1,32 @@ +#include "tb_cxxrtl_io.h" +#include "hazard3_csr.h" + +int main() { + volatile uint32_t target_word = -1u; + tb_puts("Store word, 1 byte offset\n"); + asm volatile ("sw zero, 1(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + tb_puts("Store word, 2 byte offset\n"); + asm volatile ("sw zero, 2(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + tb_puts("Store word, 3 byte offset\n"); + asm volatile ("sw zero, 3(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + tb_puts("Aligned store word, sanity check\n"); + asm volatile ("sw zero, 0(%0)" : : "r" (&target_word)); + tb_printf("Target value: %08x\n", target_word); + + return 0; +} + +void __attribute__((interrupt)) handle_exception() { + tb_printf("-> exception, mcause = %u\n", read_csr(mcause)); + write_csr(mcause, 0); + if (*(uint16_t*)read_csr(mepc) & 0x3 == 0x3) { + write_csr(mepc, read_csr(mepc) + 4); + } + else { + write_csr(mepc, read_csr(mepc) + 2); + } +} + diff --git a/test/sim/sw_testcases/store_misalign_word.expected_output b/test/sim/sw_testcases/store_misalign_word.expected_output new file mode 100644 index 0000000..7a11b68 --- /dev/null +++ b/test/sim/sw_testcases/store_misalign_word.expected_output @@ -0,0 +1,11 @@ +Store word, 1 byte offset +-> exception, mcause = 6 +Target value: ffffffff +Store word, 2 byte offset +-> exception, mcause = 6 +Target value: ffffffff +Store word, 3 byte offset +-> exception, mcause = 6 +Target value: ffffffff +Aligned store word, sanity check +Target value: 00000000