aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2024-04-30 15:31:33 -0700
committerAndrew Waterman <andrew@sifive.com>2024-05-20 18:37:48 -0700
commit10a0b7b1b0b261d83319c28657268d05c5b65de0 (patch)
tree6ab7e9beb7057e00aaf329068d7a0661e13109a2
parentbd29db434d09401375fa7550b547377b54dd01ef (diff)
downloadpk-10a0b7b1b0b261d83319c28657268d05c5b65de0.zip
pk-10a0b7b1b0b261d83319c28657268d05c5b65de0.tar.gz
pk-10a0b7b1b0b261d83319c28657268d05c5b65de0.tar.bz2
Support emulation of misaligned FLH/FSH
-rw-r--r--machine/misaligned_ldst.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/machine/misaligned_ldst.c b/machine/misaligned_ldst.c
index a421672..bc3e876 100644
--- a/machine/misaligned_ldst.c
+++ b/machine/misaligned_ldst.c
@@ -10,6 +10,7 @@
union byte_array {
uint8_t bytes[8];
uintptr_t intx;
+ uint16_t int16;
uint32_t int32;
uint64_t int64;
};
@@ -36,6 +37,8 @@ void misaligned_load_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
fp = 1, len = 8;
else if ((insn & MASK_FLW) == MATCH_FLW)
fp = 1, len = 4;
+ else if ((insn & MASK_FLH) == MATCH_FLH)
+ fp = 1, len = 2;
#endif
else if ((insn & MASK_LH) == MATCH_LH)
len = 2, shift = 8*(sizeof(uintptr_t) - len);
@@ -83,8 +86,10 @@ void misaligned_load_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
#endif
else if (len == 8)
SET_F64_RD(insn, regs, val.int64);
- else
+ else if (len == 4)
SET_F32_RD(insn, regs, val.int32);
+ else
+ SET_F32_RD(insn, regs, val.int16 | 0xffff0000U);
write_csr(mepc, npc);
}
@@ -109,6 +114,8 @@ void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc)
len = 8, val.int64 = GET_F64_RS2(insn, regs);
else if ((insn & MASK_FSW) == MATCH_FSW)
len = 4, val.intx = GET_F32_RS2(insn, regs);
+ else if ((insn & MASK_FSH) == MATCH_FSH)
+ len = 2, val.intx = GET_F32_RS2(insn, regs);
#endif
else if ((insn & MASK_SH) == MATCH_SH)
len = 2;