You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.6 KiB
67 lines
1.6 KiB
#include "fp_emulation.h"
|
|
#include "unprivileged_memory.h"
|
|
|
|
DECLARE_EMULATION_FUNC(emulate_float_load)
|
|
{
|
|
uint64_t val;
|
|
uintptr_t addr = GET_RS1(insn, regs) + IMM_I(insn);
|
|
|
|
switch (insn & MASK_FUNCT3)
|
|
{
|
|
case MATCH_FLW & MASK_FUNCT3:
|
|
if (addr % 4 != 0)
|
|
return misaligned_load_trap(regs, mcause, mepc);
|
|
|
|
SET_F32_RD(insn, regs, load_int32_t((void *)addr, mepc));
|
|
break;
|
|
|
|
case MATCH_FLD & MASK_FUNCT3:
|
|
if (addr % sizeof(uintptr_t) != 0)
|
|
return misaligned_load_trap(regs, mcause, mepc);
|
|
|
|
#ifdef __riscv64
|
|
val = load_uint64_t((void *)addr, mepc);
|
|
#else
|
|
val = load_uint32_t((void *)addr, mepc);
|
|
val += (uint64_t)load_uint32_t((void *)(addr + 4), mepc) << 32;
|
|
#endif
|
|
SET_F64_RD(insn, regs, val);
|
|
break;
|
|
|
|
default:
|
|
return truly_illegal_insn(regs, mcause, mepc, mstatus, insn);
|
|
}
|
|
}
|
|
|
|
DECLARE_EMULATION_FUNC(emulate_float_store)
|
|
{
|
|
uint64_t val;
|
|
uintptr_t addr = GET_RS1(insn, regs) + IMM_S(insn);
|
|
|
|
switch (insn & MASK_FUNCT3)
|
|
{
|
|
case MATCH_FSW & MASK_FUNCT3:
|
|
if (addr % 4 != 0)
|
|
return misaligned_store_trap(regs, mcause, mepc);
|
|
|
|
store_uint32_t((void *)addr, GET_F32_RS2(insn, regs), mepc);
|
|
break;
|
|
|
|
case MATCH_FSD & MASK_FUNCT3:
|
|
if (addr % sizeof(uintptr_t) != 0)
|
|
return misaligned_store_trap(regs, mcause, mepc);
|
|
|
|
val = GET_F64_RS2(insn, regs);
|
|
#ifdef __riscv64
|
|
store_uint64_t((void *)addr, val, mepc);
|
|
#else
|
|
store_uint32_t((void *)addr, val, mepc);
|
|
store_uint32_t((void *)(addr + 4), val >> 32, mepc);
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
return truly_illegal_insn(regs, mcause, mepc, mstatus, insn);
|
|
}
|
|
}
|
|
|
|
|