blob: 7d2adec9178582c0194f3c1a88506b77a36cd013 [file] [log] [blame]
# See LICENSE for license details.
#*****************************************************************************
# ma_fetch.S
#-----------------------------------------------------------------------------
#
# Test misaligned fetch trap.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64S
RVTEST_CODE_BEGIN
#ifdef __MACHINE_MODE
#define sscratch mscratch
#define sstatus mstatus
#define scause mcause
#define sbadaddr mbadaddr
#define sepc mepc
#define sret mret
#define stvec_handler mtvec_handler
#endif
.align 2
.option norvc
# Without RVC, the jalr should trap, and the handler will skip ahead.
# With RVC, the jalr should not trap, and "j fail" should get skipped.
li TESTNUM, 2
li t1, 0
la t0, 1f
jalr t1, t0, 2
1:
.option rvc
c.j 1f
c.j 2f
.option norvc
1:
j fail
2:
// This test should pass, since JALR ignores the target LSB
li TESTNUM, 3
la t0, 1f
jalr t1, t0, 1
1:
j 1f
j fail
1:
li TESTNUM, 4
li t1, 0
la t0, 1f
jalr t1, t0, 3
1:
.option rvc
c.j 1f
c.j 2f
.option norvc
1:
j fail
2:
# Like test 2, but with jal instead of jalr.
li TESTNUM, 5
li t1, 0
la t0, 1f
jal t1, 2f
1:
.option rvc
c.j 1f
2:
c.j 2f
.option norvc
1:
j fail
2:
# Like test 2, but with a taken branch instead of jalr.
li TESTNUM, 6
li t1, 0
la t0, 1f
beqz x0, 2f
1:
.option rvc
c.j 1f
2:
c.j 2f
.option norvc
1:
j fail
2:
# Not-taken branches should not trap, even without RVC.
li TESTNUM, 7
bnez x0, 1f
j 2f
.option rvc
c.j 1f
1:
c.j 1f
.option norvc
1:
j fail
2:
#ifdef __MACHINE_MODE
# RVC cannot be disabled if doing so would cause a misaligned instruction
# exception on the next instruction fetch. (This test assumes no other
# extensions that support misalignment are present.)
li TESTNUM, 8
csrr t2, misa
andi t2, t2, 1 << ('c' - 'a')
beqz t2, 2f
.option rvc
c.nop
csrci misa, 1 << ('c' - 'a')
1:
c.nop
.option norvc
csrr t2, misa
andi t2, t2, 1 << ('c' - 'a')
beqz t2, fail
# When RVC is disabled, mret to a misaligned mepc should succeed,
# masking off mepc[1].
la t0, 1f
addi t0, t0, -2
csrw mepc, t0
# Try to disable RVC; if it can't be disabled, skip the test.
csrci misa, 1 << ('c' - 'a')
csrr t2, misa
andi t2, t2, 1 << ('c' - 'a')
bnez t2, 2f
li t2, MSTATUS_MPP
csrs mstatus, t2
mret
# mret should transfer control to this branch. Otherwise, it will
# transfer control two bytes into the branch, which happens to be the
# illegal instruction c.unimp.
beqz x0, 1f
1:
csrsi misa, 1 << ('c' - 'a')
2:
#endif
j pass
TEST_PASSFAIL
.align 2
.global stvec_handler
stvec_handler:
# tests 2, 4, 5, 6, and 8 should trap
li a0, 2
beq TESTNUM, a0, 1f
li a0, 4
beq TESTNUM, a0, 1f
li a0, 5
beq TESTNUM, a0, 1f
li a0, 6
beq TESTNUM, a0, 1f
j fail
1:
# verify that return address was not written
bnez t1, fail
# verify trap cause
li a1, CAUSE_MISALIGNED_FETCH
csrr a0, scause
bne a0, a1, fail
# verify that epc == &jalr (== t0 - 4)
csrr a1, sepc
addi a1, a1, 4
bne t0, a1, fail
# verify that badaddr == 0 or badaddr == t0+2.
csrr a0, sbadaddr
beqz a0, 1f
addi a0, a0, -2
bne a0, t0, fail
1:
addi a1, a1, 12
csrw sepc, a1
sret
RVTEST_CODE_END
.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END