All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/11] Add support for the T-Head vendor extensions
@ 2022-09-06 12:22 Christoph Muellner
  2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
                   ` (10 more replies)
  0 siblings, 11 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This series introduces support for the T-Head vendor extensions,
which are implemented e.g. in the XuanTie C906 and XuanTie C910
processors:
* XTheadBa
* XTheadBb
* XTheadBs
* XTheadCmo
* XTheadCondMov
* XTheadFMemIdx
* XTheadMac
* XTheadMemIdx
* XTheadMemPair
* XTheadSync

The xthead* extensions are documented here:
https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.0.0/xthead-2022-09-05-2.0.0.pdf

The "th." instruction prefix prevents future conflicts with standard
extensions and has been documentented in a PR for the RISC-V toolchain
conventions:
  https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/19

The goal of this patchset is to provide access to these instruction
so that compilers/users can optimize SW accordingly.

Note, that the T-Head vendor extensions do not contain all
vendor-specific functionality of the T-Head SoCs (e.g. no vendor-specific
CSRs are included). Instead the extensions cover coherent functionality,
that is exposed to S and U mode.

To enable the extensions above, the following two methods are possible:
* add the extension to the arch string (e.g.
* QEMU_CPU="any,xtheadcmo=true,xtheadsync=true")
* implicitly select the extensions via CPU selection (e.g.
* QEMU_CPU="thead-c910")

This patchset attempts to minimize code changes in
generic/infrastructure code.
This patchset allows to boot the Xuantie Linux kernel.

Christoph Müllner (11):
  riscv: Add privilege level to DisasContext
  RISC-V: Adding T-Head CMO instructions
  RISC-V: Adding T-Head SYNC instructions
  RISC-V: Adding T-Head Bitmanip instructions
  RISC-V: Adding T-Head CondMov instructions
  RISC-V: Adding T-Head multiply-accumulate instructions
  RISC-V: Adding T-Head XMAE support
  RISC-V: Adding T-Head MemPair extension
  RISC-V: Adding T-Head MemIdx extension
  RISC-V: Adding T-Head FMemIdx extension
  RISC-V: Add initial support for T-Head C906 and C910 CPUs

 target/riscv/cpu.c                         |  43 +
 target/riscv/cpu.h                         |  14 +
 target/riscv/cpu_helper.c                  |   6 +-
 target/riscv/cpu_vendorid.h                |   6 +
 target/riscv/insn_trans/trans_xthead.c.inc | 874 +++++++++++++++++++++
 target/riscv/meson.build                   |  10 +
 target/riscv/translate.c                   |  42 +-
 target/riscv/xtheadba.decode               |  46 ++
 target/riscv/xtheadbb.decode               |  62 ++
 target/riscv/xtheadbs.decode               |  32 +
 target/riscv/xtheadcmo.decode              |  43 +
 target/riscv/xtheadcondmov.decode          |  33 +
 target/riscv/xtheadfmemidx.decode          |  34 +
 target/riscv/xtheadmac.decode              |  30 +
 target/riscv/xtheadmemidx.decode           |  73 ++
 target/riscv/xtheadmempair.decode          |  29 +
 target/riscv/xtheadsync.decode             |  25 +
 17 files changed, 1397 insertions(+), 5 deletions(-)
 create mode 100644 target/riscv/cpu_vendorid.h
 create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
 create mode 100644 target/riscv/xtheadba.decode
 create mode 100644 target/riscv/xtheadbb.decode
 create mode 100644 target/riscv/xtheadbs.decode
 create mode 100644 target/riscv/xtheadcmo.decode
 create mode 100644 target/riscv/xtheadcondmov.decode
 create mode 100644 target/riscv/xtheadfmemidx.decode
 create mode 100644 target/riscv/xtheadmac.decode
 create mode 100644 target/riscv/xtheadmemidx.decode
 create mode 100644 target/riscv/xtheadmempair.decode
 create mode 100644 target/riscv/xtheadsync.decode

-- 
2.37.2



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH 01/11] riscv: Add privilege level to DisasContext
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-16  2:46   ` LIU Zhiwei
  2022-09-16  6:00   ` Richard Henderson
  2022-09-06 12:22 ` [PATCH 02/11] RISC-V: Adding T-Head CMO instructions Christoph Muellner
                   ` (9 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This allows privileged instructions to check the required
privilege level in the translation without calling a helper.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/translate.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 63b04e8a94..fd241ff667 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -59,6 +59,9 @@ typedef struct DisasContext {
     /* pc_succ_insn points to the instruction following base.pc_next */
     target_ulong pc_succ_insn;
     target_ulong priv_ver;
+#ifndef CONFIG_USER_ONLY
+    target_ulong priv;
+#endif
     RISCVMXL misa_mxl_max;
     RISCVMXL xl;
     uint32_t misa_ext;
@@ -1079,6 +1082,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
     ctx->priv_ver = env->priv_ver;
 #if !defined(CONFIG_USER_ONLY)
+    ctx->priv = env->priv;
     if (riscv_has_ext(env, RVH)) {
         ctx->virt_enabled = riscv_cpu_virt_enabled(env);
     } else {
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 02/11] RISC-V: Adding T-Head CMO instructions
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
  2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-16  2:47   ` LIU Zhiwei
  2022-09-16  6:43   ` LIU Zhiwei
  2022-09-06 12:22 ` [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions Christoph Muellner
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head CMO instructions.
To avoid interfering with standard extensions, decoder and translation
are in its own T-Head specific files.
Future patches should be able to easily add additional T-Head extesions.

The implementation does not have much functionality (besides accepting
the instructions and not qualifying them as illegal instructions if
the hart executes in the required privilege level for the instruction),
as QEMU does not model CPU caches and instructions don't have any
exception behaviour (at least not documented).

The documentation shows, that the instructions are gated by
mxstatus.theadisaee and mxstatus.ucme. However, since these
settings are not changed by the upstream Linux kernel,
we simply enable the instructions in all modes.

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 | 66 ++++++++++++++++++++++
 target/riscv/meson.build                   |  1 +
 target/riscv/translate.c                   | 11 +++-
 target/riscv/xtheadcmo.decode              | 43 ++++++++++++++
 6 files changed, 120 insertions(+), 3 deletions(-)
 create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
 create mode 100644 target/riscv/xtheadcmo.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index ac6f82ebd0..7718ab0478 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -920,6 +920,7 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
 
     /* Vendor-specific custom extensions */
+    DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
 
     /* These are experimental so mark with 'x-' */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5c7acc055a..b7ab53b7b8 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -440,6 +440,7 @@ struct RISCVCPUConfig {
     uint64_t mimpid;
 
     /* Vendor-specific custom extensions */
+    bool ext_xtheadcmo;
     bool ext_XVentanaCondOps;
 
     uint8_t pmu_num;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
new file mode 100644
index 0000000000..1b1e21ab77
--- /dev/null
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -0,0 +1,66 @@
+/*
+ * RISC-V translation routines for the T-Head vendor extensions (xthead*).
+ *
+ * Copyright (c) 2022 VRULL GmbH.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define REQUIRE_PRIV_MHSU(ctx)
+
+#ifndef CONFIG_USER_ONLY
+#define REQUIRE_PRIV_MHS(ctx)                                   \
+do {                                                            \
+    if (!(ctx->priv == PRV_M ||                                 \
+          ctx->priv == PRV_H ||                                 \
+          ctx->priv == PRV_S)) {                                \
+        return false;                                           \
+    }                                                           \
+} while (0)
+#else
+#define REQUIRE_PRIV_MHS(ctx)                                   \
+  return false;
+#endif
+
+#define NOP_PRIVCHECK(insn, privcheck)                          \
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
+{                                                               \
+    (void) a;                                                   \
+    privcheck(ctx);                                             \
+    return true;                                                \
+}
+
+NOP_PRIVCHECK(th_dcache_call, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_iall, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cva, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_dcache_civa, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_dcache_iva, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_dcache_csw, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_isw, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_PRIV_MHS)
+
+NOP_PRIVCHECK(th_icache_iall, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_icache_ialls, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_icache_ipa, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_icache_iva, REQUIRE_PRIV_MHSU)
+
+NOP_PRIVCHECK(th_l2cache_call, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_PRIV_MHS)
+
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 6b9435d69a..1d149e05cd 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -2,6 +2,7 @@
 gen = [
   decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
   decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
+  decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
   decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
 ]
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fd241ff667..d16ae63850 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -132,7 +132,8 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
         return ctx->cfg_ptr->ext_ ## ext ; \
     }
 
-MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
+MATERIALISE_EXT_PREDICATE(xtheadcmo)
+MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
 #ifdef TARGET_RISCV32
 #define get_xl(ctx)    MXL_RV32
@@ -717,6 +718,10 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 /* Include the auto-generated decoder for 32 bit insn */
 #include "decode-insn32.c.inc"
 
+/* Include decoders for factored-out extensions */
+#include "decode-xtheadcmo.c.inc"
+#include "decode-XVentanaCondOps.c.inc"
+
 static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
                              void (*func)(TCGv, TCGv, target_long))
 {
@@ -1018,12 +1023,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
 #include "insn_trans/trans_rvk.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 #include "insn_trans/trans_svinval.c.inc"
+#include "insn_trans/trans_xthead.c.inc"
 #include "insn_trans/trans_xventanacondops.c.inc"
 
 /* Include the auto-generated decoder for 16 bit insn */
 #include "decode-insn16.c.inc"
-/* Include decoders for factored-out extensions */
-#include "decode-XVentanaCondOps.c.inc"
 
 static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
 {
@@ -1036,6 +1040,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         bool (*decode_func)(DisasContext *, uint32_t);
     } decoders[] = {
         { always_true_p,  decode_insn32 },
+        { has_xtheadcmo_p, decode_xtheadcmo },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
     };
 
diff --git a/target/riscv/xtheadcmo.decode b/target/riscv/xtheadcmo.decode
new file mode 100644
index 0000000000..8ddf9b3997
--- /dev/null
+++ b/target/riscv/xtheadcmo.decode
@@ -0,0 +1,43 @@
+#
+# RISC-V translation routines for the XTheadCmo extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadCmo extension provides instructions for cache management.
+#
+# 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:
+%rs1       15:5
+
+# Formats
+@sfence_vm  ....... ..... .....   ... ..... ....... %rs1
+
+# *** CMO instructions
+th_dcache_call   0000000 00001 00000 000 00000 0001011
+th_dcache_ciall  0000000 00011 00000 000 00000 0001011
+th_dcache_iall   0000000 00010 00000 000 00000 0001011
+th_dcache_cpa    0000001 01001 ..... 000 00000 0001011 @sfence_vm
+th_dcache_cipa   0000001 01011 ..... 000 00000 0001011 @sfence_vm
+th_dcache_ipa    0000001 01010 ..... 000 00000 0001011 @sfence_vm
+th_dcache_cva    0000001 00101 ..... 000 00000 0001011 @sfence_vm
+th_dcache_civa   0000001 00111 ..... 000 00000 0001011 @sfence_vm
+th_dcache_iva    0000001 00110 ..... 000 00000 0001011 @sfence_vm
+th_dcache_csw    0000001 00001 ..... 000 00000 0001011 @sfence_vm
+th_dcache_cisw   0000001 00011 ..... 000 00000 0001011 @sfence_vm
+th_dcache_isw    0000001 00010 ..... 000 00000 0001011 @sfence_vm
+th_dcache_cpal1  0000001 01000 ..... 000 00000 0001011 @sfence_vm
+th_dcache_cval1  0000001 00100 ..... 000 00000 0001011 @sfence_vm
+
+th_icache_iall   0000000 10000 00000 000 00000 0001011
+th_icache_ialls  0000000 10001 00000 000 00000 0001011
+th_icache_ipa    0000001 11000 ..... 000 00000 0001011 @sfence_vm
+th_icache_iva    0000001 10000 ..... 000 00000 0001011 @sfence_vm
+
+th_l2cache_call  0000000 10101 00000 000 00000 0001011
+th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
+th_l2cache_iall  0000000 10110 00000 000 00000 0001011
+
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
  2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
  2022-09-06 12:22 ` [PATCH 02/11] RISC-V: Adding T-Head CMO instructions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-08  7:29   ` Richard Henderson
  2022-09-06 12:22 ` [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions Christoph Muellner
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

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

The implementation does not have much functionality (besides accepting
the instructions and not qualifying them as illegal instructions if
the hart executes in the required privilege level for the instruction),
as QEMU does not model CPU caches, or out-of-order execution.
Further the instructions don't have any exception behaviour
(at least not documented).

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 |  6 ++++++
 target/riscv/meson.build                   |  1 +
 target/riscv/translate.c                   |  3 +++
 target/riscv/xtheadsync.decode             | 25 ++++++++++++++++++++++
 6 files changed, 37 insertions(+)
 create mode 100644 target/riscv/xtheadsync.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7718ab0478..a72722cfa6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -921,6 +921,7 @@ static Property riscv_cpu_extensions[] = {
 
     /* Vendor-specific custom extensions */
     DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
+    DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
 
     /* These are experimental so mark with 'x-' */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b7ab53b7b8..4ae22cf529 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -441,6 +441,7 @@ struct RISCVCPUConfig {
 
     /* Vendor-specific custom extensions */
     bool ext_xtheadcmo;
+    bool ext_xtheadsync;
     bool ext_XVentanaCondOps;
 
     uint8_t pmu_num;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index 1b1e21ab77..0a6719b2e2 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -64,3 +64,9 @@ NOP_PRIVCHECK(th_l2cache_call, REQUIRE_PRIV_MHS)
 NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_PRIV_MHS)
 NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_PRIV_MHS)
 
+NOP_PRIVCHECK(th_sfence_vmas, REQUIRE_PRIV_MHS)
+NOP_PRIVCHECK(th_sync, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
+NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
+
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 1d149e05cd..f201cc6997 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -3,6 +3,7 @@ gen = [
   decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
   decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
   decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
+  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 d16ae63850..a63cc3de46 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -133,6 +133,7 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
     }
 
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
+MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
 #ifdef TARGET_RISCV32
@@ -720,6 +721,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 
 /* Include decoders for factored-out extensions */
 #include "decode-xtheadcmo.c.inc"
+#include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
 
 static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
@@ -1041,6 +1043,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
     } decoders[] = {
         { always_true_p,  decode_insn32 },
         { has_xtheadcmo_p, decode_xtheadcmo },
+        { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
     };
 
diff --git a/target/riscv/xtheadsync.decode b/target/riscv/xtheadsync.decode
new file mode 100644
index 0000000000..d25735cce8
--- /dev/null
+++ b/target/riscv/xtheadsync.decode
@@ -0,0 +1,25 @@
+#
+# RISC-V translation routines for the XTheadSync extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadSync extension provides instructions for multi-processor synchronization.
+#
+# 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:
+%rs1  15:5
+%rs2  20:5
+
+# Formats
+@rs2_s          ....... ..... ..... ... ..... ....... %rs2 %rs1
+
+# *** SYNC instructions
+th_sfence_vmas   0000010 ..... ..... 000 00000 0001011 @rs2_s
+th_sync          0000000 11000 00000 000 00000 0001011
+th_sync_i        0000000 11010 00000 000 00000 0001011
+th_sync_is       0000000 11011 00000 000 00000 0001011
+th_sync_s        0000000 11001 00000 000 00000 0001011
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (2 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-16  9:12   ` LIU Zhiwei
  2022-09-06 12:22 ` [PATCH 05/11] RISC-V: Adding T-Head CondMov instructions Christoph Muellner
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

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

As the instructions are similar to those of Zb*, we can reuse
a lot of existing infrastructure code.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c                         |   3 +
 target/riscv/cpu.h                         |   3 +
 target/riscv/insn_trans/trans_xthead.c.inc | 124 +++++++++++++++++++++
 target/riscv/meson.build                   |   3 +
 target/riscv/translate.c                   |   9 ++
 target/riscv/xtheadba.decode               |  46 ++++++++
 target/riscv/xtheadbb.decode               |  62 +++++++++++
 target/riscv/xtheadbs.decode               |  32 ++++++
 8 files changed, 282 insertions(+)
 create mode 100644 target/riscv/xtheadba.decode
 create mode 100644 target/riscv/xtheadbb.decode
 create mode 100644 target/riscv/xtheadbs.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a72722cfa6..d129a6112a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -920,6 +920,9 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
 
     /* Vendor-specific custom extensions */
+    DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
+    DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
+    DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
     DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
     DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 4ae22cf529..9e2b3d6f56 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -440,6 +440,9 @@ struct RISCVCPUConfig {
     uint64_t mimpid;
 
     /* Vendor-specific custom extensions */
+    bool ext_xtheadba;
+    bool ext_xtheadbb;
+    bool ext_xtheadbs;
     bool ext_xtheadcmo;
     bool ext_xtheadsync;
     bool ext_XVentanaCondOps;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index 0a6719b2e2..b2d523b905 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -70,3 +70,127 @@ NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
 NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
 NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
 
+/*
+ * th.addsl is similar to sh[123]add (from Zba), but not an
+ * alternative encoding: while sh[123] applies the shift to rs1,
+ * th.addsl shifts rs2.
+ */
+
+#define GEN_TH_ADDSL(SHAMT)                                     \
+static void gen_th_addsl##SHAMT(TCGv ret, TCGv arg1, TCGv arg2) \
+{                                                               \
+    TCGv t = tcg_temp_new();                                    \
+    tcg_gen_shli_tl(t, arg2, SHAMT);                            \
+    tcg_gen_add_tl(ret, t, arg1);                               \
+    tcg_temp_free(t);                                           \
+}
+
+GEN_TH_ADDSL(1)
+GEN_TH_ADDSL(2)
+GEN_TH_ADDSL(3)
+
+#define GEN_TRANS_TH_ADDSL(SHAMT)                                       \
+static bool trans_th_addsl##SHAMT(DisasContext *ctx,                    \
+                                  arg_th_addsl##SHAMT * a)              \
+{                                                                       \
+    return gen_arith(ctx, a, EXT_NONE, gen_th_addsl##SHAMT, NULL);      \
+}
+
+GEN_TRANS_TH_ADDSL(1)
+GEN_TRANS_TH_ADDSL(2)
+GEN_TRANS_TH_ADDSL(3)
+
+
+/* th.srri is an alternate encoding for rori (from Zbb) */
+static bool trans_th_srri(DisasContext *ctx, arg_th_srri * a)
+{
+    return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_rotri_tl, NULL);
+}
+
+/* th.srriw is an alternate encoding for roriw (from Zbb) */
+static bool trans_th_srriw(DisasContext *ctx, arg_th_srriw *a)
+{
+    ctx->ol = MXL_RV32;
+    return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
+}
+
+/* th.ext and th.extu perform signed/unsigned bitfield extraction */
+static bool gen_th_bfextract(DisasContext *ctx, arg_th_bfext *a,
+                             void (*f)(TCGv, TCGv, unsigned int, unsigned int))
+{
+    TCGv dest = dest_gpr(ctx, a->rd);
+    TCGv source = get_gpr(ctx, a->rs1, EXT_ZERO);
+
+    if (a->lsb <= a->msb) {
+        f(dest, source, a->lsb, a->msb - a->lsb + 1);
+        gen_set_gpr(ctx, a->rd, dest);
+    }
+    return true;
+}
+
+static bool trans_th_ext(DisasContext *ctx, arg_th_ext *a)
+{
+    return gen_th_bfextract(ctx, a, tcg_gen_sextract_tl);
+}
+
+static bool trans_th_extu(DisasContext *ctx, arg_th_extu *a)
+{
+    return gen_th_bfextract(ctx, a, tcg_gen_extract_tl);
+}
+
+/* th.ff0: find first zero (clz on an inverted input) */
+static void gen_th_ff0(TCGv ret, TCGv arg1)
+{
+    TCGv t = tcg_temp_new();
+    tcg_gen_not_tl(t, arg1);
+    gen_clz(ret, t);
+    tcg_temp_free(t);
+}
+
+static bool trans_th_ff0(DisasContext *ctx, arg_th_ff0 *a)
+{
+    return gen_unary(ctx, a, EXT_NONE, gen_th_ff0);
+}
+
+/* th.ff1 is an alternate encoding for clz (from Zbb) */
+static bool trans_th_ff1(DisasContext *ctx, arg_th_ff1 *a)
+{
+    return gen_unary(ctx, a, EXT_NONE, gen_clz);
+}
+
+/* th.rev is an alternate encoding for the RV64 rev8 (from Zbb) */
+static bool trans_th_rev(DisasContext *ctx, arg_th_rev *a)
+{
+    return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl);
+}
+
+/* th.revw is a sign-extended byte-swap of the lower word */
+static void gen_th_revw(TCGv ret, TCGv arg1)
+{
+    tcg_gen_bswap_tl(ret, arg1);
+    tcg_gen_sari_tl(ret, ret, 32);
+}
+
+static bool trans_th_revw(DisasContext *ctx, arg_th_revw *a)
+{
+    return gen_unary(ctx, a, EXT_NONE, gen_th_revw);
+}
+
+/* th.tstnbz is equivalent to an orc.b (from Zbb) with inverted result */
+static void gen_th_tstnbz(TCGv ret, TCGv source1)
+{
+    gen_orc_b(ret, source1);
+    tcg_gen_not_tl(ret, ret);
+}
+
+static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
+{
+    return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
+}
+
+/* th.tst is an alternate encoding for bexti (from Zbs) */
+static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
+{
+    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
+}
+
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index f201cc6997..5ee37683cb 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -2,6 +2,9 @@
 gen = [
   decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
   decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
+  decodetree.process('xtheadba.decode', extra_args: '--static-decode=decode_xtheadba'),
+  decodetree.process('xtheadbb.decode', extra_args: '--static-decode=decode_xtheadbb'),
+  decodetree.process('xtheadbs.decode', extra_args: '--static-decode=decode_xtheadbs'),
   decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
   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 a63cc3de46..f662e403f8 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -132,6 +132,9 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
         return ctx->cfg_ptr->ext_ ## ext ; \
     }
 
+MATERIALISE_EXT_PREDICATE(xtheadba)
+MATERIALISE_EXT_PREDICATE(xtheadbb)
+MATERIALISE_EXT_PREDICATE(xtheadbs)
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
 MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
@@ -720,6 +723,9 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 #include "decode-insn32.c.inc"
 
 /* Include decoders for factored-out extensions */
+#include "decode-xtheadba.c.inc"
+#include "decode-xtheadbb.c.inc"
+#include "decode-xtheadbs.c.inc"
 #include "decode-xtheadcmo.c.inc"
 #include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
@@ -1042,6 +1048,9 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         bool (*decode_func)(DisasContext *, uint32_t);
     } decoders[] = {
         { always_true_p,  decode_insn32 },
+        { has_xtheadba_p, decode_xtheadba },
+        { has_xtheadbb_p, decode_xtheadbb },
+        { has_xtheadbs_p, decode_xtheadbs },
         { has_xtheadcmo_p, decode_xtheadcmo },
         { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
diff --git a/target/riscv/xtheadba.decode b/target/riscv/xtheadba.decode
new file mode 100644
index 0000000000..4e5e3f12f0
--- /dev/null
+++ b/target/riscv/xtheadba.decode
@@ -0,0 +1,46 @@
+#
+# RISC-V instruction decode for the XTheadBa extension
+#
+# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
+#                    Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadBa extension provides instructions for address calculations,
+# implementing the functional equivalent of a subset of Zba.
+#
+# 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
+#
+# The instruction contained in XTheadBb is:
+# - th.addsl      add rotate-right by immediate
+#                 (similar to sh[123]add, but with rs1 and rs2 switched)
+# This instruction reuses an existing instruction format.
+
+# Fields
+%rs2       20:5
+%rs1       15:5
+%rd        7:5
+
+# Argument sets
+&r         rd rs1 rs2		!extern
+
+# Formats:
+@r          ....... ..... .....  ... ..... ....... &r %rs2 %rs1 %rd
+
+# *** Bitmanip addressing instructions
+# Instead of defining a new encoding, we simply use the decoder to
+# extract the imm[0:1] field and dispatch to separate translation
+# functions (mirroring the `sh[123]add` instructions from Zba and
+# the regular RVI `add` instruction.
+#
+# The only difference between sh[123]add and addsl is that the sohift
+# is applied to rs1 (for addsl) instead of rs2 (for sh[123]add).
+#
+# Note that shift-by-0 is a valid operation according to the manual.
+# This will be equivalent to a regular add.
+add              0000000 ..... ..... 001 ..... 0001011 @r
+th_addsl1        0000001 ..... ..... 001 ..... 0001011 @r
+th_addsl2        0000010 ..... ..... 001 ..... 0001011 @r
+th_addsl3        0000011 ..... ..... 001 ..... 0001011 @r
+
diff --git a/target/riscv/xtheadbb.decode b/target/riscv/xtheadbb.decode
new file mode 100644
index 0000000000..2754a6444b
--- /dev/null
+++ b/target/riscv/xtheadbb.decode
@@ -0,0 +1,62 @@
+#
+# RISC-V instruction decode for the XTheadBb extension
+#
+# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
+#                    Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadBb extension provides basic bit-manipulation instructions,
+# implementing the functional equivalent of a subset of Zbb.
+#
+# 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
+#
+# The instructions contained in XTheadBb are:
+# - th.srri       rotate-right by immediate (matches rori)
+# - th.srriw      rotate-right by immediate, w-form (matches roriw)
+# - th.rev        byte-reverse register (matches RV64-form of rev8)
+# - th.revw       byte-reverse low word, sign-extend result (no equivalent)
+# - th.ext        signed bitfield-extract (no equivalent)
+# - th.extu       unsigned bitfield-extract (no equivalent)
+# - th.ff0        find-first zero (equivalent to clz on the inverted operand)
+# - th.ff1        find-first one (matches clz)
+# - th.tstnbz     test for zero-bytes (equivalent to the inverted result of orc.b)
+# - th.tst        test for bit (equivalent to bexti)
+#
+# These instructions generally reuse existing instruction formats.
+# Only the th.ext and th.ext introduce a new, vendor-defined instruction format.
+
+# Fields
+%rs2       20:5
+%rs1       15:5
+%rd        7:5
+%sh5       20:5
+%sh6       20:6
+
+# Argument sets
+&r2        rd rs1		!extern
+&shift     shamt rs1 rd		!extern
+&th_bfext  msb lsb rs1 rd
+
+# Formats:
+@r2         ....... ..... .....  ... ..... ....... &r2 %rs1 %rd
+@th_bfext   msb:6  lsb:6  .....  ... ..... ....... &th_bfext %rs1 %rd
+
+# Formats 64:
+@sh5        ....... ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd
+
+# Formats 128:
+@sh6        ...... ...... .....  ... ..... ....... &shift shamt=%sh6 %rs1 %rd
+
+# *** Bitmanip instructions
+th_ext           ...... ...... ..... 010 ..... 0001011 @th_bfext
+th_extu          ...... ...... ..... 011 ..... 0001011 @th_bfext
+th_ff0           1000010 00000 ..... 001 ..... 0001011 @r2
+th_ff1           1000011 00000 ..... 001 ..... 0001011 @r2
+th_srri          000100 ...... ..... 001 ..... 0001011 @sh6
+th_srriw         0001010 ..... ..... 001 ..... 0001011 @sh5
+th_rev           1000001 00000 ..... 001 ..... 0001011 @r2
+th_revw          1001000 00000 ..... 001 ..... 0001011 @r2
+th_tstnbz        1000000 00000 ..... 001 ..... 0001011 @r2
+
diff --git a/target/riscv/xtheadbs.decode b/target/riscv/xtheadbs.decode
new file mode 100644
index 0000000000..7aa345b207
--- /dev/null
+++ b/target/riscv/xtheadbs.decode
@@ -0,0 +1,32 @@
+#
+# RISC-V instruction decode for the XTheadBb extension
+#
+# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
+#                    Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# XTheadBs provides basic bit-manipulation instructions,
+# implementing the functional equivalent of a subset of Zbs.
+#
+# 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
+#
+# The instruction contained in XTheadBb is:
+# - th.tst        test if bit is set (matches bexti)
+#
+# The instruction reuses an existing instruction format.
+
+# Fields
+%rs1       15:5
+%rd        7:5
+%sh6       20:6
+
+# Argument sets
+&shift     shamt rs1 rd		!extern
+
+# Formats 128:
+@sh6        ...... ...... .....  ... ..... ....... &shift shamt=%sh6 %rs1 %rd
+
+# *** Bitmanip single-bit instructions
+th_tst           100010 ...... ..... 001 ..... 0001011 @sh6
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 05/11] RISC-V: Adding T-Head CondMov instructions
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (3 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-06 12:22 ` [PATCH 06/11] RISC-V: Adding T-Head multiply-accumulate instructions Christoph Muellner
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head CondMov 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 | 23 +++++++++++++++
 target/riscv/meson.build                   |  1 +
 target/riscv/translate.c                   |  3 ++
 target/riscv/xtheadcondmov.decode          | 33 ++++++++++++++++++++++
 6 files changed, 62 insertions(+)
 create mode 100644 target/riscv/xtheadcondmov.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d129a6112a..b7d6dbd28e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -924,6 +924,7 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
     DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
     DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
+    DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
     DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9e2b3d6f56..0b58b38335 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -444,6 +444,7 @@ struct RISCVCPUConfig {
     bool ext_xtheadbb;
     bool ext_xtheadbs;
     bool ext_xtheadcmo;
+    bool ext_xtheadcondmov;
     bool ext_xtheadsync;
     bool ext_XVentanaCondOps;
 
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index b2d523b905..da3a538400 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -194,3 +194,26 @@ static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
     return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
 }
 
+static bool gen_th_condmove(DisasContext *ctx, arg_r *a, TCGCond cond)
+{
+    TCGv dest = dest_gpr(ctx, a->rd);
+    TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
+
+    tcg_gen_movcond_tl(cond, dest, src2, ctx->zero, src1, dest);
+
+    gen_set_gpr(ctx, a->rd, dest);
+    return true;
+}
+
+/* th.mveqz: "if (rs2 == 0) rd = rs1;" */
+static bool trans_th_mveqz(DisasContext *ctx, arg_th_mveqz *a)
+{
+    return gen_th_condmove(ctx, a, TCG_COND_EQ);
+}
+
+/* th.mvnez: "if (rs2 != 0) rd = rs1;" */
+static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
+{
+    return gen_th_condmove(ctx, a, TCG_COND_NE);
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 5ee37683cb..496ae37f26 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -6,6 +6,7 @@ gen = [
   decodetree.process('xtheadbb.decode', extra_args: '--static-decode=decode_xtheadbb'),
   decodetree.process('xtheadbs.decode', extra_args: '--static-decode=decode_xtheadbs'),
   decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
+  decodetree.process('xtheadcondmov.decode', extra_args: '--static-decode=decode_xtheadcondmov'),
   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 f662e403f8..986243df99 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -136,6 +136,7 @@ MATERIALISE_EXT_PREDICATE(xtheadba)
 MATERIALISE_EXT_PREDICATE(xtheadbb)
 MATERIALISE_EXT_PREDICATE(xtheadbs)
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
+MATERIALISE_EXT_PREDICATE(xtheadcondmov);
 MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
@@ -727,6 +728,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 #include "decode-xtheadbb.c.inc"
 #include "decode-xtheadbs.c.inc"
 #include "decode-xtheadcmo.c.inc"
+#include "decode-xtheadcondmov.c.inc"
 #include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
 
@@ -1052,6 +1054,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         { has_xtheadbb_p, decode_xtheadbb },
         { has_xtheadbs_p, decode_xtheadbs },
         { has_xtheadcmo_p, decode_xtheadcmo },
+        { has_xtheadcondmov_p, decode_xtheadcondmov },
         { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
     };
diff --git a/target/riscv/xtheadcondmov.decode b/target/riscv/xtheadcondmov.decode
new file mode 100644
index 0000000000..00f9ca96c6
--- /dev/null
+++ b/target/riscv/xtheadcondmov.decode
@@ -0,0 +1,33 @@
+#
+# RISC-V instruction decode for the XTheadCondMov extension
+#
+# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
+#                    Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadCondMov extension provides conditional move instructions.
+#
+# 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
+#
+# The instructions contained in XTheadCondMov are:
+# - th.mveqz      move to register, if condition is zero
+# - th.mvnez      move to register, if condition is non-zero
+#
+# These instructions reuse existing instruction formats.
+
+# Fields
+%rs2       20:5
+%rs1       15:5
+%rd        7:5
+
+# Argument sets
+&r         rd rs1 rs2		!extern
+
+# Formats:
+@r          ....... ..... .....  ... ..... ....... &r %rs2 %rs1 %rd
+
+# T-Head conditional move instructions
+th_mveqz    0100000 ..... .....  001 ..... 0001011 @r
+th_mvnez    0100001 ..... .....  001 ..... 0001011 @r
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 06/11] RISC-V: Adding T-Head multiply-accumulate instructions
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (4 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 05/11] RISC-V: Adding T-Head CondMov instructions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-06 12:22 ` [PATCH 07/11] RISC-V: Adding T-Head XMAE support Christoph Muellner
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head MAC 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 | 67 ++++++++++++++++++++++
 target/riscv/meson.build                   |  1 +
 target/riscv/translate.c                   |  3 +
 target/riscv/xtheadmac.decode              | 30 ++++++++++
 6 files changed, 103 insertions(+)
 create mode 100644 target/riscv/xtheadmac.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index b7d6dbd28e..e2d74fa701 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -925,6 +925,7 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
     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("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
     DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
 
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0b58b38335..d0dc4ab031 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -445,6 +445,7 @@ struct RISCVCPUConfig {
     bool ext_xtheadbs;
     bool ext_xtheadcmo;
     bool ext_xtheadcondmov;
+    bool ext_xtheadmac;
     bool ext_xtheadsync;
     bool ext_XVentanaCondOps;
 
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index da3a538400..fc8307b113 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -217,3 +217,70 @@ static bool trans_th_mvnez(DisasContext *ctx, arg_th_mveqz *a)
 {
     return gen_th_condmove(ctx, a, TCG_COND_NE);
 }
+
+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)
+{
+    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)
+{
+    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)
+{
+    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)
+{
+    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)
+{
+    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)
+{
+    ctx->ol = MXL_RV32;
+    return gen_th_mac(ctx, a, tcg_gen_sub_tl, NULL);
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 496ae37f26..55c019e55b 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -7,6 +7,7 @@ gen = [
   decodetree.process('xtheadbs.decode', extra_args: '--static-decode=decode_xtheadbs'),
   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('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 986243df99..56cc89ce4a 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -137,6 +137,7 @@ MATERIALISE_EXT_PREDICATE(xtheadbb)
 MATERIALISE_EXT_PREDICATE(xtheadbs)
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
 MATERIALISE_EXT_PREDICATE(xtheadcondmov);
+MATERIALISE_EXT_PREDICATE(xtheadmac);
 MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
@@ -729,6 +730,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 #include "decode-xtheadbs.c.inc"
 #include "decode-xtheadcmo.c.inc"
 #include "decode-xtheadcondmov.c.inc"
+#include "decode-xtheadmac.c.inc"
 #include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
 
@@ -1055,6 +1057,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         { has_xtheadbs_p, decode_xtheadbs },
         { has_xtheadcmo_p, decode_xtheadcmo },
         { has_xtheadcondmov_p, decode_xtheadcondmov },
+        { has_xtheadmac_p, decode_xtheadmac },
         { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
     };
diff --git a/target/riscv/xtheadmac.decode b/target/riscv/xtheadmac.decode
new file mode 100644
index 0000000000..dda1f82334
--- /dev/null
+++ b/target/riscv/xtheadmac.decode
@@ -0,0 +1,30 @@
+#
+# RISC-V instruction decode for the XTheadMac extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadMac extension provides multiply-accumulate instructions.
+#
+# 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
+%rs2       20:5
+%rs1       15:5
+%rd        7:5
+
+# Argument sets
+&r         rd rs1 rs2		!extern
+
+# Formats:
+@r          ..... .. ..... ..... ... ..... ....... &r %rs2 %rs1 %rd
+
+# T-Head conditional move instructions
+th_mula     00100 00 ..... ..... 001 ..... 0001011 @r
+th_mulah    00101 00 ..... ..... 001 ..... 0001011 @r
+th_mulaw    00100 10 ..... ..... 001 ..... 0001011 @r
+th_muls     00100 01 ..... ..... 001 ..... 0001011 @r
+th_mulsh    00101 01 ..... ..... 001 ..... 0001011 @r
+th_mulsw    00100 11 ..... ..... 001 ..... 0001011 @r
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 07/11] RISC-V: Adding T-Head XMAE support
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (5 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 06/11] RISC-V: Adding T-Head multiply-accumulate instructions Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-06 12:22 ` [PATCH 08/11] RISC-V: Adding T-Head MemPair extension Christoph Muellner
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head specific extended memory
attributes. Similar like Svpbmt, this support does not have much effect
as most behaviour is not modelled in QEMU.

We also don't set any EDATA information, because XMAE discovery is done
using the vendor ID in the Linux kernel.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c        | 1 +
 target/riscv/cpu.h        | 1 +
 target/riscv/cpu_helper.c | 6 ++++--
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index e2d74fa701..990a1f57af 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -927,6 +927,7 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
     DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, 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),
 
     /* These are experimental so mark with 'x-' */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d0dc4ab031..1982d9293f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -447,6 +447,7 @@ struct RISCVCPUConfig {
     bool ext_xtheadcondmov;
     bool ext_xtheadmac;
     bool ext_xtheadsync;
+    bool ext_xtheadxmae;
     bool ext_XVentanaCondOps;
 
     uint8_t pmu_num;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 59b3680b1b..d7941e64e1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -927,7 +927,8 @@ restart:
 
         if (riscv_cpu_sxl(env) == MXL_RV32) {
             ppn = pte >> PTE_PPN_SHIFT;
-        } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot) {
+        } else if (cpu->cfg.ext_svpbmt || cpu->cfg.ext_svnapot ||
+                   cpu->cfg.ext_xtheadxmae) {
             ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
         } else {
             ppn = pte >> PTE_PPN_SHIFT;
@@ -939,7 +940,8 @@ restart:
         if (!(pte & PTE_V)) {
             /* Invalid PTE */
             return TRANSLATE_FAIL;
-        } else if (!cpu->cfg.ext_svpbmt && (pte & PTE_PBMT)) {
+        } else if (!cpu->cfg.ext_svpbmt && (pte & PTE_PBMT) &&
+                   !cpu->cfg.ext_xtheadxmae) {
             return TRANSLATE_FAIL;
         } else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
             /* Inner PTE, continue walking */
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 08/11] RISC-V: Adding T-Head MemPair extension
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (6 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 07/11] RISC-V: Adding T-Head XMAE support Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-06 12:22 ` [PATCH 09/11] RISC-V: Adding T-Head MemIdx extension Christoph Muellner
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

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 --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
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 09/11] RISC-V: Adding T-Head MemIdx extension
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (7 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 08/11] RISC-V: Adding T-Head MemPair extension Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-06 12:22 ` [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension Christoph Muellner
  2022-09-06 12:22 ` [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs Christoph Muellner
  10 siblings, 0 replies; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head MemIdx 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 | 377 +++++++++++++++++++++
 target/riscv/meson.build                   |   1 +
 target/riscv/translate.c                   |   3 +
 target/riscv/xtheadmemidx.decode           |  73 ++++
 6 files changed, 456 insertions(+)
 create mode 100644 target/riscv/xtheadmemidx.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9370722ffa..0af9cc7bec 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("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, 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),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6cc2d19075..590a597f39 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_xtheadmemidx;
     bool ext_xtheadmempair;
     bool ext_xtheadsync;
     bool ext_xtheadxmae;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index a2bae249fb..95c6b10d77 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -374,3 +374,380 @@ static bool trans_th_swd(DisasContext *ctx, arg_th_pair *a)
 {
     return gen_storepair_tl(ctx, a, MO_TESL, 3);
 }
+
+/*
+ * Load with memop from indexed address and add sext(imm5 << imm2) to rs1.
+ * If !preinc, then the address is rs1.
+ * If  preinc, then the address is rs1 + (sext(imm5) << imm2).
+ */
+static bool gen_load_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
+                         bool preinc)
+{
+    TCGv rd = dest_gpr(ctx, a->rd);
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+    TCGv offs = tcg_temp_new();
+
+    tcg_gen_movi_tl(offs, a->imm5);
+    tcg_gen_sextract_tl(offs, offs, 0, 5);
+    tcg_gen_shli_tl(offs, offs, a->imm2);
+
+    if (preinc) {
+        tcg_gen_add_tl(addr, base, offs);
+        if (get_xl(ctx) == MXL_RV32) {
+            tcg_gen_ext32u_tl(addr, addr);
+        }
+    } else {
+        tcg_gen_mov_tl(addr, base);
+    }
+
+    tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
+
+    if (!preinc) {
+        tcg_gen_add_tl(addr, base, offs);
+        if (get_xl(ctx) == MXL_RV32) {
+            tcg_gen_ext32u_tl(addr, addr);
+        }
+    }
+
+    gen_set_gpr(ctx, a->rd, rd);
+    gen_set_gpr(ctx, a->rs1, addr);
+
+    tcg_temp_free(addr);
+    tcg_temp_free(offs);
+    return true;
+}
+
+/*
+ * Store with memop to indexed address and add sext(imm5 << imm2) to rs1.
+ * If !preinc, then the address is rs1.
+ * If  preinc, then the address is rs1 + (sext(imm5) << imm2).
+ */
+static bool gen_store_inc(DisasContext *ctx, arg_th_meminc *a, MemOp memop,
+                          bool preinc)
+{
+    TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+    TCGv offs = tcg_temp_new();
+
+    tcg_gen_movi_tl(offs, a->imm5);
+    tcg_gen_sextract_tl(offs, offs, 0, 5);
+    tcg_gen_shli_tl(offs, offs, a->imm2);
+
+    if (preinc) {
+        tcg_gen_add_tl(addr, base, offs);
+        if (get_xl(ctx) == MXL_RV32) {
+            tcg_gen_ext32u_tl(addr, addr);
+        }
+    } else {
+        tcg_gen_mov_tl(addr, base);
+    }
+
+    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
+
+    if (!preinc) {
+        tcg_gen_add_tl(addr, base, offs);
+        if (get_xl(ctx) == MXL_RV32) {
+            tcg_gen_ext32u_tl(addr, addr);
+        }
+    }
+
+    gen_set_gpr(ctx, a->rs1, addr);
+
+    tcg_temp_free(addr);
+    tcg_temp_free(offs);
+    return true;
+}
+
+static bool trans_th_ldia(DisasContext *ctx, arg_th_meminc *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_inc(ctx, a, MO_TESQ, false);
+}
+
+static bool trans_th_ldib(DisasContext *ctx, arg_th_meminc *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_inc(ctx, a, MO_TESQ, true);
+}
+
+static bool trans_th_lwia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TESL, false);
+}
+
+static bool trans_th_lwib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TESL, true);
+}
+
+static bool trans_th_lwuia(DisasContext *ctx, arg_th_meminc *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_inc(ctx, a, MO_TEUL, false);
+}
+
+static bool trans_th_lwuib(DisasContext *ctx, arg_th_meminc *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_inc(ctx, a, MO_TEUL, true);
+}
+
+static bool trans_th_lhia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TESW, false);
+}
+
+static bool trans_th_lhib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TESW, true);
+}
+
+static bool trans_th_lhuia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TEUW, false);
+}
+
+static bool trans_th_lhuib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_TEUW, true);
+}
+
+static bool trans_th_lbia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_SB, false);
+}
+
+static bool trans_th_lbib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_SB, true);
+}
+
+static bool trans_th_lbuia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_UB, false);
+}
+
+static bool trans_th_lbuib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_load_inc(ctx, a, MO_UB, true);
+}
+
+static bool trans_th_sdia(DisasContext *ctx, arg_th_meminc *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_store_inc(ctx, a, MO_TESQ, false);
+}
+
+static bool trans_th_sdib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_TESQ, true);
+}
+
+static bool trans_th_swia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_TESL, false);
+}
+
+static bool trans_th_swib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_TESL, true);
+}
+
+static bool trans_th_shia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_TESW, false);
+}
+
+static bool trans_th_shib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_TESW, true);
+}
+
+static bool trans_th_sbia(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_SB, false);
+}
+
+static bool trans_th_sbib(DisasContext *ctx, arg_th_meminc *a)
+{
+    return gen_store_inc(ctx, a, MO_SB, true);
+}
+
+/*
+ * Load with memop from indexed address.
+ * If !zero_extend_offset, then address is rs1 + (rs2 << imm2).
+ * If  zero_extend_offset, then address is rs1 + (zext(rs2[31:0]) << imm2).
+ */
+static bool gen_load_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
+                         bool zero_extend_offset)
+{
+    TCGv rd = dest_gpr(ctx, a->rd);
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv offs = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    if (zero_extend_offset) {
+        tcg_gen_extract_tl(addr, offs, 0, 32);
+    } else {
+        tcg_gen_mov_tl(addr, offs);
+    }
+    tcg_gen_shli_tl(addr, addr, a->imm2);
+    tcg_gen_add_tl(addr, base, addr);
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
+    }
+
+    tcg_gen_qemu_ld_tl(rd, addr, ctx->mem_idx, memop);
+    gen_set_gpr(ctx, a->rd, rd);
+
+    tcg_temp_free(addr);
+    return true;
+}
+
+/*
+ * Store with memop to indexed address.
+ * If !zero_extend_offset, then address is rs1 + (rs2 << imm2).
+ * If  zero_extend_offset, then address is rs1 + (zext(rs2[31:0]) << imm2).
+ */
+static bool gen_store_idx(DisasContext *ctx, arg_th_memidx *a, MemOp memop,
+                          bool zero_extend_offset)
+{
+    TCGv data = get_gpr(ctx, a->rd, EXT_NONE);
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv offs = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    if (zero_extend_offset) {
+        tcg_gen_extract_tl(addr, offs, 0, 32);
+    } else {
+        tcg_gen_mov_tl(addr, offs);
+    }
+    tcg_gen_shli_tl(addr, addr, a->imm2);
+    tcg_gen_add_tl(addr, base, addr);
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
+    }
+
+    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
+
+    tcg_temp_free(addr);
+    return true;
+}
+
+static bool trans_th_lrd(DisasContext *ctx, arg_th_memidx *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_idx(ctx, a, MO_TESQ, false);
+}
+
+static bool trans_th_lrw(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TESL, false);
+}
+
+static bool trans_th_lrwu(DisasContext *ctx, arg_th_memidx *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_idx(ctx, a, MO_TEUL, false);
+}
+
+static bool trans_th_lrh(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TESW, false);
+}
+
+static bool trans_th_lrhu(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TEUW, false);
+}
+
+static bool trans_th_lrb(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_SB, false);
+}
+
+static bool trans_th_lrbu(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_UB, false);
+}
+
+static bool trans_th_srd(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESQ, false);
+}
+
+static bool trans_th_srw(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESL, false);
+}
+
+static bool trans_th_srh(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESW, false);
+}
+
+static bool trans_th_srb(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_SB, false);
+}
+static bool trans_th_lurd(DisasContext *ctx, arg_th_memidx *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_idx(ctx, a, MO_TESQ, true);
+}
+
+static bool trans_th_lurw(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TESL, true);
+}
+
+static bool trans_th_lurwu(DisasContext *ctx, arg_th_memidx *a)
+{
+    REQUIRE_64BIT(ctx);
+    return gen_load_idx(ctx, a, MO_TEUL, true);
+}
+
+static bool trans_th_lurh(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TESW, true);
+}
+
+static bool trans_th_lurhu(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_TEUW, true);
+}
+
+static bool trans_th_lurb(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_SB, true);
+}
+
+static bool trans_th_lurbu(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_load_idx(ctx, a, MO_UB, true);
+}
+
+static bool trans_th_surd(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESQ, true);
+}
+
+static bool trans_th_surw(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESL, true);
+}
+
+static bool trans_th_surh(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_TESW, true);
+}
+
+static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a)
+{
+    return gen_store_idx(ctx, a, MO_SB, true);
+}
+
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 998f0ba336..30bb4c5bab 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('xtheadmemidx.decode', extra_args: '--static-decode=decode_xtheadmemidx'),
   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 308de419cb..1cb0d885b8 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(xtheadmemidx);
 MATERIALISE_EXT_PREDICATE(xtheadmempair);
 MATERIALISE_EXT_PREDICATE(xtheadsync)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
@@ -732,6 +733,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-xtheadmemidx.c.inc"
 #include "decode-xtheadmempair.c.inc"
 #include "decode-xtheadsync.c.inc"
 #include "decode-XVentanaCondOps.c.inc"
@@ -1060,6 +1062,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_xtheadmemidx_p, decode_xtheadmemidx },
         { has_xtheadmempair_p, decode_xtheadmempair },
         { has_xtheadsync_p, decode_xtheadsync },
         { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
diff --git a/target/riscv/xtheadmemidx.decode b/target/riscv/xtheadmemidx.decode
new file mode 100644
index 0000000000..d2e0f2af6f
--- /dev/null
+++ b/target/riscv/xtheadmemidx.decode
@@ -0,0 +1,73 @@
+#
+# RISC-V instruction decode for the XTheadMemIdx extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadMemIdx extension provides GPR memory 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
+%imm2      25:2
+%imm5      20:5
+%rs2       20:5
+%rs1       15:5
+%rd         7:5
+
+# Argument sets
+&th_meminc      rd rs1 imm5 imm2
+&th_memidx      rd rs1 rs2 imm2
+
+# Formats:
+@th_meminc   ..... .. ..... ..... ... ..... ....... &th_meminc %rd %rs1 %imm5 %imm2
+@th_memidx   ..... .. ..... ..... ... ..... ....... &th_memidx %rd %rs1 %rs2 %imm2
+
+th_ldia      01111 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_ldib      01101 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lwia      01011 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lwib      01001 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lwuia     11011 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lwuib     11001 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lhia      00111 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lhib      00101 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lhuia     10111 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lhuib     10101 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lbia      00011 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lbib      00001 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lbuia     10011 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_lbuib     10001 .. ..... ..... 100 ..... 0001011 @th_meminc
+th_sdia      01111 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_sdib      01101 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_swia      01011 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_swib      01001 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_shia      00111 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_shib      00101 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_sbia      00011 .. ..... ..... 101 ..... 0001011 @th_meminc
+th_sbib      00001 .. ..... ..... 101 ..... 0001011 @th_meminc
+
+th_lrd       01100 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrw       01000 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrwu      11000 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrh       00100 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrhu      10100 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrb       00000 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lrbu      10000 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_srd       01100 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_srw       01000 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_srh       00100 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_srb       00000 .. ..... ..... 101 ..... 0001011 @th_memidx
+
+th_lurd      01110 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurw      01010 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurwu     11010 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurh      00110 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurhu     10110 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurb      00010 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_lurbu     10010 .. ..... ..... 100 ..... 0001011 @th_memidx
+th_surd      01110 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_surw      01010 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_surh      00110 .. ..... ..... 101 ..... 0001011 @th_memidx
+th_surb      00010 .. ..... ..... 101 ..... 0001011 @th_memidx
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (8 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 09/11] RISC-V: Adding T-Head MemIdx extension Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-08  7:45   ` Richard Henderson
  2022-09-06 12:22 ` [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs Christoph Muellner
  10 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the T-Head FMemIdx 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 | 121 +++++++++++++++++++++
 target/riscv/meson.build                   |   1 +
 target/riscv/translate.c                   |   3 +
 target/riscv/xtheadfmemidx.decode          |  34 ++++++
 6 files changed, 161 insertions(+)
 create mode 100644 target/riscv/xtheadfmemidx.decode

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 0af9cc7bec..01d85f0f96 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -925,6 +925,7 @@ static Property riscv_cpu_extensions[] = {
     DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
     DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
     DEFINE_PROP_BOOL("xtheadcondmov", RISCVCPU, cfg.ext_xtheadcondmov, false),
+    DEFINE_PROP_BOOL("xtheadfmemidx", RISCVCPU, cfg.ext_xtheadfmemidx, false),
     DEFINE_PROP_BOOL("xtheadmac", RISCVCPU, cfg.ext_xtheadmac, false),
     DEFINE_PROP_BOOL("xtheadmemidx", RISCVCPU, cfg.ext_xtheadmemidx, false),
     DEFINE_PROP_BOOL("xtheadmempair", RISCVCPU, cfg.ext_xtheadmempair, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 590a597f39..8b02f530a6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -445,6 +445,7 @@ struct RISCVCPUConfig {
     bool ext_xtheadbs;
     bool ext_xtheadcmo;
     bool ext_xtheadcondmov;
+    bool ext_xtheadfmemidx;
     bool ext_xtheadmac;
     bool ext_xtheadmemidx;
     bool ext_xtheadmempair;
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
index 95c6b10d77..1a91371318 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -751,3 +751,124 @@ static bool trans_th_surb(DisasContext *ctx, arg_th_memidx *a)
     return gen_store_idx(ctx, a, MO_SB, true);
 }
 
+/*
+ * Load 64-bit float from indexed address.
+ * If !zero_extend_offset, then address is rs1 + (rs2 << imm2).
+ * If  zero_extend_offset, then address is rs1 + (zext(rs2[31:0]) << imm2).
+ */
+static bool gen_fload_idx(DisasContext *ctx, arg_th_fmemidx *a, MemOp memop,
+                          bool zero_extend_offset)
+{
+    TCGv_i64 rd = cpu_fpr[a->rd];
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv offs = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    if (zero_extend_offset) {
+        tcg_gen_extract_tl(addr, offs, 0, 32);
+    } else {
+        tcg_gen_mov_tl(addr, offs);
+    }
+    tcg_gen_shli_tl(addr, addr, a->imm2);
+    tcg_gen_add_tl(addr, base, addr);
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
+    }
+
+    tcg_gen_qemu_ld_i64(rd, addr, ctx->mem_idx, memop);
+    if ((memop & MO_SIZE) == MO_32) {
+        gen_nanbox_s(rd, rd);
+    }
+
+    mark_fs_dirty(ctx);
+    tcg_temp_free(addr);
+    return true;
+}
+
+/*
+ * Store 64-bit float to indexed address.
+ * If !zero_extend_offset, then address is rs1 + (rs2 << imm2).
+ * If  zero_extend_offset, then address is rs1 + (zext(rs2[31:0]) << imm2).
+ */
+static bool gen_fstore_idx(DisasContext *ctx, arg_th_fmemidx *a, MemOp memop,
+                           bool zero_extend_offset)
+{
+    TCGv_i64 rd = cpu_fpr[a->rd];
+    TCGv base = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv offs = get_gpr(ctx, a->rs2, EXT_NONE);
+    TCGv addr = tcg_temp_new();
+
+    if (zero_extend_offset) {
+        tcg_gen_extract_tl(addr, offs, 0, 32);
+    } else {
+        tcg_gen_mov_tl(addr, offs);
+    }
+    tcg_gen_shli_tl(addr, addr, a->imm2);
+    tcg_gen_add_tl(addr, base, addr);
+
+    if (get_xl(ctx) == MXL_RV32) {
+        tcg_gen_ext32u_tl(addr, addr);
+    }
+
+    tcg_gen_qemu_st_i64(rd, addr, ctx->mem_idx, memop);
+
+    tcg_temp_free(addr);
+    return true;
+}
+
+static bool trans_th_flrd(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVD);
+    return gen_fload_idx(ctx, a, MO_TEUQ, false);
+}
+
+static bool trans_th_flrw(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVF);
+    return gen_fload_idx(ctx, a, MO_TEUL, false);
+}
+
+static bool trans_th_flurd(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVD);
+    return gen_fload_idx(ctx, a, MO_TEUQ, true);
+}
+
+static bool trans_th_flurw(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVF);
+    return gen_fload_idx(ctx, a, MO_TEUL, true);
+}
+
+static bool trans_th_fsrd(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVD);
+    return gen_fstore_idx(ctx, a, MO_TEUQ, false);
+}
+
+static bool trans_th_fsrw(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVF);
+    return gen_fstore_idx(ctx, a, MO_TEUL, false);
+}
+
+static bool trans_th_fsurd(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVD);
+    return gen_fstore_idx(ctx, a, MO_TEUQ, true);
+}
+
+static bool trans_th_fsurw(DisasContext *ctx, arg_th_fmemidx *a)
+{
+    REQUIRE_FPU;
+    REQUIRE_EXT(ctx, RVF);
+    return gen_fstore_idx(ctx, a, MO_TEUL, true);
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 30bb4c5bab..81175b67ce 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -7,6 +7,7 @@ gen = [
   decodetree.process('xtheadbs.decode', extra_args: '--static-decode=decode_xtheadbs'),
   decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
   decodetree.process('xtheadcondmov.decode', extra_args: '--static-decode=decode_xtheadcondmov'),
+  decodetree.process('xtheadfmemidx.decode', extra_args: '--static-decode=decode_xtheadfmemidx'),
   decodetree.process('xtheadmac.decode', extra_args: '--static-decode=decode_xtheadmac'),
   decodetree.process('xtheadmemidx.decode', extra_args: '--static-decode=decode_xtheadmemidx'),
   decodetree.process('xtheadmempair.decode', extra_args: '--static-decode=decode_xtheadmempair'),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1cb0d885b8..915ac11d3b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -137,6 +137,7 @@ MATERIALISE_EXT_PREDICATE(xtheadbb)
 MATERIALISE_EXT_PREDICATE(xtheadbs)
 MATERIALISE_EXT_PREDICATE(xtheadcmo)
 MATERIALISE_EXT_PREDICATE(xtheadcondmov);
+MATERIALISE_EXT_PREDICATE(xtheadfmemidx);
 MATERIALISE_EXT_PREDICATE(xtheadmac);
 MATERIALISE_EXT_PREDICATE(xtheadmemidx);
 MATERIALISE_EXT_PREDICATE(xtheadmempair);
@@ -732,6 +733,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 #include "decode-xtheadbs.c.inc"
 #include "decode-xtheadcmo.c.inc"
 #include "decode-xtheadcondmov.c.inc"
+#include "decode-xtheadfmemidx.c.inc"
 #include "decode-xtheadmac.c.inc"
 #include "decode-xtheadmemidx.c.inc"
 #include "decode-xtheadmempair.c.inc"
@@ -1061,6 +1063,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
         { has_xtheadbs_p, decode_xtheadbs },
         { has_xtheadcmo_p, decode_xtheadcmo },
         { has_xtheadcondmov_p, decode_xtheadcondmov },
+        { has_xtheadfmemidx_p, decode_xtheadfmemidx },
         { has_xtheadmac_p, decode_xtheadmac },
         { has_xtheadmemidx_p, decode_xtheadmemidx },
         { has_xtheadmempair_p, decode_xtheadmempair },
diff --git a/target/riscv/xtheadfmemidx.decode b/target/riscv/xtheadfmemidx.decode
new file mode 100644
index 0000000000..43e0f80df8
--- /dev/null
+++ b/target/riscv/xtheadfmemidx.decode
@@ -0,0 +1,34 @@
+#
+# RISC-V instruction decode for the XTheadMemIdx extension
+#
+# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
+#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# The XTheadFMemIdx extension provides floating-point memory 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
+%imm2       25:2
+%rs2        20:5
+%rs1        15:5
+%rd          7:5
+
+# Argument sets
+&th_fmemidx rd rs1 rs2 imm2
+
+# Formats
+@th_fmemidx ..... .. ..... ..... ... ..... ....... &th_fmemidx %rd %rs1 %rs2 %imm2
+
+# Instructions
+th_flrd     01100 .. ..... ..... 110 ..... 0001011 @th_fmemidx
+th_flrw     01000 .. ..... ..... 110 ..... 0001011 @th_fmemidx
+th_flurd    01110 .. ..... ..... 110 ..... 0001011 @th_fmemidx
+th_flurw    01010 .. ..... ..... 110 ..... 0001011 @th_fmemidx
+
+th_fsrd     01100 .. ..... ..... 111 ..... 0001011 @th_fmemidx
+th_fsrw     01000 .. ..... ..... 111 ..... 0001011 @th_fmemidx
+th_fsurd    01110 .. ..... ..... 111 ..... 0001011 @th_fmemidx
+th_fsurw    01010 .. ..... ..... 111 ..... 0001011 @th_fmemidx
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs
  2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
                   ` (9 preceding siblings ...)
  2022-09-06 12:22 ` [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension Christoph Muellner
@ 2022-09-06 12:22 ` Christoph Muellner
  2022-09-08  7:46   ` Richard Henderson
  10 siblings, 1 reply; 30+ messages in thread
From: Christoph Muellner @ 2022-09-06 12:22 UTC (permalink / raw)
  To: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds the following T-Head CPUs to the list of known CPUs:
* C906
* C910

Selecting those CPUs will automatically enable the available
ISA extensions of the CPUs (incl. vendor extensions).

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 target/riscv/cpu.c          | 32 ++++++++++++++++++++++++++++++++
 target/riscv/cpu.h          |  3 +++
 target/riscv/cpu_vendorid.h |  6 ++++++
 3 files changed, 41 insertions(+)
 create mode 100644 target/riscv/cpu_vendorid.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 01d85f0f96..1db440e21f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -194,6 +194,36 @@ static void rv64_sifive_e_cpu_init(Object *obj)
     cpu->cfg.mmu = false;
 }
 
+static void rv64_thead_c906_cpu_init(Object *obj)
+{
+    CPURISCVState *env = &RISCV_CPU(obj)->env;
+    RISCVCPU *cpu = RISCV_CPU(obj);
+
+    set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+    set_priv_version(env, PRIV_VERSION_1_10_0);
+
+    cpu->cfg.ext_g = true;
+    cpu->cfg.ext_c = true;
+    cpu->cfg.ext_u = true;
+    cpu->cfg.ext_s = true;
+    cpu->cfg.ext_icsr = true;
+    cpu->cfg.ext_zfh = true;
+    cpu->cfg.mmu = true;
+    cpu->cfg.ext_xtheadba = true;
+    cpu->cfg.ext_xtheadbb = true;
+    cpu->cfg.ext_xtheadbs = true;
+    cpu->cfg.ext_xtheadcmo = true;
+    cpu->cfg.ext_xtheadcondmov = true;
+    cpu->cfg.ext_xtheadfmemidx = true;
+    cpu->cfg.ext_xtheadmac = true;
+    cpu->cfg.ext_xtheadmemidx = true;
+    cpu->cfg.ext_xtheadmempair = true;
+    cpu->cfg.ext_xtheadsync = true;
+    cpu->cfg.ext_xtheadxmae = true;
+
+    cpu->cfg.mvendorid = THEAD_VENDOR_ID;
+}
+
 static void rv128_base_cpu_init(Object *obj)
 {
     if (qemu_tcg_mttcg_enabled()) {
@@ -1205,6 +1235,8 @@ static const TypeInfo riscv_cpu_type_infos[] = {
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,       rv64_sifive_e_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,       rv64_sifive_u_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C,         rv64_sifive_u_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,       rv64_thead_c906_cpu_init),
+    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C910,       rv64_thead_c906_cpu_init),
     DEFINE_CPU(TYPE_RISCV_CPU_BASE128,          rv128_base_cpu_init),
 #endif
 };
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8b02f530a6..74b291b4e4 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -27,6 +27,7 @@
 #include "qom/object.h"
 #include "qemu/int128.h"
 #include "cpu_bits.h"
+#include "cpu_vendorid.h"
 
 #define TCG_GUEST_DEFAULT_MO 0
 
@@ -53,6 +54,8 @@
 #define TYPE_RISCV_CPU_SIFIVE_E51       RISCV_CPU_TYPE_NAME("sifive-e51")
 #define TYPE_RISCV_CPU_SIFIVE_U34       RISCV_CPU_TYPE_NAME("sifive-u34")
 #define TYPE_RISCV_CPU_SIFIVE_U54       RISCV_CPU_TYPE_NAME("sifive-u54")
+#define TYPE_RISCV_CPU_THEAD_C906       RISCV_CPU_TYPE_NAME("thead-c906")
+#define TYPE_RISCV_CPU_THEAD_C910       RISCV_CPU_TYPE_NAME("thead-c910")
 #define TYPE_RISCV_CPU_HOST             RISCV_CPU_TYPE_NAME("host")
 
 #if defined(TARGET_RISCV32)
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
new file mode 100644
index 0000000000..a5aa249bc9
--- /dev/null
+++ b/target/riscv/cpu_vendorid.h
@@ -0,0 +1,6 @@
+#ifndef TARGET_RISCV_CPU_VENDORID_H
+#define TARGET_RISCV_CPU_VENDORID_H
+
+#define THEAD_VENDOR_ID         0x5b7
+
+#endif /*  TARGET_RISCV_CPU_VENDORID_H */
-- 
2.37.2



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions
  2022-09-06 12:22 ` [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions Christoph Muellner
@ 2022-09-08  7:29   ` Richard Henderson
  2022-09-09 17:21     ` Christoph Müllner
                       ` (2 more replies)
  0 siblings, 3 replies; 30+ messages in thread
From: Richard Henderson @ 2022-09-08  7:29 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang,
	Zhiwei Liu

On 9/6/22 13:22, Christoph Muellner wrote:
> +NOP_PRIVCHECK(th_sfence_vmas, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_sync, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)

These should not be nops: th_sfence_vmas requires a tlb flush; th.sync{,.i} needs to end 
the current translation block; th.sync.{s,is} needs multiprocessor sync, which involves a 
call to async_safe_run_on_cpu.


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension
  2022-09-06 12:22 ` [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension Christoph Muellner
@ 2022-09-08  7:45   ` Richard Henderson
  2022-09-09 17:21     ` Christoph Müllner
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2022-09-08  7:45 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang,
	Zhiwei Liu

On 9/6/22 13:22, Christoph Muellner wrote:
> @@ -732,6 +733,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>   #include "decode-xtheadbs.c.inc"
>   #include "decode-xtheadcmo.c.inc"
>   #include "decode-xtheadcondmov.c.inc"
> +#include "decode-xtheadfmemidx.c.inc"
>   #include "decode-xtheadmac.c.inc"
>   #include "decode-xtheadmemidx.c.inc"
>   #include "decode-xtheadmempair.c.inc"
> @@ -1061,6 +1063,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>           { has_xtheadbs_p, decode_xtheadbs },
>           { has_xtheadcmo_p, decode_xtheadcmo },
>           { has_xtheadcondmov_p, decode_xtheadcondmov },
> +        { has_xtheadfmemidx_p, decode_xtheadfmemidx },
>           { has_xtheadmac_p, decode_xtheadmac },
>           { has_xtheadmemidx_p, decode_xtheadmemidx },
>           { has_xtheadmempair_p, decode_xtheadmempair },

I think you should have a single decoder for all of the xthread extensions, and each 
translate function should test for the individual extension.  You know up-front that these 
extensions do not conflict.


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs
  2022-09-06 12:22 ` [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs Christoph Muellner
@ 2022-09-08  7:46   ` Richard Henderson
  2022-09-08  8:23     ` Christoph Müllner
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2022-09-08  7:46 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang,
	Zhiwei Liu

On 9/6/22 13:22, Christoph Muellner wrote:
> +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,       rv64_thead_c906_cpu_init),
> +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C910,       rv64_thead_c906_cpu_init),

Why model both if they're identical?


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs
  2022-09-08  7:46   ` Richard Henderson
@ 2022-09-08  8:23     ` Christoph Müllner
  2022-09-08  8:56       ` Richard Henderson
  0 siblings, 1 reply; 30+ messages in thread
From: Christoph Müllner @ 2022-09-08  8:23 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt, Nelson Chu,
	Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang, Zhiwei Liu

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

On Thu, Sep 8, 2022 at 9:46 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 9/6/22 13:22, Christoph Muellner wrote:
> > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,
>  rv64_thead_c906_cpu_init),
> > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C910,
>  rv64_thead_c906_cpu_init),
>
> Why model both if they're identical?
>

I figured that users might expect that (existence of "thead-c906" and
"thead-c910").
And using "thead-c9xx" feels like it would be regretted in the future.

Should I drop "thead-c910"?



>
>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1157 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs
  2022-09-08  8:23     ` Christoph Müllner
@ 2022-09-08  8:56       ` Richard Henderson
  2022-09-08  9:01         ` Christoph Müllner
  0 siblings, 1 reply; 30+ messages in thread
From: Richard Henderson @ 2022-09-08  8:56 UTC (permalink / raw)
  To: Christoph Müllner
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt, Nelson Chu,
	Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang, Zhiwei Liu

On 9/8/22 09:23, Christoph Müllner wrote:
> 
> 
> On Thu, Sep 8, 2022 at 9:46 AM Richard Henderson <richard.henderson@linaro.org 
> <mailto:richard.henderson@linaro.org>> wrote:
> 
>     On 9/6/22 13:22, Christoph Muellner wrote:
>      > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,       rv64_thead_c906_cpu_init),
>      > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C910,       rv64_thead_c906_cpu_init),
> 
>     Why model both if they're identical?
> 
> 
> I figured that users might expect that (existence of "thead-c906" and "thead-c910").
> And using "thead-c9xx" feels like it would be regretted in the future.
> 
> Should I drop "thead-c910"?

Quite possibly.  For Arm, we don't try to supply every cpu model, only those that differ 
in some substantial way.


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs
  2022-09-08  8:56       ` Richard Henderson
@ 2022-09-08  9:01         ` Christoph Müllner
  0 siblings, 0 replies; 30+ messages in thread
From: Christoph Müllner @ 2022-09-08  9:01 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt, Nelson Chu,
	Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang, Zhiwei Liu

[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

On Thu, Sep 8, 2022 at 10:56 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 9/8/22 09:23, Christoph Müllner wrote:
> >
> >
> > On Thu, Sep 8, 2022 at 9:46 AM Richard Henderson <
> richard.henderson@linaro.org
> > <mailto:richard.henderson@linaro.org>> wrote:
> >
> >     On 9/6/22 13:22, Christoph Muellner wrote:
> >      > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,
>  rv64_thead_c906_cpu_init),
> >      > +    DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C910,
>  rv64_thead_c906_cpu_init),
> >
> >     Why model both if they're identical?
> >
> >
> > I figured that users might expect that (existence of "thead-c906" and
> "thead-c910").
> > And using "thead-c9xx" feels like it would be regretted in the future.
> >
> > Should I drop "thead-c910"?
>
> Quite possibly.  For Arm, we don't try to supply every cpu model, only
> those that differ
> in some substantial way.
>

Ok, will do.

Thanks!


>
>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1775 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions
  2022-09-08  7:29   ` Richard Henderson
@ 2022-09-09 17:21     ` Christoph Müllner
  2022-12-12  9:12     ` LIU Zhiwei
  2022-12-12  9:21     ` LIU Zhiwei
  2 siblings, 0 replies; 30+ messages in thread
From: Christoph Müllner @ 2022-09-09 17:21 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt, Nelson Chu,
	Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang, Zhiwei Liu

[-- Attachment #1: Type: text/plain, Size: 992 bytes --]

On Thu, Sep 8, 2022 at 9:30 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 9/6/22 13:22, Christoph Muellner wrote:
> > +NOP_PRIVCHECK(th_sfence_vmas, REQUIRE_PRIV_MHS)
> > +NOP_PRIVCHECK(th_sync, REQUIRE_PRIV_MHSU)
> > +NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
> > +NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
> > +NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
>
> These should not be nops: th_sfence_vmas requires a tlb flush;
> th.sync{,.i} needs to end
> the current translation block; th.sync.{s,is} needs multiprocessor sync,
> which involves a
> call to async_safe_run_on_cpu.
>

Understood.
For a new revision, I'll do the following:
* th_sfence_vmas: async_safe_run_on_cpu() with run_on_cpu_func which
flushes TLB on all CPUs (similar like trans_sfence_vma())
* th_sync/th_sync_i: end the TB (similar like trans_fence_i())
* th_sync_s/th_sync_is: async_safe_run_on_cpu() with run_on_cpu_func which
ends the TB (similar like trans_fence_i())

Thanks!


>
>
> r~
>

[-- Attachment #2: Type: text/html, Size: 1601 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension
  2022-09-08  7:45   ` Richard Henderson
@ 2022-09-09 17:21     ` Christoph Müllner
  0 siblings, 0 replies; 30+ messages in thread
From: Christoph Müllner @ 2022-09-09 17:21 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-riscv, qemu-devel, Alistair Francis, Bin Meng,
	Philipp Tomsich, Heiko Stübner, Palmer Dabbelt, Nelson Chu,
	Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang, Zhiwei Liu

[-- Attachment #1: Type: text/plain, Size: 1309 bytes --]

On Thu, Sep 8, 2022 at 9:45 AM Richard Henderson <
richard.henderson@linaro.org> wrote:

> On 9/6/22 13:22, Christoph Muellner wrote:
> > @@ -732,6 +733,7 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
> >   #include "decode-xtheadbs.c.inc"
> >   #include "decode-xtheadcmo.c.inc"
> >   #include "decode-xtheadcondmov.c.inc"
> > +#include "decode-xtheadfmemidx.c.inc"
> >   #include "decode-xtheadmac.c.inc"
> >   #include "decode-xtheadmemidx.c.inc"
> >   #include "decode-xtheadmempair.c.inc"
> > @@ -1061,6 +1063,7 @@ static void decode_opc(CPURISCVState *env,
> DisasContext *ctx, uint16_t opcode)
> >           { has_xtheadbs_p, decode_xtheadbs },
> >           { has_xtheadcmo_p, decode_xtheadcmo },
> >           { has_xtheadcondmov_p, decode_xtheadcondmov },
> > +        { has_xtheadfmemidx_p, decode_xtheadfmemidx },
> >           { has_xtheadmac_p, decode_xtheadmac },
> >           { has_xtheadmemidx_p, decode_xtheadmemidx },
> >           { has_xtheadmempair_p, decode_xtheadmempair },
>
> I think you should have a single decoder for all of the xthread
> extensions, and each
> translate function should test for the individual extension.  You know
> up-front that these
> extensions do not conflict.
>
>
Ok, I will restructure the series and use a single decoder.

Thanks!


>
> r~
>

[-- Attachment #2: Type: text/html, Size: 2055 bytes --]

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 01/11] riscv: Add privilege level to DisasContext
  2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
@ 2022-09-16  2:46   ` LIU Zhiwei
  2022-09-16  6:00   ` Richard Henderson
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-09-16  2:46 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

On 2022/9/6 20:22, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This allows privileged instructions to check the required
> privilege level in the translation without calling a helper.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   target/riscv/translate.c | 4 ++++
>   1 file changed, 4 insertions(+)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 63b04e8a94..fd241ff667 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -59,6 +59,9 @@ typedef struct DisasContext {
>       /* pc_succ_insn points to the instruction following base.pc_next */
>       target_ulong pc_succ_insn;
>       target_ulong priv_ver;
> +#ifndef CONFIG_USER_ONLY
> +    target_ulong priv;
> +#endif
>       RISCVMXL misa_mxl_max;
>       RISCVMXL xl;
>       uint32_t misa_ext;
> @@ -1079,6 +1082,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>       ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
>       ctx->priv_ver = env->priv_ver;
>   #if !defined(CONFIG_USER_ONLY)
> +    ctx->priv = env->priv;
>       if (riscv_has_ext(env, RVH)) {
>           ctx->virt_enabled = riscv_cpu_virt_enabled(env);
>       } else {


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] RISC-V: Adding T-Head CMO instructions
  2022-09-06 12:22 ` [PATCH 02/11] RISC-V: Adding T-Head CMO instructions Christoph Muellner
@ 2022-09-16  2:47   ` LIU Zhiwei
  2022-09-16  6:43   ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-09-16  2:47 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang

Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>

Zhiwei

On 2022/9/6 20:22, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds support for the T-Head CMO instructions.
> To avoid interfering with standard extensions, decoder and translation
> are in its own T-Head specific files.
> Future patches should be able to easily add additional T-Head extesions.
>
> The implementation does not have much functionality (besides accepting
> the instructions and not qualifying them as illegal instructions if
> the hart executes in the required privilege level for the instruction),
> as QEMU does not model CPU caches and instructions don't have any
> exception behaviour (at least not documented).
>
> The documentation shows, that the instructions are gated by
> mxstatus.theadisaee and mxstatus.ucme. However, since these
> settings are not changed by the upstream Linux kernel,
> we simply enable the instructions in all modes.
>
> 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 | 66 ++++++++++++++++++++++
>   target/riscv/meson.build                   |  1 +
>   target/riscv/translate.c                   | 11 +++-
>   target/riscv/xtheadcmo.decode              | 43 ++++++++++++++
>   6 files changed, 120 insertions(+), 3 deletions(-)
>   create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
>   create mode 100644 target/riscv/xtheadcmo.decode
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ac6f82ebd0..7718ab0478 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -920,6 +920,7 @@ static Property riscv_cpu_extensions[] = {
>       DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
>   
>       /* Vendor-specific custom extensions */
> +    DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
>       DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
>   
>       /* These are experimental so mark with 'x-' */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5c7acc055a..b7ab53b7b8 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -440,6 +440,7 @@ struct RISCVCPUConfig {
>       uint64_t mimpid;
>   
>       /* Vendor-specific custom extensions */
> +    bool ext_xtheadcmo;
>       bool ext_XVentanaCondOps;
>   
>       uint8_t pmu_num;
> diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
> new file mode 100644
> index 0000000000..1b1e21ab77
> --- /dev/null
> +++ b/target/riscv/insn_trans/trans_xthead.c.inc
> @@ -0,0 +1,66 @@
> +/*
> + * RISC-V translation routines for the T-Head vendor extensions (xthead*).
> + *
> + * Copyright (c) 2022 VRULL GmbH.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#define REQUIRE_PRIV_MHSU(ctx)
> +
> +#ifndef CONFIG_USER_ONLY
> +#define REQUIRE_PRIV_MHS(ctx)                                   \
> +do {                                                            \
> +    if (!(ctx->priv == PRV_M ||                                 \
> +          ctx->priv == PRV_H ||                                 \
> +          ctx->priv == PRV_S)) {                                \
> +        return false;                                           \
> +    }                                                           \
> +} while (0)
> +#else
> +#define REQUIRE_PRIV_MHS(ctx)                                   \
> +  return false;
> +#endif
> +
> +#define NOP_PRIVCHECK(insn, privcheck)                          \
> +static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
> +{                                                               \
> +    (void) a;                                                   \
> +    privcheck(ctx);                                             \
> +    return true;                                                \
> +}
> +
> +NOP_PRIVCHECK(th_dcache_call, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_iall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cva, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_civa, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_iva, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_csw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_isw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_PRIV_MHS)
> +
> +NOP_PRIVCHECK(th_icache_iall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_ialls, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_ipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_iva, REQUIRE_PRIV_MHSU)
> +
> +NOP_PRIVCHECK(th_l2cache_call, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_PRIV_MHS)
> +
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index 6b9435d69a..1d149e05cd 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -2,6 +2,7 @@
>   gen = [
>     decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
>     decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
> +  decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
>     decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
>   ]
>   
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index fd241ff667..d16ae63850 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -132,7 +132,8 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
>           return ctx->cfg_ptr->ext_ ## ext ; \
>       }
>   
> -MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
> +MATERIALISE_EXT_PREDICATE(xtheadcmo)
> +MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
>   
>   #ifdef TARGET_RISCV32
>   #define get_xl(ctx)    MXL_RV32
> @@ -717,6 +718,10 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>   /* Include the auto-generated decoder for 32 bit insn */
>   #include "decode-insn32.c.inc"
>   
> +/* Include decoders for factored-out extensions */
> +#include "decode-xtheadcmo.c.inc"
> +#include "decode-XVentanaCondOps.c.inc"
> +
>   static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
>                                void (*func)(TCGv, TCGv, target_long))
>   {
> @@ -1018,12 +1023,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>   #include "insn_trans/trans_rvk.c.inc"
>   #include "insn_trans/trans_privileged.c.inc"
>   #include "insn_trans/trans_svinval.c.inc"
> +#include "insn_trans/trans_xthead.c.inc"
>   #include "insn_trans/trans_xventanacondops.c.inc"
>   
>   /* Include the auto-generated decoder for 16 bit insn */
>   #include "decode-insn16.c.inc"
> -/* Include decoders for factored-out extensions */
> -#include "decode-XVentanaCondOps.c.inc"
>   
>   static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>   {
> @@ -1036,6 +1040,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>           bool (*decode_func)(DisasContext *, uint32_t);
>       } decoders[] = {
>           { always_true_p,  decode_insn32 },
> +        { has_xtheadcmo_p, decode_xtheadcmo },
>           { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
>       };
>   
> diff --git a/target/riscv/xtheadcmo.decode b/target/riscv/xtheadcmo.decode
> new file mode 100644
> index 0000000000..8ddf9b3997
> --- /dev/null
> +++ b/target/riscv/xtheadcmo.decode
> @@ -0,0 +1,43 @@
> +#
> +# RISC-V translation routines for the XTheadCmo extension
> +#
> +# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# The XTheadCmo extension provides instructions for cache management.
> +#
> +# 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:
> +%rs1       15:5
> +
> +# Formats
> +@sfence_vm  ....... ..... .....   ... ..... ....... %rs1
> +
> +# *** CMO instructions
> +th_dcache_call   0000000 00001 00000 000 00000 0001011
> +th_dcache_ciall  0000000 00011 00000 000 00000 0001011
> +th_dcache_iall   0000000 00010 00000 000 00000 0001011
> +th_dcache_cpa    0000001 01001 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cipa   0000001 01011 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_ipa    0000001 01010 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cva    0000001 00101 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_civa   0000001 00111 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_iva    0000001 00110 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_csw    0000001 00001 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cisw   0000001 00011 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_isw    0000001 00010 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cpal1  0000001 01000 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cval1  0000001 00100 ..... 000 00000 0001011 @sfence_vm
> +
> +th_icache_iall   0000000 10000 00000 000 00000 0001011
> +th_icache_ialls  0000000 10001 00000 000 00000 0001011
> +th_icache_ipa    0000001 11000 ..... 000 00000 0001011 @sfence_vm
> +th_icache_iva    0000001 10000 ..... 000 00000 0001011 @sfence_vm
> +
> +th_l2cache_call  0000000 10101 00000 000 00000 0001011
> +th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
> +th_l2cache_iall  0000000 10110 00000 000 00000 0001011
> +


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 01/11] riscv: Add privilege level to DisasContext
  2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
  2022-09-16  2:46   ` LIU Zhiwei
@ 2022-09-16  6:00   ` Richard Henderson
  2022-09-16  6:05     ` Richard Henderson
  2022-09-16  6:21     ` LIU Zhiwei
  1 sibling, 2 replies; 30+ messages in thread
From: Richard Henderson @ 2022-09-16  6:00 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang,
	Zhiwei Liu

On 9/6/22 14:22, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
> 
> This allows privileged instructions to check the required
> privilege level in the translation without calling a helper.
> 
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   target/riscv/translate.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 63b04e8a94..fd241ff667 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -59,6 +59,9 @@ typedef struct DisasContext {
>       /* pc_succ_insn points to the instruction following base.pc_next */
>       target_ulong pc_succ_insn;
>       target_ulong priv_ver;
> +#ifndef CONFIG_USER_ONLY
> +    target_ulong priv;
> +#endif
>       RISCVMXL misa_mxl_max;
>       RISCVMXL xl;
>       uint32_t misa_ext;
> @@ -1079,6 +1082,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>       ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
>       ctx->priv_ver = env->priv_ver;
>   #if !defined(CONFIG_USER_ONLY)
> +    ctx->priv = env->priv;

Reading directly from env here is, in general, wrong.  Items that are constant, like 
priv_ver, are ok.  But otherwise these values must be recorded by cpu_get_tb_cpu_state().

This instance will happen to work, because the execution context is already constrained. 
In this case because env->priv == ctx->mem_idx (see cpu_mmu_index) so, really, you don't 
need this new field at all.  Or, keep the field, because it's usage will be more 
self-documentary, but copy the value from ctx->mmu_idx and add a comment.


>       if (riscv_has_ext(env, RVH)) {
>           ctx->virt_enabled = riscv_cpu_virt_enabled(env);
>       } else {

Incidentally, this (existing) usage appears to be a bug.  I can see nothing in 
cpu_get_tb_cpu_state that corresponds directly to this value.


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 01/11] riscv: Add privilege level to DisasContext
  2022-09-16  6:00   ` Richard Henderson
@ 2022-09-16  6:05     ` Richard Henderson
  2022-09-16  6:21     ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2022-09-16  6:05 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia, Yunhai Shang,
	Zhiwei Liu

On 9/16/22 08:00, Richard Henderson wrote:
> Or, keep the field, because it's usage will be more self-documentary, but copy the value 
> from ctx->mmu_idx and add a comment.

Or, add an inline function like

static inline int priv_level(DisasContext *ctx)
{
#ifdef CONFIG_USER_ONLY
     return PRV_U;
#else
     /* Priv level equals mmu index -- see cpu_mmu_index. */
     return ctx->mmu_idx;
#endif
}

so that usages within a user-only build are compile-time constant and folded away.


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 01/11] riscv: Add privilege level to DisasContext
  2022-09-16  6:00   ` Richard Henderson
  2022-09-16  6:05     ` Richard Henderson
@ 2022-09-16  6:21     ` LIU Zhiwei
  1 sibling, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-09-16  6:21 UTC (permalink / raw)
  To: Richard Henderson, Christoph Muellner, qemu-riscv, qemu-devel,
	Alistair Francis, Bin Meng, Philipp Tomsich, Heiko Stübner,
	Palmer Dabbelt, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang


On 2022/9/16 14:00, Richard Henderson wrote:
> On 9/6/22 14:22, Christoph Muellner wrote:
>> From: Christoph Müllner <christoph.muellner@vrull.eu>
>>
>> This allows privileged instructions to check the required
>> privilege level in the translation without calling a helper.
>>
>> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
>> ---
>>   target/riscv/translate.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
>> index 63b04e8a94..fd241ff667 100644
>> --- a/target/riscv/translate.c
>> +++ b/target/riscv/translate.c
>> @@ -59,6 +59,9 @@ typedef struct DisasContext {
>>       /* pc_succ_insn points to the instruction following 
>> base.pc_next */
>>       target_ulong pc_succ_insn;
>>       target_ulong priv_ver;
>> +#ifndef CONFIG_USER_ONLY
>> +    target_ulong priv;
>> +#endif
>>       RISCVMXL misa_mxl_max;
>>       RISCVMXL xl;
>>       uint32_t misa_ext;
>> @@ -1079,6 +1082,7 @@ static void 
>> riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>>       ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
>>       ctx->priv_ver = env->priv_ver;
>>   #if !defined(CONFIG_USER_ONLY)
>> +    ctx->priv = env->priv;
>
> Reading directly from env here is, in general, wrong.  Items that are 
> constant, like priv_ver, are ok.  But otherwise these values must be 
> recorded by cpu_get_tb_cpu_state().
>
> This instance will happen to work, because the execution context is 
> already constrained. 

Exactly. Thanks for pointing it out.

> In this case because env->priv == ctx->mem_idx (see cpu_mmu_index) so, 
> really, you don't need this new field at all.  Or, keep the field, 
> because it's usage will be more self-documentary, but copy the value 
> from ctx->mmu_idx and add a comment.
>
>
>>       if (riscv_has_ext(env, RVH)) {
>>           ctx->virt_enabled = riscv_cpu_virt_enabled(env);
>>       } else {
>
> Incidentally, this (existing) usage appears to be a bug.  I can see 
> nothing in cpu_get_tb_cpu_state that corresponds directly to this value.

Agree.

Zhiwei

>
>
> r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] RISC-V: Adding T-Head CMO instructions
  2022-09-06 12:22 ` [PATCH 02/11] RISC-V: Adding T-Head CMO instructions Christoph Muellner
  2022-09-16  2:47   ` LIU Zhiwei
@ 2022-09-16  6:43   ` LIU Zhiwei
  2022-09-16  7:59     ` Richard Henderson
  1 sibling, 1 reply; 30+ messages in thread
From: LIU Zhiwei @ 2022-09-16  6:43 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang


On 2022/9/6 20:22, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds support for the T-Head CMO instructions.
> To avoid interfering with standard extensions, decoder and translation
> are in its own T-Head specific files.
> Future patches should be able to easily add additional T-Head extesions.
>
> The implementation does not have much functionality (besides accepting
> the instructions and not qualifying them as illegal instructions if
> the hart executes in the required privilege level for the instruction),
> as QEMU does not model CPU caches and instructions don't have any
> exception behaviour (at least not documented).
>
> The documentation shows, that the instructions are gated by
> mxstatus.theadisaee and mxstatus.ucme. However, since these
> settings are not changed by the upstream Linux kernel,
> we simply enable the instructions in all modes.
>
> 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 | 66 ++++++++++++++++++++++
>   target/riscv/meson.build                   |  1 +
>   target/riscv/translate.c                   | 11 +++-
>   target/riscv/xtheadcmo.decode              | 43 ++++++++++++++
>   6 files changed, 120 insertions(+), 3 deletions(-)
>   create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
>   create mode 100644 target/riscv/xtheadcmo.decode
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index ac6f82ebd0..7718ab0478 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -920,6 +920,7 @@ static Property riscv_cpu_extensions[] = {
>       DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
>   
>       /* Vendor-specific custom extensions */
> +    DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
>       DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
>   
>       /* These are experimental so mark with 'x-' */
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5c7acc055a..b7ab53b7b8 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -440,6 +440,7 @@ struct RISCVCPUConfig {
>       uint64_t mimpid;
>   
>       /* Vendor-specific custom extensions */
> +    bool ext_xtheadcmo;
>       bool ext_XVentanaCondOps;
>   
>       uint8_t pmu_num;
> diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
> new file mode 100644
> index 0000000000..1b1e21ab77
> --- /dev/null
> +++ b/target/riscv/insn_trans/trans_xthead.c.inc
> @@ -0,0 +1,66 @@
> +/*
> + * RISC-V translation routines for the T-Head vendor extensions (xthead*).
> + *
> + * Copyright (c) 2022 VRULL GmbH.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#define REQUIRE_PRIV_MHSU(ctx)
> +
> +#ifndef CONFIG_USER_ONLY
> +#define REQUIRE_PRIV_MHS(ctx)                                   \
> +do {                                                            \
> +    if (!(ctx->priv == PRV_M ||                                 \
> +          ctx->priv == PRV_H ||                                 \
> +          ctx->priv == PRV_S)) {                                \
> +        return false;                                           \
> +    }                                                           \
> +} while (0)
No ';' here. And in #else
> +#else
> +#define REQUIRE_PRIV_MHS(ctx)                                   \
> +  return false;

with ';'

Are both right?

Zhiwei

> +#endif
> +
> +#define NOP_PRIVCHECK(insn, privcheck)                          \
> +static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn * a) \
> +{                                                               \
> +    (void) a;                                                   \
> +    privcheck(ctx);                                             \
> +    return true;                                                \
> +}
> +
> +NOP_PRIVCHECK(th_dcache_call, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_ciall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_iall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cpa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_ipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cva, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_civa, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_iva, REQUIRE_PRIV_MHSU)
> +NOP_PRIVCHECK(th_dcache_csw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_isw, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_PRIV_MHS)
> +
> +NOP_PRIVCHECK(th_icache_iall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_ialls, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_ipa, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_icache_iva, REQUIRE_PRIV_MHSU)
> +
> +NOP_PRIVCHECK(th_l2cache_call, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_l2cache_ciall, REQUIRE_PRIV_MHS)
> +NOP_PRIVCHECK(th_l2cache_iall, REQUIRE_PRIV_MHS)
> +
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index 6b9435d69a..1d149e05cd 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -2,6 +2,7 @@
>   gen = [
>     decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
>     decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
> +  decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
>     decodetree.process('XVentanaCondOps.decode', extra_args: '--static-decode=decode_XVentanaCodeOps'),
>   ]
>   
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index fd241ff667..d16ae63850 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -132,7 +132,8 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
>           return ctx->cfg_ptr->ext_ ## ext ; \
>       }
>   
> -MATERIALISE_EXT_PREDICATE(XVentanaCondOps);
> +MATERIALISE_EXT_PREDICATE(xtheadcmo)
> +MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
>   
>   #ifdef TARGET_RISCV32
>   #define get_xl(ctx)    MXL_RV32
> @@ -717,6 +718,10 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>   /* Include the auto-generated decoder for 32 bit insn */
>   #include "decode-insn32.c.inc"
>   
> +/* Include decoders for factored-out extensions */
> +#include "decode-xtheadcmo.c.inc"
> +#include "decode-XVentanaCondOps.c.inc"
> +
>   static bool gen_logic_imm_fn(DisasContext *ctx, arg_i *a,
>                                void (*func)(TCGv, TCGv, target_long))
>   {
> @@ -1018,12 +1023,11 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>   #include "insn_trans/trans_rvk.c.inc"
>   #include "insn_trans/trans_privileged.c.inc"
>   #include "insn_trans/trans_svinval.c.inc"
> +#include "insn_trans/trans_xthead.c.inc"
>   #include "insn_trans/trans_xventanacondops.c.inc"
>   
>   /* Include the auto-generated decoder for 16 bit insn */
>   #include "decode-insn16.c.inc"
> -/* Include decoders for factored-out extensions */
> -#include "decode-XVentanaCondOps.c.inc"
>   
>   static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>   {
> @@ -1036,6 +1040,7 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>           bool (*decode_func)(DisasContext *, uint32_t);
>       } decoders[] = {
>           { always_true_p,  decode_insn32 },
> +        { has_xtheadcmo_p, decode_xtheadcmo },
>           { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
>       };
>   
> diff --git a/target/riscv/xtheadcmo.decode b/target/riscv/xtheadcmo.decode
> new file mode 100644
> index 0000000000..8ddf9b3997
> --- /dev/null
> +++ b/target/riscv/xtheadcmo.decode
> @@ -0,0 +1,43 @@
> +#
> +# RISC-V translation routines for the XTheadCmo extension
> +#
> +# Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# The XTheadCmo extension provides instructions for cache management.
> +#
> +# 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:
> +%rs1       15:5
> +
> +# Formats
> +@sfence_vm  ....... ..... .....   ... ..... ....... %rs1
> +
> +# *** CMO instructions
> +th_dcache_call   0000000 00001 00000 000 00000 0001011
> +th_dcache_ciall  0000000 00011 00000 000 00000 0001011
> +th_dcache_iall   0000000 00010 00000 000 00000 0001011
> +th_dcache_cpa    0000001 01001 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cipa   0000001 01011 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_ipa    0000001 01010 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cva    0000001 00101 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_civa   0000001 00111 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_iva    0000001 00110 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_csw    0000001 00001 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cisw   0000001 00011 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_isw    0000001 00010 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cpal1  0000001 01000 ..... 000 00000 0001011 @sfence_vm
> +th_dcache_cval1  0000001 00100 ..... 000 00000 0001011 @sfence_vm
> +
> +th_icache_iall   0000000 10000 00000 000 00000 0001011
> +th_icache_ialls  0000000 10001 00000 000 00000 0001011
> +th_icache_ipa    0000001 11000 ..... 000 00000 0001011 @sfence_vm
> +th_icache_iva    0000001 10000 ..... 000 00000 0001011 @sfence_vm
> +
> +th_l2cache_call  0000000 10101 00000 000 00000 0001011
> +th_l2cache_ciall 0000000 10111 00000 000 00000 0001011
> +th_l2cache_iall  0000000 10110 00000 000 00000 0001011
> +


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 02/11] RISC-V: Adding T-Head CMO instructions
  2022-09-16  6:43   ` LIU Zhiwei
@ 2022-09-16  7:59     ` Richard Henderson
  0 siblings, 0 replies; 30+ messages in thread
From: Richard Henderson @ 2022-09-16  7:59 UTC (permalink / raw)
  To: LIU Zhiwei, Christoph Muellner, qemu-riscv, qemu-devel,
	Alistair Francis, Bin Meng, Philipp Tomsich, Heiko Stübner,
	Palmer Dabbelt, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang

On 9/16/22 08:43, LIU Zhiwei wrote:
> 
> On 2022/9/6 20:22, Christoph Muellner wrote:
>> From: Christoph Müllner <christoph.muellner@vrull.eu>
>>
>> This patch adds support for the T-Head CMO instructions.
>> To avoid interfering with standard extensions, decoder and translation
>> are in its own T-Head specific files.
>> Future patches should be able to easily add additional T-Head extesions.
>>
>> The implementation does not have much functionality (besides accepting
>> the instructions and not qualifying them as illegal instructions if
>> the hart executes in the required privilege level for the instruction),
>> as QEMU does not model CPU caches and instructions don't have any
>> exception behaviour (at least not documented).
>>
>> The documentation shows, that the instructions are gated by
>> mxstatus.theadisaee and mxstatus.ucme. However, since these
>> settings are not changed by the upstream Linux kernel,
>> we simply enable the instructions in all modes.
>>
>> 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 | 66 ++++++++++++++++++++++
>>   target/riscv/meson.build                   |  1 +
>>   target/riscv/translate.c                   | 11 +++-
>>   target/riscv/xtheadcmo.decode              | 43 ++++++++++++++
>>   6 files changed, 120 insertions(+), 3 deletions(-)
>>   create mode 100644 target/riscv/insn_trans/trans_xthead.c.inc
>>   create mode 100644 target/riscv/xtheadcmo.decode
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index ac6f82ebd0..7718ab0478 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -920,6 +920,7 @@ static Property riscv_cpu_extensions[] = {
>>       DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
>>       /* Vendor-specific custom extensions */
>> +    DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
>>       DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
>>       /* These are experimental so mark with 'x-' */
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 5c7acc055a..b7ab53b7b8 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -440,6 +440,7 @@ struct RISCVCPUConfig {
>>       uint64_t mimpid;
>>       /* Vendor-specific custom extensions */
>> +    bool ext_xtheadcmo;
>>       bool ext_XVentanaCondOps;
>>       uint8_t pmu_num;
>> diff --git a/target/riscv/insn_trans/trans_xthead.c.inc 
>> b/target/riscv/insn_trans/trans_xthead.c.inc
>> new file mode 100644
>> index 0000000000..1b1e21ab77
>> --- /dev/null
>> +++ b/target/riscv/insn_trans/trans_xthead.c.inc
>> @@ -0,0 +1,66 @@
>> +/*
>> + * RISC-V translation routines for the T-Head vendor extensions (xthead*).
>> + *
>> + * Copyright (c) 2022 VRULL GmbH.
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2 or later, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>> + * more details.
>> + *
>> + * You should have received a copy of the GNU General Public License along with
>> + * this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#define REQUIRE_PRIV_MHSU(ctx)
>> +
>> +#ifndef CONFIG_USER_ONLY
>> +#define REQUIRE_PRIV_MHS(ctx)                                   \
>> +do {                                                            \
>> +    if (!(ctx->priv == PRV_M ||                                 \
>> +          ctx->priv == PRV_H ||                                 \
>> +          ctx->priv == PRV_S)) {                                \
>> +        return false;                                           \
>> +    }                                                           \
>> +} while (0)
> No ';' here. And in #else
>> +#else
>> +#define REQUIRE_PRIV_MHS(ctx)                                   \
>> +  return false;
> 
> with ';'

Using the inline function that I suggested in response to patch 1, this ifdef is not 
required.  Also, better with an explicit test against PRV_U?


r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions
  2022-09-06 12:22 ` [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions Christoph Muellner
@ 2022-09-16  9:12   ` LIU Zhiwei
  0 siblings, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-09-16  9:12 UTC (permalink / raw)
  To: Christoph Muellner, qemu-riscv, qemu-devel, Alistair Francis,
	Bin Meng, Philipp Tomsich, Heiko Stübner, Palmer Dabbelt,
	Richard Henderson, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang


On 2022/9/6 20:22, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
>
> This patch adds support for the T-Head Bitmanip instructions.
> The patch uses the T-Head specific decoder and translation.
>
> As the instructions are similar to those of Zb*, we can reuse
> a lot of existing infrastructure code.
>
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>   target/riscv/cpu.c                         |   3 +
>   target/riscv/cpu.h                         |   3 +
>   target/riscv/insn_trans/trans_xthead.c.inc | 124 +++++++++++++++++++++
>   target/riscv/meson.build                   |   3 +
>   target/riscv/translate.c                   |   9 ++
>   target/riscv/xtheadba.decode               |  46 ++++++++
>   target/riscv/xtheadbb.decode               |  62 +++++++++++
>   target/riscv/xtheadbs.decode               |  32 ++++++
>   8 files changed, 282 insertions(+)
>   create mode 100644 target/riscv/xtheadba.decode
>   create mode 100644 target/riscv/xtheadbb.decode
>   create mode 100644 target/riscv/xtheadbs.decode
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index a72722cfa6..d129a6112a 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -920,6 +920,9 @@ static Property riscv_cpu_extensions[] = {
>       DEFINE_PROP_BOOL("zhinxmin", RISCVCPU, cfg.ext_zhinxmin, false),
>   
>       /* Vendor-specific custom extensions */
> +    DEFINE_PROP_BOOL("xtheadba", RISCVCPU, cfg.ext_xtheadba, false),
> +    DEFINE_PROP_BOOL("xtheadbb", RISCVCPU, cfg.ext_xtheadbb, false),
> +    DEFINE_PROP_BOOL("xtheadbs", RISCVCPU, cfg.ext_xtheadbs, false),
>       DEFINE_PROP_BOOL("xtheadcmo", RISCVCPU, cfg.ext_xtheadcmo, false),
>       DEFINE_PROP_BOOL("xtheadsync", RISCVCPU, cfg.ext_xtheadsync, false),
>       DEFINE_PROP_BOOL("xventanacondops", RISCVCPU, cfg.ext_XVentanaCondOps, false),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 4ae22cf529..9e2b3d6f56 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -440,6 +440,9 @@ struct RISCVCPUConfig {
>       uint64_t mimpid;
>   
>       /* Vendor-specific custom extensions */
> +    bool ext_xtheadba;
> +    bool ext_xtheadbb;
> +    bool ext_xtheadbs;
>       bool ext_xtheadcmo;
>       bool ext_xtheadsync;
>       bool ext_XVentanaCondOps;
> diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc
> index 0a6719b2e2..b2d523b905 100644
> --- a/target/riscv/insn_trans/trans_xthead.c.inc
> +++ b/target/riscv/insn_trans/trans_xthead.c.inc
> @@ -70,3 +70,127 @@ NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
>   NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
>   NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
>   
> +/*
> + * th.addsl is similar to sh[123]add (from Zba), but not an
> + * alternative encoding: while sh[123] applies the shift to rs1,
> + * th.addsl shifts rs2.
> + */
> +
> +#define GEN_TH_ADDSL(SHAMT)                                     \
> +static void gen_th_addsl##SHAMT(TCGv ret, TCGv arg1, TCGv arg2) \
> +{                                                               \
> +    TCGv t = tcg_temp_new();                                    \
> +    tcg_gen_shli_tl(t, arg2, SHAMT);                            \
> +    tcg_gen_add_tl(ret, t, arg1);                               \
> +    tcg_temp_free(t);                                           \
> +}
> +
> +GEN_TH_ADDSL(1)
> +GEN_TH_ADDSL(2)
> +GEN_TH_ADDSL(3)
> +
> +#define GEN_TRANS_TH_ADDSL(SHAMT)                                       \
> +static bool trans_th_addsl##SHAMT(DisasContext *ctx,                    \
> +                                  arg_th_addsl##SHAMT * a)              \
> +{                                                                       \
> +    return gen_arith(ctx, a, EXT_NONE, gen_th_addsl##SHAMT, NULL);      \
> +}
> +
> +GEN_TRANS_TH_ADDSL(1)
> +GEN_TRANS_TH_ADDSL(2)
> +GEN_TRANS_TH_ADDSL(3)
> +
> +
> +/* th.srri is an alternate encoding for rori (from Zbb) */
> +static bool trans_th_srri(DisasContext *ctx, arg_th_srri * a)
> +{
> +    return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_rotri_tl, NULL);
> +}
> +

We should ensure that if the instruction only exists when XLEN is 64 or 
it can exist both when XLEN is 32 or 64.

If it can exist both when XLEN is 32 or 64,  we should ensure the 
calculation is right for both. trans_th_srri will not right when XLEN is 
32-bit. Please refer to gen_roriw().

> +/* th.srriw is an alternate encoding for roriw (from Zbb) */
> +static bool trans_th_srriw(DisasContext *ctx, arg_th_srriw *a)
> +{
> +    ctx->ol = MXL_RV32;

And if only exists when XLEN is 64, such as th.srriw, we should check 
the XLEN.

Thanks,
Zhiwei

> +    return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
> +}
> +
> +/* th.ext and th.extu perform signed/unsigned bitfield extraction */
> +static bool gen_th_bfextract(DisasContext *ctx, arg_th_bfext *a,
> +                             void (*f)(TCGv, TCGv, unsigned int, unsigned int))
> +{
> +    TCGv dest = dest_gpr(ctx, a->rd);
> +    TCGv source = get_gpr(ctx, a->rs1, EXT_ZERO);
> +
> +    if (a->lsb <= a->msb) {
> +        f(dest, source, a->lsb, a->msb - a->lsb + 1);
> +        gen_set_gpr(ctx, a->rd, dest);
> +    }
> +    return true;
> +}
> +
> +static bool trans_th_ext(DisasContext *ctx, arg_th_ext *a)
> +{
> +    return gen_th_bfextract(ctx, a, tcg_gen_sextract_tl);
> +}
> +
> +static bool trans_th_extu(DisasContext *ctx, arg_th_extu *a)
> +{
> +    return gen_th_bfextract(ctx, a, tcg_gen_extract_tl);
> +}
> +
> +/* th.ff0: find first zero (clz on an inverted input) */
> +static void gen_th_ff0(TCGv ret, TCGv arg1)
> +{
> +    TCGv t = tcg_temp_new();
> +    tcg_gen_not_tl(t, arg1);
> +    gen_clz(ret, t);
> +    tcg_temp_free(t);
> +}
> +
> +static bool trans_th_ff0(DisasContext *ctx, arg_th_ff0 *a)
> +{
> +    return gen_unary(ctx, a, EXT_NONE, gen_th_ff0);
> +}
> +
> +/* th.ff1 is an alternate encoding for clz (from Zbb) */
> +static bool trans_th_ff1(DisasContext *ctx, arg_th_ff1 *a)
> +{
> +    return gen_unary(ctx, a, EXT_NONE, gen_clz);
> +}
> +
> +/* th.rev is an alternate encoding for the RV64 rev8 (from Zbb) */
> +static bool trans_th_rev(DisasContext *ctx, arg_th_rev *a)
> +{
> +    return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl);
> +}
> +
> +/* th.revw is a sign-extended byte-swap of the lower word */
> +static void gen_th_revw(TCGv ret, TCGv arg1)
> +{
> +    tcg_gen_bswap_tl(ret, arg1);
> +    tcg_gen_sari_tl(ret, ret, 32);
> +}
> +
> +static bool trans_th_revw(DisasContext *ctx, arg_th_revw *a)
> +{
> +    return gen_unary(ctx, a, EXT_NONE, gen_th_revw);
> +}
> +
> +/* th.tstnbz is equivalent to an orc.b (from Zbb) with inverted result */
> +static void gen_th_tstnbz(TCGv ret, TCGv source1)
> +{
> +    gen_orc_b(ret, source1);
> +    tcg_gen_not_tl(ret, ret);
> +}
> +
> +static bool trans_th_tstnbz(DisasContext *ctx, arg_th_tstnbz *a)
> +{
> +    return gen_unary(ctx, a, EXT_ZERO, gen_th_tstnbz);
> +}
> +
> +/* th.tst is an alternate encoding for bexti (from Zbs) */
> +static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
> +{
> +    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
> +}
> +
> diff --git a/target/riscv/meson.build b/target/riscv/meson.build
> index f201cc6997..5ee37683cb 100644
> --- a/target/riscv/meson.build
> +++ b/target/riscv/meson.build
> @@ -2,6 +2,9 @@
>   gen = [
>     decodetree.process('insn16.decode', extra_args: ['--static-decode=decode_insn16', '--insnwidth=16']),
>     decodetree.process('insn32.decode', extra_args: '--static-decode=decode_insn32'),
> +  decodetree.process('xtheadba.decode', extra_args: '--static-decode=decode_xtheadba'),
> +  decodetree.process('xtheadbb.decode', extra_args: '--static-decode=decode_xtheadbb'),
> +  decodetree.process('xtheadbs.decode', extra_args: '--static-decode=decode_xtheadbs'),
>     decodetree.process('xtheadcmo.decode', extra_args: '--static-decode=decode_xtheadcmo'),
>     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 a63cc3de46..f662e403f8 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -132,6 +132,9 @@ static bool always_true_p(DisasContext *ctx  __attribute__((__unused__)))
>           return ctx->cfg_ptr->ext_ ## ext ; \
>       }
>   
> +MATERIALISE_EXT_PREDICATE(xtheadba)
> +MATERIALISE_EXT_PREDICATE(xtheadbb)
> +MATERIALISE_EXT_PREDICATE(xtheadbs)
>   MATERIALISE_EXT_PREDICATE(xtheadcmo)
>   MATERIALISE_EXT_PREDICATE(xtheadsync)
>   MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
> @@ -720,6 +723,9 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>   #include "decode-insn32.c.inc"
>   
>   /* Include decoders for factored-out extensions */
> +#include "decode-xtheadba.c.inc"
> +#include "decode-xtheadbb.c.inc"
> +#include "decode-xtheadbs.c.inc"
>   #include "decode-xtheadcmo.c.inc"
>   #include "decode-xtheadsync.c.inc"
>   #include "decode-XVentanaCondOps.c.inc"
> @@ -1042,6 +1048,9 @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
>           bool (*decode_func)(DisasContext *, uint32_t);
>       } decoders[] = {
>           { always_true_p,  decode_insn32 },
> +        { has_xtheadba_p, decode_xtheadba },
> +        { has_xtheadbb_p, decode_xtheadbb },
> +        { has_xtheadbs_p, decode_xtheadbs },
>           { has_xtheadcmo_p, decode_xtheadcmo },
>           { has_xtheadsync_p, decode_xtheadsync },
>           { has_XVentanaCondOps_p,  decode_XVentanaCodeOps },
> diff --git a/target/riscv/xtheadba.decode b/target/riscv/xtheadba.decode
> new file mode 100644
> index 0000000000..4e5e3f12f0
> --- /dev/null
> +++ b/target/riscv/xtheadba.decode
> @@ -0,0 +1,46 @@
> +#
> +# RISC-V instruction decode for the XTheadBa extension
> +#
> +# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
> +#                    Christoph Muellner, christoph.muellner@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# The XTheadBa extension provides instructions for address calculations,
> +# implementing the functional equivalent of a subset of Zba.
> +#
> +# 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
> +#
> +# The instruction contained in XTheadBb is:
> +# - th.addsl      add rotate-right by immediate
> +#                 (similar to sh[123]add, but with rs1 and rs2 switched)
> +# This instruction reuses an existing instruction format.
> +
> +# Fields
> +%rs2       20:5
> +%rs1       15:5
> +%rd        7:5
> +
> +# Argument sets
> +&r         rd rs1 rs2		!extern
> +
> +# Formats:
> +@r          ....... ..... .....  ... ..... ....... &r %rs2 %rs1 %rd
> +
> +# *** Bitmanip addressing instructions
> +# Instead of defining a new encoding, we simply use the decoder to
> +# extract the imm[0:1] field and dispatch to separate translation
> +# functions (mirroring the `sh[123]add` instructions from Zba and
> +# the regular RVI `add` instruction.
> +#
> +# The only difference between sh[123]add and addsl is that the sohift
> +# is applied to rs1 (for addsl) instead of rs2 (for sh[123]add).
> +#
> +# Note that shift-by-0 is a valid operation according to the manual.
> +# This will be equivalent to a regular add.
> +add              0000000 ..... ..... 001 ..... 0001011 @r
> +th_addsl1        0000001 ..... ..... 001 ..... 0001011 @r
> +th_addsl2        0000010 ..... ..... 001 ..... 0001011 @r
> +th_addsl3        0000011 ..... ..... 001 ..... 0001011 @r
> +
> diff --git a/target/riscv/xtheadbb.decode b/target/riscv/xtheadbb.decode
> new file mode 100644
> index 0000000000..2754a6444b
> --- /dev/null
> +++ b/target/riscv/xtheadbb.decode
> @@ -0,0 +1,62 @@
> +#
> +# RISC-V instruction decode for the XTheadBb extension
> +#
> +# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
> +#                    Christoph Muellner, christoph.muellner@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# The XTheadBb extension provides basic bit-manipulation instructions,
> +# implementing the functional equivalent of a subset of Zbb.
> +#
> +# 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
> +#
> +# The instructions contained in XTheadBb are:
> +# - th.srri       rotate-right by immediate (matches rori)
> +# - th.srriw      rotate-right by immediate, w-form (matches roriw)
> +# - th.rev        byte-reverse register (matches RV64-form of rev8)
> +# - th.revw       byte-reverse low word, sign-extend result (no equivalent)
> +# - th.ext        signed bitfield-extract (no equivalent)
> +# - th.extu       unsigned bitfield-extract (no equivalent)
> +# - th.ff0        find-first zero (equivalent to clz on the inverted operand)
> +# - th.ff1        find-first one (matches clz)
> +# - th.tstnbz     test for zero-bytes (equivalent to the inverted result of orc.b)
> +# - th.tst        test for bit (equivalent to bexti)
> +#
> +# These instructions generally reuse existing instruction formats.
> +# Only the th.ext and th.ext introduce a new, vendor-defined instruction format.
> +
> +# Fields
> +%rs2       20:5
> +%rs1       15:5
> +%rd        7:5
> +%sh5       20:5
> +%sh6       20:6
> +
> +# Argument sets
> +&r2        rd rs1		!extern
> +&shift     shamt rs1 rd		!extern
> +&th_bfext  msb lsb rs1 rd
> +
> +# Formats:
> +@r2         ....... ..... .....  ... ..... ....... &r2 %rs1 %rd
> +@th_bfext   msb:6  lsb:6  .....  ... ..... ....... &th_bfext %rs1 %rd
> +
> +# Formats 64:
> +@sh5        ....... ..... .....  ... ..... ....... &shift  shamt=%sh5      %rs1 %rd
> +
> +# Formats 128:
> +@sh6        ...... ...... .....  ... ..... ....... &shift shamt=%sh6 %rs1 %rd
> +
> +# *** Bitmanip instructions
> +th_ext           ...... ...... ..... 010 ..... 0001011 @th_bfext
> +th_extu          ...... ...... ..... 011 ..... 0001011 @th_bfext
> +th_ff0           1000010 00000 ..... 001 ..... 0001011 @r2
> +th_ff1           1000011 00000 ..... 001 ..... 0001011 @r2
> +th_srri          000100 ...... ..... 001 ..... 0001011 @sh6
> +th_srriw         0001010 ..... ..... 001 ..... 0001011 @sh5
> +th_rev           1000001 00000 ..... 001 ..... 0001011 @r2
> +th_revw          1001000 00000 ..... 001 ..... 0001011 @r2
> +th_tstnbz        1000000 00000 ..... 001 ..... 0001011 @r2
> +
> diff --git a/target/riscv/xtheadbs.decode b/target/riscv/xtheadbs.decode
> new file mode 100644
> index 0000000000..7aa345b207
> --- /dev/null
> +++ b/target/riscv/xtheadbs.decode
> @@ -0,0 +1,32 @@
> +#
> +# RISC-V instruction decode for the XTheadBb extension
> +#
> +# Copyright (c) 2022 Dr. Philipp Tomsich, philipp.tomsich@vrull.eu
> +#                    Christoph Muellner, christoph.muellner@vrull.eu
> +#
> +# SPDX-License-Identifier: LGPL-2.1-or-later
> +#
> +# XTheadBs provides basic bit-manipulation instructions,
> +# implementing the functional equivalent of a subset of Zbs.
> +#
> +# 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
> +#
> +# The instruction contained in XTheadBb is:
> +# - th.tst        test if bit is set (matches bexti)
> +#
> +# The instruction reuses an existing instruction format.
> +
> +# Fields
> +%rs1       15:5
> +%rd        7:5
> +%sh6       20:6
> +
> +# Argument sets
> +&shift     shamt rs1 rd		!extern
> +
> +# Formats 128:
> +@sh6        ...... ...... .....  ... ..... ....... &shift shamt=%sh6 %rs1 %rd
> +
> +# *** Bitmanip single-bit instructions
> +th_tst           100010 ...... ..... 001 ..... 0001011 @sh6


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions
  2022-09-08  7:29   ` Richard Henderson
  2022-09-09 17:21     ` Christoph Müllner
@ 2022-12-12  9:12     ` LIU Zhiwei
  2022-12-12  9:21     ` LIU Zhiwei
  2 siblings, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-12-12  9:12 UTC (permalink / raw)
  To: Richard Henderson, Christoph Muellner, qemu-riscv, qemu-devel,
	Alistair Francis, Bin Meng, Philipp Tomsich, Heiko Stübner,
	Palmer Dabbelt, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang


On 2022/9/8 15:29, Richard Henderson wrote:
> On 9/6/22 13:22, Christoph Muellner wrote:
>> +NOP_PRIVCHECK(th_sfence_vmas, REQUIRE_PRIV_MHS)
>> +NOP_PRIVCHECK(th_sync, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
>
> These should not be nops: th_sfence_vmas requires a tlb flush; 
> th.sync{,.i} needs to end the current translation block; 
> th.sync.{s,is} needs multiprocessor sync, which involves a call to 
> async_safe_run_on_cpu.

Hi Richard,

I have fixed the description of T-Head custom synchronization 
instructions according to the implementation of hardware. Sorry for the 
misleading.

https://github.com/T-head-Semi/thead-extension-spec/tree/master/xtheadsync


The fix is as below:

1)th.sync.s has the same function with th.sync.

2) th.sync. has the same function with th.sync.i

3) th.sync has the function of memory barrier, but it is stricter than 
RISC-V fence instruction as it order all the instructions instead of 
load/store instructions.

4) th.sync.i has the function to flush the pipeline besides the function 
of th.sync.


On QEMU,  I think they should be emulated them as below:

1) th.sync should be emulated as " 'tcg_gen_mb()'  and  'end the current 
translation block'" on QEMU.

2) th.sync should be emulated as " 'tcg_gen_mb()'  and  'end the current 
translation block'" on QEMU because we don't have the cache model for 
guest on QEMU. Thus we don't have to synchronize between the icache and 
dcache for guest.


'tcg_gen_mb' is for the function of memory barrier,  and  'end the 
current translation block' is to reflect the influence of other 
instructions, such as to take interrupts which only at the end of 
translation block.
Maybe we can also just implement these instructions as 'tcg_gen_mb' 
because currently all CSR instructions which may influence the 
interrupts taking have ended the TB on QEMU.

Is it right?

Thanks,
Zhiwei

>
>
> r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions
  2022-09-08  7:29   ` Richard Henderson
  2022-09-09 17:21     ` Christoph Müllner
  2022-12-12  9:12     ` LIU Zhiwei
@ 2022-12-12  9:21     ` LIU Zhiwei
  2 siblings, 0 replies; 30+ messages in thread
From: LIU Zhiwei @ 2022-12-12  9:21 UTC (permalink / raw)
  To: Richard Henderson, Christoph Muellner, qemu-riscv, qemu-devel,
	Alistair Francis, Bin Meng, Philipp Tomsich, Heiko Stübner,
	Palmer Dabbelt, Nelson Chu, Kito Cheng, Cooper Qu, Lifang Xia,
	Yunhai Shang


On 2022/9/8 15:29, Richard Henderson wrote:
> On 9/6/22 13:22, Christoph Muellner wrote:
>> +NOP_PRIVCHECK(th_sfence_vmas, REQUIRE_PRIV_MHS)
>> +NOP_PRIVCHECK(th_sync, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_i, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_is, REQUIRE_PRIV_MHSU)
>> +NOP_PRIVCHECK(th_sync_s, REQUIRE_PRIV_MHSU)
>
> These should not be nops: th_sfence_vmas requires a tlb flush; 
> th.sync{,.i} needs to end the current translation block; 
> th.sync.{s,is} needs multiprocessor sync, which involves a call to 
> async_safe_run_on_cpu.
Hi Richard,

I have fixed the description of T-Head custom synchronization 
instructions according to the implementation of hardware. Sorry for the 
misleading.

https://github.com/T-head-Semi/thead-extension-spec/tree/master/xtheadsync


The fix is as below:

1)th.sync.s has the same function with th.sync.

2) th.sync.is has the same function with th.sync.i

3) th.sync has the function of memory barrier, but it is stricter than 
RISC-V fence instruction as it order all the instructions instead of 
load/store instructions.

4) th.sync.i has the function to flush the pipeline besides the function 
of th.sync.


On QEMU,  I think they should be emulated them as below:

1) th.sync should be emulated as " 'tcg_gen_mb()'  and  'end the current 
translation block'" on QEMU.

2) th.sync.i should be emulated as " 'tcg_gen_mb()'  and  'end the 
current translation block'" on QEMU because we don't have the cache 
model for guest on QEMU. Thus we don't have to synchronize between the 
icache and dcache for guest.


'tcg_gen_mb' is for the function of memory barrier. And  'end the 
current translation block' is to reflect the influence of other 
instructions, such as taking interrupts which happens only at the end of 
a translation block.
Maybe we can also just implement these instructions as 'tcg_gen_mb' 
because currently all CSR instructions which may influence the 
interrupts taking have ended the TB on QEMU.


Is it right?

Thanks,
Zhiwei
>
>
> r~


^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2022-12-12  9:26 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-06 12:22 [PATCH 00/11] Add support for the T-Head vendor extensions Christoph Muellner
2022-09-06 12:22 ` [PATCH 01/11] riscv: Add privilege level to DisasContext Christoph Muellner
2022-09-16  2:46   ` LIU Zhiwei
2022-09-16  6:00   ` Richard Henderson
2022-09-16  6:05     ` Richard Henderson
2022-09-16  6:21     ` LIU Zhiwei
2022-09-06 12:22 ` [PATCH 02/11] RISC-V: Adding T-Head CMO instructions Christoph Muellner
2022-09-16  2:47   ` LIU Zhiwei
2022-09-16  6:43   ` LIU Zhiwei
2022-09-16  7:59     ` Richard Henderson
2022-09-06 12:22 ` [PATCH 03/11] RISC-V: Adding T-Head SYNC instructions Christoph Muellner
2022-09-08  7:29   ` Richard Henderson
2022-09-09 17:21     ` Christoph Müllner
2022-12-12  9:12     ` LIU Zhiwei
2022-12-12  9:21     ` LIU Zhiwei
2022-09-06 12:22 ` [PATCH 04/11] RISC-V: Adding T-Head Bitmanip instructions Christoph Muellner
2022-09-16  9:12   ` LIU Zhiwei
2022-09-06 12:22 ` [PATCH 05/11] RISC-V: Adding T-Head CondMov instructions Christoph Muellner
2022-09-06 12:22 ` [PATCH 06/11] RISC-V: Adding T-Head multiply-accumulate instructions Christoph Muellner
2022-09-06 12:22 ` [PATCH 07/11] RISC-V: Adding T-Head XMAE support Christoph Muellner
2022-09-06 12:22 ` [PATCH 08/11] RISC-V: Adding T-Head MemPair extension Christoph Muellner
2022-09-06 12:22 ` [PATCH 09/11] RISC-V: Adding T-Head MemIdx extension Christoph Muellner
2022-09-06 12:22 ` [PATCH 10/11] RISC-V: Adding T-Head FMemIdx extension Christoph Muellner
2022-09-08  7:45   ` Richard Henderson
2022-09-09 17:21     ` Christoph Müllner
2022-09-06 12:22 ` [PATCH 11/11] RISC-V: Add initial support for T-Head C906 and C910 CPUs Christoph Muellner
2022-09-08  7:46   ` Richard Henderson
2022-09-08  8:23     ` Christoph Müllner
2022-09-08  8:56       ` Richard Henderson
2022-09-08  9:01         ` Christoph Müllner

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.