aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/insn_trans
diff options
context:
space:
mode:
authorChristoph Müllner <christoph.muellner@vrull.eu>2023-01-31 21:20:06 +0100
committerAlistair Francis <alistair.francis@wdc.com>2023-02-07 08:19:23 +1000
commitb8a5832b87fb513725cd6d960cae6476f3a515c7 (patch)
treebd425d347086055700077debabd8e0899e914122 /target/riscv/insn_trans
parent3290933853c2c8a4a50a990cc395471097f0a173 (diff)
RISC-V: Adding T-Head multiply-accumulate instructions
This patch adds support for the T-Head MAC instructions. The patch uses the T-Head specific decoder and translation. Co-developed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu> Message-Id: <20230131202013.2541053-8-christoph.muellner@vrull.eu> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/insn_trans')
-rw-r--r--target/riscv/insn_trans/trans_xthead.c.inc83
1 files changed, 83 insertions, 0 deletions
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index 089b51f468..31a4034927 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -46,6 +46,12 @@
} \
} while (0)
+#define REQUIRE_XTHEADMAC(ctx) do { \
+ if (!ctx->cfg_ptr->ext_xtheadmac) { \
+ return false; \
+ } \
+} while (0)
+
#define REQUIRE_XTHEADSYNC(ctx) do { \
if (!ctx->cfg_ptr->ext_xtheadsync) { \
return false; \
@@ -299,6 +305,83 @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
return gen_th_condmove(ctx, a, TCG_COND_NE);
}
+/* XTheadMac */
+
+static bool gen_th_mac(DisasContext *ctx, arg_r *a,
+ void (*accumulate_func)(TCGv, TCGv, TCGv),
+ void (*extend_operand_func)(TCGv, TCGv))
+{
+ TCGv dest = dest_gpr(ctx, a->rd);
+ TCGv src0 = get_gpr(ctx, a->rd, EXT_NONE);
+ TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+ TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+ TCGv tmp = tcg_temp_new();
+
+ if (extend_operand_func) {
+ TCGv tmp2 = tcg_temp_new();
+ extend_operand_func(tmp, src1);
+ extend_operand_func(tmp2, src2);
+ tcg_gen_mul_tl(tmp, tmp, tmp2);
+ tcg_temp_free(tmp2);
+ } else {
+ tcg_gen_mul_tl(tmp, src1, src2);
+ }
+
+ accumulate_func(dest, src0, tmp);
+ gen_set_gpr(ctx, a->rd, dest);
+ tcg_temp_free(tmp);
+
+ return true;
+}
+
+/* th.mula: "rd = rd + rs1 * rs2" */
+static bool trans_th_mula(DisasContext *ctx, arg_th_mula *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
+}
+
+/* th.mulah: "rd = sext.w(rd + sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
+static bool trans_th_mulah(DisasContext *ctx, arg_th_mulah *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ ctx->ol = MXL_RV32;
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, tcg_gen_ext16s_tl);
+}
+
+/* th.mulaw: "rd = sext.w(rd + rs1 * rs2)" */
+static bool trans_th_mulaw(DisasContext *ctx, arg_th_mulaw *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ REQUIRE_64BIT(ctx);
+ ctx->ol = MXL_RV32;
+ return gen_th_mac(ctx, a, tcg_gen_add_tl, NULL);
+}
+
+/* th.muls: "rd = rd - rs1 * rs2" */
+static bool trans_th_muls(DisasContext *ctx, arg_th_muls *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
+}
+
+/* th.mulsh: "rd = sext.w(rd - sext.w(rs1[15:0]) * sext.w(rs2[15:0]))" */
+static bool trans_th_mulsh(DisasContext *ctx, arg_th_mulsh *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ ctx->ol = MXL_RV32;
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, tcg_gen_ext16s_tl);
+}
+
+/* th.mulsw: "rd = sext.w(rd - rs1 * rs2)" */
+static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
+{
+ REQUIRE_XTHEADMAC(ctx);
+ REQUIRE_64BIT(ctx);
+ ctx->ol = MXL_RV32;
+ return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
+}
+
/* XTheadSync */
static bool trans_th_sfence_vmas(DisasContext *ctx, arg_th_sfence_vmas *a)