diff options
author | Andrew Waterman <andrew@sifive.com> | 2017-07-17 15:02:31 -0700 |
---|---|---|
committer | Andrew Waterman <andrew@sifive.com> | 2017-07-17 15:02:31 -0700 |
commit | 57bb80fb7df07b40295a70a5aca6e110ba4dcbb0 (patch) | |
tree | aa4b0d1ff3ccdab1e7408d1219907cafbeee8219 /machine | |
parent | 66701f82f88d08d3700d8b0bc5d5306abfd0044f (diff) | |
download | pk-57bb80fb7df07b40295a70a5aca6e110ba4dcbb0.zip pk-57bb80fb7df07b40295a70a5aca6e110ba4dcbb0.tar.gz pk-57bb80fb7df07b40295a70a5aca6e110ba4dcbb0.tar.bz2 |
Fix emulation of misaligned RVC loads/stores
We were accidentally advancing the PC by 4, not 2.
Diffstat (limited to 'machine')
-rw-r--r-- | machine/misaligned_ldst.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/machine/misaligned_ldst.c b/machine/misaligned_ldst.c index 8c96c18..2fccd50 100644 --- a/machine/misaligned_ldst.c +++ b/machine/misaligned_ldst.c @@ -3,6 +3,7 @@ #include "unprivileged_memory.h" #include "mtrap.h" #include "config.h" +#include "pk.h" union byte_array { uint8_t bytes[8]; @@ -15,6 +16,7 @@ void misaligned_load_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) union byte_array val; uintptr_t mstatus; insn_t insn = get_insn(mepc, &mstatus); + uintptr_t npc = mepc + insn_len(insn); uintptr_t addr = read_csr(mbadaddr); int shift = 0, fp = 0, len; @@ -74,7 +76,7 @@ void misaligned_load_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) else SET_F32_RD(insn, regs, val.intx); - write_csr(mepc, mepc + 4); + write_csr(mepc, npc); } void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) @@ -82,6 +84,7 @@ void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) union byte_array val; uintptr_t mstatus; insn_t insn = get_insn(mepc, &mstatus); + uintptr_t npc = mepc + insn_len(insn); int len; val.intx = GET_RS2(insn, regs); @@ -130,5 +133,5 @@ void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) for (int i = 0; i < len; i++) store_uint8_t((void *)(addr + i), val.bytes[i], mepc); - write_csr(mepc, mepc + 4); + write_csr(mepc, npc); } |