diff --git a/include/unicorn/riscv.h b/include/unicorn/riscv.h index c71446e2..3305b081 100644 --- a/include/unicorn/riscv.h +++ b/include/unicorn/riscv.h @@ -68,6 +68,133 @@ typedef enum uc_riscv_reg { UC_RISCV_REG_X30, UC_RISCV_REG_X31, + //> RISCV CSR + UC_RISCV_REG_USTATUS, + UC_RISCV_REG_UIE, + UC_RISCV_REG_UTVEC, + UC_RISCV_REG_USCRATCH, + UC_RISCV_REG_UEPC, + UC_RISCV_REG_UCAUSE, + UC_RISCV_REG_UTVAL, + UC_RISCV_REG_UIP, + UC_RISCV_REG_FFLAGS, + UC_RISCV_REG_FRM, + UC_RISCV_REG_FCSR, + UC_RISCV_REG_CYCLE, + UC_RISCV_REG_TIME, + UC_RISCV_REG_INSTRET, + UC_RISCV_REG_HPMCOUNTER3, + UC_RISCV_REG_HPMCOUNTER4, + UC_RISCV_REG_HPMCOUNTER5, + UC_RISCV_REG_HPMCOUNTER6, + UC_RISCV_REG_HPMCOUNTER7, + UC_RISCV_REG_HPMCOUNTER8, + UC_RISCV_REG_HPMCOUNTER9, + UC_RISCV_REG_HPMCOUNTER10, + UC_RISCV_REG_HPMCOUNTER11, + UC_RISCV_REG_HPMCOUNTER12, + UC_RISCV_REG_HPMCOUNTER13, + UC_RISCV_REG_HPMCOUNTER14, + UC_RISCV_REG_HPMCOUNTER15, + UC_RISCV_REG_HPMCOUNTER16, + UC_RISCV_REG_HPMCOUNTER17, + UC_RISCV_REG_HPMCOUNTER18, + UC_RISCV_REG_HPMCOUNTER19, + UC_RISCV_REG_HPMCOUNTER20, + UC_RISCV_REG_HPMCOUNTER21, + UC_RISCV_REG_HPMCOUNTER22, + UC_RISCV_REG_HPMCOUNTER23, + UC_RISCV_REG_HPMCOUNTER24, + UC_RISCV_REG_HPMCOUNTER25, + UC_RISCV_REG_HPMCOUNTER26, + UC_RISCV_REG_HPMCOUNTER27, + UC_RISCV_REG_HPMCOUNTER28, + UC_RISCV_REG_HPMCOUNTER29, + UC_RISCV_REG_HPMCOUNTER30, + UC_RISCV_REG_HPMCOUNTER31, + UC_RISCV_REG_CYCLEH, + UC_RISCV_REG_TIMEH, + UC_RISCV_REG_INSTRETH, + UC_RISCV_REG_HPMCOUNTER3H, + UC_RISCV_REG_HPMCOUNTER4H, + UC_RISCV_REG_HPMCOUNTER5H, + UC_RISCV_REG_HPMCOUNTER6H, + UC_RISCV_REG_HPMCOUNTER7H, + UC_RISCV_REG_HPMCOUNTER8H, + UC_RISCV_REG_HPMCOUNTER9H, + UC_RISCV_REG_HPMCOUNTER10H, + UC_RISCV_REG_HPMCOUNTER11H, + UC_RISCV_REG_HPMCOUNTER12H, + UC_RISCV_REG_HPMCOUNTER13H, + UC_RISCV_REG_HPMCOUNTER14H, + UC_RISCV_REG_HPMCOUNTER15H, + UC_RISCV_REG_HPMCOUNTER16H, + UC_RISCV_REG_HPMCOUNTER17H, + UC_RISCV_REG_HPMCOUNTER18H, + UC_RISCV_REG_HPMCOUNTER19H, + UC_RISCV_REG_HPMCOUNTER20H, + UC_RISCV_REG_HPMCOUNTER21H, + UC_RISCV_REG_HPMCOUNTER22H, + UC_RISCV_REG_HPMCOUNTER23H, + UC_RISCV_REG_HPMCOUNTER24H, + UC_RISCV_REG_HPMCOUNTER25H, + UC_RISCV_REG_HPMCOUNTER26H, + UC_RISCV_REG_HPMCOUNTER27H, + UC_RISCV_REG_HPMCOUNTER28H, + UC_RISCV_REG_HPMCOUNTER29H, + UC_RISCV_REG_HPMCOUNTER30H, + UC_RISCV_REG_HPMCOUNTER31H, + UC_RISCV_REG_MCYCLE, + UC_RISCV_REG_MINSTRET, + UC_RISCV_REG_MCYCLEH, + UC_RISCV_REG_MINSTRETH, + UC_RISCV_REG_MVENDORID, + UC_RISCV_REG_MARCHID, + UC_RISCV_REG_MIMPID, + UC_RISCV_REG_MHARTID, + UC_RISCV_REG_MSTATUS, + UC_RISCV_REG_MISA, + UC_RISCV_REG_MEDELEG, + UC_RISCV_REG_MIDELEG, + UC_RISCV_REG_MIE, + UC_RISCV_REG_MTVEC, + UC_RISCV_REG_MCOUNTEREN, + UC_RISCV_REG_MSTATUSH, + UC_RISCV_REG_MUCOUNTEREN, + UC_RISCV_REG_MSCOUNTEREN, + UC_RISCV_REG_MHCOUNTEREN, + UC_RISCV_REG_MSCRATCH, + UC_RISCV_REG_MEPC, + UC_RISCV_REG_MCAUSE, + UC_RISCV_REG_MTVAL, + UC_RISCV_REG_MIP, + UC_RISCV_REG_MBADADDR, + UC_RISCV_REG_SSTATUS, + UC_RISCV_REG_SEDELEG, + UC_RISCV_REG_SIDELEG, + UC_RISCV_REG_SIE, + UC_RISCV_REG_STVEC, + UC_RISCV_REG_SCOUNTEREN, + UC_RISCV_REG_SSCRATCH, + UC_RISCV_REG_SEPC, + UC_RISCV_REG_SCAUSE, + UC_RISCV_REG_STVAL, + UC_RISCV_REG_SIP, + UC_RISCV_REG_SBADADDR, + UC_RISCV_REG_SPTBR, + UC_RISCV_REG_SATP, + UC_RISCV_REG_HSTATUS, + UC_RISCV_REG_HEDELEG, + UC_RISCV_REG_HIDELEG, + UC_RISCV_REG_HIE, + UC_RISCV_REG_HCOUNTEREN, + UC_RISCV_REG_HTVAL, + UC_RISCV_REG_HIP, + UC_RISCV_REG_HTINST, + UC_RISCV_REG_HGATP, + UC_RISCV_REG_HTIMEDELTA, + UC_RISCV_REG_HTIMEDELTAH, + //> Floating-point registers UC_RISCV_REG_F0, // "ft0" UC_RISCV_REG_F1, // "ft1" diff --git a/qemu/target/riscv/unicorn.c b/qemu/target/riscv/unicorn.c index 1badb57a..82c4826d 100644 --- a/qemu/target/riscv/unicorn.c +++ b/qemu/target/riscv/unicorn.c @@ -10,6 +10,41 @@ #include #include "unicorn.h" +static int csrno_map[] = { + CSR_USTATUS, CSR_UIE, CSR_UTVEC, CSR_USCRATCH, + CSR_UEPC, CSR_UCAUSE, CSR_UTVAL, CSR_UIP, + CSR_FFLAGS, CSR_FRM, CSR_FCSR, CSR_CYCLE, + CSR_TIME, CSR_INSTRET, CSR_HPMCOUNTER3, CSR_HPMCOUNTER4, + CSR_HPMCOUNTER5, CSR_HPMCOUNTER6, CSR_HPMCOUNTER7, CSR_HPMCOUNTER8, + CSR_HPMCOUNTER9, CSR_HPMCOUNTER10, CSR_HPMCOUNTER11, CSR_HPMCOUNTER12, + CSR_HPMCOUNTER13, CSR_HPMCOUNTER14, CSR_HPMCOUNTER15, CSR_HPMCOUNTER16, + CSR_HPMCOUNTER17, CSR_HPMCOUNTER18, CSR_HPMCOUNTER19, CSR_HPMCOUNTER20, + CSR_HPMCOUNTER21, CSR_HPMCOUNTER22, CSR_HPMCOUNTER23, CSR_HPMCOUNTER24, + CSR_HPMCOUNTER25, CSR_HPMCOUNTER26, CSR_HPMCOUNTER27, CSR_HPMCOUNTER28, + CSR_HPMCOUNTER29, CSR_HPMCOUNTER30, CSR_HPMCOUNTER31, CSR_CYCLEH, + CSR_TIMEH, CSR_INSTRETH, CSR_HPMCOUNTER3H, CSR_HPMCOUNTER4H, + CSR_HPMCOUNTER5H, CSR_HPMCOUNTER6H, CSR_HPMCOUNTER7H, CSR_HPMCOUNTER8H, + CSR_HPMCOUNTER9H, CSR_HPMCOUNTER10H, CSR_HPMCOUNTER11H, CSR_HPMCOUNTER12H, + CSR_HPMCOUNTER13H, CSR_HPMCOUNTER14H, CSR_HPMCOUNTER15H, CSR_HPMCOUNTER16H, + CSR_HPMCOUNTER17H, CSR_HPMCOUNTER18H, CSR_HPMCOUNTER19H, CSR_HPMCOUNTER20H, + CSR_HPMCOUNTER21H, CSR_HPMCOUNTER22H, CSR_HPMCOUNTER23H, CSR_HPMCOUNTER24H, + CSR_HPMCOUNTER25H, CSR_HPMCOUNTER26H, CSR_HPMCOUNTER27H, CSR_HPMCOUNTER28H, + CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H, CSR_MCYCLE, + CSR_MINSTRET, CSR_MCYCLEH, CSR_MINSTRETH, CSR_MVENDORID, + CSR_MARCHID, CSR_MIMPID, CSR_MHARTID, CSR_MSTATUS, + CSR_MISA, CSR_MEDELEG, CSR_MIDELEG, CSR_MIE, + CSR_MTVEC, CSR_MCOUNTEREN, CSR_MSTATUSH, CSR_MUCOUNTEREN, + CSR_MSCOUNTEREN, CSR_MHCOUNTEREN, CSR_MSCRATCH, CSR_MEPC, + CSR_MCAUSE, CSR_MTVAL, CSR_MIP, CSR_MBADADDR, + CSR_SSTATUS, CSR_SEDELEG, CSR_SIDELEG, CSR_SIE, + CSR_STVEC, CSR_SCOUNTEREN, CSR_SSCRATCH, CSR_SEPC, + CSR_SCAUSE, CSR_STVAL, CSR_SIP, CSR_SBADADDR, + CSR_SPTBR, CSR_SATP, CSR_HSTATUS, CSR_HEDELEG, + CSR_HIDELEG, CSR_HIE, CSR_HCOUNTEREN, CSR_HTVAL, + CSR_HIP, CSR_HTINST, CSR_HGATP, CSR_HTIMEDELTA, + CSR_HTIMEDELTAH, +}; + RISCVCPU *cpu_riscv_init(struct uc_struct *uc); static void riscv_set_pc(struct uc_struct *uc, uint64_t address) @@ -125,6 +160,141 @@ static void reg_read(CPURISCVState *env, unsigned int regid, void *value) *(int32_t *)value = env->fpr[regid - UC_RISCV_REG_F0]; #endif break; + case UC_RISCV_REG_USTATUS: + case UC_RISCV_REG_UIE: + case UC_RISCV_REG_UTVEC: + case UC_RISCV_REG_USCRATCH: + case UC_RISCV_REG_UEPC: + case UC_RISCV_REG_UCAUSE: + case UC_RISCV_REG_UTVAL: + case UC_RISCV_REG_UIP: + case UC_RISCV_REG_FFLAGS: + case UC_RISCV_REG_FRM: + case UC_RISCV_REG_FCSR: + case UC_RISCV_REG_CYCLE: + case UC_RISCV_REG_TIME: + case UC_RISCV_REG_INSTRET: + case UC_RISCV_REG_HPMCOUNTER3: + case UC_RISCV_REG_HPMCOUNTER4: + case UC_RISCV_REG_HPMCOUNTER5: + case UC_RISCV_REG_HPMCOUNTER6: + case UC_RISCV_REG_HPMCOUNTER7: + case UC_RISCV_REG_HPMCOUNTER8: + case UC_RISCV_REG_HPMCOUNTER9: + case UC_RISCV_REG_HPMCOUNTER10: + case UC_RISCV_REG_HPMCOUNTER11: + case UC_RISCV_REG_HPMCOUNTER12: + case UC_RISCV_REG_HPMCOUNTER13: + case UC_RISCV_REG_HPMCOUNTER14: + case UC_RISCV_REG_HPMCOUNTER15: + case UC_RISCV_REG_HPMCOUNTER16: + case UC_RISCV_REG_HPMCOUNTER17: + case UC_RISCV_REG_HPMCOUNTER18: + case UC_RISCV_REG_HPMCOUNTER19: + case UC_RISCV_REG_HPMCOUNTER20: + case UC_RISCV_REG_HPMCOUNTER21: + case UC_RISCV_REG_HPMCOUNTER22: + case UC_RISCV_REG_HPMCOUNTER23: + case UC_RISCV_REG_HPMCOUNTER24: + case UC_RISCV_REG_HPMCOUNTER25: + case UC_RISCV_REG_HPMCOUNTER26: + case UC_RISCV_REG_HPMCOUNTER27: + case UC_RISCV_REG_HPMCOUNTER28: + case UC_RISCV_REG_HPMCOUNTER29: + case UC_RISCV_REG_HPMCOUNTER30: + case UC_RISCV_REG_HPMCOUNTER31: + case UC_RISCV_REG_CYCLEH: + case UC_RISCV_REG_TIMEH: + case UC_RISCV_REG_INSTRETH: + case UC_RISCV_REG_HPMCOUNTER3H: + case UC_RISCV_REG_HPMCOUNTER4H: + case UC_RISCV_REG_HPMCOUNTER5H: + case UC_RISCV_REG_HPMCOUNTER6H: + case UC_RISCV_REG_HPMCOUNTER7H: + case UC_RISCV_REG_HPMCOUNTER8H: + case UC_RISCV_REG_HPMCOUNTER9H: + case UC_RISCV_REG_HPMCOUNTER10H: + case UC_RISCV_REG_HPMCOUNTER11H: + case UC_RISCV_REG_HPMCOUNTER12H: + case UC_RISCV_REG_HPMCOUNTER13H: + case UC_RISCV_REG_HPMCOUNTER14H: + case UC_RISCV_REG_HPMCOUNTER15H: + case UC_RISCV_REG_HPMCOUNTER16H: + case UC_RISCV_REG_HPMCOUNTER17H: + case UC_RISCV_REG_HPMCOUNTER18H: + case UC_RISCV_REG_HPMCOUNTER19H: + case UC_RISCV_REG_HPMCOUNTER20H: + case UC_RISCV_REG_HPMCOUNTER21H: + case UC_RISCV_REG_HPMCOUNTER22H: + case UC_RISCV_REG_HPMCOUNTER23H: + case UC_RISCV_REG_HPMCOUNTER24H: + case UC_RISCV_REG_HPMCOUNTER25H: + case UC_RISCV_REG_HPMCOUNTER26H: + case UC_RISCV_REG_HPMCOUNTER27H: + case UC_RISCV_REG_HPMCOUNTER28H: + case UC_RISCV_REG_HPMCOUNTER29H: + case UC_RISCV_REG_HPMCOUNTER30H: + case UC_RISCV_REG_HPMCOUNTER31H: + case UC_RISCV_REG_MCYCLE: + case UC_RISCV_REG_MINSTRET: + case UC_RISCV_REG_MCYCLEH: + case UC_RISCV_REG_MINSTRETH: + case UC_RISCV_REG_MVENDORID: + case UC_RISCV_REG_MARCHID: + case UC_RISCV_REG_MIMPID: + case UC_RISCV_REG_MHARTID: + case UC_RISCV_REG_MSTATUS: + case UC_RISCV_REG_MISA: + case UC_RISCV_REG_MEDELEG: + case UC_RISCV_REG_MIDELEG: + case UC_RISCV_REG_MIE: + case UC_RISCV_REG_MTVEC: + case UC_RISCV_REG_MCOUNTEREN: + case UC_RISCV_REG_MSTATUSH: + case UC_RISCV_REG_MUCOUNTEREN: + case UC_RISCV_REG_MSCOUNTEREN: + case UC_RISCV_REG_MHCOUNTEREN: + case UC_RISCV_REG_MSCRATCH: + case UC_RISCV_REG_MEPC: + case UC_RISCV_REG_MCAUSE: + case UC_RISCV_REG_MTVAL: + case UC_RISCV_REG_MIP: + case UC_RISCV_REG_MBADADDR: + case UC_RISCV_REG_SSTATUS: + case UC_RISCV_REG_SEDELEG: + case UC_RISCV_REG_SIDELEG: + case UC_RISCV_REG_SIE: + case UC_RISCV_REG_STVEC: + case UC_RISCV_REG_SCOUNTEREN: + case UC_RISCV_REG_SSCRATCH: + case UC_RISCV_REG_SEPC: + case UC_RISCV_REG_SCAUSE: + case UC_RISCV_REG_STVAL: + case UC_RISCV_REG_SIP: + case UC_RISCV_REG_SBADADDR: + case UC_RISCV_REG_SPTBR: + case UC_RISCV_REG_SATP: + case UC_RISCV_REG_HSTATUS: + case UC_RISCV_REG_HEDELEG: + case UC_RISCV_REG_HIDELEG: + case UC_RISCV_REG_HIE: + case UC_RISCV_REG_HCOUNTEREN: + case UC_RISCV_REG_HTVAL: + case UC_RISCV_REG_HIP: + case UC_RISCV_REG_HTINST: + case UC_RISCV_REG_HGATP: + case UC_RISCV_REG_HTIMEDELTA: + case UC_RISCV_REG_HTIMEDELTAH: { + target_ulong val; + int csrno = csrno_map[regid - UC_RISCV_REG_USTATUS]; + riscv_csrrw(env, csrno, &val, -1, 0); +#ifdef TARGET_RISCV64 + *(uint64_t *)value = (uint64_t)val; +#else + *(uint32_t *)value = (uint32_t)val; +#endif + break; + } default: break; } @@ -218,6 +388,140 @@ static void reg_write(CPURISCVState *env, unsigned int regid, const void *value) env->fpr[regid - UC_RISCV_REG_F0] = *(uint32_t *)value; #endif break; + case UC_RISCV_REG_USTATUS: + case UC_RISCV_REG_UIE: + case UC_RISCV_REG_UTVEC: + case UC_RISCV_REG_USCRATCH: + case UC_RISCV_REG_UEPC: + case UC_RISCV_REG_UCAUSE: + case UC_RISCV_REG_UTVAL: + case UC_RISCV_REG_UIP: + case UC_RISCV_REG_FFLAGS: + case UC_RISCV_REG_FRM: + case UC_RISCV_REG_FCSR: + case UC_RISCV_REG_CYCLE: + case UC_RISCV_REG_TIME: + case UC_RISCV_REG_INSTRET: + case UC_RISCV_REG_HPMCOUNTER3: + case UC_RISCV_REG_HPMCOUNTER4: + case UC_RISCV_REG_HPMCOUNTER5: + case UC_RISCV_REG_HPMCOUNTER6: + case UC_RISCV_REG_HPMCOUNTER7: + case UC_RISCV_REG_HPMCOUNTER8: + case UC_RISCV_REG_HPMCOUNTER9: + case UC_RISCV_REG_HPMCOUNTER10: + case UC_RISCV_REG_HPMCOUNTER11: + case UC_RISCV_REG_HPMCOUNTER12: + case UC_RISCV_REG_HPMCOUNTER13: + case UC_RISCV_REG_HPMCOUNTER14: + case UC_RISCV_REG_HPMCOUNTER15: + case UC_RISCV_REG_HPMCOUNTER16: + case UC_RISCV_REG_HPMCOUNTER17: + case UC_RISCV_REG_HPMCOUNTER18: + case UC_RISCV_REG_HPMCOUNTER19: + case UC_RISCV_REG_HPMCOUNTER20: + case UC_RISCV_REG_HPMCOUNTER21: + case UC_RISCV_REG_HPMCOUNTER22: + case UC_RISCV_REG_HPMCOUNTER23: + case UC_RISCV_REG_HPMCOUNTER24: + case UC_RISCV_REG_HPMCOUNTER25: + case UC_RISCV_REG_HPMCOUNTER26: + case UC_RISCV_REG_HPMCOUNTER27: + case UC_RISCV_REG_HPMCOUNTER28: + case UC_RISCV_REG_HPMCOUNTER29: + case UC_RISCV_REG_HPMCOUNTER30: + case UC_RISCV_REG_HPMCOUNTER31: + case UC_RISCV_REG_CYCLEH: + case UC_RISCV_REG_TIMEH: + case UC_RISCV_REG_INSTRETH: + case UC_RISCV_REG_HPMCOUNTER3H: + case UC_RISCV_REG_HPMCOUNTER4H: + case UC_RISCV_REG_HPMCOUNTER5H: + case UC_RISCV_REG_HPMCOUNTER6H: + case UC_RISCV_REG_HPMCOUNTER7H: + case UC_RISCV_REG_HPMCOUNTER8H: + case UC_RISCV_REG_HPMCOUNTER9H: + case UC_RISCV_REG_HPMCOUNTER10H: + case UC_RISCV_REG_HPMCOUNTER11H: + case UC_RISCV_REG_HPMCOUNTER12H: + case UC_RISCV_REG_HPMCOUNTER13H: + case UC_RISCV_REG_HPMCOUNTER14H: + case UC_RISCV_REG_HPMCOUNTER15H: + case UC_RISCV_REG_HPMCOUNTER16H: + case UC_RISCV_REG_HPMCOUNTER17H: + case UC_RISCV_REG_HPMCOUNTER18H: + case UC_RISCV_REG_HPMCOUNTER19H: + case UC_RISCV_REG_HPMCOUNTER20H: + case UC_RISCV_REG_HPMCOUNTER21H: + case UC_RISCV_REG_HPMCOUNTER22H: + case UC_RISCV_REG_HPMCOUNTER23H: + case UC_RISCV_REG_HPMCOUNTER24H: + case UC_RISCV_REG_HPMCOUNTER25H: + case UC_RISCV_REG_HPMCOUNTER26H: + case UC_RISCV_REG_HPMCOUNTER27H: + case UC_RISCV_REG_HPMCOUNTER28H: + case UC_RISCV_REG_HPMCOUNTER29H: + case UC_RISCV_REG_HPMCOUNTER30H: + case UC_RISCV_REG_HPMCOUNTER31H: + case UC_RISCV_REG_MCYCLE: + case UC_RISCV_REG_MINSTRET: + case UC_RISCV_REG_MCYCLEH: + case UC_RISCV_REG_MINSTRETH: + case UC_RISCV_REG_MVENDORID: + case UC_RISCV_REG_MARCHID: + case UC_RISCV_REG_MIMPID: + case UC_RISCV_REG_MHARTID: + case UC_RISCV_REG_MSTATUS: + case UC_RISCV_REG_MISA: + case UC_RISCV_REG_MEDELEG: + case UC_RISCV_REG_MIDELEG: + case UC_RISCV_REG_MIE: + case UC_RISCV_REG_MTVEC: + case UC_RISCV_REG_MCOUNTEREN: + case UC_RISCV_REG_MSTATUSH: + case UC_RISCV_REG_MUCOUNTEREN: + case UC_RISCV_REG_MSCOUNTEREN: + case UC_RISCV_REG_MHCOUNTEREN: + case UC_RISCV_REG_MSCRATCH: + case UC_RISCV_REG_MEPC: + case UC_RISCV_REG_MCAUSE: + case UC_RISCV_REG_MTVAL: + case UC_RISCV_REG_MIP: + case UC_RISCV_REG_MBADADDR: + case UC_RISCV_REG_SSTATUS: + case UC_RISCV_REG_SEDELEG: + case UC_RISCV_REG_SIDELEG: + case UC_RISCV_REG_SIE: + case UC_RISCV_REG_STVEC: + case UC_RISCV_REG_SCOUNTEREN: + case UC_RISCV_REG_SSCRATCH: + case UC_RISCV_REG_SEPC: + case UC_RISCV_REG_SCAUSE: + case UC_RISCV_REG_STVAL: + case UC_RISCV_REG_SIP: + case UC_RISCV_REG_SBADADDR: + case UC_RISCV_REG_SPTBR: + case UC_RISCV_REG_SATP: + case UC_RISCV_REG_HSTATUS: + case UC_RISCV_REG_HEDELEG: + case UC_RISCV_REG_HIDELEG: + case UC_RISCV_REG_HIE: + case UC_RISCV_REG_HCOUNTEREN: + case UC_RISCV_REG_HTVAL: + case UC_RISCV_REG_HIP: + case UC_RISCV_REG_HTINST: + case UC_RISCV_REG_HGATP: + case UC_RISCV_REG_HTIMEDELTA: + case UC_RISCV_REG_HTIMEDELTAH: { + target_ulong val; + int csrno = csrno_map[regid - UC_RISCV_REG_USTATUS]; +#ifdef TARGET_RISCV64 + riscv_csrrw(env, csrno, &val, *(uint64_t *)value, -1); +#else + riscv_csrrw(env, csrno, &val, *(uint32_t *)value, -1); +#endif + break; + } default: break; } diff --git a/tests/unit/test_riscv.c b/tests/unit/test_riscv.c index 07e8844c..af0d35a1 100644 --- a/tests/unit/test_riscv.c +++ b/tests/unit/test_riscv.c @@ -306,6 +306,37 @@ static void test_riscv64_fp_move_from_int(void) uc_close(uc); } +static void test_riscv64_fp_move_from_int_reg_write(void) +{ + uc_engine *uc; + char code[] = "\x53\x00\x0b\xf2"; // fmvd.d.x ft0, s6 + + uint64_t r_ft0 = 0x12341234; + uint64_t r_s6 = 0x56785678; + uint64_t r_mstatus = 0x6000; + + uc_common_setup(&uc, UC_ARCH_RISCV, UC_MODE_RISCV64, code, + sizeof(code) - 1); + + // initialize machine registers + OK(uc_reg_write(uc, UC_RISCV_REG_FT0, &r_ft0)); + OK(uc_reg_write(uc, UC_RISCV_REG_S6, &r_s6)); + + // mstatus.fs + OK(uc_reg_write(uc, UC_RISCV_REG_MSTATUS, &r_mstatus)); + + // emulate the instruction + OK(uc_emu_start(uc, code_start, -1, 0, 1)); + + OK(uc_reg_read(uc, UC_RISCV_REG_FT0, &r_ft0)); + OK(uc_reg_read(uc, UC_RISCV_REG_S6, &r_s6)); + + TEST_CHECK(r_ft0 == 0x56785678); + TEST_CHECK(r_s6 == 0x56785678); + + OK(uc_close(uc)); +} + static void test_riscv64_fp_move_to_int(void) { uc_engine *uc; @@ -376,6 +407,8 @@ TEST_LIST = {{"test_riscv32_nop", test_riscv32_nop}, {"test_riscv32_fp_move", test_riscv32_fp_move}, {"test_riscv64_fp_move", test_riscv64_fp_move}, {"test_riscv64_fp_move_from_int", test_riscv64_fp_move_from_int}, + {"test_riscv64_fp_move_from_int_reg_write", + test_riscv64_fp_move_from_int_reg_write}, {"test_riscv64_fp_move_to_int", test_riscv64_fp_move_to_int}, {"test_riscv64_ecall", test_riscv64_ecall}, {NULL, NULL}};