aboutsummaryrefslogtreecommitdiff
path: root/isa
diff options
context:
space:
mode:
Diffstat (limited to 'isa')
-rw-r--r--isa/Makefile4
-rw-r--r--isa/hypervisor/2-stage_translation.S136
-rw-r--r--isa/hypervisor/Makefrag8
-rw-r--r--isa/macros/scalar/test_macros.h38
-rw-r--r--isa/rv32ui/Makefrag4
-rw-r--r--isa/rv32ui/ld_st.S7
-rw-r--r--isa/rv32ui/st_ld.S7
-rw-r--r--isa/rv64ui/Makefrag4
-rw-r--r--isa/rv64ui/ld_st.S130
-rw-r--r--isa/rv64ui/st_ld.S130
10 files changed, 462 insertions, 6 deletions
diff --git a/isa/Makefile b/isa/Makefile
index bf85e1f..e3b6719 100644
--- a/isa/Makefile
+++ b/isa/Makefile
@@ -22,6 +22,7 @@ include $(src_dir)/rv64si/Makefrag
include $(src_dir)/rv64ssvnapot/Makefrag
include $(src_dir)/rv64mi/Makefrag
include $(src_dir)/rv64mzicbo/Makefrag
+include $(src_dir)/hypervisor/Makefrag
endif
include $(src_dir)/rv32ui/Makefrag
include $(src_dir)/rv32uc/Makefrag
@@ -58,7 +59,7 @@ vpath %.S $(src_dir)
$(RISCV_OBJDUMP) $< > $@
%.out: %
- $(RISCV_SIM) --isa=rv64gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
+ $(RISCV_SIM) --isa=rv64gch_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
%.out32: %
$(RISCV_SIM) --isa=rv32gc_zfh_zicboz_svnapot_zicntr_zba_zbb_zbc_zbs --misaligned $< 2> $@
@@ -116,6 +117,7 @@ $(eval $(call compile_template,rv64mzicbo,-march=rv64g_zicboz -mabi=lp64))
$(eval $(call compile_template,rv64si,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64ssvnapot,-march=rv64g -mabi=lp64))
$(eval $(call compile_template,rv64mi,-march=rv64g -mabi=lp64))
+$(eval $(call compile_template,hypervisor,-march=rv64gh -mabi=lp64))
endif
tests_dump = $(addsuffix .dump, $(tests))
diff --git a/isa/hypervisor/2-stage_translation.S b/isa/hypervisor/2-stage_translation.S
new file mode 100644
index 0000000..93b4340
--- /dev/null
+++ b/isa/hypervisor/2-stage_translation.S
@@ -0,0 +1,136 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# 2-stage_translation.S
+#-----------------------------------------------------------------------------
+#
+# Set 2 stage translation, do a simple load store.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+#define vspt0_gpa 0x0
+#define vspt1_gpa 0x1000
+#define vspt2_gpa 0x2000
+#define GPA 0x200000
+
+RVTEST_RV64M
+RVTEST_CODE_BEGIN
+
+ li TESTNUM, 2
+
+# map GVA 0x0~0xfff to GPA 0x200000~0x200fff
+vs_pt_init:
+ li t0, vspt1_gpa
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, vspt_0, t1
+
+ li t0, vspt2_gpa
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, vspt_1, t1
+
+ li t0, GPA
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_X | PTE_A | PTE_D | PTE_R | PTE_W
+ sd t0, vspt_2, t1
+
+init_vsatp:
+ li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+ la a1, vspt0_gpa
+ srl a1, a1, RISCV_PGSHIFT
+ or a1, a1, a0
+ csrw vsatp, a1
+ hfence.vvma
+
+
+# map GPA 0x200000~0x200fff to data_page
+guest_pt_init:
+ la t0, gpt_1
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_0, t1
+
+ la t0, gpt_2
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_1, t1
+
+ la t0, gpt_3
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V
+ sd t0, gpt_1 + 8, t1
+
+ la t0, vspt_0
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2, t1
+
+ la t0, vspt_1
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2 + 8, t1
+
+ la t0, vspt_2
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_2 + 16, t1
+
+ la t0, data_page
+ srl t0, t0, RISCV_PGSHIFT - PTE_PPN_SHIFT
+ ori t0, t0, PTE_V | PTE_R | PTE_W | PTE_A | PTE_D | PTE_U
+ sd t0, gpt_3, t1
+
+init_hgatp:
+ li a0, (SATP_MODE & ~(SATP_MODE<<1)) * SATP_MODE_SV39
+ la a1, gpt_0
+ srl a1, a1, RISCV_PGSHIFT
+ or a1, a1, a0
+ csrw hgatp, a1
+ hfence.gvma
+
+hstatus_init:
+ li a0, HSTATUS_SPVP
+ csrs hstatus, a0
+
+ la a0, data_page
+ li a1, 0x12345678
+ sw a1, 0(a0)
+
+ li t0, 0x0
+ hlv.w t2, 0(t0) # should be 0x12345678
+ hsv.w t2, 0(t0)
+ bne t2, a1, fail
+
+ RVTEST_PASS
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+.align 12
+vspt_0: .dword 0
+.align 12
+vspt_1: .dword 0
+.align 12
+vspt_2: .dword 0
+
+.align 14
+gpt_0: .dword 0
+.align 14
+gpt_1: .dword 0
+.align 12
+gpt_2: .dword 0
+.align 12
+gpt_3: .dword 0
+.align 12
+data_page: .dword 0
+
+RVTEST_DATA_END
diff --git a/isa/hypervisor/Makefrag b/isa/hypervisor/Makefrag
new file mode 100644
index 0000000..08f711a
--- /dev/null
+++ b/isa/hypervisor/Makefrag
@@ -0,0 +1,8 @@
+#=======================================================================
+# Makefrag for hypervisor tests
+#-----------------------------------------------------------------------
+
+hypervisor_sc_tests = \
+ 2-stage_translation \
+
+hypervisor_p_tests = $(addprefix hypervisor-p-, $(hypervisor_sc_tests))
diff --git a/isa/macros/scalar/test_macros.h b/isa/macros/scalar/test_macros.h
index 518476c..f3c404d 100644
--- a/isa/macros/scalar/test_macros.h
+++ b/isa/macros/scalar/test_macros.h
@@ -32,6 +32,13 @@ test_ ## testnum: \
#define TEST_INSERT_NOPS_9 nop; TEST_INSERT_NOPS_8
#define TEST_INSERT_NOPS_10 nop; TEST_INSERT_NOPS_9
+#if __riscv_xlen == 64
+#define LOAD_PTR ld
+#define STORE_PTR sd
+#else
+#define LOAD_PTR lw
+#define STORE_PTR sw
+#endif
#-----------------------------------------------------------------------
# RV64UI MACROS
@@ -295,7 +302,36 @@ test_ ## testnum: \
li x5, 2; \
bne x4, x5, 1b \
-#define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
+#define TEST_LD_ST_BYPASS(testnum, load_inst, store_inst, result, offset, base) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la x2, base; \
+ li x1, result; \
+ store_inst x1, offset(x2); \
+ load_inst x14, offset(x2); \
+ store_inst x14, offset(x2); \
+ load_inst x2, offset(x2); \
+ li x7, result; \
+ bne x2, x7, fail; \
+ la x2, base; \
+ STORE_PTR x2,8(x2); \
+ LOAD_PTR x4,8(x2); \
+ store_inst x1, offset(x4); \
+ bne x4, x2, fail; \
+ load_inst x14, offset(x4); \
+ bne x14, x7, fail; \
+
+#define TEST_ST_LD_BYPASS(testnum, load_inst, store_inst, result, offset, base) \
+test_ ## testnum: \
+ li TESTNUM, testnum; \
+ la x2, base; \
+ li x1, result; \
+ store_inst x1, offset(x2); \
+ load_inst x14, offset(x2); \
+ li x7, result; \
+ bne x14, x7, fail; \
+
+#define TEST_BR2_OP_TAKEN(testnum, inst, val1, val2 ) \
test_ ## testnum: \
li TESTNUM, testnum; \
li x1, val1; \
diff --git a/isa/rv32ui/Makefrag b/isa/rv32ui/Makefrag
index b7d85e1..d797e61 100644
--- a/isa/rv32ui/Makefrag
+++ b/isa/rv32ui/Makefrag
@@ -10,11 +10,11 @@ rv32ui_sc_tests = \
beq bge bgeu blt bltu bne \
fence_i \
jal jalr \
- lb lbu lh lhu lw \
+ lb lbu lh lhu lw ld_st \
lui \
ma_data \
or ori \
- sb sh sw \
+ sb sh sw st_ld \
sll slli \
slt slti sltiu sltu \
sra srai \
diff --git a/isa/rv32ui/ld_st.S b/isa/rv32ui/ld_st.S
new file mode 100644
index 0000000..476b806
--- /dev/null
+++ b/isa/rv32ui/ld_st.S
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64U
+#define RVTEST_RV64U RVTEST_RV32U
+
+#include "../rv64ui/ld_st.S"
diff --git a/isa/rv32ui/st_ld.S b/isa/rv32ui/st_ld.S
new file mode 100644
index 0000000..22b303c
--- /dev/null
+++ b/isa/rv32ui/st_ld.S
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64U
+#define RVTEST_RV64U RVTEST_RV32U
+
+#include "../rv64ui/st_ld.S"
diff --git a/isa/rv64ui/Makefrag b/isa/rv64ui/Makefrag
index d90347c..59e40cf 100644
--- a/isa/rv64ui/Makefrag
+++ b/isa/rv64ui/Makefrag
@@ -10,11 +10,11 @@ rv64ui_sc_tests = \
simple \
fence_i \
jal jalr \
- lb lbu lh lhu lw lwu ld \
+ lb lbu lh lhu lw lwu ld ld_st \
lui \
ma_data \
or ori \
- sb sh sw sd \
+ sb sh sw sd st_ld \
sll slli slliw sllw \
slt slti sltiu sltu \
sra srai sraiw sraw \
diff --git a/isa/rv64ui/ld_st.S b/isa/rv64ui/ld_st.S
new file mode 100644
index 0000000..d03e132
--- /dev/null
+++ b/isa/rv64ui/ld_st.S
@@ -0,0 +1,130 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# ld_st.S
+#-----------------------------------------------------------------------------
+#
+# Test load and store instructions
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Bypassing Tests
+ #-------------------------------------------------------------
+
+ # Test sb and lb (signed byte)
+ TEST_LD_ST_BYPASS(2, lb, sb, 0xffffffffffffffdd, 0, tdat );
+ TEST_LD_ST_BYPASS(3, lb, sb, 0xffffffffffffffcd, 1, tdat );
+ TEST_LD_ST_BYPASS(4, lb, sb, 0xffffffffffffffcc, 2, tdat );
+ TEST_LD_ST_BYPASS(5, lb, sb, 0xffffffffffffffbc, 3, tdat );
+ TEST_LD_ST_BYPASS(6, lb, sb, 0xffffffffffffffbb, 4, tdat );
+ TEST_LD_ST_BYPASS(7, lb, sb, 0xffffffffffffffab, 5, tdat );
+
+ TEST_LD_ST_BYPASS(8, lb, sb, 0x33, 0, tdat );
+ TEST_LD_ST_BYPASS(9, lb, sb, 0x23, 1, tdat );
+ TEST_LD_ST_BYPASS(10, lb, sb, 0x22, 2, tdat );
+ TEST_LD_ST_BYPASS(11, lb, sb, 0x12, 3, tdat );
+ TEST_LD_ST_BYPASS(12, lb, sb, 0x11, 4, tdat );
+ TEST_LD_ST_BYPASS(13, lb, sb, 0x01, 5, tdat );
+
+ # Test sb and lbu (unsigned byte)
+ TEST_LD_ST_BYPASS(14, lbu, sb, 0x33, 0, tdat );
+ TEST_LD_ST_BYPASS(15, lbu, sb, 0x23, 1, tdat );
+ TEST_LD_ST_BYPASS(16, lbu, sb, 0x22, 2, tdat );
+ TEST_LD_ST_BYPASS(17, lbu, sb, 0x12, 3, tdat );
+ TEST_LD_ST_BYPASS(18, lbu, sb, 0x11, 4, tdat );
+ TEST_LD_ST_BYPASS(19, lbu, sb, 0x01, 5, tdat );
+
+ # Test sw and lw (signed word)
+ TEST_LD_ST_BYPASS(20, lw, sw, 0xffffffffaabbccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(21, lw, sw, 0xffffffffdaabbccd, 4, tdat );
+ TEST_LD_ST_BYPASS(22, lw, sw, 0xffffffffddaabbcc, 8, tdat );
+ TEST_LD_ST_BYPASS(23, lw, sw, 0xffffffffcddaabbc, 12, tdat );
+ TEST_LD_ST_BYPASS(24, lw, sw, 0xffffffffccddaabb, 16, tdat );
+ TEST_LD_ST_BYPASS(25, lw, sw, 0xffffffffbccddaab, 20, tdat );
+
+ TEST_LD_ST_BYPASS(26, lw, sw, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(27, lw, sw, 0x30011223, 4, tdat );
+ TEST_LD_ST_BYPASS(28, lw, sw, 0x33001122, 8, tdat );
+ TEST_LD_ST_BYPASS(29, lw, sw, 0x23300112, 12, tdat );
+ TEST_LD_ST_BYPASS(30, lw, sw, 0x22330011, 16, tdat );
+ TEST_LD_ST_BYPASS(31, lw, sw, 0x12233001, 20, tdat );
+
+ # Test sh and lh (signed halfword)
+ TEST_LD_ST_BYPASS(32, lh, sh, 0xffffffffffffccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(33, lh, sh, 0xffffffffffffbccd, 2, tdat );
+ TEST_LD_ST_BYPASS(34, lh, sh, 0xffffffffffffbbcc, 4, tdat );
+ TEST_LD_ST_BYPASS(35, lh, sh, 0xffffffffffffabbc, 6, tdat );
+ TEST_LD_ST_BYPASS(36, lh, sh, 0xffffffffffffaabb, 8, tdat );
+ TEST_LD_ST_BYPASS(37, lh, sh, 0xffffffffffffdaab, 10, tdat );
+
+ TEST_LD_ST_BYPASS(38, lh, sh, 0x2233, 0, tdat );
+ TEST_LD_ST_BYPASS(39, lh, sh, 0x1223, 2, tdat );
+ TEST_LD_ST_BYPASS(40, lh, sh, 0x1122, 4, tdat );
+ TEST_LD_ST_BYPASS(41, lh, sh, 0x0112, 6, tdat );
+ TEST_LD_ST_BYPASS(42, lh, sh, 0x0011, 8, tdat );
+ TEST_LD_ST_BYPASS(43, lh, sh, 0x3001, 10, tdat );
+
+ # Test sh and lhu (unsigned halfword)
+ TEST_LD_ST_BYPASS(44, lhu, sh, 0x2233, 0, tdat );
+ TEST_LD_ST_BYPASS(45, lhu, sh, 0x1223, 2, tdat );
+ TEST_LD_ST_BYPASS(46, lhu, sh, 0x1122, 4, tdat );
+ TEST_LD_ST_BYPASS(47, lhu, sh, 0x0112, 6, tdat );
+ TEST_LD_ST_BYPASS(48, lhu, sh, 0x0011, 8, tdat );
+ TEST_LD_ST_BYPASS(49, lhu, sh, 0x3001, 10, tdat );
+
+ # RV64-specific tests for ld, sd, and lwu
+#if __riscv_xlen == 64
+ # Test sd and ld (doubleword)
+ TEST_LD_ST_BYPASS(50, ld, sd, 0x0011223344556677, 0, tdat );
+ TEST_LD_ST_BYPASS(51, ld, sd, 0x1122334455667788, 8, tdat );
+ TEST_LD_ST_BYPASS(52, ld, sd, 0x2233445566778899, 16, tdat );
+ TEST_LD_ST_BYPASS(53, ld, sd, 0xabbccdd, 0, tdat );
+ TEST_LD_ST_BYPASS(54, ld, sd, 0xaabbccd, 8, tdat );
+ TEST_LD_ST_BYPASS(55, ld, sd, 0xdaabbcc, 16, tdat );
+ TEST_LD_ST_BYPASS(56, ld, sd, 0xddaabbc, 24, tdat );
+ TEST_LD_ST_BYPASS(57, ld, sd, 0xcddaabb, 32, tdat );
+ TEST_LD_ST_BYPASS(58, ld, sd, 0xccddaab, 40, tdat );
+
+ TEST_LD_ST_BYPASS(59, ld, sd, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(60, ld, sd, 0x30011223, 8, tdat );
+ TEST_LD_ST_BYPASS(61, ld, sd, 0x33001122, 16, tdat );
+ TEST_LD_ST_BYPASS(62, ld, sd, 0x23300112, 24, tdat );
+ TEST_LD_ST_BYPASS(63, ld, sd, 0x22330011, 32, tdat );
+ TEST_LD_ST_BYPASS(64, ld, sd, 0x12233001, 40, tdat );
+
+ # Test sw and lwu (unsigned word)
+ TEST_LD_ST_BYPASS(65, lwu, sw, 0x00112233, 0, tdat );
+ TEST_LD_ST_BYPASS(66, lwu, sw, 0x33001122, 8, tdat );
+ TEST_LD_ST_BYPASS(67, lwu, sw, 0x30011223, 4, tdat );
+ TEST_LD_ST_BYPASS(68, lwu, sw, 0x23300112, 12, tdat );
+ TEST_LD_ST_BYPASS(69, lwu, sw, 0x22330011, 16, tdat );
+ TEST_LD_ST_BYPASS(70, lwu, sw, 0x12233001, 20, tdat );
+#endif
+
+ li a0, 0xef # Immediate load for manual store test
+ la a1, tdat # Load address of tdat
+ sb a0, 3(a1) # Store byte at offset 3 of tdat
+ lb a2, 3(a1) # Load byte back for verification
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+ .rept 20
+ .word 0xdeadbeef
+ .endr
+
+
+RVTEST_DATA_END
diff --git a/isa/rv64ui/st_ld.S b/isa/rv64ui/st_ld.S
new file mode 100644
index 0000000..89608db
--- /dev/null
+++ b/isa/rv64ui/st_ld.S
@@ -0,0 +1,130 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# st_ld.S
+#-----------------------------------------------------------------------------
+#
+# Test store and load instructions
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+ #-------------------------------------------------------------
+ # Bypassing Tests
+ #-------------------------------------------------------------
+
+ # Test sb and lb (signed byte)
+ TEST_ST_LD_BYPASS(2, lb, sb, 0xffffffffffffffdd, 0, tdat );
+ TEST_ST_LD_BYPASS(3, lb, sb, 0xffffffffffffffcd, 1, tdat );
+ TEST_ST_LD_BYPASS(4, lb, sb, 0xffffffffffffffcc, 2, tdat );
+ TEST_ST_LD_BYPASS(5, lb, sb, 0xffffffffffffffbc, 3, tdat );
+ TEST_ST_LD_BYPASS(6, lb, sb, 0xffffffffffffffbb, 4, tdat );
+ TEST_ST_LD_BYPASS(7, lb, sb, 0xffffffffffffffab, 5, tdat );
+
+ TEST_ST_LD_BYPASS(8, lb, sb, 0x33, 0, tdat );
+ TEST_ST_LD_BYPASS(9, lb, sb, 0x23, 1, tdat );
+ TEST_ST_LD_BYPASS(10, lb, sb, 0x22, 2, tdat );
+ TEST_ST_LD_BYPASS(11, lb, sb, 0x12, 3, tdat );
+ TEST_ST_LD_BYPASS(12, lb, sb, 0x11, 4, tdat );
+ TEST_ST_LD_BYPASS(13, lb, sb, 0x01, 5, tdat );
+
+ # Test sb and lbu (unsigned byte)
+ TEST_ST_LD_BYPASS(14, lbu, sb, 0x33, 0, tdat );
+ TEST_ST_LD_BYPASS(15, lbu, sb, 0x23, 1, tdat );
+ TEST_ST_LD_BYPASS(16, lbu, sb, 0x22, 2, tdat );
+ TEST_ST_LD_BYPASS(17, lbu, sb, 0x12, 3, tdat );
+ TEST_ST_LD_BYPASS(18, lbu, sb, 0x11, 4, tdat );
+ TEST_ST_LD_BYPASS(19, lbu, sb, 0x01, 5, tdat );
+
+ # Test sw and lw (signed word)
+ TEST_ST_LD_BYPASS(20, lw, sw, 0xffffffffaabbccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(21, lw, sw, 0xffffffffdaabbccd, 4, tdat );
+ TEST_ST_LD_BYPASS(22, lw, sw, 0xffffffffddaabbcc, 8, tdat );
+ TEST_ST_LD_BYPASS(23, lw, sw, 0xffffffffcddaabbc, 12, tdat );
+ TEST_ST_LD_BYPASS(24, lw, sw, 0xffffffffccddaabb, 16, tdat );
+ TEST_ST_LD_BYPASS(25, lw, sw, 0xffffffffbccddaab, 20, tdat );
+
+ TEST_ST_LD_BYPASS(26, lw, sw, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(27, lw, sw, 0x30011223, 4, tdat );
+ TEST_ST_LD_BYPASS(28, lw, sw, 0x33001122, 8, tdat );
+ TEST_ST_LD_BYPASS(29, lw, sw, 0x23300112, 12, tdat );
+ TEST_ST_LD_BYPASS(30, lw, sw, 0x22330011, 16, tdat );
+ TEST_ST_LD_BYPASS(31, lw, sw, 0x12233001, 20, tdat );
+
+ # Test sh and lh (signed halfword)
+ TEST_ST_LD_BYPASS(32, lh, sh, 0xffffffffffffccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(33, lh, sh, 0xffffffffffffbccd, 2, tdat );
+ TEST_ST_LD_BYPASS(34, lh, sh, 0xffffffffffffbbcc, 4, tdat );
+ TEST_ST_LD_BYPASS(35, lh, sh, 0xffffffffffffabbc, 6, tdat );
+ TEST_ST_LD_BYPASS(36, lh, sh, 0xffffffffffffaabb, 8, tdat );
+ TEST_ST_LD_BYPASS(37, lh, sh, 0xffffffffffffdaab, 10, tdat );
+
+ TEST_ST_LD_BYPASS(38, lh, sh, 0x2233, 0, tdat );
+ TEST_ST_LD_BYPASS(39, lh, sh, 0x1223, 2, tdat );
+ TEST_ST_LD_BYPASS(40, lh, sh, 0x1122, 4, tdat );
+ TEST_ST_LD_BYPASS(41, lh, sh, 0x0112, 6, tdat );
+ TEST_ST_LD_BYPASS(42, lh, sh, 0x0011, 8, tdat );
+ TEST_ST_LD_BYPASS(43, lh, sh, 0x3001, 10, tdat );
+
+ # Test sh and lhu (unsigned halfword)
+ TEST_ST_LD_BYPASS(44, lhu, sh, 0x2233, 0, tdat );
+ TEST_ST_LD_BYPASS(45, lhu, sh, 0x1223, 2, tdat );
+ TEST_ST_LD_BYPASS(46, lhu, sh, 0x1122, 4, tdat );
+ TEST_ST_LD_BYPASS(47, lhu, sh, 0x0112, 6, tdat );
+ TEST_ST_LD_BYPASS(48, lhu, sh, 0x0011, 8, tdat );
+ TEST_ST_LD_BYPASS(49, lhu, sh, 0x3001, 10, tdat );
+
+ # RV64-specific tests for ld, sd, and lwu
+#if __riscv_xlen == 64
+ # Test sd and ld (doubleword)
+ TEST_ST_LD_BYPASS(50, ld, sd, 0x0011223344556677, 0, tdat );
+ TEST_ST_LD_BYPASS(51, ld, sd, 0x1122334455667788, 8, tdat );
+ TEST_ST_LD_BYPASS(52, ld, sd, 0x2233445566778899, 16, tdat );
+ TEST_ST_LD_BYPASS(53, ld, sd, 0xabbccdd, 0, tdat );
+ TEST_ST_LD_BYPASS(54, ld, sd, 0xaabbccd, 8, tdat );
+ TEST_ST_LD_BYPASS(55, ld, sd, 0xdaabbcc, 16, tdat );
+ TEST_ST_LD_BYPASS(56, ld, sd, 0xddaabbc, 24, tdat );
+ TEST_ST_LD_BYPASS(57, ld, sd, 0xcddaabb, 32, tdat );
+ TEST_ST_LD_BYPASS(58, ld, sd, 0xccddaab, 40, tdat );
+
+ TEST_ST_LD_BYPASS(59, ld, sd, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(60, ld, sd, 0x30011223, 8, tdat );
+ TEST_ST_LD_BYPASS(61, ld, sd, 0x33001122, 16, tdat );
+ TEST_ST_LD_BYPASS(62, ld, sd, 0x23300112, 24, tdat );
+ TEST_ST_LD_BYPASS(63, ld, sd, 0x22330011, 32, tdat );
+ TEST_ST_LD_BYPASS(64, ld, sd, 0x12233001, 40, tdat );
+
+ # Test sw and lwu (unsigned word)
+ TEST_ST_LD_BYPASS(65, lwu, sw, 0x00112233, 0, tdat );
+ TEST_ST_LD_BYPASS(66, lwu, sw, 0x33001122, 8, tdat );
+ TEST_ST_LD_BYPASS(67, lwu, sw, 0x30011223, 4, tdat );
+ TEST_ST_LD_BYPASS(68, lwu, sw, 0x23300112, 12, tdat );
+ TEST_ST_LD_BYPASS(69, lwu, sw, 0x22330011, 16, tdat );
+ TEST_ST_LD_BYPASS(70, lwu, sw, 0x12233001, 20, tdat );
+#endif
+
+ li a0, 0xef # Immediate load for manual store test
+ la a1, tdat # Load address of tdat
+ sb a0, 3(a1) # Store byte at offset 3 of tdat
+ lb a2, 3(a1) # Load byte back for verification
+
+ TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+ .data
+RVTEST_DATA_BEGIN
+
+ TEST_DATA
+
+tdat:
+ .rept 20
+ .word 0xdeadbeef
+ .endr
+
+
+RVTEST_DATA_END