Given the side effects they have, the csr instructions are realized as helpers. We extend this existing infrastructure for 128-bit sized csr. We have a slight issue with returning 128-bit values: we use the globals we added to support div/rem insns to that end. Theses helpers all call a unique function that is currently a stub. The trans_csrxx functions supporting 128-bit are yet to be implemented.
Signed-off-by: Frédéric Pétrot <frederic.pet...@univ-grenoble-alpes.fr> Co-authored-by: Fabien Portas <fabien.por...@grenoble-inp.org> --- target/riscv/cpu.h | 4 ++++ target/riscv/helper.h | 3 +++ target/riscv/csr.c | 7 +++++++ target/riscv/op_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 27ec4fec63..eb4f63fcbf 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -470,6 +470,10 @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno, target_ulong new_value, target_ulong write_mask); +RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, + Int128 *ret_value, + Int128 new_value, Int128 write_mask); + typedef struct { const char *name; riscv_csr_predicate_fn predicate; diff --git a/target/riscv/helper.h b/target/riscv/helper.h index 67f5d23692..e27bdb9075 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -66,6 +66,9 @@ DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) DEF_HELPER_2(csrr, tl, env, int) DEF_HELPER_3(csrw, void, env, int, tl) DEF_HELPER_4(csrrw, tl, env, int, tl, tl) +DEF_HELPER_2(csrr_i128, void, env, int) +DEF_HELPER_4(csrw_i128, void, env, int, tl, tl) +DEF_HELPER_6(csrrw_i128, void, env, int, tl, tl, tl, tl) #ifndef CONFIG_USER_ONLY DEF_HELPER_2(sret, tl, env, tl) DEF_HELPER_2(mret, tl, env, tl) diff --git a/target/riscv/csr.c b/target/riscv/csr.c index 69e4d65fcd..b802ee0dbc 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -1516,6 +1516,13 @@ RISCVException riscv_csrrw(CPURISCVState *env, int csrno, return RISCV_EXCP_NONE; } +RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno, + Int128 *ret_value, + Int128 new_value, Int128 write_mask) +{ + return RISCV_EXCP_ILLEGAL_INST; +} + /* * Debugger support. If not in user mode, set env->debugger before the * riscv_csrrw call and clear it after the call. diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index ee7c24efe7..753eb35000 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -69,6 +69,50 @@ target_ulong helper_csrrw(CPURISCVState *env, int csr, return val; } +void helper_csrr_i128(CPURISCVState *env, int csr) +{ + Int128 rv = int128_zero(); + RISCVException ret = riscv_csrrw_i128(env, csr, &rv, + int128_zero(), + int128_zero()); + + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, GETPC()); + } + + env->hlpr[0] = int128_getlo(rv); + env->hlpr[1] = int128_gethi(rv); +} + +void helper_csrw_i128(CPURISCVState *env, int csr, + target_ulong srcl, target_ulong srch) +{ + RISCVException ret = riscv_csrrw_i128(env, csr, NULL, + int128_make128(srcl, srch), + UINT128_MAX); + + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, GETPC()); + } +} + +void helper_csrrw_i128(CPURISCVState *env, int csr, + target_ulong srcl, target_ulong srch, + target_ulong maskl, target_ulong maskh) +{ + Int128 rv = int128_zero(); + RISCVException ret = riscv_csrrw_i128(env, csr, &rv, + int128_make128(srcl, srch), + int128_make128(maskl, maskh)); + + if (ret != RISCV_EXCP_NONE) { + riscv_raise_exception(env, ret, GETPC()); + } + + env->hlpr[0] = int128_getlo(rv); + env->hlpr[1] = int128_gethi(rv); +} + #ifndef CONFIG_USER_ONLY target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) -- 2.33.0