On Tue, Dec 14, 2021 at 2:46 AM Frédéric Pétrot <frederic.pet...@univ-grenoble-alpes.fr> wrote: > > Given the side effects they have, the csr instructions are realized as > helpers. We extend this existing infrastructure for 128-bit sized csr. > We return 128-bit values using the same approach as for div/rem. > Theses helpers all call a unique function that is currently a fallback > on the 64-bit version. > 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> > Reviewed-by: Richard Henderson <richard.hender...@linaro.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > target/riscv/cpu.h | 5 +++++ > target/riscv/helper.h | 3 +++ > target/riscv/csr.c | 17 ++++++++++++++++ > target/riscv/op_helper.c | 44 ++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 69 insertions(+) > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h > index a7c2e5c93e..00e5081598 100644 > --- a/target/riscv/cpu.h > +++ b/target/riscv/cpu.h > @@ -25,6 +25,7 @@ > #include "exec/cpu-defs.h" > #include "fpu/softfloat-types.h" > #include "qom/object.h" > +#include "qemu/int128.h" > #include "cpu_bits.h" > > #define TCG_GUEST_DEFAULT_MO 0 > @@ -481,6 +482,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 c036825723..bf2b338bfd 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, tl, env, int) > +DEF_HELPER_4(csrw_i128, void, env, int, tl, tl) > +DEF_HELPER_6(csrrw_i128, tl, 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 9f41954894..dca9e19a64 100644 > --- a/target/riscv/csr.c > +++ b/target/riscv/csr.c > @@ -1788,6 +1788,23 @@ 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) > +{ > + /* fall back to 64-bit version for now */ > + target_ulong ret_64; > + RISCVException ret = riscv_csrrw(env, csrno, &ret_64, > + int128_getlo(new_value), > + int128_getlo(write_mask)); > + > + if (ret_value) { > + *ret_value = int128_make64(ret_64); > + } > + > + return ret; > +} > + > /* > * 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..f4cf9c4698 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; > } > > +target_ulong 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->retxh = int128_gethi(rv); > + return int128_getlo(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()); > + } > +} > + > +target_ulong 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->retxh = int128_gethi(rv); > + return int128_getlo(rv); > +} > + > #ifndef CONFIG_USER_ONLY > > target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb) > -- > 2.34.1 > >