From fb04a343df61c55849edc7734bc2a60d615fe49c Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Tue, 7 Jun 2022 13:34:39 -0700 Subject: Test misaligned loads. Cover lh, lw, and ld (only on rv64). --- isa/macros/scalar/test_macros.h | 16 +++++++++++++++ isa/rv32mi/Makefrag | 2 ++ isa/rv32mi/lh-misaligned.S | 8 ++++++++ isa/rv32mi/lw-misaligned.S | 8 ++++++++ isa/rv64mi/Makefrag | 3 +++ isa/rv64mi/ld-misaligned.S | 45 +++++++++++++++++++++++++++++++++++++++++ isa/rv64mi/lh-misaligned.S | 38 ++++++++++++++++++++++++++++++++++ isa/rv64mi/lw-misaligned.S | 40 ++++++++++++++++++++++++++++++++++++ 8 files changed, 160 insertions(+) create mode 100644 isa/rv32mi/lh-misaligned.S create mode 100644 isa/rv32mi/lw-misaligned.S create mode 100644 isa/rv64mi/ld-misaligned.S create mode 100644 isa/rv64mi/lh-misaligned.S create mode 100644 isa/rv64mi/lw-misaligned.S (limited to 'isa') diff --git a/isa/macros/scalar/test_macros.h b/isa/macros/scalar/test_macros.h index ee352e4..e286a44 100644 --- a/isa/macros/scalar/test_macros.h +++ b/isa/macros/scalar/test_macros.h @@ -217,6 +217,7 @@ test_ ## testnum: \ #define TEST_LD_OP( testnum, inst, result, offset, base ) \ TEST_CASE( testnum, x14, result, \ + li x15, result; /* Tell the exception handler the expected result. */ \ la x1, base; \ inst x14, offset(x1); \ ) @@ -701,6 +702,21 @@ test_ ## testnum: \ // ^ x14 is used in some other macros, to avoid issues we use x15 for upper word +#define MISALIGNED_LOAD_HANDLER \ + li t0, CAUSE_MISALIGNED_LOAD; \ + csrr t1, mcause; \ + bne t0, t1, fail; \ + \ + /* We got a misaligned exception. Pretend we handled it in software */ \ + /* by loading the correct result here. */ \ + mv a4, a5; \ + \ + /* And skip this instruction */ \ + csrr t0, mepc; \ + addi t0, t0, 4; \ + csrw mepc, t0; \ + mret + #----------------------------------------------------------------------- # Pass and fail code (assumes test num is in TESTNUM) #----------------------------------------------------------------------- diff --git a/isa/rv32mi/Makefrag b/isa/rv32mi/Makefrag index 2142570..e3d81af 100644 --- a/isa/rv32mi/Makefrag +++ b/isa/rv32mi/Makefrag @@ -12,5 +12,7 @@ rv32mi_sc_tests = \ scall \ sbreak \ shamt \ + lw-misaligned \ + lh-misaligned \ rv32mi_p_tests = $(addprefix rv32mi-p-, $(rv32mi_sc_tests)) diff --git a/isa/rv32mi/lh-misaligned.S b/isa/rv32mi/lh-misaligned.S new file mode 100644 index 0000000..42755f5 --- /dev/null +++ b/isa/rv32mi/lh-misaligned.S @@ -0,0 +1,8 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64M +#define RVTEST_RV64M RVTEST_RV32M +#define __MACHINE_MODE + +#include "../rv64mi/lh-misaligned.S" diff --git a/isa/rv32mi/lw-misaligned.S b/isa/rv32mi/lw-misaligned.S new file mode 100644 index 0000000..0614aee --- /dev/null +++ b/isa/rv32mi/lw-misaligned.S @@ -0,0 +1,8 @@ +# See LICENSE for license details. + +#include "riscv_test.h" +#undef RVTEST_RV64M +#define RVTEST_RV64M RVTEST_RV32M +#define __MACHINE_MODE + +#include "../rv64mi/lw-misaligned.S" diff --git a/isa/rv64mi/Makefrag b/isa/rv64mi/Makefrag index 645622b..2f88249 100644 --- a/isa/rv64mi/Makefrag +++ b/isa/rv64mi/Makefrag @@ -12,5 +12,8 @@ rv64mi_sc_tests = \ ma_addr \ scall \ sbreak \ + ld-misaligned \ + lw-misaligned \ + lh-misaligned \ rv64mi_p_tests = $(addprefix rv64mi-p-, $(rv64mi_sc_tests)) diff --git a/isa/rv64mi/ld-misaligned.S b/isa/rv64mi/ld-misaligned.S new file mode 100644 index 0000000..fb210ad --- /dev/null +++ b/isa/rv64mi/ld-misaligned.S @@ -0,0 +1,45 @@ +# See LICENSE for license details. + +#***************************************************************************** +# lw-unaligned.S +#----------------------------------------------------------------------------- +# +# Test that misaligned loads work or raise the correct exception +# This test assumes the target is little-endian +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64M +RVTEST_CODE_BEGIN + + TEST_LD_OP( 2, ld, 0x0807060504030201, 0, tdat ); + TEST_LD_OP( 3, ld, 0x0908070605040302, 1, tdat ); + TEST_LD_OP( 4, ld, 0x0a09080706050403, 2, tdat ); + TEST_LD_OP( 5, ld, 0x0b0a090807060504, 3, tdat ); + TEST_LD_OP( 6, ld, 0x0c0b0a0908070605, 4, tdat ); + TEST_LD_OP( 7, ld, 0x0d0c0b0a09080706, 5, tdat ); + TEST_LD_OP( 8, ld, 0x0e0d0c0b0a090807, 6, tdat ); + TEST_LD_OP( 9, ld, 0x0f0e0d0c0b0a0908, 7, tdat ); + +2: + TEST_PASSFAIL + + .align 2 + .global mtvec_handler +mtvec_handler: + MISALIGNED_LOAD_HANDLER + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +tdat: + .byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 + .byte 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 + +RVTEST_DATA_END diff --git a/isa/rv64mi/lh-misaligned.S b/isa/rv64mi/lh-misaligned.S new file mode 100644 index 0000000..c21551d --- /dev/null +++ b/isa/rv64mi/lh-misaligned.S @@ -0,0 +1,38 @@ +# See LICENSE for license details. + +#***************************************************************************** +# lh-unaligned.S +#----------------------------------------------------------------------------- +# +# Test that misaligned loads work or raise the correct exception +# This test assumes the target is little-endian +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64M +RVTEST_CODE_BEGIN + + TEST_LD_OP( 2, lh, 0x0201, 0, tdat ); + TEST_LD_OP( 3, lh, 0x0302, 1, tdat ); + +2: + TEST_PASSFAIL + + .align 2 + .global mtvec_handler +mtvec_handler: + MISALIGNED_LOAD_HANDLER + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +tdat: + .byte 0x01, 0x02, 0x03, 0x04 + +RVTEST_DATA_END diff --git a/isa/rv64mi/lw-misaligned.S b/isa/rv64mi/lw-misaligned.S new file mode 100644 index 0000000..3029085 --- /dev/null +++ b/isa/rv64mi/lw-misaligned.S @@ -0,0 +1,40 @@ +# See LICENSE for license details. + +#***************************************************************************** +# lw-unaligned.S +#----------------------------------------------------------------------------- +# +# Test that misaligned loads work or raise the correct exception +# This test assumes the target is little-endian +# + +#include "riscv_test.h" +#include "test_macros.h" + +RVTEST_RV64M +RVTEST_CODE_BEGIN + + TEST_LD_OP( 2, lw, 0x04030201, 0, tdat ); + TEST_LD_OP( 3, lw, 0x05040302, 1, tdat ); + TEST_LD_OP( 4, lw, 0x06050403, 2, tdat ); + TEST_LD_OP( 5, lw, 0x07060504, 3, tdat ); + +2: + TEST_PASSFAIL + + .align 2 + .global mtvec_handler +mtvec_handler: + MISALIGNED_LOAD_HANDLER + +RVTEST_CODE_END + + .data +RVTEST_DATA_BEGIN + + TEST_DATA + +tdat: + .byte 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 + +RVTEST_DATA_END -- cgit v1.1