diff mbox series

[08/11] RISC-V: Adding T-Head MemPair extension

Message ID 20220906122243.1243354-9-christoph.muellner@vrull.eu (mailing list archive)
State New, archived
Headers show
Series Add support for the T-Head vendor extensions | expand

Commit Message

Christoph Müllner Sept. 6, 2022, 12:22 p.m. UTC
From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head MemPair instructions.
The patch uses the T-Head specific decoder and translation.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c                         |  1 +
 target/riscv/cpu.h                         |  1 +
 target/riscv/insn_trans/trans_xthead.c.inc | 90 ++++++++++++++++++++++
 target/riscv/meson.build                   |  1 +
 target/riscv/translate.c                   |  3 +
 target/riscv/xtheadmempair.decode          | 29 +++++++
 6 files changed, 125 insertions(+)
 create mode 100644 target/riscv/xtheadmempair.decode
diff mbox series

Patch

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 990a1f57af..9370722ffa 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -926,6 +926,7 @@  static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
     DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
     DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
+    DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
     DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
     DEFINE_PROP_BOOL("xtheadxmae", RISCVCPU, cfg.ext_xtheadxmae, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1982d9293f..6cc2d19075 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -446,6 +446,7 @@  struct RISCVCPUConfig {
     bool ext_xtheadcmo;
     bool ext_xtheadcondmov;
     bool ext_xtheadmac;
+    bool ext_xtheadmempair;
     bool ext_xtheadsync;
     bool ext_xtheadxmae;
     bool ext_XVentanaCondOps;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index fc8307b113..a2bae249fb 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -284,3 +284,93 @@  static bool trans_th_mulsw(DisasContext *ctx, arg_th_mulsw *a)
     ctx->ol = MXL_RV32;
     return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
 }
+
+static bool gen_loadpair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
+                            int shamt)
+{
+    TCGv rd1 = dest_gpr(ctx, a->rd1);
+    TCGv rd2 = dest_gpr(ctx, a->rd2);
+    TCGv rs = get_gpr(ctx, a->rs, EXT_NONE);
+    TCGv addr1 = tcg_temp_new();
+    TCGv addr2 = tcg_temp_new();
+
+    tcg_gen_movi_tl(addr1, a->sh2);
+    tcg_gen_shli_tl(addr1, addr1, shamt);
+    tcg_gen_add_tl(addr1, rs, addr1);
+    if ((memop & MO_SIZE) == MO_64) {
+        tcg_gen_addi_tl(addr2, addr1, 8);
+    } else {
+        tcg_gen_addi_tl(addr2, addr1, 4);
+    }
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr1, addr1);
+        tcg_gen_ext32u_tl(addr2, addr2);
+    }
+
+    tcg_gen_qemu_ld_tl(rd1, addr1, ctx->mem_idx, memop);
+    tcg_gen_qemu_ld_tl(rd2, addr2, ctx->mem_idx, memop);
+    gen_set_gpr(ctx, a->rd1, rd1);
+    gen_set_gpr(ctx, a->rd2, rd2);
+
+    tcg_temp_free(addr1);
+    tcg_temp_free(addr2);
+    return true;
+}
+
+static bool trans_th_ldd(DisasContext *ctx, arg_th_pair *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_loadpair_tl(ctx, a, MO_TESQ, 4);
+}
+
+static bool trans_th_lwd(DisasContext *ctx, arg_th_pair *a)
+{
+    return gen_loadpair_tl(ctx, a, MO_TESL, 3);
+}
+
+static bool trans_th_lwud(DisasContext *ctx, arg_th_pair *a)
+{
+    return gen_loadpair_tl(ctx, a, MO_TEUL, 3);
+}
+
+static bool gen_storepair_tl(DisasContext *ctx, arg_th_pair *a, MemOp memop,
+                             int shamt)
+{
+    TCGv data1 = get_gpr(ctx, a->rd1, EXT_NONE);
+    TCGv data2 = get_gpr(ctx, a->rd2, EXT_NONE);
+    TCGv rs = get_gpr(ctx, a->rs, EXT_NONE);
+    TCGv addr1 = tcg_temp_new();
+    TCGv addr2 = tcg_temp_new();
+
+    tcg_gen_movi_tl(addr1, a->sh2);
+    tcg_gen_shli_tl(addr1, addr1, shamt);
+    tcg_gen_add_tl(addr1, rs, addr1);
+    if ((memop & MO_SIZE) == MO_64) {
+        tcg_gen_addi_tl(addr2, addr1, 8);
+    } else {
+        tcg_gen_addi_tl(addr2, addr1, 4);
+    }
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr1, addr1);
+        tcg_gen_ext32u_tl(addr2, addr2);
+    }
+
+    tcg_gen_qemu_st_tl(data1, addr1, ctx->mem_idx, memop);
+    tcg_gen_qemu_st_tl(data2, addr2, ctx->mem_idx, memop);
+
+    tcg_temp_free(addr1);
+    tcg_temp_free(addr2);
+    return true;
+}
+
+static bool trans_th_sdd(DisasContext *ctx, arg_th_pair *a)
+{
+    return gen_storepair_tl(ctx, a, MO_TESQ, 4);
+}
+
+static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a)
+{
+    return gen_storepair_tl(ctx, a, MO_TESL, 3);
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 55c019e55b..998f0ba336 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -8,6 +8,7 @@  gen = [
   decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
   decodetree.process('xtheadcondmov.decode', extra_args: '--static-decode=decode_xtheadcondmov'),
   decodetree.process('xtheadmac.decode', extra_args: '--static-decode=decode_xtheadmac'),
+  decodetree.process('xtheadmempair.decode', extra_args: '--static-decode=decode_xtheadmempair'),
   decodetree.process('xtheadsync.decode', extra_args: '--static-decode=decode_xtheadsync'),
   decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
 ]
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 56cc89ce4a..308de419cb 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -138,6 +138,7 @@  MATERIALISE_EXT_PREDICATE(xtheadbs)
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
 MATERIALISE_EXT_PREDICATE(xtheadcondmov);
 MATERIALISE_EXT_PREDICATE(xtheadmac);
+MATERIALISE_EXT_PREDICATE(xtheadmempair);
 MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
@@ -731,6 +732,7 @@  static int ex_rvc_shifti(DisasContext *ctx, int imm)
 #include "decode-xtheadcmo.c.inc"
 #include "decode-xtheadcondmov.c.inc"
 #include "decode-xtheadmac.c.inc"
+#include "decode-xtheadmempair.c.inc"
 #include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
 
@@ -1058,6 +1060,7 @@  static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         { has_xtheadcmo_p, decode_xtheadcmo },
         { has_xtheadcondmov_p, decode_xtheadcondmov },
         { has_xtheadmac_p, decode_xtheadmac },
+        { has_xtheadmempair_p, decode_xtheadmempair },
         { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
     };
diff --git a/target/riscv/xtheadmempair.decode b/target/riscv/xtheadmempair.decode
new file mode 100644
index 0000000000..135dc10a59
--- /dev/null
+++ b/target/riscv/xtheadmempair.decode
@@ -0,0 +1,29 @@ 
+#
+# RISC-V instruction decode for the XTheadMemPair extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+# The XTheadMemPair extension provides two-GP-register operations.
+#
+# It is documented in
+# https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.0.0/xthead-2022-09-05-2.0.0.pdf
+
+# Fields
+%sh2       25:2
+%rd2       20:5
+%rs        15:5
+%rd1        7:5
+
+# Argument sets
+&th_pair        rd1 rs rd2 sh2
+
+# Formats:
+@th_pair     ..... .. ..... ..... ... ..... ....... &th_pair %rd1 %rs %rd2 %sh2
+
+th_ldd       11111 .. ..... ..... 100 ..... 0001011 @th_pair
+th_lwd       11100 .. ..... ..... 100 ..... 0001011 @th_pair
+th_lwud      11110 .. ..... ..... 100 ..... 0001011 @th_pair
+th_sdd       11111 .. ..... ..... 101 ..... 0001011 @th_pair
+th_swd       11100 .. ..... ..... 101 ..... 0001011 @th_pair