134 lines
3.2 KiB
ArmAsm
134 lines
3.2 KiB
ArmAsm
# See LICENSE for license details.
|
|
|
|
#*****************************************************************************
|
|
# ma_addr.S
|
|
#-----------------------------------------------------------------------------
|
|
#
|
|
# Test misaligned ld/st trap.
|
|
#
|
|
|
|
#include "riscv_test.h"
|
|
#include "test_macros.h"
|
|
|
|
RVTEST_RV64M
|
|
RVTEST_CODE_BEGIN
|
|
|
|
.align 2
|
|
.option norvc
|
|
|
|
la s0, data
|
|
|
|
# indicate it's a load test
|
|
li s1, CAUSE_MISALIGNED_LOAD
|
|
li s2, CAUSE_LOAD_ACCESS
|
|
|
|
#define SEXT(x, n) ((-((x) >> ((n)-1)) << (n)) | ((x) & ((1 << (n))-1)))
|
|
|
|
/* Check that a misaligned load either writes the correct value, or
|
|
takes an exception and performs no writeback. */
|
|
#define MISALIGNED_LOAD_TEST(testnum, insn, base, offset, res) \
|
|
li TESTNUM, testnum; \
|
|
la t2, 1f; \
|
|
addi t1, base, offset; \
|
|
insn t1, offset(base); \
|
|
li t2, res; \
|
|
bne t1, t2, fail; \
|
|
1:
|
|
|
|
MISALIGNED_LOAD_TEST(2, lh, s0, 1, SEXT(0xbbcc, 16))
|
|
MISALIGNED_LOAD_TEST(3, lhu, s0, 1, 0xbbcc)
|
|
MISALIGNED_LOAD_TEST(4, lw, s0, 1, SEXT(0x99aabbcc, 32))
|
|
MISALIGNED_LOAD_TEST(5, lw, s0, 2, SEXT(0x8899aabb, 32))
|
|
MISALIGNED_LOAD_TEST(6, lw, s0, 3, SEXT(0x778899aa, 32))
|
|
|
|
#if __riscv_xlen == 64
|
|
MISALIGNED_LOAD_TEST(7, lwu, s0, 1, 0x99aabbcc)
|
|
MISALIGNED_LOAD_TEST(8, lwu, s0, 2, 0x8899aabb)
|
|
MISALIGNED_LOAD_TEST(9, lwu, s0, 3, 0x778899aa)
|
|
|
|
MISALIGNED_LOAD_TEST(10, ld, s0, 1, 0x5566778899aabbcc)
|
|
MISALIGNED_LOAD_TEST(11, ld, s0, 2, 0x445566778899aabb)
|
|
MISALIGNED_LOAD_TEST(12, ld, s0, 3, 0x33445566778899aa)
|
|
MISALIGNED_LOAD_TEST(13, ld, s0, 4, 0x2233445566778899)
|
|
MISALIGNED_LOAD_TEST(14, ld, s0, 5, 0x1122334455667788)
|
|
MISALIGNED_LOAD_TEST(15, ld, s0, 6, 0xee11223344556677)
|
|
MISALIGNED_LOAD_TEST(16, ld, s0, 7, 0xffee112233445566)
|
|
#endif
|
|
|
|
# indicate it's a store test
|
|
li s1, CAUSE_MISALIGNED_STORE
|
|
li s2, CAUSE_STORE_ACCESS
|
|
|
|
/* Check that a misaligned store has some effect and takes no exception,
|
|
or takes no effect and generates an exception. This is not very
|
|
thorough. */
|
|
#define MISALIGNED_STORE_TEST(testnum, insn, base, offset, size) \
|
|
li TESTNUM, testnum; \
|
|
la t2, 1f; \
|
|
addi t1, base, offset; \
|
|
insn x0, offset(base); \
|
|
lb t1, (offset - 1)(base); \
|
|
beqz t1, fail; \
|
|
lb t1, (offset + size)(base); \
|
|
beqz t1, fail; \
|
|
lb t1, (offset + 0)(base); \
|
|
bnez t1, fail; \
|
|
lb t1, (offset + size - 1)(base); \
|
|
bnez t1, fail; \
|
|
1:
|
|
|
|
MISALIGNED_STORE_TEST(22, sh, s0, 1, 2)
|
|
MISALIGNED_STORE_TEST(23, sw, s0, 5, 4)
|
|
MISALIGNED_STORE_TEST(24, sw, s0, 10, 4)
|
|
MISALIGNED_STORE_TEST(25, sw, s0, 15, 4)
|
|
|
|
#if __riscv_xlen == 64
|
|
MISALIGNED_STORE_TEST(26, sd, s0, 25, 8)
|
|
MISALIGNED_STORE_TEST(27, sd, s0, 34, 8)
|
|
MISALIGNED_STORE_TEST(28, sd, s0, 43, 8)
|
|
MISALIGNED_STORE_TEST(29, sd, s0, 52, 8)
|
|
MISALIGNED_STORE_TEST(30, sd, s0, 61, 8)
|
|
MISALIGNED_STORE_TEST(31, sd, s0, 70, 8)
|
|
MISALIGNED_STORE_TEST(32, sd, s0, 79, 8)
|
|
#endif
|
|
|
|
TEST_PASSFAIL
|
|
|
|
.align 3
|
|
.global mtvec_handler
|
|
mtvec_handler:
|
|
csrr t0, mcause
|
|
beq t0, s1, 1f
|
|
beq t0, s2, 1f
|
|
j fail
|
|
1:
|
|
|
|
csrr t0, mbadaddr
|
|
beqz t0, 1f
|
|
bne t0, t1, fail
|
|
|
|
lb t0, (t0)
|
|
beqz t0, fail
|
|
1:
|
|
|
|
csrw mepc, t2
|
|
mret
|
|
|
|
RVTEST_CODE_END
|
|
|
|
.data
|
|
RVTEST_DATA_BEGIN
|
|
|
|
data:
|
|
.align 3
|
|
.word 0xaabbccdd
|
|
.word 0x66778899
|
|
.word 0x22334455
|
|
.word 0xeeffee11
|
|
.fill 0xff, 1, 80
|
|
|
|
|
|
TEST_DATA
|
|
|
|
RVTEST_DATA_END
|