@@ -198,6 +198,13 @@ divuw 0000001 ..... ..... 101 ..... 0111011 @r
remw 0000001 ..... ..... 110 ..... 0111011 @r
remuw 0000001 ..... ..... 111 ..... 0111011 @r
+# *** RV128M Standard Extension (in addition to RV64M) ***
+muld 0000001 ..... ..... 000 ..... 1111011 @r
+divd 0000001 ..... ..... 100 ..... 1111011 @r
+divud 0000001 ..... ..... 101 ..... 1111011 @r
+remd 0000001 ..... ..... 110 ..... 1111011 @r
+remud 0000001 ..... ..... 111 ..... 1111011 @r
+
# *** RV32A Standard Extension ***
lr_w 00010 . . 00000 ..... 010 ..... 0101111 @atom_ld
sc_w 00011 . . ..... ..... 010 ..... 0101111 @atom_st
@@ -390,13 +390,25 @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
tcg_gen_mul_tl, tcg_gen_mul_tl, gen_mulw_i128);
}
+static void gen_divw_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_div(rdl, rs1l, rs2l);
+}
+
static bool trans_divw(DisasContext *ctx, arg_divw *a)
{
REQUIRE_64_OR_128BIT(ctx);
REQUIRE_EXT(ctx, RVM);
ctx->w = true;
return gen_arith(ctx, a, EXT_SIGN,
- gen_div, gen_div, NULL);
+ gen_div, gen_div, gen_divw_i128);
+}
+
+static void gen_divuw_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_divu(rdl, rs1l, rs2l);
}
static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
@@ -405,7 +417,13 @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
REQUIRE_EXT(ctx, RVM);
ctx->w = true;
return gen_arith(ctx, a, EXT_ZERO,
- gen_divu, gen_divu, NULL);
+ gen_divu, gen_divu, gen_divuw_i128);
+}
+
+static void gen_remw_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_rem(rdl, rs1l, rs2l);
}
static bool trans_remw(DisasContext *ctx, arg_remw *a)
@@ -414,7 +432,13 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a)
REQUIRE_EXT(ctx, RVM);
ctx->w = true;
return gen_arith(ctx, a, EXT_SIGN,
- gen_rem, gen_rem, NULL);
+ gen_rem, gen_rem, gen_remw_i128);
+}
+
+static void gen_remuw_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_remu(rdl, rs1l, rs2l);
}
static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
@@ -423,5 +447,85 @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
REQUIRE_EXT(ctx, RVM);
ctx->w = true;
return gen_arith(ctx, a, EXT_ZERO,
- gen_remu, gen_remu, NULL);
+ gen_remu, gen_remu, gen_remuw_i128);
+}
+
+static void gen_muld_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ tcg_gen_mul_tl(rdl, rs1l, rs2l);
+}
+
+static bool trans_muld(DisasContext *ctx, arg_muld *a)
+{
+ REQUIRE_128BIT(ctx);
+ REQUIRE_EXT(ctx, RVM);
+ ctx->d = true;
+
+ return gen_arith(ctx, a, EXT_SIGN,
+ tcg_gen_mul_tl, tcg_gen_mul_tl, gen_muld_i128);
+}
+
+static void gen_divd_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_div(rdl, rs1l, rs2l);
+}
+
+static bool trans_divd(DisasContext *ctx, arg_divd *a)
+{
+ REQUIRE_128BIT(ctx);
+ REQUIRE_EXT(ctx, RVM);
+ ctx->d = true;
+
+ return gen_arith(ctx, a, EXT_SIGN,
+ gen_div, gen_div, gen_divd_i128);
+}
+
+static void gen_divud_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_divu(rdl, rs1l, rs2l);
+}
+
+static bool trans_divud(DisasContext *ctx, arg_divud *a)
+{
+ REQUIRE_128BIT(ctx);
+ REQUIRE_EXT(ctx, RVM);
+ ctx->d = true;
+
+ return gen_arith(ctx, a, EXT_ZERO,
+ gen_divu, gen_divu, gen_divud_i128);
+}
+
+static void gen_remd_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_rem(rdl, rs1l, rs2l);
+}
+
+static bool trans_remd(DisasContext *ctx, arg_remd *a)
+{
+ REQUIRE_128BIT(ctx);
+ REQUIRE_EXT(ctx, RVM);
+ ctx->d = true;
+
+ return gen_arith(ctx, a, EXT_SIGN,
+ gen_rem, gen_rem, gen_remd_i128);
+}
+
+static void gen_remud_i128(TCGv rdl, TCGv rdh,
+ TCGv rs1l, TCGv rs1h, TCGv rs2l, TCGv rs2h)
+{
+ gen_remu(rdl, rs1l, rs2l);
+}
+
+static bool trans_remud(DisasContext *ctx, arg_remud *a)
+{
+ REQUIRE_128BIT(ctx);
+ REQUIRE_EXT(ctx, RVM);
+ ctx->d = true;
+
+ return gen_arith(ctx, a, EXT_ZERO,
+ gen_remu, gen_remu, gen_remud_i128);
}
All mult/div/rem instructions that work on double integers (suffixed 'd') can be tcg-generated in a few micro-ops, they are added here. 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/insn32.decode | 7 ++ target/riscv/insn_trans/trans_rvm.c.inc | 112 +++++++++++++++++++++++- 2 files changed, 115 insertions(+), 4 deletions(-)