diff options
Diffstat (limited to 'machine/misaligned_ldst.c')
-rw-r--r-- | machine/misaligned_ldst.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/machine/misaligned_ldst.c b/machine/misaligned_ldst.c index a187d25..707de2a 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; + uint32_t int32; uint64_t int64; }; @@ -75,11 +76,15 @@ void misaligned_load_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) val.bytes[i] = load_uint8_t((void *)(addr + i), mepc); if (!fp) +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ SET_RD(insn, regs, (intptr_t)val.intx << shift >> shift); +#else + SET_RD(insn, regs, (intptr_t)val.intx >> shift); +#endif else if (len == 8) SET_F64_RD(insn, regs, val.int64); else - SET_F32_RD(insn, regs, val.intx); + SET_F32_RD(insn, regs, val.int32); write_csr(mepc, npc); } @@ -138,8 +143,13 @@ void misaligned_store_trap(uintptr_t* regs, uintptr_t mcause, uintptr_t mepc) } uintptr_t addr = read_csr(mbadaddr); +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + intptr_t offs = (len == 8? 0 : sizeof(val.intx) - len); +#else + intptr_t offs = 0; +#endif for (int i = 0; i < len; i++) - store_uint8_t((void *)(addr + i), val.bytes[i], mepc); + store_uint8_t((void *)(addr + i), val.bytes[offs + i], mepc); write_csr(mepc, npc); } |