@@ -962,20 +962,74 @@ 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_i32 csr = tcg_constant_i32(rc);
+
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
+ }
+ gen_helper_csrr_i128(cpu_env, csr);
+ gen_set_gpr(ctx, rd, cpu_hlpr[0]);
+ gen_set_gprh(ctx, rd, cpu_hlpr[1]);
+ 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_i32 csr = tcg_constant_i32(rc);
+
+ if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+ gen_io_start();
+ }
+ gen_helper_csrrw_i128(cpu_env, csr, srcl, srch, maskl, maskh);
+ gen_set_gpr(ctx, rd, cpu_hlpr[0]);
+ gen_set_gprh(ctx, rd, cpu_hlpr[1]);
+ return do_csr_post(ctx);
+}
+
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
{
- 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 (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);
+ }
+
+ 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)
@@ -987,13 +1041,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);
+ } 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);
}
-
- 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);
}
static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
@@ -1005,28 +1070,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);
+ } 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);
}
-
- TCGv mask = get_gpr(ctx, a->rs1, EXT_ZERO);
- return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
}
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
{
- 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 (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);
+ }
+
+ 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)
@@ -1038,16 +1129,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);
+ } 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);
}
-
- TCGv ones = tcg_constant_tl(-1);
- TCGv mask = tcg_constant_tl(a->rs1);
- return do_csrrw(ctx, a->rd, a->csr, ones, mask);
}
-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
@@ -1056,10 +1157,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);
+ } 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);
}
-
- TCGv mask = tcg_constant_tl(a->rs1);
- return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
}
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> --- target/riscv/insn_trans/trans_rvi.c.inc | 201 ++++++++++++++++++------ 1 file changed, 156 insertions(+), 45 deletions(-)