Make ma_addr test work for systems with misaligned ld/st
authorAndrew Waterman <andrew@sifive.com>
Thu, 6 Apr 2017 04:45:34 +0000 (21:45 -0700)
committerAndrew Waterman <andrew@sifive.com>
Thu, 6 Apr 2017 04:45:34 +0000 (21:45 -0700)
isa/rv64mi/ma_addr.S

index ba96606335e9acd6322cbaf2eb8502d508489d09..1e5ab6888bd889357dc733306c5d8d9e3a0573c9 100644 (file)
@@ -20,48 +20,73 @@ RVTEST_CODE_BEGIN
   # indicate it's a load test
   li s1, CAUSE_MISALIGNED_LOAD
 
   # indicate it's a load test
   li s1, CAUSE_MISALIGNED_LOAD
 
-#define MISALIGNED_LDST_TEST(testnum, insn, base, offset) \
+#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; \
   li TESTNUM, testnum; \
+  la t2, 1f; \
   addi t1, base, offset; \
   addi t1, base, offset; \
-  insn x0, offset(base); \
-  j fail \
+  insn t1, offset(base); \
+  li t2, res; \
+  bne t1, t2, fail; \
+1:
 
 
-  MISALIGNED_LDST_TEST(2,  lh,  s0, 1)
-  MISALIGNED_LDST_TEST(3,  lhu, s0, 1)
-  MISALIGNED_LDST_TEST(4,  lw,  s0, 1)
-  MISALIGNED_LDST_TEST(5,  lw,  s0, 2)
-  MISALIGNED_LDST_TEST(6,  lw,  s0, 3)
+  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
 
 #if __riscv_xlen == 64
-  MISALIGNED_LDST_TEST(7,  lwu, s0, 1)
-  MISALIGNED_LDST_TEST(8,  lwu, s0, 2)
-  MISALIGNED_LDST_TEST(9,  lwu, s0, 3)
-
-  MISALIGNED_LDST_TEST(10, ld, s0, 1)
-  MISALIGNED_LDST_TEST(11, ld, s0, 2)
-  MISALIGNED_LDST_TEST(12, ld, s0, 3)
-  MISALIGNED_LDST_TEST(13, ld, s0, 4)
-  MISALIGNED_LDST_TEST(14, ld, s0, 5)
-  MISALIGNED_LDST_TEST(15, ld, s0, 6)
-  MISALIGNED_LDST_TEST(16, ld, s0, 7)
+  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
 
 #endif
 
   # indicate it's a store test
   li s1, CAUSE_MISALIGNED_STORE
 
-  MISALIGNED_LDST_TEST(22,  sh,  s0, 1)
-  MISALIGNED_LDST_TEST(23,  sw,  s0, 1)
-  MISALIGNED_LDST_TEST(24,  sw,  s0, 2)
-  MISALIGNED_LDST_TEST(25,  sw,  s0, 3)
+/* 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
 
 #if __riscv_xlen == 64
-  MISALIGNED_LDST_TEST(26, sd, s0, 1)
-  MISALIGNED_LDST_TEST(27, sd, s0, 2)
-  MISALIGNED_LDST_TEST(28, sd, s0, 3)
-  MISALIGNED_LDST_TEST(29, sd, s0, 4)
-  MISALIGNED_LDST_TEST(30, sd, s0, 5)
-  MISALIGNED_LDST_TEST(31, sd, s0, 6)
-  MISALIGNED_LDST_TEST(32, sd, s0, 7)
+  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
 #endif
 
   TEST_PASSFAIL
@@ -74,9 +99,10 @@ mtvec_handler:
   csrr t0, mbadaddr
   bne t0, t1, fail
 
   csrr t0, mbadaddr
   bne t0, t1, fail
 
-  csrr t0, mepc
-  addi t0, t0, 8
-  csrw mepc, t0
+  lb t0, (t0)
+  beqz t0, fail
+
+  csrw mepc, t2
   mret
 
 RVTEST_CODE_END
   mret
 
 RVTEST_CODE_END
@@ -85,7 +111,13 @@ RVTEST_CODE_END
 RVTEST_DATA_BEGIN
 
 data:
 RVTEST_DATA_BEGIN
 
 data:
-  .dword 0
+  .align 3
+.word 0xaabbccdd
+.word 0x66778899
+.word 0x22334455
+.word 0xeeffee11
+.fill 0xff, 1, 80
+
 
   TEST_DATA
 
 
   TEST_DATA