aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2022-07-18 08:21:09 -0700
committerGitHub <noreply@github.com>2022-07-18 08:21:09 -0700
commit3742db886a8ae7b03c5e7e0ececf997a2fc16cfd (patch)
tree9b2a347d0737a7b44eb328874b037e861f8072ae
parent80a078f0d5dd0a9f457d23aaa36a021cd68038dd (diff)
parent43ecb3424d68391e033f4df421c67c7f468fdff6 (diff)
downloadriscv-isa-sim-3742db886a8ae7b03c5e7e0ececf997a2fc16cfd.zip
riscv-isa-sim-3742db886a8ae7b03c5e7e0ececf997a2fc16cfd.tar.gz
riscv-isa-sim-3742db886a8ae7b03c5e7e0ececf997a2fc16cfd.tar.bz2
Merge pull request #1047 from scottj97/fix-misaligned-hlv
Fix misaligned HLV/HLVX/HSV
-rw-r--r--riscv/mmu.h23
1 files changed, 19 insertions, 4 deletions
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 5e776a9..4e12805 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -56,8 +56,15 @@ public:
{
#ifdef RISCV_ENABLE_MISALIGNED
reg_t res = 0;
- for (size_t i = 0; i < size; i++)
- res += (reg_t)load_uint8(addr + (target_big_endian? size-1-i : i)) << (i * 8);
+ for (size_t i = 0; i < size; i++) {
+ const reg_t byteaddr = addr + (target_big_endian? size-1-i : i);
+ const reg_t bytedata
+ = (RISCV_XLATE_VIRT_HLVX & xlate_flags) ? guest_load_x_uint8(byteaddr)
+ : (RISCV_XLATE_VIRT & xlate_flags) ? guest_load_uint8(byteaddr)
+ : load_uint8(byteaddr)
+ ;
+ res += bytedata << (i * 8);
+ }
return res;
#else
bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags);
@@ -68,8 +75,15 @@ public:
inline void misaligned_store(reg_t addr, reg_t data, size_t size, uint32_t xlate_flags, bool actually_store=true)
{
#ifdef RISCV_ENABLE_MISALIGNED
- for (size_t i = 0; i < size; i++)
- store_uint8(addr + (target_big_endian? size-1-i : i), data >> (i * 8), actually_store);
+ for (size_t i = 0; i < size; i++) {
+ const reg_t byteaddr = addr + (target_big_endian? size-1-i : i);
+ const reg_t bytedata = data >> (i * 8);
+ if (RISCV_XLATE_VIRT & xlate_flags) {
+ guest_store_uint8(byteaddr, bytedata, actually_store);
+ } else {
+ store_uint8(byteaddr, bytedata, actually_store);
+ }
+ }
#else
bool gva = ((proc) ? proc->state.v : false) || (RISCV_XLATE_VIRT & xlate_flags);
throw trap_store_address_misaligned(gva, addr, 0, 0);
@@ -123,6 +137,7 @@ public:
load_func(uint16, guest_load, RISCV_XLATE_VIRT)
load_func(uint32, guest_load, RISCV_XLATE_VIRT)
load_func(uint64, guest_load, RISCV_XLATE_VIRT)
+ load_func(uint8, guest_load_x, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX) // only for use by misaligned HLVX
load_func(uint16, guest_load_x, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX)
load_func(uint32, guest_load_x, RISCV_XLATE_VIRT|RISCV_XLATE_VIRT_HLVX)