mirror of
https://github.com/qemu/qemu.git
synced 2024-12-04 09:13:39 +08:00
target/riscv: modification of the trans_csrxx for 128-bit support
As opposed to the gen_arith and gen_shift generation helpers, the csr insns do not have a common prototype, so the choice to generate 32/64 or 128-bit helper calls is done in the trans_csrxx functions. 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-18-frederic.petrot@univ-grenoble-alpes.fr Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
961738ffea
commit
7934fdeee7
@ -881,20 +881,78 @@ static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
|
||||
return do_csr_post(ctx);
|
||||
}
|
||||
|
||||
static bool do_csrr_i128(DisasContext *ctx, int rd, int rc)
|
||||
{
|
||||
TCGv destl = dest_gpr(ctx, rd);
|
||||
TCGv desth = dest_gprh(ctx, rd);
|
||||
TCGv_i32 csr = tcg_constant_i32(rc);
|
||||
|
||||
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
|
||||
gen_io_start();
|
||||
}
|
||||
gen_helper_csrr_i128(destl, cpu_env, csr);
|
||||
tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
|
||||
gen_set_gpr128(ctx, rd, destl, desth);
|
||||
return do_csr_post(ctx);
|
||||
}
|
||||
|
||||
static bool do_csrw_i128(DisasContext *ctx, int rc, TCGv srcl, TCGv srch)
|
||||
{
|
||||
TCGv_i32 csr = tcg_constant_i32(rc);
|
||||
|
||||
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
|
||||
gen_io_start();
|
||||
}
|
||||
gen_helper_csrw_i128(cpu_env, csr, srcl, srch);
|
||||
return do_csr_post(ctx);
|
||||
}
|
||||
|
||||
static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
|
||||
TCGv srcl, TCGv srch, TCGv maskl, TCGv maskh)
|
||||
{
|
||||
TCGv destl = dest_gpr(ctx, rd);
|
||||
TCGv desth = dest_gprh(ctx, rd);
|
||||
TCGv_i32 csr = tcg_constant_i32(rc);
|
||||
|
||||
if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
|
||||
gen_io_start();
|
||||
}
|
||||
gen_helper_csrrw_i128(destl, cpu_env, csr, srcl, srch, maskl, maskh);
|
||||
tcg_gen_ld_tl(desth, cpu_env, offsetof(CPURISCVState, retxh));
|
||||
gen_set_gpr128(ctx, rd, destl, desth);
|
||||
return do_csr_post(ctx);
|
||||
}
|
||||
|
||||
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
|
||||
{
|
||||
TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw(ctx, a->csr, src);
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw(ctx, a->csr, src);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, src, mask);
|
||||
} else {
|
||||
TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
|
||||
TCGv srch = get_gprh(ctx, a->rs1);
|
||||
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw_i128(ctx, a->csr, srcl, srch);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr, srcl, srch, mask, mask);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, src, mask);
|
||||
}
|
||||
|
||||
static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
|
||||
@ -906,13 +964,24 @@ static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
|
||||
* a zero value, the instruction will still attempt to write the
|
||||
* unmodified value back to the csr and will cause side effects.
|
||||
*/
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ones, mask);
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ones, mask);
|
||||
} else {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr_i128(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv maskl = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
TCGv maskh = get_gprh(ctx, a->rs1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr, ones, ones, maskl, maskh);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
|
||||
@ -924,28 +993,54 @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
|
||||
* a zero value, the instruction will still attempt to write the
|
||||
* unmodified value back to the csr and will cause side effects.
|
||||
*/
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
|
||||
TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
|
||||
} else {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr_i128(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv maskl = get_gpr(ctx, a->rs1, EXT_ZERO);
|
||||
TCGv maskh = get_gprh(ctx, a->rs1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr,
|
||||
ctx->zero, ctx->zero, maskl, maskh);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
|
||||
{
|
||||
TCGv src = tcg_constant_tl(a->rs1);
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
TCGv src = tcg_constant_tl(a->rs1);
|
||||
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw(ctx, a->csr, src);
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw(ctx, a->csr, src);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, src, mask);
|
||||
} else {
|
||||
TCGv src = tcg_constant_tl(a->rs1);
|
||||
|
||||
/*
|
||||
* If rd == 0, the insn shall not read the csr, nor cause any of the
|
||||
* side effects that might occur on a csr read.
|
||||
*/
|
||||
if (a->rd == 0) {
|
||||
return do_csrw_i128(ctx, a->csr, src, ctx->zero);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr, src, ctx->zero, mask, mask);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(-1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, src, mask);
|
||||
}
|
||||
|
||||
static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
|
||||
@ -957,16 +1052,26 @@ static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
|
||||
* a zero value, the instruction will still attempt to write the
|
||||
* unmodified value back to the csr and will cause side effects.
|
||||
*/
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ones, mask);
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ones, mask);
|
||||
} else {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr_i128(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv ones = tcg_constant_tl(-1);
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr, ones, ones, mask, ctx->zero);
|
||||
}
|
||||
}
|
||||
|
||||
static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
|
||||
static bool trans_csrrci(DisasContext *ctx, arg_csrrci * a)
|
||||
{
|
||||
/*
|
||||
* If rs1 == 0, the insn shall not write to the csr at all, nor
|
||||
@ -975,10 +1080,20 @@ static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
|
||||
* a zero value, the instruction will still attempt to write the
|
||||
* unmodified value back to the csr and will cause side effects.
|
||||
*/
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
if (get_xl(ctx) < MXL_RV128) {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
|
||||
} else {
|
||||
if (a->rs1 == 0) {
|
||||
return do_csrr_i128(ctx, a->rd, a->csr);
|
||||
}
|
||||
|
||||
TCGv mask = tcg_constant_tl(a->rs1);
|
||||
return do_csrrw_i128(ctx, a->rd, a->csr,
|
||||
ctx->zero, ctx->zero, mask, ctx->zero);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user