target/riscv: helper functions to wrap calls to 128-bit csr insns
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.petrot@univ-grenoble-alpes.fr> Co-authored-by: Fabien Portas <fabien.portas@grenoble-inp.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-id: 20220106210108.138226-17-frederic.petrot@univ-grenoble-alpes.fr Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
2c64ab66c1
commit
961738ffea
@ -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
|
||||
@ -500,6 +501,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;
|
||||
|
@ -1817,6 +1817,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.
|
||||
|
@ -96,6 +96,9 @@ DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
|
||||
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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user