qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 00/14] tcg/riscv: Add support for vector
@ 2024-10-16 19:31 Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
                   ` (14 more replies)
  0 siblings, 15 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu

Introduce support for the RISC-V vector extension in the TCG backend.

v5: https://lore.kernel.org/qemu-devel/20241007025700.47259-1-zhiwei_liu@linux.alibaba.com/

Changes for v6:
  - Fix problem with TB overflow restart wrt the constant pool.
  - Fix vsetivli disassembly.
  - Change set_vtype to precompute all instructions.
  - Extract one element before comparison in tcg_out_dupi_vec.
  - Extract one element before comparison in tcg_target_const_match.
  - Drop 'vm' parameter from most tcg_out_opc_* functions.
  - Add tcg_out_opc_vv_vi and accept K constants for operations
    which have .v.i instructions.
  - Do not expand cmp_vec early.
  - Fix expansion of rotls_vec.

I've tested this on cfarm95, a banana pi bpi-f3 with 256-bit rvv-1.0,
with qemu-aarch64 and some vectorized test cases.

Barring further comment, I plan to include this in a PR at the
end of the week.


r~


Huang Shiyuan (1):
  tcg/riscv: Add basic support for vector

Richard Henderson (3):
  tcg: Reset data_gen_ptr correctly
  disas/riscv: Fix vsetivli disassembly
  tcg/riscv: Accept constant first argument to sub_vec

TANG Tiancheng (10):
  util: Add RISC-V vector extension probe in cpuinfo
  tcg/riscv: Implement vector mov/dup{m/i}
  tcg/riscv: Add support for basic vector opcodes
  tcg/riscv: Implement vector cmp/cmpsel ops
  tcg/riscv: Implement vector neg ops
  tcg/riscv: Implement vector sat/mul ops
  tcg/riscv: Implement vector min/max ops
  tcg/riscv: Implement vector shi/s/v ops
  tcg/riscv: Implement vector roti/v/x ops
  tcg/riscv: Enable native vector support for TCG host

 disas/riscv.h                     |   2 +-
 host/include/riscv/host/cpuinfo.h |   2 +
 include/tcg/tcg.h                 |   6 +
 tcg/riscv/tcg-target-con-set.h    |   9 +
 tcg/riscv/tcg-target-con-str.h    |   3 +
 tcg/riscv/tcg-target.h            |  78 ++-
 tcg/riscv/tcg-target.opc.h        |  12 +
 disas/riscv.c                     |   2 +-
 tcg/tcg.c                         |   2 +-
 util/cpuinfo-riscv.c              |  24 +-
 tcg/riscv/tcg-target.c.inc        | 994 +++++++++++++++++++++++++++---
 11 files changed, 1011 insertions(+), 123 deletions(-)
 create mode 100644 tcg/riscv/tcg-target.opc.h

-- 
2.43.0



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

* [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-21  1:16   ` Alistair Francis
                     ` (2 more replies)
  2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
                   ` (13 subsequent siblings)
  14 siblings, 3 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, qemu-stable

This pointer needs to be reset after overflow just like
code_buf and code_ptr.

Cc: qemu-stable@nongnu.org
Fixes: 57a269469db ("tcg: Infrastructure for managing constant pools")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/tcg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 5decd83cf4..0babae1b88 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1399,7 +1399,6 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
         goto retry;
     }
     qatomic_set(&s->code_gen_ptr, next);
-    s->data_gen_ptr = NULL;
     return tb;
 }
 
@@ -6172,6 +6171,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
      */
     s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
     s->code_ptr = s->code_buf;
+    s->data_gen_ptr = NULL;
 
 #ifdef TCG_TARGET_NEED_LDST_LABELS
     QSIMPLEQ_INIT(&s->ldst_labels);
-- 
2.43.0



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

* [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-21  1:17   ` Alistair Francis
                     ` (2 more replies)
  2024-10-16 19:31 ` [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo Richard Henderson
                   ` (12 subsequent siblings)
  14 siblings, 3 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu

The first immediate field is unsigned, whereas operand_vimm
extracts a signed value.  There is no need to mask the result
with 'u'; just print the immediate with 'i'.

Fixes: 07f4964d178 ("disas/riscv.c: rvv: Add disas support for vector instructions")
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 disas/riscv.h | 2 +-
 disas/riscv.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/disas/riscv.h b/disas/riscv.h
index 16a08e4895..0d1f89ce8a 100644
--- a/disas/riscv.h
+++ b/disas/riscv.h
@@ -290,7 +290,7 @@ enum {
 #define rv_fmt_fd_vs2                 "O\t3,F"
 #define rv_fmt_vd_vm                  "O\tDm"
 #define rv_fmt_vsetvli                "O\t0,1,v"
-#define rv_fmt_vsetivli               "O\t0,u,v"
+#define rv_fmt_vsetivli               "O\t0,i,v"
 #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
 #define rv_fmt_push_rlist             "O\tx,-i"
 #define rv_fmt_pop_rlist              "O\tx,i"
diff --git a/disas/riscv.c b/disas/riscv.c
index 5965574d87..fc0331b90b 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -4808,7 +4808,7 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
         break;
     case rv_codec_vsetivli:
         dec->rd = operand_rd(inst);
-        dec->imm = operand_vimm(inst);
+        dec->imm = extract32(inst, 15, 5);
         dec->vzimm = operand_vzimm10(inst);
         break;
     case rv_codec_zcb_lb:
-- 
2.43.0



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

* [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-21  1:20   ` Alistair Francis
  2024-10-21 18:25   ` Daniel Henrique Barboza
  2024-10-16 19:31 ` [PATCH v6 04/14] tcg/riscv: Add basic support for vector Richard Henderson
                   ` (11 subsequent siblings)
  14 siblings, 2 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Add support for probing RISC-V vector extension availability in
the backend. This information will be used when deciding whether
to use vector instructions in code generation.

Cache lg2(vlenb) for the backend. The storing of lg2(vlenb) means
we can convert all of the division into subtraction.

While the compiler doesn't support RISCV_HWPROBE_EXT_ZVE64X,
we use RISCV_HWPROBE_IMA_V instead. RISCV_HWPROBE_IMA_V is more
strictly constrainted than RISCV_HWPROBE_EXT_ZVE64X. At least in
current QEMU implemenation, the V vector extension depends on the
zve64d extension.

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-ID: <20241007025700.47259-2-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 host/include/riscv/host/cpuinfo.h |  2 ++
 util/cpuinfo-riscv.c              | 24 ++++++++++++++++++++++--
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/host/include/riscv/host/cpuinfo.h b/host/include/riscv/host/cpuinfo.h
index 2b00660e36..cdc784e7b6 100644
--- a/host/include/riscv/host/cpuinfo.h
+++ b/host/include/riscv/host/cpuinfo.h
@@ -10,9 +10,11 @@
 #define CPUINFO_ZBA             (1u << 1)
 #define CPUINFO_ZBB             (1u << 2)
 #define CPUINFO_ZICOND          (1u << 3)
+#define CPUINFO_ZVE64X          (1u << 4)
 
 /* Initialized with a constructor. */
 extern unsigned cpuinfo;
+extern unsigned riscv_lg2_vlenb;
 
 /*
  * We cannot rely on constructor ordering, so other constructors must
diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
index 8cacc67645..16114ffd32 100644
--- a/util/cpuinfo-riscv.c
+++ b/util/cpuinfo-riscv.c
@@ -4,6 +4,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "host/cpuinfo.h"
 
 #ifdef CONFIG_ASM_HWPROBE_H
@@ -13,6 +14,7 @@
 #endif
 
 unsigned cpuinfo;
+unsigned riscv_lg2_vlenb;
 static volatile sig_atomic_t got_sigill;
 
 static void sigill_handler(int signo, siginfo_t *si, void *data)
@@ -34,7 +36,7 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
 /* Called both as constructor and (possibly) via other constructors. */
 unsigned __attribute__((constructor)) cpuinfo_init(void)
 {
-    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND;
+    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;
     unsigned info = cpuinfo;
 
     if (info) {
@@ -50,6 +52,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
 #endif
 #if defined(__riscv_arch_test) && defined(__riscv_zicond)
     info |= CPUINFO_ZICOND;
+#endif
+#if defined(__riscv_arch_test) && defined(__riscv_zve64x)
+    info |= CPUINFO_ZVE64X;
 #endif
     left &= ~info;
 
@@ -65,7 +70,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
             && pair.key >= 0) {
             info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
             info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
-            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
+            info |= pair.value & RISCV_HWPROBE_IMA_V ? CPUINFO_ZVE64X : 0;
+            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZVE64X);
 #ifdef RISCV_HWPROBE_EXT_ZICOND
             info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
             left &= ~CPUINFO_ZICOND;
@@ -113,6 +119,20 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
         assert(left == 0);
     }
 
+    if (info & CPUINFO_ZVE64X) {
+        /*
+         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
+         * We are guaranteed by Zve64x that VLEN >= 64, and that
+         * EEW of {8,16,32,64} are supported.
+         *
+         * Cache VLEN in a convenient form.
+         */
+        unsigned long vlenb;
+        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
+        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
+        riscv_lg2_vlenb = ctz32(vlenb);
+    }
+
     info |= CPUINFO_ALWAYS;
     cpuinfo = info;
     return info;
-- 
2.43.0



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

* [PATCH v6 04/14] tcg/riscv: Add basic support for vector
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (2 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 05/14] tcg/riscv: Implement vector mov/dup{m/i} Richard Henderson
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, alistair.francis, zhiwei_liu, Huang Shiyuan,
	TANG Tiancheng

From: Huang Shiyuan <swung0x48@outlook.com>

The RISC-V vector instruction set utilizes the LMUL field to group
multiple registers, enabling variable-length vector registers. This
implementation uses only the first register number of each group while
reserving the other register numbers within the group.

In TCG, each VEC_IR can have 3 types (TCG_TYPE_V64/128/256), and the
host runtime needs to adjust LMUL based on the type to use different
register groups.

This presents challenges for TCG's register allocation. Currently, we
avoid modifying the register allocation part of TCG and only expose the
minimum number of vector registers.

For example, when the host vlen is 64 bits and type is TCG_TYPE_V256, with
LMUL equal to 4, we use 4 vector registers as one register group. We can
use a maximum of 8 register groups, but the V0 register number is reserved
as a mask register, so we can effectively use at most 7 register groups.
Moreover, when type is smaller than TCG_TYPE_V256, only 7 registers are
forced to be used. This is because TCG cannot yet dynamically constrain
registers with type; likewise, when the host vlen is 128 bits and
TCG_TYPE_V256, we can use at most 15 registers.

There is not much pressure on vector register allocation in TCG now, so
using 7 registers is feasible and will not have a major impact on code
generation.

This patch:
1. Reserves vector register 0 for use as a mask register.
2. When using register groups, reserves the additional registers within
   each group.

Signed-off-by: Huang Shiyuan <swung0x48@outlook.com>
Co-authored-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Swung0x48 <swung0x48@outlook.com>
Message-ID: <20241007025700.47259-3-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/tcg/tcg.h              |   6 +
 tcg/riscv/tcg-target-con-set.h |   2 +
 tcg/riscv/tcg-target-con-str.h |   1 +
 tcg/riscv/tcg-target.h         |  78 ++++---
 tcg/riscv/tcg-target.opc.h     |  12 +
 tcg/riscv/tcg-target.c.inc     | 414 ++++++++++++++++++++++++++++++---
 6 files changed, 442 insertions(+), 71 deletions(-)
 create mode 100644 tcg/riscv/tcg-target.opc.h

diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h
index 824fb3560d..a77ed12b9d 100644
--- a/include/tcg/tcg.h
+++ b/include/tcg/tcg.h
@@ -521,6 +521,12 @@ struct TCGContext {
     struct qemu_plugin_insn *plugin_insn;
 #endif
 
+    /* For host-specific values. */
+#ifdef __riscv
+    MemOp riscv_cur_vsew;
+    TCGType riscv_cur_type;
+#endif
+
     GHashTable *const_table[TCG_TYPE_COUNT];
     TCGTempSet free_temps[TCG_TYPE_COUNT];
     TCGTemp temps[TCG_MAX_TEMPS]; /* globals first, temps after */
diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index aac5ceee2b..d73a62b0f2 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -21,3 +21,5 @@ C_O1_I2(r, rZ, rZ)
 C_N1_I2(r, r, rM)
 C_O1_I4(r, r, rI, rM, rM)
 C_O2_I4(r, r, rZ, rZ, rM, rM)
+C_O0_I2(v, r)
+C_O1_I1(v, r)
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
index d5c419dff1..b2b3211bcb 100644
--- a/tcg/riscv/tcg-target-con-str.h
+++ b/tcg/riscv/tcg-target-con-str.h
@@ -9,6 +9,7 @@
  * REGS(letter, register_mask)
  */
 REGS('r', ALL_GENERAL_REGS)
+REGS('v', ALL_VECTOR_REGS)
 
 /*
  * Define constraint letters for constants:
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 1a347eaf6e..12a7a37aaa 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -28,42 +28,28 @@
 #include "host/cpuinfo.h"
 
 #define TCG_TARGET_INSN_UNIT_SIZE 4
-#define TCG_TARGET_NB_REGS 32
+#define TCG_TARGET_NB_REGS 64
 #define MAX_CODE_GEN_BUFFER_SIZE  ((size_t)-1)
 
 typedef enum {
-    TCG_REG_ZERO,
-    TCG_REG_RA,
-    TCG_REG_SP,
-    TCG_REG_GP,
-    TCG_REG_TP,
-    TCG_REG_T0,
-    TCG_REG_T1,
-    TCG_REG_T2,
-    TCG_REG_S0,
-    TCG_REG_S1,
-    TCG_REG_A0,
-    TCG_REG_A1,
-    TCG_REG_A2,
-    TCG_REG_A3,
-    TCG_REG_A4,
-    TCG_REG_A5,
-    TCG_REG_A6,
-    TCG_REG_A7,
-    TCG_REG_S2,
-    TCG_REG_S3,
-    TCG_REG_S4,
-    TCG_REG_S5,
-    TCG_REG_S6,
-    TCG_REG_S7,
-    TCG_REG_S8,
-    TCG_REG_S9,
-    TCG_REG_S10,
-    TCG_REG_S11,
-    TCG_REG_T3,
-    TCG_REG_T4,
-    TCG_REG_T5,
-    TCG_REG_T6,
+    TCG_REG_ZERO, TCG_REG_RA,  TCG_REG_SP,  TCG_REG_GP,
+    TCG_REG_TP,   TCG_REG_T0,  TCG_REG_T1,  TCG_REG_T2,
+    TCG_REG_S0,   TCG_REG_S1,  TCG_REG_A0,  TCG_REG_A1,
+    TCG_REG_A2,   TCG_REG_A3,  TCG_REG_A4,  TCG_REG_A5,
+    TCG_REG_A6,   TCG_REG_A7,  TCG_REG_S2,  TCG_REG_S3,
+    TCG_REG_S4,   TCG_REG_S5,  TCG_REG_S6,  TCG_REG_S7,
+    TCG_REG_S8,   TCG_REG_S9,  TCG_REG_S10, TCG_REG_S11,
+    TCG_REG_T3,   TCG_REG_T4,  TCG_REG_T5,  TCG_REG_T6,
+
+    /* RISC-V V Extension registers */
+    TCG_REG_V0,   TCG_REG_V1,  TCG_REG_V2,  TCG_REG_V3,
+    TCG_REG_V4,   TCG_REG_V5,  TCG_REG_V6,  TCG_REG_V7,
+    TCG_REG_V8,   TCG_REG_V9,  TCG_REG_V10, TCG_REG_V11,
+    TCG_REG_V12,  TCG_REG_V13, TCG_REG_V14, TCG_REG_V15,
+    TCG_REG_V16,  TCG_REG_V17, TCG_REG_V18, TCG_REG_V19,
+    TCG_REG_V20,  TCG_REG_V21, TCG_REG_V22, TCG_REG_V23,
+    TCG_REG_V24,  TCG_REG_V25, TCG_REG_V26, TCG_REG_V27,
+    TCG_REG_V28,  TCG_REG_V29, TCG_REG_V30, TCG_REG_V31,
 
     /* aliases */
     TCG_AREG0          = TCG_REG_S0,
@@ -156,6 +142,32 @@ typedef enum {
 
 #define TCG_TARGET_HAS_tst              0
 
+/* vector instructions */
+#define TCG_TARGET_HAS_v64              0
+#define TCG_TARGET_HAS_v128             0
+#define TCG_TARGET_HAS_v256             0
+#define TCG_TARGET_HAS_andc_vec         0
+#define TCG_TARGET_HAS_orc_vec          0
+#define TCG_TARGET_HAS_nand_vec         0
+#define TCG_TARGET_HAS_nor_vec          0
+#define TCG_TARGET_HAS_eqv_vec          0
+#define TCG_TARGET_HAS_not_vec          0
+#define TCG_TARGET_HAS_neg_vec          0
+#define TCG_TARGET_HAS_abs_vec          0
+#define TCG_TARGET_HAS_roti_vec         0
+#define TCG_TARGET_HAS_rots_vec         0
+#define TCG_TARGET_HAS_rotv_vec         0
+#define TCG_TARGET_HAS_shi_vec          0
+#define TCG_TARGET_HAS_shs_vec          0
+#define TCG_TARGET_HAS_shv_vec          0
+#define TCG_TARGET_HAS_mul_vec          0
+#define TCG_TARGET_HAS_sat_vec          0
+#define TCG_TARGET_HAS_minmax_vec       0
+#define TCG_TARGET_HAS_bitsel_vec       0
+#define TCG_TARGET_HAS_cmpsel_vec       0
+
+#define TCG_TARGET_HAS_tst_vec          0
+
 #define TCG_TARGET_DEFAULT_MO (0)
 
 #define TCG_TARGET_NEED_LDST_LABELS
diff --git a/tcg/riscv/tcg-target.opc.h b/tcg/riscv/tcg-target.opc.h
new file mode 100644
index 0000000000..b80b39e1e5
--- /dev/null
+++ b/tcg/riscv/tcg-target.opc.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) C-SKY Microsystems Co., Ltd.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.
+ *
+ * See the COPYING file in the top-level directory for details.
+ *
+ * Target-specific opcodes for host vector expansion.  These will be
+ * emitted by tcg_expand_vec_op.  For those familiar with GCC internals,
+ * consider these to be UNSPEC with names.
+ */
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index d334857226..38d71111c9 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -32,38 +32,14 @@
 
 #ifdef CONFIG_DEBUG_TCG
 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
-    "zero",
-    "ra",
-    "sp",
-    "gp",
-    "tp",
-    "t0",
-    "t1",
-    "t2",
-    "s0",
-    "s1",
-    "a0",
-    "a1",
-    "a2",
-    "a3",
-    "a4",
-    "a5",
-    "a6",
-    "a7",
-    "s2",
-    "s3",
-    "s4",
-    "s5",
-    "s6",
-    "s7",
-    "s8",
-    "s9",
-    "s10",
-    "s11",
-    "t3",
-    "t4",
-    "t5",
-    "t6"
+    "zero", "ra",  "sp",  "gp",  "tp",  "t0",  "t1",  "t2",
+    "s0",   "s1",  "a0",  "a1",  "a2",  "a3",  "a4",  "a5",
+    "a6",   "a7",  "s2",  "s3",  "s4",  "s5",  "s6",  "s7",
+    "s8",   "s9",  "s10", "s11", "t3",  "t4",  "t5",  "t6",
+    "v0",   "v1",  "v2",  "v3",  "v4",  "v5",  "v6",  "v7",
+    "v8",   "v9",  "v10", "v11", "v12", "v13", "v14", "v15",
+    "v16",  "v17", "v18", "v19", "v20", "v21", "v22", "v23",
+    "v24",  "v25", "v26", "v27", "v28", "v29", "v30", "v31",
 };
 #endif
 
@@ -100,6 +76,16 @@ static const int tcg_target_reg_alloc_order[] = {
     TCG_REG_A5,
     TCG_REG_A6,
     TCG_REG_A7,
+
+    /* Vector registers and TCG_REG_V0 reserved for mask. */
+    TCG_REG_V1,  TCG_REG_V2,  TCG_REG_V3,  TCG_REG_V4,
+    TCG_REG_V5,  TCG_REG_V6,  TCG_REG_V7,  TCG_REG_V8,
+    TCG_REG_V9,  TCG_REG_V10, TCG_REG_V11, TCG_REG_V12,
+    TCG_REG_V13, TCG_REG_V14, TCG_REG_V15, TCG_REG_V16,
+    TCG_REG_V17, TCG_REG_V18, TCG_REG_V19, TCG_REG_V20,
+    TCG_REG_V21, TCG_REG_V22, TCG_REG_V23, TCG_REG_V24,
+    TCG_REG_V25, TCG_REG_V26, TCG_REG_V27, TCG_REG_V28,
+    TCG_REG_V29, TCG_REG_V30, TCG_REG_V31,
 };
 
 static const int tcg_target_call_iarg_regs[] = {
@@ -127,6 +113,9 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 #define TCG_CT_CONST_J12  0x1000
 
 #define ALL_GENERAL_REGS   MAKE_64BIT_MASK(0, 32)
+#define ALL_VECTOR_REGS    MAKE_64BIT_MASK(32, 32)
+#define ALL_DVECTOR_REG_GROUPS 0x5555555500000000
+#define ALL_QVECTOR_REG_GROUPS 0x1111111100000000
 
 #define sextreg  sextract64
 
@@ -176,6 +165,31 @@ static bool tcg_target_const_match(int64_t val, int ct,
  * RISC-V Base ISA opcodes (IM)
  */
 
+#define V_OPIVV (0x0 << 12)
+#define V_OPFVV (0x1 << 12)
+#define V_OPMVV (0x2 << 12)
+#define V_OPIVI (0x3 << 12)
+#define V_OPIVX (0x4 << 12)
+#define V_OPFVF (0x5 << 12)
+#define V_OPMVX (0x6 << 12)
+#define V_OPCFG (0x7 << 12)
+
+/* NF <= 7 && NF >= 0 */
+#define V_NF(x) (x << 29)
+#define V_UNIT_STRIDE (0x0 << 20)
+#define V_UNIT_STRIDE_WHOLE_REG (0x8 << 20)
+
+typedef enum {
+    VLMUL_M1 = 0, /* LMUL=1 */
+    VLMUL_M2,     /* LMUL=2 */
+    VLMUL_M4,     /* LMUL=4 */
+    VLMUL_M8,     /* LMUL=8 */
+    VLMUL_RESERVED,
+    VLMUL_MF8,    /* LMUL=1/8 */
+    VLMUL_MF4,    /* LMUL=1/4 */
+    VLMUL_MF2,    /* LMUL=1/2 */
+} RISCVVlmul;
+
 typedef enum {
     OPC_ADD = 0x33,
     OPC_ADDI = 0x13,
@@ -271,6 +285,30 @@ typedef enum {
     /* Zicond: integer conditional operations */
     OPC_CZERO_EQZ = 0x0e005033,
     OPC_CZERO_NEZ = 0x0e007033,
+
+    /* V: Vector extension 1.0 */
+    OPC_VSETVLI  = 0x57 | V_OPCFG,
+    OPC_VSETIVLI = 0xc0000057 | V_OPCFG,
+    OPC_VSETVL   = 0x80000057 | V_OPCFG,
+
+    OPC_VLE8_V  = 0x7 | V_UNIT_STRIDE,
+    OPC_VLE16_V = 0x5007 | V_UNIT_STRIDE,
+    OPC_VLE32_V = 0x6007 | V_UNIT_STRIDE,
+    OPC_VLE64_V = 0x7007 | V_UNIT_STRIDE,
+    OPC_VSE8_V  = 0x27 | V_UNIT_STRIDE,
+    OPC_VSE16_V = 0x5027 | V_UNIT_STRIDE,
+    OPC_VSE32_V = 0x6027 | V_UNIT_STRIDE,
+    OPC_VSE64_V = 0x7027 | V_UNIT_STRIDE,
+
+    OPC_VL1RE64_V = 0x2007007 | V_UNIT_STRIDE_WHOLE_REG | V_NF(0),
+    OPC_VL2RE64_V = 0x2007007 | V_UNIT_STRIDE_WHOLE_REG | V_NF(1),
+    OPC_VL4RE64_V = 0x2007007 | V_UNIT_STRIDE_WHOLE_REG | V_NF(3),
+    OPC_VL8RE64_V = 0x2007007 | V_UNIT_STRIDE_WHOLE_REG | V_NF(7),
+
+    OPC_VS1R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(0),
+    OPC_VS2R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(1),
+    OPC_VS4R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(3),
+    OPC_VS8R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(7),
 } RISCVInsn;
 
 /*
@@ -363,6 +401,35 @@ static int32_t encode_uj(RISCVInsn opc, TCGReg rd, uint32_t imm)
     return opc | (rd & 0x1f) << 7 | encode_ujimm20(imm);
 }
 
+/* Type-OPIVV/OPMVV/OPIVX/OPMVX, Vector load and store */
+
+static int32_t encode_v(RISCVInsn opc, TCGReg d, TCGReg s1,
+                        TCGReg s2, bool vm)
+{
+    return opc | (d & 0x1f) << 7 | (s1 & 0x1f) << 15 |
+           (s2 & 0x1f) << 20 | (vm << 25);
+}
+
+/* Vector vtype */
+
+static uint32_t encode_vtype(bool vta, bool vma,
+                            MemOp vsew, RISCVVlmul vlmul)
+{
+    return vma << 7 | vta << 6 | vsew << 3 | vlmul;
+}
+
+static int32_t encode_vset(RISCVInsn opc, TCGReg rd,
+                           TCGArg rs1, uint32_t vtype)
+{
+    return opc | (rd & 0x1f) << 7 | (rs1 & 0x1f) << 15 | (vtype & 0x7ff) << 20;
+}
+
+static int32_t encode_vseti(RISCVInsn opc, TCGReg rd,
+                            uint32_t uimm, uint32_t vtype)
+{
+    return opc | (rd & 0x1f) << 7 | (uimm & 0x1f) << 15 | (vtype & 0x3ff) << 20;
+}
+
 /*
  * RISC-V instruction emitters
  */
@@ -475,6 +542,38 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
     }
 }
 
+/*
+ * RISC-V vector instruction emitters
+ */
+
+typedef struct VsetCache {
+    uint32_t movi_insn;
+    uint32_t vset_insn;
+} VsetCache;
+
+static VsetCache riscv_vset_cache[3][4];
+
+static void set_vtype(TCGContext *s, TCGType type, MemOp vsew)
+{
+    const VsetCache *p = &riscv_vset_cache[type - TCG_TYPE_V64][vsew];
+
+    s->riscv_cur_type = type;
+    s->riscv_cur_vsew = vsew;
+
+    if (p->movi_insn) {
+        tcg_out32(s, p->movi_insn);
+    }
+    tcg_out32(s, p->vset_insn);
+}
+
+static MemOp set_vtype_len(TCGContext *s, TCGType type)
+{
+    if (type != s->riscv_cur_type) {
+        set_vtype(s, type, MO_64);
+    }
+    return s->riscv_cur_vsew;
+}
+
 /*
  * TCG intrinsics
  */
@@ -681,18 +780,101 @@ static void tcg_out_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
     }
 }
 
+static void tcg_out_vec_ldst(TCGContext *s, RISCVInsn opc, TCGReg data,
+                             TCGReg addr, intptr_t offset)
+{
+    tcg_debug_assert(data >= TCG_REG_V0);
+    tcg_debug_assert(addr < TCG_REG_V0);
+
+    if (offset) {
+        tcg_debug_assert(addr != TCG_REG_ZERO);
+        if (offset == sextreg(offset, 0, 12)) {
+            tcg_out_opc_imm(s, OPC_ADDI, TCG_REG_TMP0, addr, offset);
+        } else {
+            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_TMP0, offset);
+            tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP0, addr);
+        }
+        addr = TCG_REG_TMP0;
+    }
+    tcg_out32(s, encode_v(opc, data, addr, 0, true));
+}
+
 static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg arg,
                        TCGReg arg1, intptr_t arg2)
 {
-    RISCVInsn insn = type == TCG_TYPE_I32 ? OPC_LW : OPC_LD;
-    tcg_out_ldst(s, insn, arg, arg1, arg2);
+    RISCVInsn insn;
+
+    switch (type) {
+    case TCG_TYPE_I32:
+        tcg_out_ldst(s, OPC_LW, arg, arg1, arg2);
+        break;
+    case TCG_TYPE_I64:
+        tcg_out_ldst(s, OPC_LD, arg, arg1, arg2);
+        break;
+    case TCG_TYPE_V64:
+    case TCG_TYPE_V128:
+    case TCG_TYPE_V256:
+        if (type >= riscv_lg2_vlenb) {
+            static const RISCVInsn whole_reg_ld[] = {
+                OPC_VL1RE64_V, OPC_VL2RE64_V, OPC_VL4RE64_V, OPC_VL8RE64_V
+            };
+            unsigned idx = type - riscv_lg2_vlenb;
+
+            tcg_debug_assert(idx < ARRAY_SIZE(whole_reg_ld));
+            insn = whole_reg_ld[idx];
+        } else {
+            static const RISCVInsn unit_stride_ld[] = {
+                OPC_VLE8_V, OPC_VLE16_V, OPC_VLE32_V, OPC_VLE64_V
+            };
+            MemOp prev_vsew = set_vtype_len(s, type);
+
+            tcg_debug_assert(prev_vsew < ARRAY_SIZE(unit_stride_ld));
+            insn = unit_stride_ld[prev_vsew];
+        }
+        tcg_out_vec_ldst(s, insn, arg, arg1, arg2);
+        break;
+    default:
+        g_assert_not_reached();
+    }
 }
 
 static void tcg_out_st(TCGContext *s, TCGType type, TCGReg arg,
                        TCGReg arg1, intptr_t arg2)
 {
-    RISCVInsn insn = type == TCG_TYPE_I32 ? OPC_SW : OPC_SD;
-    tcg_out_ldst(s, insn, arg, arg1, arg2);
+    RISCVInsn insn;
+
+    switch (type) {
+    case TCG_TYPE_I32:
+        tcg_out_ldst(s, OPC_SW, arg, arg1, arg2);
+        break;
+    case TCG_TYPE_I64:
+        tcg_out_ldst(s, OPC_SD, arg, arg1, arg2);
+        break;
+    case TCG_TYPE_V64:
+    case TCG_TYPE_V128:
+    case TCG_TYPE_V256:
+        if (type >= riscv_lg2_vlenb) {
+            static const RISCVInsn whole_reg_st[] = {
+                OPC_VS1R_V, OPC_VS2R_V, OPC_VS4R_V, OPC_VS8R_V
+            };
+            unsigned idx = type - riscv_lg2_vlenb;
+
+            tcg_debug_assert(idx < ARRAY_SIZE(whole_reg_st));
+            insn = whole_reg_st[idx];
+        } else {
+            static const RISCVInsn unit_stride_st[] = {
+                OPC_VSE8_V, OPC_VSE16_V, OPC_VSE32_V, OPC_VSE64_V
+            };
+            MemOp prev_vsew = set_vtype_len(s, type);
+
+            tcg_debug_assert(prev_vsew < ARRAY_SIZE(unit_stride_st));
+            insn = unit_stride_st[prev_vsew];
+        }
+        tcg_out_vec_ldst(s, insn, arg, arg1, arg2);
+        break;
+    default:
+        g_assert_not_reached();
+    }
 }
 
 static bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
@@ -766,6 +948,23 @@ static void tcg_out_addsub2(TCGContext *s,
     }
 }
 
+static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
+                                   TCGReg dst, TCGReg src)
+{
+    return false;
+}
+
+static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
+                                    TCGReg dst, TCGReg base, intptr_t offset)
+{
+    return false;
+}
+
+static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
+                                    TCGReg dst, int64_t arg)
+{
+}
+
 static const struct {
     RISCVInsn op;
     bool swap;
@@ -1104,12 +1303,19 @@ static void tcg_out_cltz(TCGContext *s, TCGType type, RISCVInsn insn,
     }
 }
 
+static void init_setting_vtype(TCGContext *s)
+{
+    s->riscv_cur_type = TCG_TYPE_COUNT;
+}
+
 static void tcg_out_call_int(TCGContext *s, const tcg_insn_unit *arg, bool tail)
 {
     TCGReg link = tail ? TCG_REG_ZERO : TCG_REG_RA;
     ptrdiff_t offset = tcg_pcrel_diff(s, arg);
     int ret;
 
+    init_setting_vtype(s);
+
     tcg_debug_assert((offset & 1) == 0);
     if (offset == sextreg(offset, 0, 20)) {
         /* short jump: -2097150 to 2097152 */
@@ -1247,6 +1453,8 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
         ldst->oi = oi;
         ldst->addrlo_reg = addr_reg;
 
+        init_setting_vtype(s);
+
         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP0, TCG_AREG0, mask_ofs);
         tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_TMP1, TCG_AREG0, table_ofs);
 
@@ -1308,6 +1516,8 @@ static TCGLabelQemuLdst *prepare_host_addr(TCGContext *s, TCGReg *pbase,
             ldst->oi = oi;
             ldst->addrlo_reg = addr_reg;
 
+            init_setting_vtype(s);
+
             /* We are expecting alignment max 7, so we can always use andi. */
             tcg_debug_assert(a_mask == sextreg(a_mask, 0, 12));
             tcg_out_opc_imm(s, OPC_ANDI, TCG_REG_TMP1, addr_reg, a_mask);
@@ -1881,6 +2091,46 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
     }
 }
 
+static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
+                           unsigned vecl, unsigned vece,
+                           const TCGArg args[TCG_MAX_OP_ARGS],
+                           const int const_args[TCG_MAX_OP_ARGS])
+{
+    TCGType type = vecl + TCG_TYPE_V64;
+    TCGArg a0, a1, a2;
+
+    a0 = args[0];
+    a1 = args[1];
+    a2 = args[2];
+
+    switch (opc) {
+    case INDEX_op_ld_vec:
+        tcg_out_ld(s, type, a0, a1, a2);
+        break;
+    case INDEX_op_st_vec:
+        tcg_out_st(s, type, a0, a1, a2);
+        break;
+    case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov.  */
+    case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec.  */
+    default:
+        g_assert_not_reached();
+    }
+}
+
+void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
+                       TCGArg a0, ...)
+{
+    g_assert_not_reached();
+}
+
+int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
+{
+    switch (opc) {
+    default:
+        return 0;
+    }
+}
+
 static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 {
     switch (op) {
@@ -2020,6 +2270,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_qemu_st_a64_i64:
         return C_O0_I2(rZ, r);
 
+    case INDEX_op_st_vec:
+        return C_O0_I2(v, r);
+    case INDEX_op_ld_vec:
+        return C_O1_I1(v, r);
     default:
         g_assert_not_reached();
     }
@@ -2093,7 +2347,65 @@ static void tcg_target_qemu_prologue(TCGContext *s)
 
 static void tcg_out_tb_start(TCGContext *s)
 {
-    /* nothing to do */
+    init_setting_vtype(s);
+}
+
+static bool vtype_check(unsigned vtype)
+{
+    unsigned long tmp;
+
+    /* vsetvl tmp, zero, vtype */
+    asm(".insn r 0x57, 7, 0x40, %0, zero, %1" : "=r"(tmp) : "r"(vtype));
+    return tmp != 0;
+}
+
+static void probe_frac_lmul_1(TCGType type, MemOp vsew)
+{
+    VsetCache *p = &riscv_vset_cache[type - TCG_TYPE_V64][vsew];
+    unsigned avl = tcg_type_size(type) >> vsew;
+    int lmul = type - riscv_lg2_vlenb;
+    unsigned vtype = encode_vtype(true, true, vsew, lmul & 7);
+    bool lmul_eq_avl = true;
+
+    /* Guaranteed by Zve64x. */
+    assert(lmul < 3);
+
+    /*
+     * For LMUL < -3, the host vector size is so large that TYPE
+     * is smaller than the minimum 1/8 fraction.
+     *
+     * For other fractional LMUL settings, implementations must
+     * support SEW settings between SEW_MIN and LMUL * ELEN, inclusive.
+     * So if ELEN = 64, LMUL = 1/2, then SEW will support e8, e16, e32,
+     * but e64 may not be supported. In other words, the hardware only
+     * guarantees SEW_MIN <= SEW <= LMUL * ELEN.  Check.
+     */
+    if (lmul < 0 && (lmul < -3 || !vtype_check(vtype))) {
+        vtype = encode_vtype(true, true, vsew, VLMUL_M1);
+        lmul_eq_avl = false;
+    }
+
+    if (avl < 32) {
+        p->vset_insn = encode_vseti(OPC_VSETIVLI, TCG_REG_ZERO, avl, vtype);
+    } else if (lmul_eq_avl) {
+        /* rd != 0 and rs1 == 0 uses vlmax */
+        p->vset_insn = encode_vset(OPC_VSETVLI, TCG_REG_TMP0, TCG_REG_ZERO, vtype);
+    } else {
+        p->movi_insn = encode_i(OPC_ADDI, TCG_REG_TMP0, TCG_REG_ZERO, avl);
+        p->vset_insn = encode_vset(OPC_VSETVLI, TCG_REG_ZERO, TCG_REG_TMP0, vtype);
+    }
+}
+
+static void probe_frac_lmul(void)
+{
+    /* Match riscv_lg2_vlenb to TCG_TYPE_V64. */
+    QEMU_BUILD_BUG_ON(TCG_TYPE_V64 != 3);
+
+    for (TCGType t = TCG_TYPE_V64; t <= TCG_TYPE_V256; t++) {
+        for (MemOp e = MO_8; e <= MO_64; e++) {
+            probe_frac_lmul_1(t, e);
+        }
+    }
 }
 
 static void tcg_target_init(TCGContext *s)
@@ -2101,7 +2413,7 @@ static void tcg_target_init(TCGContext *s)
     tcg_target_available_regs[TCG_TYPE_I32] = 0xffffffff;
     tcg_target_available_regs[TCG_TYPE_I64] = 0xffffffff;
 
-    tcg_target_call_clobber_regs = -1u;
+    tcg_target_call_clobber_regs = -1;
     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S0);
     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S1);
     tcg_regset_reset_reg(tcg_target_call_clobber_regs, TCG_REG_S2);
@@ -2123,6 +2435,32 @@ static void tcg_target_init(TCGContext *s)
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_SP);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_GP);
     tcg_regset_set_reg(s->reserved_regs, TCG_REG_TP);
+
+    if (cpuinfo & CPUINFO_ZVE64X) {
+        switch (riscv_lg2_vlenb) {
+        case TCG_TYPE_V64:
+            tcg_target_available_regs[TCG_TYPE_V64] = ALL_VECTOR_REGS;
+            tcg_target_available_regs[TCG_TYPE_V128] = ALL_DVECTOR_REG_GROUPS;
+            tcg_target_available_regs[TCG_TYPE_V256] = ALL_QVECTOR_REG_GROUPS;
+            s->reserved_regs |= (~ALL_QVECTOR_REG_GROUPS & ALL_VECTOR_REGS);
+            break;
+        case TCG_TYPE_V128:
+            tcg_target_available_regs[TCG_TYPE_V64] = ALL_VECTOR_REGS;
+            tcg_target_available_regs[TCG_TYPE_V128] = ALL_VECTOR_REGS;
+            tcg_target_available_regs[TCG_TYPE_V256] = ALL_DVECTOR_REG_GROUPS;
+            s->reserved_regs |= (~ALL_DVECTOR_REG_GROUPS & ALL_VECTOR_REGS);
+            break;
+        default:
+            /* Guaranteed by Zve64x. */
+            tcg_debug_assert(riscv_lg2_vlenb >= TCG_TYPE_V256);
+            tcg_target_available_regs[TCG_TYPE_V64] = ALL_VECTOR_REGS;
+            tcg_target_available_regs[TCG_TYPE_V128] = ALL_VECTOR_REGS;
+            tcg_target_available_regs[TCG_TYPE_V256] = ALL_VECTOR_REGS;
+            break;
+        }
+        tcg_regset_set_reg(s->reserved_regs, TCG_REG_V0);
+        probe_frac_lmul();
+    }
 }
 
 typedef struct {
-- 
2.43.0



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

* [PATCH v6 05/14] tcg/riscv: Implement vector mov/dup{m/i}
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (3 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 04/14] tcg/riscv: Add basic support for vector Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 06/14] tcg/riscv: Add support for basic vector opcodes Richard Henderson
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-5-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.c.inc | 76 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 38d71111c9..17fcc21b0e 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -309,6 +309,12 @@ typedef enum {
     OPC_VS2R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(1),
     OPC_VS4R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(3),
     OPC_VS8R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(7),
+
+    OPC_VMV_V_V = 0x5e000057 | V_OPIVV,
+    OPC_VMV_V_I = 0x5e000057 | V_OPIVI,
+    OPC_VMV_V_X = 0x5e000057 | V_OPIVX,
+
+    OPC_VMVNR_V = 0x9e000057 | V_OPIVI,
 } RISCVInsn;
 
 /*
@@ -401,6 +407,16 @@ static int32_t encode_uj(RISCVInsn opc, TCGReg rd, uint32_t imm)
     return opc | (rd & 0x1f) << 7 | encode_ujimm20(imm);
 }
 
+
+/* Type-OPIVI */
+
+static int32_t encode_vi(RISCVInsn opc, TCGReg rd, int32_t imm,
+                         TCGReg vs2, bool vm)
+{
+    return opc | (rd & 0x1f) << 7 | (imm & 0x1f) << 15 |
+           (vs2 & 0x1f) << 20 | (vm << 25);
+}
+
 /* Type-OPIVV/OPMVV/OPIVX/OPMVX, Vector load and store */
 
 static int32_t encode_v(RISCVInsn opc, TCGReg d, TCGReg s1,
@@ -546,6 +562,24 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
  * RISC-V vector instruction emitters
  */
 
+/*
+ * Vector registers uses the same 5 lower bits as GPR registers,
+ * and vm=0 (vm = false) means vector masking ENABLED.
+ * With RVV 1.0, vs2 is the first operand, while rs1/imm is the
+ * second operand.
+ */
+static void tcg_out_opc_vx(TCGContext *s, RISCVInsn opc,
+                           TCGReg vd, TCGReg vs2, TCGReg rs1)
+{
+    tcg_out32(s, encode_v(opc, vd, rs1, vs2, true));
+}
+
+static void tcg_out_opc_vi(TCGContext *s, RISCVInsn opc,
+                           TCGReg vd, TCGReg vs2, int32_t imm)
+{
+    tcg_out32(s, encode_vi(opc, vd, imm, vs2, true));
+}
+
 typedef struct VsetCache {
     uint32_t movi_insn;
     uint32_t vset_insn;
@@ -574,6 +608,13 @@ static MemOp set_vtype_len(TCGContext *s, TCGType type)
     return s->riscv_cur_vsew;
 }
 
+static void set_vtype_len_sew(TCGContext *s, TCGType type, MemOp vsew)
+{
+    if (type != s->riscv_cur_type || vsew != s->riscv_cur_vsew) {
+        set_vtype(s, type, vsew);
+    }
+}
+
 /*
  * TCG intrinsics
  */
@@ -588,6 +629,15 @@ static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
     case TCG_TYPE_I64:
         tcg_out_opc_imm(s, OPC_ADDI, ret, arg, 0);
         break;
+    case TCG_TYPE_V64:
+    case TCG_TYPE_V128:
+    case TCG_TYPE_V256:
+        {
+            int lmul = type - riscv_lg2_vlenb;
+            int nf = 1 << MAX(lmul, 0);
+            tcg_out_opc_vi(s, OPC_VMVNR_V, ret, arg, nf - 1);
+        }
+        break;
     default:
         g_assert_not_reached();
     }
@@ -951,18 +1001,35 @@ static void tcg_out_addsub2(TCGContext *s,
 static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
                                    TCGReg dst, TCGReg src)
 {
-    return false;
+    set_vtype_len_sew(s, type, vece);
+    tcg_out_opc_vx(s, OPC_VMV_V_X, dst, 0, src);
+    return true;
 }
 
 static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
                                     TCGReg dst, TCGReg base, intptr_t offset)
 {
-    return false;
+    tcg_out_ld(s, TCG_TYPE_REG, TCG_REG_TMP0, base, offset);
+    return tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0);
 }
 
 static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
                                     TCGReg dst, int64_t arg)
 {
+    /* Arg is replicated by VECE; extract the highest element. */
+    arg >>= (-8 << vece) & 63;
+
+    if (arg >= -16 && arg < 16) {
+        if (arg == 0 || arg == -1) {
+            set_vtype_len(s, type);
+        } else {
+            set_vtype_len_sew(s, type, vece);
+        }
+        tcg_out_opc_vi(s, OPC_VMV_V_I, dst, 0, arg);
+        return;
+    }
+    tcg_out_movi(s, TCG_TYPE_I64, TCG_REG_TMP0, arg);
+    tcg_out_dup_vec(s, type, vece, dst, TCG_REG_TMP0);
 }
 
 static const struct {
@@ -2104,6 +2171,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
     a2 = args[2];
 
     switch (opc) {
+    case INDEX_op_dupm_vec:
+        tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
+        break;
     case INDEX_op_ld_vec:
         tcg_out_ld(s, type, a0, a1, a2);
         break;
@@ -2272,6 +2342,8 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
 
     case INDEX_op_st_vec:
         return C_O0_I2(v, r);
+    case INDEX_op_dup_vec:
+    case INDEX_op_dupm_vec:
     case INDEX_op_ld_vec:
         return C_O1_I1(v, r);
     default:
-- 
2.43.0



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

* [PATCH v6 06/14] tcg/riscv: Add support for basic vector opcodes
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (4 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 05/14] tcg/riscv: Implement vector mov/dup{m/i} Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 07/14] tcg/riscv: Implement vector cmp/cmpsel ops Richard Henderson
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-6-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target-con-set.h |  3 ++
 tcg/riscv/tcg-target-con-str.h |  1 +
 tcg/riscv/tcg-target.h         |  2 +-
 tcg/riscv/tcg-target.c.inc     | 80 ++++++++++++++++++++++++++++++++++
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index d73a62b0f2..6513cebc4c 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -23,3 +23,6 @@ C_O1_I4(r, r, rI, rM, rM)
 C_O2_I4(r, r, rZ, rZ, rM, rM)
 C_O0_I2(v, r)
 C_O1_I1(v, r)
+C_O1_I1(v, v)
+C_O1_I2(v, v, v)
+C_O1_I2(v, v, vK)
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
index b2b3211bcb..0aaad7b753 100644
--- a/tcg/riscv/tcg-target-con-str.h
+++ b/tcg/riscv/tcg-target-con-str.h
@@ -17,6 +17,7 @@ REGS('v', ALL_VECTOR_REGS)
  */
 CONST('I', TCG_CT_CONST_S12)
 CONST('J', TCG_CT_CONST_J12)
+CONST('K', TCG_CT_CONST_S5)
 CONST('N', TCG_CT_CONST_N12)
 CONST('M', TCG_CT_CONST_M12)
 CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 12a7a37aaa..acb8dfdf16 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -151,7 +151,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nand_vec         0
 #define TCG_TARGET_HAS_nor_vec          0
 #define TCG_TARGET_HAS_eqv_vec          0
-#define TCG_TARGET_HAS_not_vec          0
+#define TCG_TARGET_HAS_not_vec          1
 #define TCG_TARGET_HAS_neg_vec          0
 #define TCG_TARGET_HAS_abs_vec          0
 #define TCG_TARGET_HAS_roti_vec         0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 17fcc21b0e..c8540f9a75 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -111,6 +111,7 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 #define TCG_CT_CONST_N12   0x400
 #define TCG_CT_CONST_M12   0x800
 #define TCG_CT_CONST_J12  0x1000
+#define TCG_CT_CONST_S5   0x2000
 
 #define ALL_GENERAL_REGS   MAKE_64BIT_MASK(0, 32)
 #define ALL_VECTOR_REGS    MAKE_64BIT_MASK(32, 32)
@@ -129,6 +130,10 @@ static bool tcg_target_const_match(int64_t val, int ct,
     if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
         return 1;
     }
+    if (type >= TCG_TYPE_V64) {
+        /* Val is replicated by VECE; extract the highest element. */
+        val >>= (-8 << vece) & 63;
+    }
     /*
      * Sign extended from 12 bits: [-0x800, 0x7ff].
      * Used for most arithmetic, as this is the isa field.
@@ -158,6 +163,13 @@ static bool tcg_target_const_match(int64_t val, int ct,
     if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
         return 1;
     }
+    /*
+     * Sign extended from 5 bits: [-0x10, 0x0f].
+     * Used for vector-immediate.
+     */
+    if ((ct & TCG_CT_CONST_S5) && val >= -0x10 && val <= 0x0f) {
+        return 1;
+    }
     return 0;
 }
 
@@ -310,6 +322,16 @@ typedef enum {
     OPC_VS4R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(3),
     OPC_VS8R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(7),
 
+    OPC_VADD_VV = 0x57 | V_OPIVV,
+    OPC_VADD_VI = 0x57 | V_OPIVI,
+    OPC_VSUB_VV = 0x8000057 | V_OPIVV,
+    OPC_VAND_VV = 0x24000057 | V_OPIVV,
+    OPC_VAND_VI = 0x24000057 | V_OPIVI,
+    OPC_VOR_VV = 0x28000057 | V_OPIVV,
+    OPC_VOR_VI = 0x28000057 | V_OPIVI,
+    OPC_VXOR_VV = 0x2c000057 | V_OPIVV,
+    OPC_VXOR_VI = 0x2c000057 | V_OPIVI,
+
     OPC_VMV_V_V = 0x5e000057 | V_OPIVV,
     OPC_VMV_V_I = 0x5e000057 | V_OPIVI,
     OPC_VMV_V_X = 0x5e000057 | V_OPIVX,
@@ -568,6 +590,12 @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
  * With RVV 1.0, vs2 is the first operand, while rs1/imm is the
  * second operand.
  */
+static void tcg_out_opc_vv(TCGContext *s, RISCVInsn opc,
+                           TCGReg vd, TCGReg vs2, TCGReg vs1)
+{
+    tcg_out32(s, encode_v(opc, vd, vs1, vs2, true));
+}
+
 static void tcg_out_opc_vx(TCGContext *s, RISCVInsn opc,
                            TCGReg vd, TCGReg vs2, TCGReg rs1)
 {
@@ -580,6 +608,16 @@ static void tcg_out_opc_vi(TCGContext *s, RISCVInsn opc,
     tcg_out32(s, encode_vi(opc, vd, imm, vs2, true));
 }
 
+static void tcg_out_opc_vv_vi(TCGContext *s, RISCVInsn o_vv, RISCVInsn o_vi,
+                              TCGReg vd, TCGReg vs2, TCGArg vi1, int c_vi1)
+{
+    if (c_vi1) {
+        tcg_out_opc_vi(s, o_vi, vd, vs2, vi1);
+    } else {
+        tcg_out_opc_vv(s, o_vv, vd, vs2, vi1);
+    }
+}
+
 typedef struct VsetCache {
     uint32_t movi_insn;
     uint32_t vset_insn;
@@ -2165,10 +2203,12 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
 {
     TCGType type = vecl + TCG_TYPE_V64;
     TCGArg a0, a1, a2;
+    int c2;
 
     a0 = args[0];
     a1 = args[1];
     a2 = args[2];
+    c2 = const_args[2];
 
     switch (opc) {
     case INDEX_op_dupm_vec:
@@ -2180,6 +2220,30 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
     case INDEX_op_st_vec:
         tcg_out_st(s, type, a0, a1, a2);
         break;
+    case INDEX_op_add_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VADD_VV, OPC_VADD_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_sub_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv(s, OPC_VSUB_VV, a0, a1, a2);
+        break;
+    case INDEX_op_and_vec:
+        set_vtype_len(s, type);
+        tcg_out_opc_vv_vi(s, OPC_VAND_VV, OPC_VAND_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_or_vec:
+        set_vtype_len(s, type);
+        tcg_out_opc_vv_vi(s, OPC_VOR_VV, OPC_VOR_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_xor_vec:
+        set_vtype_len(s, type);
+        tcg_out_opc_vv_vi(s, OPC_VXOR_VV, OPC_VXOR_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_not_vec:
+        set_vtype_len(s, type);
+        tcg_out_opc_vi(s, OPC_VXOR_VI, a0, a1, -1);
+        break;
     case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov.  */
     case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec.  */
     default:
@@ -2196,6 +2260,13 @@ void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
 int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
 {
     switch (opc) {
+    case INDEX_op_add_vec:
+    case INDEX_op_sub_vec:
+    case INDEX_op_and_vec:
+    case INDEX_op_or_vec:
+    case INDEX_op_xor_vec:
+    case INDEX_op_not_vec:
+        return 1;
     default:
         return 0;
     }
@@ -2346,6 +2417,15 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_dupm_vec:
     case INDEX_op_ld_vec:
         return C_O1_I1(v, r);
+    case INDEX_op_not_vec:
+        return C_O1_I1(v, v);
+    case INDEX_op_add_vec:
+    case INDEX_op_and_vec:
+    case INDEX_op_or_vec:
+    case INDEX_op_xor_vec:
+        return C_O1_I2(v, v, vK);
+    case INDEX_op_sub_vec:
+        return C_O1_I2(v, v, v);
     default:
         g_assert_not_reached();
     }
-- 
2.43.0



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

* [PATCH v6 07/14] tcg/riscv: Implement vector cmp/cmpsel ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (5 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 06/14] tcg/riscv: Add support for basic vector opcodes Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 08/14] tcg/riscv: Implement vector neg ops Richard Henderson
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Extend comparison results from mask registers to SEW-width elements,
following recommendations in The RISC-V SPEC Volume I (Version 20240411).
This aligns with TCG's cmp_vec behavior by expanding compare results to
full element width: all 1s for true, all 0s for false.

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-7-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target-con-set.h |   2 +
 tcg/riscv/tcg-target-con-str.h |   1 +
 tcg/riscv/tcg-target.h         |   2 +-
 tcg/riscv/tcg-target.c.inc     | 255 +++++++++++++++++++++++++--------
 4 files changed, 200 insertions(+), 60 deletions(-)

diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index 6513cebc4c..97e6ecdb0f 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -26,3 +26,5 @@ C_O1_I1(v, r)
 C_O1_I1(v, v)
 C_O1_I2(v, v, v)
 C_O1_I2(v, v, vK)
+C_O1_I2(v, v, vL)
+C_O1_I4(v, v, vL, vK, vK)
diff --git a/tcg/riscv/tcg-target-con-str.h b/tcg/riscv/tcg-target-con-str.h
index 0aaad7b753..089efe96ca 100644
--- a/tcg/riscv/tcg-target-con-str.h
+++ b/tcg/riscv/tcg-target-con-str.h
@@ -18,6 +18,7 @@ REGS('v', ALL_VECTOR_REGS)
 CONST('I', TCG_CT_CONST_S12)
 CONST('J', TCG_CT_CONST_J12)
 CONST('K', TCG_CT_CONST_S5)
+CONST('L', TCG_CT_CONST_CMP_VI)
 CONST('N', TCG_CT_CONST_N12)
 CONST('M', TCG_CT_CONST_M12)
 CONST('Z', TCG_CT_CONST_ZERO)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index acb8dfdf16..94034504b2 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -164,7 +164,7 @@ typedef enum {
 #define TCG_TARGET_HAS_sat_vec          0
 #define TCG_TARGET_HAS_minmax_vec       0
 #define TCG_TARGET_HAS_bitsel_vec       0
-#define TCG_TARGET_HAS_cmpsel_vec       0
+#define TCG_TARGET_HAS_cmpsel_vec       1
 
 #define TCG_TARGET_HAS_tst_vec          0
 
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index c8540f9a75..1893c419c6 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -106,12 +106,13 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
     return TCG_REG_A0 + slot;
 }
 
-#define TCG_CT_CONST_ZERO  0x100
-#define TCG_CT_CONST_S12   0x200
-#define TCG_CT_CONST_N12   0x400
-#define TCG_CT_CONST_M12   0x800
-#define TCG_CT_CONST_J12  0x1000
-#define TCG_CT_CONST_S5   0x2000
+#define TCG_CT_CONST_ZERO    0x100
+#define TCG_CT_CONST_S12     0x200
+#define TCG_CT_CONST_N12     0x400
+#define TCG_CT_CONST_M12     0x800
+#define TCG_CT_CONST_J12    0x1000
+#define TCG_CT_CONST_S5     0x2000
+#define TCG_CT_CONST_CMP_VI 0x4000
 
 #define ALL_GENERAL_REGS   MAKE_64BIT_MASK(0, 32)
 #define ALL_VECTOR_REGS    MAKE_64BIT_MASK(32, 32)
@@ -120,59 +121,6 @@ static TCGReg tcg_target_call_oarg_reg(TCGCallReturnKind kind, int slot)
 
 #define sextreg  sextract64
 
-/* test if a constant matches the constraint */
-static bool tcg_target_const_match(int64_t val, int ct,
-                                   TCGType type, TCGCond cond, int vece)
-{
-    if (ct & TCG_CT_CONST) {
-        return 1;
-    }
-    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
-        return 1;
-    }
-    if (type >= TCG_TYPE_V64) {
-        /* Val is replicated by VECE; extract the highest element. */
-        val >>= (-8 << vece) & 63;
-    }
-    /*
-     * Sign extended from 12 bits: [-0x800, 0x7ff].
-     * Used for most arithmetic, as this is the isa field.
-     */
-    if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
-        return 1;
-    }
-    /*
-     * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
-     * Used for subtraction, where a constant must be handled by ADDI.
-     */
-    if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
-        return 1;
-    }
-    /*
-     * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
-     * Used by addsub2 and movcond, which may need the negative value,
-     * and requires the modified constant to be representable.
-     */
-    if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
-        return 1;
-    }
-    /*
-     * Inverse of sign extended from 12 bits: ~[-0x800, 0x7ff].
-     * Used to map ANDN back to ANDI, etc.
-     */
-    if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
-        return 1;
-    }
-    /*
-     * Sign extended from 5 bits: [-0x10, 0x0f].
-     * Used for vector-immediate.
-     */
-    if ((ct & TCG_CT_CONST_S5) && val >= -0x10 && val <= 0x0f) {
-        return 1;
-    }
-    return 0;
-}
-
 /*
  * RISC-V Base ISA opcodes (IM)
  */
@@ -322,6 +270,9 @@ typedef enum {
     OPC_VS4R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(3),
     OPC_VS8R_V = 0x2000027 | V_UNIT_STRIDE_WHOLE_REG | V_NF(7),
 
+    OPC_VMERGE_VIM = 0x5c000057 | V_OPIVI,
+    OPC_VMERGE_VVM = 0x5c000057 | V_OPIVV,
+
     OPC_VADD_VV = 0x57 | V_OPIVV,
     OPC_VADD_VI = 0x57 | V_OPIVI,
     OPC_VSUB_VV = 0x8000057 | V_OPIVV,
@@ -332,6 +283,29 @@ typedef enum {
     OPC_VXOR_VV = 0x2c000057 | V_OPIVV,
     OPC_VXOR_VI = 0x2c000057 | V_OPIVI,
 
+    OPC_VMSEQ_VV = 0x60000057 | V_OPIVV,
+    OPC_VMSEQ_VI = 0x60000057 | V_OPIVI,
+    OPC_VMSEQ_VX = 0x60000057 | V_OPIVX,
+    OPC_VMSNE_VV = 0x64000057 | V_OPIVV,
+    OPC_VMSNE_VI = 0x64000057 | V_OPIVI,
+    OPC_VMSNE_VX = 0x64000057 | V_OPIVX,
+
+    OPC_VMSLTU_VV = 0x68000057 | V_OPIVV,
+    OPC_VMSLTU_VX = 0x68000057 | V_OPIVX,
+    OPC_VMSLT_VV = 0x6c000057 | V_OPIVV,
+    OPC_VMSLT_VX = 0x6c000057 | V_OPIVX,
+    OPC_VMSLEU_VV = 0x70000057 | V_OPIVV,
+    OPC_VMSLEU_VX = 0x70000057 | V_OPIVX,
+    OPC_VMSLE_VV = 0x74000057 | V_OPIVV,
+    OPC_VMSLE_VX = 0x74000057 | V_OPIVX,
+
+    OPC_VMSLEU_VI = 0x70000057 | V_OPIVI,
+    OPC_VMSLE_VI = 0x74000057 | V_OPIVI,
+    OPC_VMSGTU_VI = 0x78000057 | V_OPIVI,
+    OPC_VMSGTU_VX = 0x78000057 | V_OPIVX,
+    OPC_VMSGT_VI = 0x7c000057 | V_OPIVI,
+    OPC_VMSGT_VX = 0x7c000057 | V_OPIVX,
+
     OPC_VMV_V_V = 0x5e000057 | V_OPIVV,
     OPC_VMV_V_I = 0x5e000057 | V_OPIVI,
     OPC_VMV_V_X = 0x5e000057 | V_OPIVX,
@@ -339,6 +313,101 @@ typedef enum {
     OPC_VMVNR_V = 0x9e000057 | V_OPIVI,
 } RISCVInsn;
 
+static const struct {
+    RISCVInsn op;
+    bool swap;
+} tcg_cmpcond_to_rvv_vv[] = {
+    [TCG_COND_EQ] =  { OPC_VMSEQ_VV,  false },
+    [TCG_COND_NE] =  { OPC_VMSNE_VV,  false },
+    [TCG_COND_LT] =  { OPC_VMSLT_VV,  false },
+    [TCG_COND_GE] =  { OPC_VMSLE_VV,  true  },
+    [TCG_COND_GT] =  { OPC_VMSLT_VV,  true  },
+    [TCG_COND_LE] =  { OPC_VMSLE_VV,  false },
+    [TCG_COND_LTU] = { OPC_VMSLTU_VV, false },
+    [TCG_COND_GEU] = { OPC_VMSLEU_VV, true  },
+    [TCG_COND_GTU] = { OPC_VMSLTU_VV, true  },
+    [TCG_COND_LEU] = { OPC_VMSLEU_VV, false }
+};
+
+static const struct {
+    RISCVInsn op;
+    int min;
+    int max;
+    bool adjust;
+}  tcg_cmpcond_to_rvv_vi[] = {
+    [TCG_COND_EQ]  = { OPC_VMSEQ_VI,  -16, 15, false },
+    [TCG_COND_NE]  = { OPC_VMSNE_VI,  -16, 15, false },
+    [TCG_COND_GT]  = { OPC_VMSGT_VI,  -16, 15, false },
+    [TCG_COND_LE]  = { OPC_VMSLE_VI,  -16, 15, false },
+    [TCG_COND_LT]  = { OPC_VMSLE_VI,  -15, 16, true  },
+    [TCG_COND_GE]  = { OPC_VMSGT_VI,  -15, 16, true  },
+    [TCG_COND_LEU] = { OPC_VMSLEU_VI,   0, 15, false },
+    [TCG_COND_GTU] = { OPC_VMSGTU_VI,   0, 15, false },
+    [TCG_COND_LTU] = { OPC_VMSLEU_VI,   1, 16, true  },
+    [TCG_COND_GEU] = { OPC_VMSGTU_VI,   1, 16, true  },
+};
+
+/* test if a constant matches the constraint */
+static bool tcg_target_const_match(int64_t val, int ct,
+                                   TCGType type, TCGCond cond, int vece)
+{
+    if (ct & TCG_CT_CONST) {
+        return 1;
+    }
+    if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
+        return 1;
+    }
+    if (type >= TCG_TYPE_V64) {
+        /* Val is replicated by VECE; extract the highest element. */
+        val >>= (-8 << vece) & 63;
+    }
+    /*
+     * Sign extended from 12 bits: [-0x800, 0x7ff].
+     * Used for most arithmetic, as this is the isa field.
+     */
+    if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
+        return 1;
+    }
+    /*
+     * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
+     * Used for subtraction, where a constant must be handled by ADDI.
+     */
+    if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
+        return 1;
+    }
+    /*
+     * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
+     * Used by addsub2 and movcond, which may need the negative value,
+     * and requires the modified constant to be representable.
+     */
+    if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
+        return 1;
+    }
+    /*
+     * Inverse of sign extended from 12 bits: ~[-0x800, 0x7ff].
+     * Used to map ANDN back to ANDI, etc.
+     */
+    if ((ct & TCG_CT_CONST_J12) && ~val >= -0x800 && ~val <= 0x7ff) {
+        return 1;
+    }
+    /*
+     * Sign extended from 5 bits: [-0x10, 0x0f].
+     * Used for vector-immediate.
+     */
+    if ((ct & TCG_CT_CONST_S5) && val >= -0x10 && val <= 0x0f) {
+        return 1;
+    }
+    /*
+     * Used for vector compare OPIVI instructions.
+     */
+    if ((ct & TCG_CT_CONST_CMP_VI) &&
+        val >= tcg_cmpcond_to_rvv_vi[cond].min &&
+        val <= tcg_cmpcond_to_rvv_vi[cond].max) {
+        return true;
+     }
+    return 0;
+}
+
 /*
  * RISC-V immediate and instruction encoders (excludes 16-bit RVC)
  */
@@ -618,6 +687,18 @@ static void tcg_out_opc_vv_vi(TCGContext *s, RISCVInsn o_vv, RISCVInsn o_vi,
     }
 }
 
+static void tcg_out_opc_vim_mask(TCGContext *s, RISCVInsn opc, TCGReg vd,
+                                 TCGReg vs2, int32_t imm)
+{
+    tcg_out32(s, encode_vi(opc, vd, imm, vs2, false));
+}
+
+static void tcg_out_opc_vvm_mask(TCGContext *s, RISCVInsn opc, TCGReg vd,
+                                 TCGReg vs2, TCGReg vs1)
+{
+    tcg_out32(s, encode_v(opc, vd, vs1, vs2, false));
+}
+
 typedef struct VsetCache {
     uint32_t movi_insn;
     uint32_t vset_insn;
@@ -1408,6 +1489,48 @@ static void tcg_out_cltz(TCGContext *s, TCGType type, RISCVInsn insn,
     }
 }
 
+static void tcg_out_cmpsel(TCGContext *s, TCGType type, unsigned vece,
+                           TCGCond cond, TCGReg ret,
+                           TCGReg cmp1, TCGReg cmp2, bool c_cmp2,
+                           TCGReg val1, bool c_val1,
+                           TCGReg val2, bool c_val2)
+{
+    set_vtype_len_sew(s, type, vece);
+
+    /* Use only vmerge_vim if possible, by inverting the test. */
+    if (c_val2 && !c_val1) {
+        TCGArg temp = val1;
+        cond = tcg_invert_cond(cond);
+        val1 = val2;
+        val2 = temp;
+        c_val1 = true;
+        c_val2 = false;
+    }
+
+    /* Perform the comparison into V0 mask. */
+    if (c_cmp2) {
+        tcg_out_opc_vi(s, tcg_cmpcond_to_rvv_vi[cond].op, TCG_REG_V0, cmp1,
+                       cmp2 - tcg_cmpcond_to_rvv_vi[cond].adjust);
+    } else if (tcg_cmpcond_to_rvv_vv[cond].swap) {
+        tcg_out_opc_vv(s, tcg_cmpcond_to_rvv_vv[cond].op,
+                       TCG_REG_V0, cmp2, cmp1);
+    } else {
+        tcg_out_opc_vv(s, tcg_cmpcond_to_rvv_vv[cond].op,
+                       TCG_REG_V0, cmp1, cmp2);
+    }
+    if (c_val1) {
+        if (c_val2) {
+            tcg_out_opc_vi(s, OPC_VMV_V_I, ret, 0, val2);
+            val2 = ret;
+        }
+        /* vd[i] == v0.mask[i] ? imm : vs2[i] */
+        tcg_out_opc_vim_mask(s, OPC_VMERGE_VIM, ret, val2, val1);
+    } else {
+        /* vd[i] == v0.mask[i] ? vs1[i] : vs2[i] */
+        tcg_out_opc_vvm_mask(s, OPC_VMERGE_VVM, ret, val2, val1);
+    }
+}
+
 static void init_setting_vtype(TCGContext *s)
 {
     s->riscv_cur_type = TCG_TYPE_COUNT;
@@ -2244,6 +2367,14 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len(s, type);
         tcg_out_opc_vi(s, OPC_VXOR_VI, a0, a1, -1);
         break;
+    case INDEX_op_cmp_vec:
+        tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
+                       -1, true, 0, true);
+        break;
+    case INDEX_op_cmpsel_vec:
+        tcg_out_cmpsel(s, type, vece, args[5], a0, a1, a2, c2,
+                       args[3], const_args[3], args[4], const_args[4]);
+        break;
     case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov.  */
     case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec.  */
     default:
@@ -2266,6 +2397,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_or_vec:
     case INDEX_op_xor_vec:
     case INDEX_op_not_vec:
+    case INDEX_op_cmp_vec:
+    case INDEX_op_cmpsel_vec:
         return 1;
     default:
         return 0;
@@ -2426,6 +2559,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
         return C_O1_I2(v, v, vK);
     case INDEX_op_sub_vec:
         return C_O1_I2(v, v, v);
+    case INDEX_op_cmp_vec:
+        return C_O1_I2(v, v, vL);
+    case INDEX_op_cmpsel_vec:
+        return C_O1_I4(v, v, vL, vK, vK);
     default:
         g_assert_not_reached();
     }
-- 
2.43.0



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

* [PATCH v6 08/14] tcg/riscv: Implement vector neg ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (6 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 07/14] tcg/riscv: Implement vector cmp/cmpsel ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec Richard Henderson
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-8-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.h     | 2 +-
 tcg/riscv/tcg-target.c.inc | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 94034504b2..ae10381e02 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -152,7 +152,7 @@ typedef enum {
 #define TCG_TARGET_HAS_nor_vec          0
 #define TCG_TARGET_HAS_eqv_vec          0
 #define TCG_TARGET_HAS_not_vec          1
-#define TCG_TARGET_HAS_neg_vec          0
+#define TCG_TARGET_HAS_neg_vec          1
 #define TCG_TARGET_HAS_abs_vec          0
 #define TCG_TARGET_HAS_roti_vec         0
 #define TCG_TARGET_HAS_rots_vec         0
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 1893c419c6..ce8d6d0293 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -276,6 +276,7 @@ typedef enum {
     OPC_VADD_VV = 0x57 | V_OPIVV,
     OPC_VADD_VI = 0x57 | V_OPIVI,
     OPC_VSUB_VV = 0x8000057 | V_OPIVV,
+    OPC_VRSUB_VI = 0xc000057 | V_OPIVI,
     OPC_VAND_VV = 0x24000057 | V_OPIVV,
     OPC_VAND_VI = 0x24000057 | V_OPIVI,
     OPC_VOR_VV = 0x28000057 | V_OPIVV,
@@ -2367,6 +2368,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len(s, type);
         tcg_out_opc_vi(s, OPC_VXOR_VI, a0, a1, -1);
         break;
+    case INDEX_op_neg_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vi(s, OPC_VRSUB_VI, a0, a1, 0);
+        break;
     case INDEX_op_cmp_vec:
         tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
                        -1, true, 0, true);
@@ -2397,6 +2402,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_or_vec:
     case INDEX_op_xor_vec:
     case INDEX_op_not_vec:
+    case INDEX_op_neg_vec:
     case INDEX_op_cmp_vec:
     case INDEX_op_cmpsel_vec:
         return 1;
@@ -2550,6 +2556,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_dupm_vec:
     case INDEX_op_ld_vec:
         return C_O1_I1(v, r);
+    case INDEX_op_neg_vec:
     case INDEX_op_not_vec:
         return C_O1_I1(v, v);
     case INDEX_op_add_vec:
-- 
2.43.0



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

* [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (7 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 08/14] tcg/riscv: Implement vector neg ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-22  6:31   ` LIU Zhiwei
  2024-10-16 19:31 ` [PATCH v6 10/14] tcg/riscv: Implement vector sat/mul ops Richard Henderson
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu

Use vrsub.vi to subtract from a constant.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target-con-set.h | 1 +
 tcg/riscv/tcg-target.c.inc     | 8 ++++++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index 97e6ecdb0f..d8ce5414f5 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -25,6 +25,7 @@ C_O0_I2(v, r)
 C_O1_I1(v, r)
 C_O1_I1(v, v)
 C_O1_I2(v, v, v)
+C_O1_I2(v, vK, v)
 C_O1_I2(v, v, vK)
 C_O1_I2(v, v, vL)
 C_O1_I4(v, v, vL, vK, vK)
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index ce8d6d0293..1ce2f291d3 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -2350,7 +2350,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         break;
     case INDEX_op_sub_vec:
         set_vtype_len_sew(s, type, vece);
-        tcg_out_opc_vv(s, OPC_VSUB_VV, a0, a1, a2);
+        if (const_args[1]) {
+            tcg_out_opc_vi(s, OPC_VRSUB_VI, a0, a2, a1);
+        } else {
+            tcg_out_opc_vv(s, OPC_VSUB_VV, a0, a1, a2);
+        }
         break;
     case INDEX_op_and_vec:
         set_vtype_len(s, type);
@@ -2565,7 +2569,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_xor_vec:
         return C_O1_I2(v, v, vK);
     case INDEX_op_sub_vec:
-        return C_O1_I2(v, v, v);
+        return C_O1_I2(v, vK, v);
     case INDEX_op_cmp_vec:
         return C_O1_I2(v, v, vL);
     case INDEX_op_cmpsel_vec:
-- 
2.43.0



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

* [PATCH v6 10/14] tcg/riscv: Implement vector sat/mul ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (8 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 11/14] tcg/riscv: Implement vector min/max ops Richard Henderson
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-9-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.h     |  4 ++--
 tcg/riscv/tcg-target.c.inc | 41 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index ae10381e02..1d4d8878ce 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -160,8 +160,8 @@ typedef enum {
 #define TCG_TARGET_HAS_shi_vec          0
 #define TCG_TARGET_HAS_shs_vec          0
 #define TCG_TARGET_HAS_shv_vec          0
-#define TCG_TARGET_HAS_mul_vec          0
-#define TCG_TARGET_HAS_sat_vec          0
+#define TCG_TARGET_HAS_mul_vec          1
+#define TCG_TARGET_HAS_sat_vec          1
 #define TCG_TARGET_HAS_minmax_vec       0
 #define TCG_TARGET_HAS_bitsel_vec       0
 #define TCG_TARGET_HAS_cmpsel_vec       1
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 1ce2f291d3..4758555565 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -284,6 +284,16 @@ typedef enum {
     OPC_VXOR_VV = 0x2c000057 | V_OPIVV,
     OPC_VXOR_VI = 0x2c000057 | V_OPIVI,
 
+    OPC_VMUL_VV = 0x94000057 | V_OPMVV,
+    OPC_VSADD_VV = 0x84000057 | V_OPIVV,
+    OPC_VSADD_VI = 0x84000057 | V_OPIVI,
+    OPC_VSSUB_VV = 0x8c000057 | V_OPIVV,
+    OPC_VSSUB_VI = 0x8c000057 | V_OPIVI,
+    OPC_VSADDU_VV = 0x80000057 | V_OPIVV,
+    OPC_VSADDU_VI = 0x80000057 | V_OPIVI,
+    OPC_VSSUBU_VV = 0x88000057 | V_OPIVV,
+    OPC_VSSUBU_VI = 0x88000057 | V_OPIVI,
+
     OPC_VMSEQ_VV = 0x60000057 | V_OPIVV,
     OPC_VMSEQ_VI = 0x60000057 | V_OPIVI,
     OPC_VMSEQ_VX = 0x60000057 | V_OPIVX,
@@ -2376,6 +2386,26 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len_sew(s, type, vece);
         tcg_out_opc_vi(s, OPC_VRSUB_VI, a0, a1, 0);
         break;
+    case INDEX_op_mul_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv(s, OPC_VMUL_VV, a0, a1, a2);
+        break;
+    case INDEX_op_ssadd_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VSADD_VV, OPC_VSADD_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_sssub_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VSSUB_VV, OPC_VSSUB_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_usadd_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VSADDU_VV, OPC_VSADDU_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_ussub_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VSSUBU_VV, OPC_VSSUBU_VI, a0, a1, a2, c2);
+        break;
     case INDEX_op_cmp_vec:
         tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
                        -1, true, 0, true);
@@ -2407,6 +2437,11 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_xor_vec:
     case INDEX_op_not_vec:
     case INDEX_op_neg_vec:
+    case INDEX_op_mul_vec:
+    case INDEX_op_ssadd_vec:
+    case INDEX_op_sssub_vec:
+    case INDEX_op_usadd_vec:
+    case INDEX_op_ussub_vec:
     case INDEX_op_cmp_vec:
     case INDEX_op_cmpsel_vec:
         return 1;
@@ -2567,9 +2602,15 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_and_vec:
     case INDEX_op_or_vec:
     case INDEX_op_xor_vec:
+    case INDEX_op_ssadd_vec:
+    case INDEX_op_sssub_vec:
+    case INDEX_op_usadd_vec:
+    case INDEX_op_ussub_vec:
         return C_O1_I2(v, v, vK);
     case INDEX_op_sub_vec:
         return C_O1_I2(v, vK, v);
+    case INDEX_op_mul_vec:
+        return C_O1_I2(v, v, v);
     case INDEX_op_cmp_vec:
         return C_O1_I2(v, v, vL);
     case INDEX_op_cmpsel_vec:
-- 
2.43.0



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

* [PATCH v6 11/14] tcg/riscv: Implement vector min/max ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (9 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 10/14] tcg/riscv: Implement vector sat/mul ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 12/14] tcg/riscv: Implement vector shi/s/v ops Richard Henderson
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-10-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.h     |  2 +-
 tcg/riscv/tcg-target.c.inc | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 1d4d8878ce..7005099810 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -162,7 +162,7 @@ typedef enum {
 #define TCG_TARGET_HAS_shv_vec          0
 #define TCG_TARGET_HAS_mul_vec          1
 #define TCG_TARGET_HAS_sat_vec          1
-#define TCG_TARGET_HAS_minmax_vec       0
+#define TCG_TARGET_HAS_minmax_vec       1
 #define TCG_TARGET_HAS_bitsel_vec       0
 #define TCG_TARGET_HAS_cmpsel_vec       1
 
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 4758555565..35b244b7a2 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -294,6 +294,15 @@ typedef enum {
     OPC_VSSUBU_VV = 0x88000057 | V_OPIVV,
     OPC_VSSUBU_VI = 0x88000057 | V_OPIVI,
 
+    OPC_VMAX_VV = 0x1c000057 | V_OPIVV,
+    OPC_VMAX_VI = 0x1c000057 | V_OPIVI,
+    OPC_VMAXU_VV = 0x18000057 | V_OPIVV,
+    OPC_VMAXU_VI = 0x18000057 | V_OPIVI,
+    OPC_VMIN_VV = 0x14000057 | V_OPIVV,
+    OPC_VMIN_VI = 0x14000057 | V_OPIVI,
+    OPC_VMINU_VV = 0x10000057 | V_OPIVV,
+    OPC_VMINU_VI = 0x10000057 | V_OPIVI,
+
     OPC_VMSEQ_VV = 0x60000057 | V_OPIVV,
     OPC_VMSEQ_VI = 0x60000057 | V_OPIVI,
     OPC_VMSEQ_VX = 0x60000057 | V_OPIVX,
@@ -2406,6 +2415,22 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len_sew(s, type, vece);
         tcg_out_opc_vv_vi(s, OPC_VSSUBU_VV, OPC_VSSUBU_VI, a0, a1, a2, c2);
         break;
+    case INDEX_op_smax_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VMAX_VV, OPC_VMAX_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_smin_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VMIN_VV, OPC_VMIN_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_umax_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VMAXU_VV, OPC_VMAXU_VI, a0, a1, a2, c2);
+        break;
+    case INDEX_op_umin_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv_vi(s, OPC_VMINU_VV, OPC_VMINU_VI, a0, a1, a2, c2);
+        break;
     case INDEX_op_cmp_vec:
         tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
                        -1, true, 0, true);
@@ -2442,6 +2467,10 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_sssub_vec:
     case INDEX_op_usadd_vec:
     case INDEX_op_ussub_vec:
+    case INDEX_op_smax_vec:
+    case INDEX_op_smin_vec:
+    case INDEX_op_umax_vec:
+    case INDEX_op_umin_vec:
     case INDEX_op_cmp_vec:
     case INDEX_op_cmpsel_vec:
         return 1;
@@ -2606,6 +2635,10 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_sssub_vec:
     case INDEX_op_usadd_vec:
     case INDEX_op_ussub_vec:
+    case INDEX_op_smax_vec:
+    case INDEX_op_smin_vec:
+    case INDEX_op_umax_vec:
+    case INDEX_op_umin_vec:
         return C_O1_I2(v, v, vK);
     case INDEX_op_sub_vec:
         return C_O1_I2(v, vK, v);
-- 
2.43.0



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

* [PATCH v6 12/14] tcg/riscv: Implement vector shi/s/v ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (10 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 11/14] tcg/riscv: Implement vector min/max ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 13/14] tcg/riscv: Implement vector roti/v/x ops Richard Henderson
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-11-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target-con-set.h |  1 +
 tcg/riscv/tcg-target.h         |  6 +--
 tcg/riscv/tcg-target.c.inc     | 76 ++++++++++++++++++++++++++++++++++
 3 files changed, 80 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
index d8ce5414f5..3c4ef44eb0 100644
--- a/tcg/riscv/tcg-target-con-set.h
+++ b/tcg/riscv/tcg-target-con-set.h
@@ -24,6 +24,7 @@ C_O2_I4(r, r, rZ, rZ, rM, rM)
 C_O0_I2(v, r)
 C_O1_I1(v, r)
 C_O1_I1(v, v)
+C_O1_I2(v, v, r)
 C_O1_I2(v, v, v)
 C_O1_I2(v, vK, v)
 C_O1_I2(v, v, vK)
diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 7005099810..76d30e789b 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -157,9 +157,9 @@ typedef enum {
 #define TCG_TARGET_HAS_roti_vec         0
 #define TCG_TARGET_HAS_rots_vec         0
 #define TCG_TARGET_HAS_rotv_vec         0
-#define TCG_TARGET_HAS_shi_vec          0
-#define TCG_TARGET_HAS_shs_vec          0
-#define TCG_TARGET_HAS_shv_vec          0
+#define TCG_TARGET_HAS_shi_vec          1
+#define TCG_TARGET_HAS_shs_vec          1
+#define TCG_TARGET_HAS_shv_vec          1
 #define TCG_TARGET_HAS_mul_vec          1
 #define TCG_TARGET_HAS_sat_vec          1
 #define TCG_TARGET_HAS_minmax_vec       1
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 35b244b7a2..2c78ea6507 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -326,6 +326,16 @@ typedef enum {
     OPC_VMSGT_VI = 0x7c000057 | V_OPIVI,
     OPC_VMSGT_VX = 0x7c000057 | V_OPIVX,
 
+    OPC_VSLL_VV = 0x94000057 | V_OPIVV,
+    OPC_VSLL_VI = 0x94000057 | V_OPIVI,
+    OPC_VSLL_VX = 0x94000057 | V_OPIVX,
+    OPC_VSRL_VV = 0xa0000057 | V_OPIVV,
+    OPC_VSRL_VI = 0xa0000057 | V_OPIVI,
+    OPC_VSRL_VX = 0xa0000057 | V_OPIVX,
+    OPC_VSRA_VV = 0xa4000057 | V_OPIVV,
+    OPC_VSRA_VI = 0xa4000057 | V_OPIVI,
+    OPC_VSRA_VX = 0xa4000057 | V_OPIVX,
+
     OPC_VMV_V_V = 0x5e000057 | V_OPIVV,
     OPC_VMV_V_I = 0x5e000057 | V_OPIVI,
     OPC_VMV_V_X = 0x5e000057 | V_OPIVX,
@@ -1551,6 +1561,17 @@ static void tcg_out_cmpsel(TCGContext *s, TCGType type, unsigned vece,
     }
 }
 
+static void tcg_out_vshifti(TCGContext *s, RISCVInsn opc_vi, RISCVInsn opc_vx,
+                             TCGReg dst, TCGReg src, unsigned imm)
+{
+    if (imm < 32) {
+        tcg_out_opc_vi(s, opc_vi, dst, src, imm);
+    } else {
+        tcg_out_movi(s, TCG_TYPE_I32, TCG_REG_TMP0, imm);
+        tcg_out_opc_vx(s, opc_vx, dst, src, TCG_REG_TMP0);
+    }
+}
+
 static void init_setting_vtype(TCGContext *s)
 {
     s->riscv_cur_type = TCG_TYPE_COUNT;
@@ -2431,6 +2452,42 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len_sew(s, type, vece);
         tcg_out_opc_vv_vi(s, OPC_VMINU_VV, OPC_VMINU_VI, a0, a1, a2, c2);
         break;
+    case INDEX_op_shls_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vx(s, OPC_VSLL_VX, a0, a1, a2);
+        break;
+    case INDEX_op_shrs_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vx(s, OPC_VSRL_VX, a0, a1, a2);
+        break;
+    case INDEX_op_sars_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vx(s, OPC_VSRA_VX, a0, a1, a2);
+        break;
+    case INDEX_op_shlv_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv(s, OPC_VSLL_VV, a0, a1, a2);
+        break;
+    case INDEX_op_shrv_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv(s, OPC_VSRL_VV, a0, a1, a2);
+        break;
+    case INDEX_op_sarv_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vv(s, OPC_VSRA_VV, a0, a1, a2);
+        break;
+    case INDEX_op_shli_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_vshifti(s, OPC_VSLL_VI, OPC_VSLL_VX, a0, a1, a2);
+        break;
+    case INDEX_op_shri_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_vshifti(s, OPC_VSRL_VI, OPC_VSRL_VX, a0, a1, a2);
+        break;
+    case INDEX_op_sari_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_vshifti(s, OPC_VSRA_VI, OPC_VSRA_VX, a0, a1, a2);
+        break;
     case INDEX_op_cmp_vec:
         tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
                        -1, true, 0, true);
@@ -2471,6 +2528,15 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_smin_vec:
     case INDEX_op_umax_vec:
     case INDEX_op_umin_vec:
+    case INDEX_op_shls_vec:
+    case INDEX_op_shrs_vec:
+    case INDEX_op_sars_vec:
+    case INDEX_op_shlv_vec:
+    case INDEX_op_shrv_vec:
+    case INDEX_op_sarv_vec:
+    case INDEX_op_shri_vec:
+    case INDEX_op_shli_vec:
+    case INDEX_op_sari_vec:
     case INDEX_op_cmp_vec:
     case INDEX_op_cmpsel_vec:
         return 1;
@@ -2626,6 +2692,9 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
         return C_O1_I1(v, r);
     case INDEX_op_neg_vec:
     case INDEX_op_not_vec:
+    case INDEX_op_shli_vec:
+    case INDEX_op_shri_vec:
+    case INDEX_op_sari_vec:
         return C_O1_I1(v, v);
     case INDEX_op_add_vec:
     case INDEX_op_and_vec:
@@ -2643,7 +2712,14 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_sub_vec:
         return C_O1_I2(v, vK, v);
     case INDEX_op_mul_vec:
+    case INDEX_op_shlv_vec:
+    case INDEX_op_shrv_vec:
+    case INDEX_op_sarv_vec:
         return C_O1_I2(v, v, v);
+    case INDEX_op_shls_vec:
+    case INDEX_op_shrs_vec:
+    case INDEX_op_sars_vec:
+        return C_O1_I2(v, v, r);
     case INDEX_op_cmp_vec:
         return C_O1_I2(v, v, vL);
     case INDEX_op_cmpsel_vec:
-- 
2.43.0



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

* [PATCH v6 13/14] tcg/riscv: Implement vector roti/v/x ops
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (11 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 12/14] tcg/riscv: Implement vector shi/s/v ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-16 19:31 ` [PATCH v6 14/14] tcg/riscv: Enable native vector support for TCG host Richard Henderson
  2024-10-21  1:42 ` [PATCH v6 00/14] tcg/riscv: Add support for vector Alistair Francis
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Message-ID: <20241007025700.47259-12-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.h     |  6 +++---
 tcg/riscv/tcg-target.c.inc | 36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index 76d30e789b..e6d66cd1b9 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -154,9 +154,9 @@ typedef enum {
 #define TCG_TARGET_HAS_not_vec          1
 #define TCG_TARGET_HAS_neg_vec          1
 #define TCG_TARGET_HAS_abs_vec          0
-#define TCG_TARGET_HAS_roti_vec         0
-#define TCG_TARGET_HAS_rots_vec         0
-#define TCG_TARGET_HAS_rotv_vec         0
+#define TCG_TARGET_HAS_roti_vec         1
+#define TCG_TARGET_HAS_rots_vec         1
+#define TCG_TARGET_HAS_rotv_vec         1
 #define TCG_TARGET_HAS_shi_vec          1
 #define TCG_TARGET_HAS_shs_vec          1
 #define TCG_TARGET_HAS_shv_vec          1
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
index 2c78ea6507..f8331e4688 100644
--- a/tcg/riscv/tcg-target.c.inc
+++ b/tcg/riscv/tcg-target.c.inc
@@ -2488,6 +2488,34 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
         set_vtype_len_sew(s, type, vece);
         tcg_out_vshifti(s, OPC_VSRA_VI, OPC_VSRA_VX, a0, a1, a2);
         break;
+    case INDEX_op_rotli_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_vshifti(s, OPC_VSLL_VI, OPC_VSLL_VX, TCG_REG_V0, a1, a2);
+        tcg_out_vshifti(s, OPC_VSRL_VI, OPC_VSRL_VX, a0, a1,
+                        -a2 & ((8 << vece) - 1));
+        tcg_out_opc_vv(s, OPC_VOR_VV, a0, a0, TCG_REG_V0);
+        break;
+    case INDEX_op_rotls_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vx(s, OPC_VSLL_VX, TCG_REG_V0, a1, a2);
+        tcg_out_opc_reg(s, OPC_SUBW, TCG_REG_TMP0, TCG_REG_ZERO, a2);
+        tcg_out_opc_vx(s, OPC_VSRL_VX, a0, a1, TCG_REG_TMP0);
+        tcg_out_opc_vv(s, OPC_VOR_VV, a0, a0, TCG_REG_V0);
+        break;
+    case INDEX_op_rotlv_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vi(s, OPC_VRSUB_VI, TCG_REG_V0, a2, 0);
+        tcg_out_opc_vv(s, OPC_VSRL_VV, TCG_REG_V0, a1, TCG_REG_V0);
+        tcg_out_opc_vv(s, OPC_VSLL_VV, a0, a1, a2);
+        tcg_out_opc_vv(s, OPC_VOR_VV, a0, a0, TCG_REG_V0);
+        break;
+    case INDEX_op_rotrv_vec:
+        set_vtype_len_sew(s, type, vece);
+        tcg_out_opc_vi(s, OPC_VRSUB_VI, TCG_REG_V0, a2, 0);
+        tcg_out_opc_vv(s, OPC_VSLL_VV, TCG_REG_V0, a1, TCG_REG_V0);
+        tcg_out_opc_vv(s, OPC_VSRL_VV, a0, a1, a2);
+        tcg_out_opc_vv(s, OPC_VOR_VV, a0, a0, TCG_REG_V0);
+        break;
     case INDEX_op_cmp_vec:
         tcg_out_cmpsel(s, type, vece, args[3], a0, a1, a2, c2,
                        -1, true, 0, true);
@@ -2537,6 +2565,10 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
     case INDEX_op_shri_vec:
     case INDEX_op_shli_vec:
     case INDEX_op_sari_vec:
+    case INDEX_op_rotls_vec:
+    case INDEX_op_rotlv_vec:
+    case INDEX_op_rotrv_vec:
+    case INDEX_op_rotli_vec:
     case INDEX_op_cmp_vec:
     case INDEX_op_cmpsel_vec:
         return 1;
@@ -2695,6 +2727,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_shli_vec:
     case INDEX_op_shri_vec:
     case INDEX_op_sari_vec:
+    case INDEX_op_rotli_vec:
         return C_O1_I1(v, v);
     case INDEX_op_add_vec:
     case INDEX_op_and_vec:
@@ -2715,10 +2748,13 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_shlv_vec:
     case INDEX_op_shrv_vec:
     case INDEX_op_sarv_vec:
+    case INDEX_op_rotlv_vec:
+    case INDEX_op_rotrv_vec:
         return C_O1_I2(v, v, v);
     case INDEX_op_shls_vec:
     case INDEX_op_shrs_vec:
     case INDEX_op_sars_vec:
+    case INDEX_op_rotls_vec:
         return C_O1_I2(v, v, r);
     case INDEX_op_cmp_vec:
         return C_O1_I2(v, v, vL);
-- 
2.43.0



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

* [PATCH v6 14/14] tcg/riscv: Enable native vector support for TCG host
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (12 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 13/14] tcg/riscv: Implement vector roti/v/x ops Richard Henderson
@ 2024-10-16 19:31 ` Richard Henderson
  2024-10-21  1:42 ` [PATCH v6 00/14] tcg/riscv: Add support for vector Alistair Francis
  14 siblings, 0 replies; 29+ messages in thread
From: Richard Henderson @ 2024-10-16 19:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>

Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20241007025700.47259-13-zhiwei_liu@linux.alibaba.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/riscv/tcg-target.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tcg/riscv/tcg-target.h b/tcg/riscv/tcg-target.h
index e6d66cd1b9..334c37cbe6 100644
--- a/tcg/riscv/tcg-target.h
+++ b/tcg/riscv/tcg-target.h
@@ -143,9 +143,9 @@ typedef enum {
 #define TCG_TARGET_HAS_tst              0
 
 /* vector instructions */
-#define TCG_TARGET_HAS_v64              0
-#define TCG_TARGET_HAS_v128             0
-#define TCG_TARGET_HAS_v256             0
+#define TCG_TARGET_HAS_v64              (cpuinfo & CPUINFO_ZVE64X)
+#define TCG_TARGET_HAS_v128             (cpuinfo & CPUINFO_ZVE64X)
+#define TCG_TARGET_HAS_v256             (cpuinfo & CPUINFO_ZVE64X)
 #define TCG_TARGET_HAS_andc_vec         0
 #define TCG_TARGET_HAS_orc_vec          0
 #define TCG_TARGET_HAS_nand_vec         0
-- 
2.43.0



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

* Re: [PATCH v6 00/14] tcg/riscv: Add support for vector
@ 2024-10-17  2:38 TangTianCheng
  0 siblings, 0 replies; 29+ messages in thread
From: TangTianCheng @ 2024-10-17  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: qemu-riscv, palmer, alistair.francis, dbarboza, liwei1518,
	bmeng.cn, richard.henderson

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

> Signed-off-by: Huang Shiyuan<swung0x48@outlook.com>
> Co-authored-by: TANG Tiancheng<tangtiancheng.ttc@alibaba-inc.com>
> Signed-off-by: TANG Tiancheng<tangtiancheng.ttc@alibaba-inc.com>
> Reviewed-by: Liu Zhiwei<zhiwei_liu@linux.alibaba.com>
> Reviewed-by: Richard Henderson<richard.henderson@linaro.org>
> Signed-off-by: Swung0x48<swung0x48@outlook.com>
Hi,

We should remove the tag "Signed-off-by: Swung0x48swung0x48@outlook.com" since the author's real name, Huang Shiyuan, is already correctly included as "Signed-off-by: Huang Shiyuanswung0x48@outlook.com".

Thanks,
TianCheng.
> Message-ID: <20241007025700.47259-3-zhiwei_liu@linux.alibaba.com <https://lists.gnu.org/archive/html/qemu-riscv/2024-10/msg00141.html>>
> Signed-off-by: Richard Henderson<richard.henderson@linaro.org>

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

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

* Re: [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
@ 2024-10-21  1:16   ` Alistair Francis
  2024-10-21 17:31   ` Pierrick Bouvier
  2024-10-22  2:48   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: Alistair Francis @ 2024-10-21  1:16 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, qemu-riscv, alistair.francis, zhiwei_liu, qemu-stable

On Thu, Oct 17, 2024 at 5:35 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This pointer needs to be reset after overflow just like
> code_buf and code_ptr.
>
> Cc: qemu-stable@nongnu.org
> Fixes: 57a269469db ("tcg: Infrastructure for managing constant pools")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  tcg/tcg.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 5decd83cf4..0babae1b88 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -1399,7 +1399,6 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
>          goto retry;
>      }
>      qatomic_set(&s->code_gen_ptr, next);
> -    s->data_gen_ptr = NULL;
>      return tb;
>  }
>
> @@ -6172,6 +6171,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
>       */
>      s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
>      s->code_ptr = s->code_buf;
> +    s->data_gen_ptr = NULL;
>
>  #ifdef TCG_TARGET_NEED_LDST_LABELS
>      QSIMPLEQ_INIT(&s->ldst_labels);
> --
> 2.43.0
>
>


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

* Re: [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly
  2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
@ 2024-10-21  1:17   ` Alistair Francis
  2024-10-21 17:41   ` Pierrick Bouvier
  2024-10-22  3:12   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: Alistair Francis @ 2024-10-21  1:17 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, zhiwei_liu

On Thu, Oct 17, 2024 at 5:35 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The first immediate field is unsigned, whereas operand_vimm
> extracts a signed value.  There is no need to mask the result
> with 'u'; just print the immediate with 'i'.
>
> Fixes: 07f4964d178 ("disas/riscv.c: rvv: Add disas support for vector instructions")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  disas/riscv.h | 2 +-
>  disas/riscv.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 16a08e4895..0d1f89ce8a 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -290,7 +290,7 @@ enum {
>  #define rv_fmt_fd_vs2                 "O\t3,F"
>  #define rv_fmt_vd_vm                  "O\tDm"
>  #define rv_fmt_vsetvli                "O\t0,1,v"
> -#define rv_fmt_vsetivli               "O\t0,u,v"
> +#define rv_fmt_vsetivli               "O\t0,i,v"
>  #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
>  #define rv_fmt_push_rlist             "O\tx,-i"
>  #define rv_fmt_pop_rlist              "O\tx,i"
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 5965574d87..fc0331b90b 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -4808,7 +4808,7 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
>          break;
>      case rv_codec_vsetivli:
>          dec->rd = operand_rd(inst);
> -        dec->imm = operand_vimm(inst);
> +        dec->imm = extract32(inst, 15, 5);
>          dec->vzimm = operand_vzimm10(inst);
>          break;
>      case rv_codec_zcb_lb:
> --
> 2.43.0
>
>


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

* Re: [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo
  2024-10-16 19:31 ` [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo Richard Henderson
@ 2024-10-21  1:20   ` Alistair Francis
  2024-10-21 18:25   ` Daniel Henrique Barboza
  1 sibling, 0 replies; 29+ messages in thread
From: Alistair Francis @ 2024-10-21  1:20 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, qemu-riscv, alistair.francis, zhiwei_liu,
	TANG Tiancheng

On Thu, Oct 17, 2024 at 5:35 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
>
> Add support for probing RISC-V vector extension availability in
> the backend. This information will be used when deciding whether
> to use vector instructions in code generation.
>
> Cache lg2(vlenb) for the backend. The storing of lg2(vlenb) means
> we can convert all of the division into subtraction.
>
> While the compiler doesn't support RISCV_HWPROBE_EXT_ZVE64X,
> we use RISCV_HWPROBE_IMA_V instead. RISCV_HWPROBE_IMA_V is more
> strictly constrainted than RISCV_HWPROBE_EXT_ZVE64X. At least in
> current QEMU implemenation, the V vector extension depends on the
> zve64d extension.
>
> Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
> Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
> Message-ID: <20241007025700.47259-2-zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  host/include/riscv/host/cpuinfo.h |  2 ++
>  util/cpuinfo-riscv.c              | 24 ++++++++++++++++++++++--
>  2 files changed, 24 insertions(+), 2 deletions(-)
>
> diff --git a/host/include/riscv/host/cpuinfo.h b/host/include/riscv/host/cpuinfo.h
> index 2b00660e36..cdc784e7b6 100644
> --- a/host/include/riscv/host/cpuinfo.h
> +++ b/host/include/riscv/host/cpuinfo.h
> @@ -10,9 +10,11 @@
>  #define CPUINFO_ZBA             (1u << 1)
>  #define CPUINFO_ZBB             (1u << 2)
>  #define CPUINFO_ZICOND          (1u << 3)
> +#define CPUINFO_ZVE64X          (1u << 4)
>
>  /* Initialized with a constructor. */
>  extern unsigned cpuinfo;
> +extern unsigned riscv_lg2_vlenb;
>
>  /*
>   * We cannot rely on constructor ordering, so other constructors must
> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
> index 8cacc67645..16114ffd32 100644
> --- a/util/cpuinfo-riscv.c
> +++ b/util/cpuinfo-riscv.c
> @@ -4,6 +4,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/host-utils.h"
>  #include "host/cpuinfo.h"
>
>  #ifdef CONFIG_ASM_HWPROBE_H
> @@ -13,6 +14,7 @@
>  #endif
>
>  unsigned cpuinfo;
> +unsigned riscv_lg2_vlenb;
>  static volatile sig_atomic_t got_sigill;
>
>  static void sigill_handler(int signo, siginfo_t *si, void *data)
> @@ -34,7 +36,7 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
>  /* Called both as constructor and (possibly) via other constructors. */
>  unsigned __attribute__((constructor)) cpuinfo_init(void)
>  {
> -    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND;
> +    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;
>      unsigned info = cpuinfo;
>
>      if (info) {
> @@ -50,6 +52,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>  #endif
>  #if defined(__riscv_arch_test) && defined(__riscv_zicond)
>      info |= CPUINFO_ZICOND;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zve64x)
> +    info |= CPUINFO_ZVE64X;
>  #endif
>      left &= ~info;
>
> @@ -65,7 +70,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>              && pair.key >= 0) {
>              info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
>              info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
> -            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
> +            info |= pair.value & RISCV_HWPROBE_IMA_V ? CPUINFO_ZVE64X : 0;
> +            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZVE64X);
>  #ifdef RISCV_HWPROBE_EXT_ZICOND
>              info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
>              left &= ~CPUINFO_ZICOND;
> @@ -113,6 +119,20 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>          assert(left == 0);
>      }
>
> +    if (info & CPUINFO_ZVE64X) {
> +        /*
> +         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
> +         * We are guaranteed by Zve64x that VLEN >= 64, and that
> +         * EEW of {8,16,32,64} are supported.
> +         *
> +         * Cache VLEN in a convenient form.
> +         */
> +        unsigned long vlenb;
> +        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
> +        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
> +        riscv_lg2_vlenb = ctz32(vlenb);
> +    }
> +
>      info |= CPUINFO_ALWAYS;
>      cpuinfo = info;
>      return info;
> --
> 2.43.0
>
>


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

* Re: [PATCH v6 00/14] tcg/riscv: Add support for vector
  2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
                   ` (13 preceding siblings ...)
  2024-10-16 19:31 ` [PATCH v6 14/14] tcg/riscv: Enable native vector support for TCG host Richard Henderson
@ 2024-10-21  1:42 ` Alistair Francis
  2024-10-22  6:59   ` LIU Zhiwei
  14 siblings, 1 reply; 29+ messages in thread
From: Alistair Francis @ 2024-10-21  1:42 UTC (permalink / raw)
  To: Richard Henderson; +Cc: qemu-devel, qemu-riscv, alistair.francis, zhiwei_liu

On Thu, Oct 17, 2024 at 5:33 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Introduce support for the RISC-V vector extension in the TCG backend.
>
> v5: https://lore.kernel.org/qemu-devel/20241007025700.47259-1-zhiwei_liu@linux.alibaba.com/
>
> Changes for v6:
>   - Fix problem with TB overflow restart wrt the constant pool.
>   - Fix vsetivli disassembly.
>   - Change set_vtype to precompute all instructions.
>   - Extract one element before comparison in tcg_out_dupi_vec.
>   - Extract one element before comparison in tcg_target_const_match.
>   - Drop 'vm' parameter from most tcg_out_opc_* functions.
>   - Add tcg_out_opc_vv_vi and accept K constants for operations
>     which have .v.i instructions.
>   - Do not expand cmp_vec early.
>   - Fix expansion of rotls_vec.
>
> I've tested this on cfarm95, a banana pi bpi-f3 with 256-bit rvv-1.0,
> with qemu-aarch64 and some vectorized test cases.
>
> Barring further comment, I plan to include this in a PR at the
> end of the week.
>
>
> r~
>
>
> Huang Shiyuan (1):
>   tcg/riscv: Add basic support for vector
>
> Richard Henderson (3):
>   tcg: Reset data_gen_ptr correctly
>   disas/riscv: Fix vsetivli disassembly
>   tcg/riscv: Accept constant first argument to sub_vec
>
> TANG Tiancheng (10):
>   util: Add RISC-V vector extension probe in cpuinfo
>   tcg/riscv: Implement vector mov/dup{m/i}
>   tcg/riscv: Add support for basic vector opcodes
>   tcg/riscv: Implement vector cmp/cmpsel ops
>   tcg/riscv: Implement vector neg ops
>   tcg/riscv: Implement vector sat/mul ops
>   tcg/riscv: Implement vector min/max ops
>   tcg/riscv: Implement vector shi/s/v ops
>   tcg/riscv: Implement vector roti/v/x ops
>   tcg/riscv: Enable native vector support for TCG host

Thanks!

Applied to riscv-to-apply.next

I have removed the Swung0x48 Signed-off-by line.

Alistair

>
>  disas/riscv.h                     |   2 +-
>  host/include/riscv/host/cpuinfo.h |   2 +
>  include/tcg/tcg.h                 |   6 +
>  tcg/riscv/tcg-target-con-set.h    |   9 +
>  tcg/riscv/tcg-target-con-str.h    |   3 +
>  tcg/riscv/tcg-target.h            |  78 ++-
>  tcg/riscv/tcg-target.opc.h        |  12 +
>  disas/riscv.c                     |   2 +-
>  tcg/tcg.c                         |   2 +-
>  util/cpuinfo-riscv.c              |  24 +-
>  tcg/riscv/tcg-target.c.inc        | 994 +++++++++++++++++++++++++++---
>  11 files changed, 1011 insertions(+), 123 deletions(-)
>  create mode 100644 tcg/riscv/tcg-target.opc.h
>
> --
> 2.43.0
>
>


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

* Re: [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
  2024-10-21  1:16   ` Alistair Francis
@ 2024-10-21 17:31   ` Pierrick Bouvier
  2024-10-22  2:48   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: Pierrick Bouvier @ 2024-10-21 17:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-riscv, alistair.francis, zhiwei_liu, qemu-stable



On 10/16/24 12:31, Richard Henderson wrote:
> This pointer needs to be reset after overflow just like
> code_buf and code_ptr.
> 
> Cc: qemu-stable@nongnu.org
> Fixes: 57a269469db ("tcg: Infrastructure for managing constant pools")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/tcg.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 5decd83cf4..0babae1b88 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -1399,7 +1399,6 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
>           goto retry;
>       }
>       qatomic_set(&s->code_gen_ptr, next);
> -    s->data_gen_ptr = NULL;
>       return tb;
>   }
>   
> @@ -6172,6 +6171,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
>        */
>       s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
>       s->code_ptr = s->code_buf;
> +    s->data_gen_ptr = NULL;
>   
>   #ifdef TCG_TARGET_NEED_LDST_LABELS
>       QSIMPLEQ_INIT(&s->ldst_labels);

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>


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

* Re: [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly
  2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
  2024-10-21  1:17   ` Alistair Francis
@ 2024-10-21 17:41   ` Pierrick Bouvier
  2024-10-22  3:12   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: Pierrick Bouvier @ 2024-10-21 17:41 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, zhiwei_liu

On 10/16/24 12:31, Richard Henderson wrote:
> The first immediate field is unsigned, whereas operand_vimm
> extracts a signed value.  There is no need to mask the result
> with 'u'; just print the immediate with 'i'.
> 
> Fixes: 07f4964d178 ("disas/riscv.c: rvv: Add disas support for vector instructions")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   disas/riscv.h | 2 +-
>   disas/riscv.c | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 16a08e4895..0d1f89ce8a 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -290,7 +290,7 @@ enum {
>   #define rv_fmt_fd_vs2                 "O\t3,F"
>   #define rv_fmt_vd_vm                  "O\tDm"
>   #define rv_fmt_vsetvli                "O\t0,1,v"
> -#define rv_fmt_vsetivli               "O\t0,u,v"
> +#define rv_fmt_vsetivli               "O\t0,i,v"
>   #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
>   #define rv_fmt_push_rlist             "O\tx,-i"
>   #define rv_fmt_pop_rlist              "O\tx,i"
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 5965574d87..fc0331b90b 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -4808,7 +4808,7 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
>           break;
>       case rv_codec_vsetivli:
>           dec->rd = operand_rd(inst);
> -        dec->imm = operand_vimm(inst);
> +        dec->imm = extract32(inst, 15, 5);
>           dec->vzimm = operand_vzimm10(inst);
>           break;
>       case rv_codec_zcb_lb:

Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>


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

* Re: [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo
  2024-10-16 19:31 ` [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo Richard Henderson
  2024-10-21  1:20   ` Alistair Francis
@ 2024-10-21 18:25   ` Daniel Henrique Barboza
  2024-10-21 18:52     ` Richard Henderson
  1 sibling, 1 reply; 29+ messages in thread
From: Daniel Henrique Barboza @ 2024-10-21 18:25 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

Hi,

This patch is breaking a KVM guest that runs  with '-cpu host' in an emulated
Risc-V host. The break happens regardless of the RVV support in the emulated
host:


$ qemu-system-riscv64 \
	-machine virt,accel=kvm -m 2G -smp 1 \
	-cpu host \
	-nographic -snapshot \
	-kernel ./guest_imgs/Image \
	-initrd ./guest_imgs/rootfs_kvm_riscv64.img \
	-append "root=/dev/ram rw console=ttyS0 earlycon=sbi"

qemu-system-riscv64: ../util/cpuinfo-riscv.c:119: cpuinfo_init: Assertion `left == 0' failed.
Aborted


In a quick debug:


On 10/16/24 4:31 PM, Richard Henderson wrote:
> From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
> 
> Add support for probing RISC-V vector extension availability in
> the backend. This information will be used when deciding whether
> to use vector instructions in code generation.
> 
> Cache lg2(vlenb) for the backend. The storing of lg2(vlenb) means
> we can convert all of the division into subtraction.
> 
> While the compiler doesn't support RISCV_HWPROBE_EXT_ZVE64X,
> we use RISCV_HWPROBE_IMA_V instead. RISCV_HWPROBE_IMA_V is more
> strictly constrainted than RISCV_HWPROBE_EXT_ZVE64X. At least in
> current QEMU implemenation, the V vector extension depends on the
> zve64d extension.
> 
> Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
> Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
> Message-ID: <20241007025700.47259-2-zhiwei_liu@linux.alibaba.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   host/include/riscv/host/cpuinfo.h |  2 ++
>   util/cpuinfo-riscv.c              | 24 ++++++++++++++++++++++--
>   2 files changed, 24 insertions(+), 2 deletions(-)
> 
> diff --git a/host/include/riscv/host/cpuinfo.h b/host/include/riscv/host/cpuinfo.h
> index 2b00660e36..cdc784e7b6 100644
> --- a/host/include/riscv/host/cpuinfo.h
> +++ b/host/include/riscv/host/cpuinfo.h
> @@ -10,9 +10,11 @@
>   #define CPUINFO_ZBA             (1u << 1)
>   #define CPUINFO_ZBB             (1u << 2)
>   #define CPUINFO_ZICOND          (1u << 3)
> +#define CPUINFO_ZVE64X          (1u << 4)
>   
>   /* Initialized with a constructor. */
>   extern unsigned cpuinfo;
> +extern unsigned riscv_lg2_vlenb;
>   
>   /*
>    * We cannot rely on constructor ordering, so other constructors must
> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
> index 8cacc67645..16114ffd32 100644
> --- a/util/cpuinfo-riscv.c
> +++ b/util/cpuinfo-riscv.c
> @@ -4,6 +4,7 @@
>    */
>   
>   #include "qemu/osdep.h"
> +#include "qemu/host-utils.h"
>   #include "host/cpuinfo.h"
>   
>   #ifdef CONFIG_ASM_HWPROBE_H
> @@ -13,6 +14,7 @@
>   #endif
>   
>   unsigned cpuinfo;
> +unsigned riscv_lg2_vlenb;
>   static volatile sig_atomic_t got_sigill;
>   
>   static void sigill_handler(int signo, siginfo_t *si, void *data)
> @@ -34,7 +36,7 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
>   /* Called both as constructor and (possibly) via other constructors. */
>   unsigned __attribute__((constructor)) cpuinfo_init(void)
>   {
> -    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND;
> +    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;


This will init 'left' with 30 (2 + 4 + 8 + 16)


>       unsigned info = cpuinfo;
>   
>       if (info) {
> @@ -50,6 +52,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>   #endif
>   #if defined(__riscv_arch_test) && defined(__riscv_zicond)
>       info |= CPUINFO_ZICOND;
> +#endif
> +#if defined(__riscv_arch_test) && defined(__riscv_zve64x)
> +    info |= CPUINFO_ZVE64X;
>   #endif
>       left &= ~info;
>   
> @@ -65,7 +70,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>               && pair.key >= 0) {
>               info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
>               info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
> -            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
> +            info |= pair.value & RISCV_HWPROBE_IMA_V ? CPUINFO_ZVE64X : 0;
> +            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZVE64X);
>   #ifdef RISCV_HWPROBE_EXT_ZICOND
>               info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
>               left &= ~CPUINFO_ZICOND;
> @@ -113,6 +119,20 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>           assert(left == 0);

To better understand, this is the 'if' block that contains this assert:

     if (left) {
         struct sigaction sa_old, sa_new;

         memset(&sa_new, 0, sizeof(sa_new));
         sa_new.sa_flags = SA_SIGINFO;
         sa_new.sa_sigaction = sigill_handler;
         sigaction(SIGILL, &sa_new, &sa_old);

         if (left & CPUINFO_ZBA) {
             /* Probe for Zba: add.uw zero,zero,zero. */
             got_sigill = 0;
             asm volatile(".insn r 0x3b, 0, 0x04, zero, zero, zero"
                          : : : "memory");
             info |= got_sigill ? 0 : CPUINFO_ZBA;
             left &= ~CPUINFO_ZBA;
         }

         if (left & CPUINFO_ZBB) {
             /* Probe for Zbb: andn zero,zero,zero. */
             got_sigill = 0;
             asm volatile(".insn r 0x33, 7, 0x20, zero, zero, zero"
                          : : : "memory");
             info |= got_sigill ? 0 : CPUINFO_ZBB;
             left &= ~CPUINFO_ZBB;
         }

         if (left & CPUINFO_ZICOND) {
             /* Probe for Zicond: czero.eqz zero,zero,zero. */
             got_sigill = 0;
             asm volatile(".insn r 0x33, 5, 0x07, zero, zero, zero"
                          : : : "memory");
             info |= got_sigill ? 0 : CPUINFO_ZICOND;
             left &= ~CPUINFO_ZICOND;
         }

         sigaction(SIGILL, &sa_old, NULL);
         assert(left == 0);
     }


The 'assert' is hit at this point because left is 16, i.e. left = CPUINFO_ZVE64X.

I did a fix based on what seems to be the usual flow of how 'left' is being calculated:


$ git diff
diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
index 16114ffd32..25a98a75ad 100644
--- a/util/cpuinfo-riscv.c
+++ b/util/cpuinfo-riscv.c
@@ -115,24 +115,27 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
              left &= ~CPUINFO_ZICOND;
          }
  
+        if (left & CPUINFO_ZVE64X) {
+            /*
+             * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
+             * We are guaranteed by Zve64x that VLEN >= 64, and that
+             * EEW of {8,16,32,64} are supported.
+             *
+             * Cache VLEN in a convenient form.
+             */
+            unsigned long vlenb;
+            got_sigill = 0;
+            /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
+            asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
+            info |= got_sigill ? 0 : CPUINFO_ZVE64X;
+            left &= ~CPUINFO_ZVE64X;
+            riscv_lg2_vlenb = ctz32(vlenb);
+        }
+
          sigaction(SIGILL, &sa_old, NULL);
          assert(left == 0);
      }
  
-    if (info & CPUINFO_ZVE64X) {
-        /*
-         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
-         * We are guaranteed by Zve64x that VLEN >= 64, and that
-         * EEW of {8,16,32,64} are supported.
-         *
-         * Cache VLEN in a convenient form.
-         */
-        unsigned long vlenb;
-        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
-        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
-        riscv_lg2_vlenb = ctz32(vlenb);
-    }
-
      info |= CPUINFO_ALWAYS;
      cpuinfo = info;
      return info;



i.e. I moved the CPUINFO_ZVE64X inside the 'if (left)' block, then update both 'info' and
'left' depending on if we found the vlenb CSR.

Note that this fixes the issue I'm seeing (KVM guest boot), but I can't say if the original
intent of the patch is preserved. If this is a good fix feel free to squash this diff into
the patch.


Thanks,

Daniel


>       }>   
> +    if (info & CPUINFO_ZVE64X) {
> +        /*
> +         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
> +         * We are guaranteed by Zve64x that VLEN >= 64, and that
> +         * EEW of {8,16,32,64} are supported.
> +         *
> +         * Cache VLEN in a convenient form.
> +         */
> +        unsigned long vlenb;
> +        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
> +        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
> +        riscv_lg2_vlenb = ctz32(vlenb);
> +    }
> +
>       info |= CPUINFO_ALWAYS;
>       cpuinfo = info;
>       return info;


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

* Re: [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo
  2024-10-21 18:25   ` Daniel Henrique Barboza
@ 2024-10-21 18:52     ` Richard Henderson
  2024-10-21 19:16       ` Daniel Henrique Barboza
  0 siblings, 1 reply; 29+ messages in thread
From: Richard Henderson @ 2024-10-21 18:52 UTC (permalink / raw)
  To: Daniel Henrique Barboza, qemu-devel
  Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng

On 10/21/24 11:25, Daniel Henrique Barboza wrote:
> Hi,
> 
> This patch is breaking a KVM guest that runs  with '-cpu host' in an emulated
> Risc-V host. The break happens regardless of the RVV support in the emulated
> host:
> 
> 
> $ qemu-system-riscv64 \
>      -machine virt,accel=kvm -m 2G -smp 1 \
>      -cpu host \
>      -nographic -snapshot \
>      -kernel ./guest_imgs/Image \
>      -initrd ./guest_imgs/rootfs_kvm_riscv64.img \
>      -append "root=/dev/ram rw console=ttyS0 earlycon=sbi"
> 
> qemu-system-riscv64: ../util/cpuinfo-riscv.c:119: cpuinfo_init: Assertion `left == 0' failed.
> Aborted
> 
> 
> In a quick debug:
> 
> 
> On 10/16/24 4:31 PM, Richard Henderson wrote:
>> From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
>>
>> Add support for probing RISC-V vector extension availability in
>> the backend. This information will be used when deciding whether
>> to use vector instructions in code generation.
>>
>> Cache lg2(vlenb) for the backend. The storing of lg2(vlenb) means
>> we can convert all of the division into subtraction.
>>
>> While the compiler doesn't support RISCV_HWPROBE_EXT_ZVE64X,
>> we use RISCV_HWPROBE_IMA_V instead. RISCV_HWPROBE_IMA_V is more
>> strictly constrainted than RISCV_HWPROBE_EXT_ZVE64X. At least in
>> current QEMU implemenation, the V vector extension depends on the
>> zve64d extension.
>>
>> Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
>> Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
>> Message-ID: <20241007025700.47259-2-zhiwei_liu@linux.alibaba.com>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>> ---
>>   host/include/riscv/host/cpuinfo.h |  2 ++
>>   util/cpuinfo-riscv.c              | 24 ++++++++++++++++++++++--
>>   2 files changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/host/include/riscv/host/cpuinfo.h b/host/include/riscv/host/cpuinfo.h
>> index 2b00660e36..cdc784e7b6 100644
>> --- a/host/include/riscv/host/cpuinfo.h
>> +++ b/host/include/riscv/host/cpuinfo.h
>> @@ -10,9 +10,11 @@
>>   #define CPUINFO_ZBA             (1u << 1)
>>   #define CPUINFO_ZBB             (1u << 2)
>>   #define CPUINFO_ZICOND          (1u << 3)
>> +#define CPUINFO_ZVE64X          (1u << 4)
>>   /* Initialized with a constructor. */
>>   extern unsigned cpuinfo;
>> +extern unsigned riscv_lg2_vlenb;
>>   /*
>>    * We cannot rely on constructor ordering, so other constructors must
>> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
>> index 8cacc67645..16114ffd32 100644
>> --- a/util/cpuinfo-riscv.c
>> +++ b/util/cpuinfo-riscv.c
>> @@ -4,6 +4,7 @@
>>    */
>>   #include "qemu/osdep.h"
>> +#include "qemu/host-utils.h"
>>   #include "host/cpuinfo.h"
>>   #ifdef CONFIG_ASM_HWPROBE_H
>> @@ -13,6 +14,7 @@
>>   #endif
>>   unsigned cpuinfo;
>> +unsigned riscv_lg2_vlenb;
>>   static volatile sig_atomic_t got_sigill;
>>   static void sigill_handler(int signo, siginfo_t *si, void *data)
>> @@ -34,7 +36,7 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
>>   /* Called both as constructor and (possibly) via other constructors. */
>>   unsigned __attribute__((constructor)) cpuinfo_init(void)
>>   {
>> -    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND;
>> +    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;
> 
> 
> This will init 'left' with 30 (2 + 4 + 8 + 16)
> 
> 
>>       unsigned info = cpuinfo;
>>       if (info) {
>> @@ -50,6 +52,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>   #endif
>>   #if defined(__riscv_arch_test) && defined(__riscv_zicond)
>>       info |= CPUINFO_ZICOND;
>> +#endif
>> +#if defined(__riscv_arch_test) && defined(__riscv_zve64x)
>> +    info |= CPUINFO_ZVE64X;
>>   #endif
>>       left &= ~info;
>> @@ -65,7 +70,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>               && pair.key >= 0) {
>>               info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
>>               info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
>> -            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
>> +            info |= pair.value & RISCV_HWPROBE_IMA_V ? CPUINFO_ZVE64X : 0;
>> +            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZVE64X);
>>   #ifdef RISCV_HWPROBE_EXT_ZICOND
>>               info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
>>               left &= ~CPUINFO_ZICOND;
>> @@ -113,6 +119,20 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>           assert(left == 0);
> 
> To better understand, this is the 'if' block that contains this assert:
> 
>      if (left) {
>          struct sigaction sa_old, sa_new;
> 
>          memset(&sa_new, 0, sizeof(sa_new));
>          sa_new.sa_flags = SA_SIGINFO;
>          sa_new.sa_sigaction = sigill_handler;
>          sigaction(SIGILL, &sa_new, &sa_old);
> 
>          if (left & CPUINFO_ZBA) {
>              /* Probe for Zba: add.uw zero,zero,zero. */
>              got_sigill = 0;
>              asm volatile(".insn r 0x3b, 0, 0x04, zero, zero, zero"
>                           : : : "memory");
>              info |= got_sigill ? 0 : CPUINFO_ZBA;
>              left &= ~CPUINFO_ZBA;
>          }
> 
>          if (left & CPUINFO_ZBB) {
>              /* Probe for Zbb: andn zero,zero,zero. */
>              got_sigill = 0;
>              asm volatile(".insn r 0x33, 7, 0x20, zero, zero, zero"
>                           : : : "memory");
>              info |= got_sigill ? 0 : CPUINFO_ZBB;
>              left &= ~CPUINFO_ZBB;
>          }
> 
>          if (left & CPUINFO_ZICOND) {
>              /* Probe for Zicond: czero.eqz zero,zero,zero. */
>              got_sigill = 0;
>              asm volatile(".insn r 0x33, 5, 0x07, zero, zero, zero"
>                           : : : "memory");
>              info |= got_sigill ? 0 : CPUINFO_ZICOND;
>              left &= ~CPUINFO_ZICOND;
>          }
> 
>          sigaction(SIGILL, &sa_old, NULL);
>          assert(left == 0);
>      }
> 
> 
> The 'assert' is hit at this point because left is 16, i.e. left = CPUINFO_ZVE64X.
> 
> I did a fix based on what seems to be the usual flow of how 'left' is being calculated:
> 
> 
> $ git diff
> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
> index 16114ffd32..25a98a75ad 100644
> --- a/util/cpuinfo-riscv.c
> +++ b/util/cpuinfo-riscv.c
> @@ -115,24 +115,27 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>               left &= ~CPUINFO_ZICOND;
>           }
> 
> +        if (left & CPUINFO_ZVE64X) {
> +            /*
> +             * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
> +             * We are guaranteed by Zve64x that VLEN >= 64, and that
> +             * EEW of {8,16,32,64} are supported.
> +             *
> +             * Cache VLEN in a convenient form.
> +             */
> +            unsigned long vlenb;
> +            got_sigill = 0;
> +            /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
> +            asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
> +            info |= got_sigill ? 0 : CPUINFO_ZVE64X;
> +            left &= ~CPUINFO_ZVE64X;
> +            riscv_lg2_vlenb = ctz32(vlenb);
> +        }
> +
>           sigaction(SIGILL, &sa_old, NULL);
>           assert(left == 0);
>       }
> 
> -    if (info & CPUINFO_ZVE64X) {
> -        /*
> -         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
> -         * We are guaranteed by Zve64x that VLEN >= 64, and that
> -         * EEW of {8,16,32,64} are supported.
> -         *
> -         * Cache VLEN in a convenient form.
> -         */
> -        unsigned long vlenb;
> -        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
> -        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
> -        riscv_lg2_vlenb = ctz32(vlenb);
> -    }
> -
>       info |= CPUINFO_ALWAYS;
>       cpuinfo = info;
>       return info;
> 
> 
> 
> i.e. I moved the CPUINFO_ZVE64X inside the 'if (left)' block, then update both 'info' and
> 'left' depending on if we found the vlenb CSR.
> 
> Note that this fixes the issue I'm seeing (KVM guest boot), but I can't say if the original
> intent of the patch is preserved. If this is a good fix feel free to squash this diff into
> the patch.

This is not a good fix.  The vlenb probe must happen whenever vector support is detected 
-- it is not for detection itself.

It is my understanding that kernel support for riscv_hwprobe pre-dates kernel support for 
vectors in userspace.  I believe that we really don't care about old kernel header installs.

Therefore we should simply

     left &= ~CPUINFO_ZVE64X;

with a comment after the CONFIG_ASM_HWPROBE_H block.

I'll post a v7 for testing.


r~


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

* Re: [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo
  2024-10-21 18:52     ` Richard Henderson
@ 2024-10-21 19:16       ` Daniel Henrique Barboza
  0 siblings, 0 replies; 29+ messages in thread
From: Daniel Henrique Barboza @ 2024-10-21 19:16 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-riscv, alistair.francis, zhiwei_liu, TANG Tiancheng



On 10/21/24 3:52 PM, Richard Henderson wrote:
> On 10/21/24 11:25, Daniel Henrique Barboza wrote:
>> Hi,
>>
>> This patch is breaking a KVM guest that runs  with '-cpu host' in an emulated
>> Risc-V host. The break happens regardless of the RVV support in the emulated
>> host:
>>
>>
>> $ qemu-system-riscv64 \
>>      -machine virt,accel=kvm -m 2G -smp 1 \
>>      -cpu host \
>>      -nographic -snapshot \
>>      -kernel ./guest_imgs/Image \
>>      -initrd ./guest_imgs/rootfs_kvm_riscv64.img \
>>      -append "root=/dev/ram rw console=ttyS0 earlycon=sbi"
>>
>> qemu-system-riscv64: ../util/cpuinfo-riscv.c:119: cpuinfo_init: Assertion `left == 0' failed.
>> Aborted
>>
>>
>> In a quick debug:
>>
>>
>> On 10/16/24 4:31 PM, Richard Henderson wrote:
>>> From: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
>>>
>>> Add support for probing RISC-V vector extension availability in
>>> the backend. This information will be used when deciding whether
>>> to use vector instructions in code generation.
>>>
>>> Cache lg2(vlenb) for the backend. The storing of lg2(vlenb) means
>>> we can convert all of the division into subtraction.
>>>
>>> While the compiler doesn't support RISCV_HWPROBE_EXT_ZVE64X,
>>> we use RISCV_HWPROBE_IMA_V instead. RISCV_HWPROBE_IMA_V is more
>>> strictly constrainted than RISCV_HWPROBE_EXT_ZVE64X. At least in
>>> current QEMU implemenation, the V vector extension depends on the
>>> zve64d extension.
>>>
>>> Signed-off-by: TANG Tiancheng <tangtiancheng.ttc@alibaba-inc.com>
>>> Reviewed-by: Liu Zhiwei <zhiwei_liu@linux.alibaba.com>
>>> Message-ID: <20241007025700.47259-2-zhiwei_liu@linux.alibaba.com>
>>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
>>> ---
>>>   host/include/riscv/host/cpuinfo.h |  2 ++
>>>   util/cpuinfo-riscv.c              | 24 ++++++++++++++++++++++--
>>>   2 files changed, 24 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/host/include/riscv/host/cpuinfo.h b/host/include/riscv/host/cpuinfo.h
>>> index 2b00660e36..cdc784e7b6 100644
>>> --- a/host/include/riscv/host/cpuinfo.h
>>> +++ b/host/include/riscv/host/cpuinfo.h
>>> @@ -10,9 +10,11 @@
>>>   #define CPUINFO_ZBA             (1u << 1)
>>>   #define CPUINFO_ZBB             (1u << 2)
>>>   #define CPUINFO_ZICOND          (1u << 3)
>>> +#define CPUINFO_ZVE64X          (1u << 4)
>>>   /* Initialized with a constructor. */
>>>   extern unsigned cpuinfo;
>>> +extern unsigned riscv_lg2_vlenb;
>>>   /*
>>>    * We cannot rely on constructor ordering, so other constructors must
>>> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
>>> index 8cacc67645..16114ffd32 100644
>>> --- a/util/cpuinfo-riscv.c
>>> +++ b/util/cpuinfo-riscv.c
>>> @@ -4,6 +4,7 @@
>>>    */
>>>   #include "qemu/osdep.h"
>>> +#include "qemu/host-utils.h"
>>>   #include "host/cpuinfo.h"
>>>   #ifdef CONFIG_ASM_HWPROBE_H
>>> @@ -13,6 +14,7 @@
>>>   #endif
>>>   unsigned cpuinfo;
>>> +unsigned riscv_lg2_vlenb;
>>>   static volatile sig_atomic_t got_sigill;
>>>   static void sigill_handler(int signo, siginfo_t *si, void *data)
>>> @@ -34,7 +36,7 @@ static void sigill_handler(int signo, siginfo_t *si, void *data)
>>>   /* Called both as constructor and (possibly) via other constructors. */
>>>   unsigned __attribute__((constructor)) cpuinfo_init(void)
>>>   {
>>> -    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND;
>>> +    unsigned left = CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZICOND | CPUINFO_ZVE64X;
>>
>>
>> This will init 'left' with 30 (2 + 4 + 8 + 16)
>>
>>
>>>       unsigned info = cpuinfo;
>>>       if (info) {
>>> @@ -50,6 +52,9 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>>   #endif
>>>   #if defined(__riscv_arch_test) && defined(__riscv_zicond)
>>>       info |= CPUINFO_ZICOND;
>>> +#endif
>>> +#if defined(__riscv_arch_test) && defined(__riscv_zve64x)
>>> +    info |= CPUINFO_ZVE64X;
>>>   #endif
>>>       left &= ~info;
>>> @@ -65,7 +70,8 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>>               && pair.key >= 0) {
>>>               info |= pair.value & RISCV_HWPROBE_EXT_ZBA ? CPUINFO_ZBA : 0;
>>>               info |= pair.value & RISCV_HWPROBE_EXT_ZBB ? CPUINFO_ZBB : 0;
>>> -            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB);
>>> +            info |= pair.value & RISCV_HWPROBE_IMA_V ? CPUINFO_ZVE64X : 0;
>>> +            left &= ~(CPUINFO_ZBA | CPUINFO_ZBB | CPUINFO_ZVE64X);
>>>   #ifdef RISCV_HWPROBE_EXT_ZICOND
>>>               info |= pair.value & RISCV_HWPROBE_EXT_ZICOND ? CPUINFO_ZICOND : 0;
>>>               left &= ~CPUINFO_ZICOND;
>>> @@ -113,6 +119,20 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>>           assert(left == 0);
>>
>> To better understand, this is the 'if' block that contains this assert:
>>
>>      if (left) {
>>          struct sigaction sa_old, sa_new;
>>
>>          memset(&sa_new, 0, sizeof(sa_new));
>>          sa_new.sa_flags = SA_SIGINFO;
>>          sa_new.sa_sigaction = sigill_handler;
>>          sigaction(SIGILL, &sa_new, &sa_old);
>>
>>          if (left & CPUINFO_ZBA) {
>>              /* Probe for Zba: add.uw zero,zero,zero. */
>>              got_sigill = 0;
>>              asm volatile(".insn r 0x3b, 0, 0x04, zero, zero, zero"
>>                           : : : "memory");
>>              info |= got_sigill ? 0 : CPUINFO_ZBA;
>>              left &= ~CPUINFO_ZBA;
>>          }
>>
>>          if (left & CPUINFO_ZBB) {
>>              /* Probe for Zbb: andn zero,zero,zero. */
>>              got_sigill = 0;
>>              asm volatile(".insn r 0x33, 7, 0x20, zero, zero, zero"
>>                           : : : "memory");
>>              info |= got_sigill ? 0 : CPUINFO_ZBB;
>>              left &= ~CPUINFO_ZBB;
>>          }
>>
>>          if (left & CPUINFO_ZICOND) {
>>              /* Probe for Zicond: czero.eqz zero,zero,zero. */
>>              got_sigill = 0;
>>              asm volatile(".insn r 0x33, 5, 0x07, zero, zero, zero"
>>                           : : : "memory");
>>              info |= got_sigill ? 0 : CPUINFO_ZICOND;
>>              left &= ~CPUINFO_ZICOND;
>>          }
>>
>>          sigaction(SIGILL, &sa_old, NULL);
>>          assert(left == 0);
>>      }
>>
>>
>> The 'assert' is hit at this point because left is 16, i.e. left = CPUINFO_ZVE64X.
>>
>> I did a fix based on what seems to be the usual flow of how 'left' is being calculated:
>>
>>
>> $ git diff
>> diff --git a/util/cpuinfo-riscv.c b/util/cpuinfo-riscv.c
>> index 16114ffd32..25a98a75ad 100644
>> --- a/util/cpuinfo-riscv.c
>> +++ b/util/cpuinfo-riscv.c
>> @@ -115,24 +115,27 @@ unsigned __attribute__((constructor)) cpuinfo_init(void)
>>               left &= ~CPUINFO_ZICOND;
>>           }
>>
>> +        if (left & CPUINFO_ZVE64X) {
>> +            /*
>> +             * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
>> +             * We are guaranteed by Zve64x that VLEN >= 64, and that
>> +             * EEW of {8,16,32,64} are supported.
>> +             *
>> +             * Cache VLEN in a convenient form.
>> +             */
>> +            unsigned long vlenb;
>> +            got_sigill = 0;
>> +            /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
>> +            asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
>> +            info |= got_sigill ? 0 : CPUINFO_ZVE64X;
>> +            left &= ~CPUINFO_ZVE64X;
>> +            riscv_lg2_vlenb = ctz32(vlenb);
>> +        }
>> +
>>           sigaction(SIGILL, &sa_old, NULL);
>>           assert(left == 0);
>>       }
>>
>> -    if (info & CPUINFO_ZVE64X) {
>> -        /*
>> -         * We are guaranteed by RVV-1.0 that VLEN is a power of 2.
>> -         * We are guaranteed by Zve64x that VLEN >= 64, and that
>> -         * EEW of {8,16,32,64} are supported.
>> -         *
>> -         * Cache VLEN in a convenient form.
>> -         */
>> -        unsigned long vlenb;
>> -        /* Read csr "vlenb" with "csrr %0, vlenb" : "=r"(vlenb) */
>> -        asm volatile(".insn i 0x73, 0x2, %0, zero, -990" : "=r"(vlenb));
>> -        riscv_lg2_vlenb = ctz32(vlenb);
>> -    }
>> -
>>       info |= CPUINFO_ALWAYS;
>>       cpuinfo = info;
>>       return info;
>>
>>
>>
>> i.e. I moved the CPUINFO_ZVE64X inside the 'if (left)' block, then update both 'info' and
>> 'left' depending on if we found the vlenb CSR.
>>
>> Note that this fixes the issue I'm seeing (KVM guest boot), but I can't say if the original
>> intent of the patch is preserved. If this is a good fix feel free to squash this diff into
>> the patch.
> 
> This is not a good fix.  The vlenb probe must happen whenever vector support is detected -- it is not for detection itself.
> 
> It is my understanding that kernel support for riscv_hwprobe pre-dates kernel support for vectors in userspace.  I believe that we really don't care about old kernel header installs.
> 
> Therefore we should simply
> 
>      left &= ~CPUINFO_ZVE64X;
> 
> with a comment after the CONFIG_ASM_HWPROBE_H block.
> 
> I'll post a v7 for testing.

Put me in Cc for v7 and I'll give it a go. Thanks,

Daniel


> 
> 
> r~


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

* Re: [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly
  2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
  2024-10-21  1:16   ` Alistair Francis
  2024-10-21 17:31   ` Pierrick Bouvier
@ 2024-10-22  2:48   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: LIU Zhiwei @ 2024-10-22  2:48 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis, qemu-stable


On 2024/10/17 03:31, Richard Henderson wrote:
> This pointer needs to be reset after overflow just like
> code_buf and code_ptr.
>
> Cc: qemu-stable@nongnu.org
> Fixes: 57a269469db ("tcg: Infrastructure for managing constant pools")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/tcg.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/tcg/tcg.c b/tcg/tcg.c
> index 5decd83cf4..0babae1b88 100644
> --- a/tcg/tcg.c
> +++ b/tcg/tcg.c
> @@ -1399,7 +1399,6 @@ TranslationBlock *tcg_tb_alloc(TCGContext *s)
>           goto retry;
>       }
>       qatomic_set(&s->code_gen_ptr, next);
> -    s->data_gen_ptr = NULL;
>       return tb;
>   }
>   
> @@ -6172,6 +6171,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb, uint64_t pc_start)
>        */
>       s->code_buf = tcg_splitwx_to_rw(tb->tc.ptr);
>       s->code_ptr = s->code_buf;
> +    s->data_gen_ptr = NULL;
>   
>   #ifdef TCG_TARGET_NEED_LDST_LABELS
>       QSIMPLEQ_INIT(&s->ldst_labels);

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

Zhiwei



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

* Re: [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly
  2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
  2024-10-21  1:17   ` Alistair Francis
  2024-10-21 17:41   ` Pierrick Bouvier
@ 2024-10-22  3:12   ` LIU Zhiwei
  2 siblings, 0 replies; 29+ messages in thread
From: LIU Zhiwei @ 2024-10-22  3:12 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis


On 2024/10/17 03:31, Richard Henderson wrote:
> The first immediate field is unsigned, whereas operand_vimm
> extracts a signed value.  There is no need to mask the result
> with 'u'; just print the immediate with 'i'.
>
> Fixes: 07f4964d178 ("disas/riscv.c: rvv: Add disas support for vector instructions")
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   disas/riscv.h | 2 +-
>   disas/riscv.c | 2 +-
>   2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/disas/riscv.h b/disas/riscv.h
> index 16a08e4895..0d1f89ce8a 100644
> --- a/disas/riscv.h
> +++ b/disas/riscv.h
> @@ -290,7 +290,7 @@ enum {
>   #define rv_fmt_fd_vs2                 "O\t3,F"
>   #define rv_fmt_vd_vm                  "O\tDm"
>   #define rv_fmt_vsetvli                "O\t0,1,v"
> -#define rv_fmt_vsetivli               "O\t0,u,v"
> +#define rv_fmt_vsetivli               "O\t0,i,v"
>   #define rv_fmt_rs1_rs2_zce_ldst       "O\t2,i(1)"
>   #define rv_fmt_push_rlist             "O\tx,-i"
>   #define rv_fmt_pop_rlist              "O\tx,i"
> diff --git a/disas/riscv.c b/disas/riscv.c
> index 5965574d87..fc0331b90b 100644
> --- a/disas/riscv.c
> +++ b/disas/riscv.c
> @@ -4808,7 +4808,7 @@ static void decode_inst_operands(rv_decode *dec, rv_isa isa)
>           break;
>       case rv_codec_vsetivli:
>           dec->rd = operand_rd(inst);
> -        dec->imm = operand_vimm(inst);
> +        dec->imm = extract32(inst, 15, 5);

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

Zhiwei

>           dec->vzimm = operand_vzimm10(inst);
>           break;
>       case rv_codec_zcb_lb:


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

* Re: [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec
  2024-10-16 19:31 ` [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec Richard Henderson
@ 2024-10-22  6:31   ` LIU Zhiwei
  0 siblings, 0 replies; 29+ messages in thread
From: LIU Zhiwei @ 2024-10-22  6:31 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis


On 2024/10/17 03:31, Richard Henderson wrote:
> Use vrsub.vi to subtract from a constant.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/riscv/tcg-target-con-set.h | 1 +
>   tcg/riscv/tcg-target.c.inc     | 8 ++++++--
>   2 files changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/tcg/riscv/tcg-target-con-set.h b/tcg/riscv/tcg-target-con-set.h
> index 97e6ecdb0f..d8ce5414f5 100644
> --- a/tcg/riscv/tcg-target-con-set.h
> +++ b/tcg/riscv/tcg-target-con-set.h
> @@ -25,6 +25,7 @@ C_O0_I2(v, r)
>   C_O1_I1(v, r)
>   C_O1_I1(v, v)
>   C_O1_I2(v, v, v)
> +C_O1_I2(v, vK, v)
>   C_O1_I2(v, v, vK)
>   C_O1_I2(v, v, vL)
>   C_O1_I4(v, v, vL, vK, vK)
> diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
> index ce8d6d0293..1ce2f291d3 100644
> --- a/tcg/riscv/tcg-target.c.inc
> +++ b/tcg/riscv/tcg-target.c.inc
> @@ -2350,7 +2350,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
>           break;
>       case INDEX_op_sub_vec:
>           set_vtype_len_sew(s, type, vece);
> -        tcg_out_opc_vv(s, OPC_VSUB_VV, a0, a1, a2);
> +        if (const_args[1]) {
> +            tcg_out_opc_vi(s, OPC_VRSUB_VI, a0, a2, a1);
> +        } else {
> +            tcg_out_opc_vv(s, OPC_VSUB_VV, a0, a1, a2);
> +        }
>           break;
>       case INDEX_op_and_vec:
>           set_vtype_len(s, type);
> @@ -2565,7 +2569,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
>       case INDEX_op_xor_vec:
>           return C_O1_I2(v, v, vK);
>       case INDEX_op_sub_vec:
> -        return C_O1_I2(v, v, v);
> +        return C_O1_I2(v, vK, v);

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

Zhiwei

>       case INDEX_op_cmp_vec:
>           return C_O1_I2(v, v, vL);
>       case INDEX_op_cmpsel_vec:


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

* Re: [PATCH v6 00/14] tcg/riscv: Add support for vector
  2024-10-21  1:42 ` [PATCH v6 00/14] tcg/riscv: Add support for vector Alistair Francis
@ 2024-10-22  6:59   ` LIU Zhiwei
  0 siblings, 0 replies; 29+ messages in thread
From: LIU Zhiwei @ 2024-10-22  6:59 UTC (permalink / raw)
  To: Alistair Francis, Richard Henderson
  Cc: qemu-devel, qemu-riscv, alistair.francis


On 2024/10/21 09:42, Alistair Francis wrote:
> On Thu, Oct 17, 2024 at 5:33 AM Richard Henderson
> <richard.henderson@linaro.org> wrote:
>> Introduce support for the RISC-V vector extension in the TCG backend.
>>
>> v5: https://lore.kernel.org/qemu-devel/20241007025700.47259-1-zhiwei_liu@linux.alibaba.com/
>>
>> Changes for v6:
>>    - Fix problem with TB overflow restart wrt the constant pool.
>>    - Fix vsetivli disassembly.
>>    - Change set_vtype to precompute all instructions.
>>    - Extract one element before comparison in tcg_out_dupi_vec.
>>    - Extract one element before comparison in tcg_target_const_match.
>>    - Drop 'vm' parameter from most tcg_out_opc_* functions.
>>    - Add tcg_out_opc_vv_vi and accept K constants for operations
>>      which have .v.i instructions.
>>    - Do not expand cmp_vec early.
>>    - Fix expansion of rotls_vec.
>>
>> I've tested this on cfarm95, a banana pi bpi-f3 with 256-bit rvv-1.0,
>> with qemu-aarch64 and some vectorized test cases.
>>
>> Barring further comment, I plan to include this in a PR at the
>> end of the week.
>>
>>
>> r~
>>
>>
>> Huang Shiyuan (1):
>>    tcg/riscv: Add basic support for vector
>>
>> Richard Henderson (3):
>>    tcg: Reset data_gen_ptr correctly
>>    disas/riscv: Fix vsetivli disassembly
>>    tcg/riscv: Accept constant first argument to sub_vec
>>
>> TANG Tiancheng (10):
>>    util: Add RISC-V vector extension probe in cpuinfo
>>    tcg/riscv: Implement vector mov/dup{m/i}
>>    tcg/riscv: Add support for basic vector opcodes
>>    tcg/riscv: Implement vector cmp/cmpsel ops
>>    tcg/riscv: Implement vector neg ops
>>    tcg/riscv: Implement vector sat/mul ops
>>    tcg/riscv: Implement vector min/max ops
>>    tcg/riscv: Implement vector shi/s/v ops
>>    tcg/riscv: Implement vector roti/v/x ops
>>    tcg/riscv: Enable native vector support for TCG host
> Thanks!
>
> Applied to riscv-to-apply.next
>
> I have removed the Swung0x48 Signed-off-by line.

I think we should use this tag as pointed here[1]:

Signed-off-by: Huang Shiyuan <swung0x48@outlook.com>

[1]: https://mail.gnu.org/archive/html/qemu-riscv/2024-09/msg00526.html

Thanks,
Zhiwei

>
> Alistair
>
>>   disas/riscv.h                     |   2 +-
>>   host/include/riscv/host/cpuinfo.h |   2 +
>>   include/tcg/tcg.h                 |   6 +
>>   tcg/riscv/tcg-target-con-set.h    |   9 +
>>   tcg/riscv/tcg-target-con-str.h    |   3 +
>>   tcg/riscv/tcg-target.h            |  78 ++-
>>   tcg/riscv/tcg-target.opc.h        |  12 +
>>   disas/riscv.c                     |   2 +-
>>   tcg/tcg.c                         |   2 +-
>>   util/cpuinfo-riscv.c              |  24 +-
>>   tcg/riscv/tcg-target.c.inc        | 994 +++++++++++++++++++++++++++---
>>   11 files changed, 1011 insertions(+), 123 deletions(-)
>>   create mode 100644 tcg/riscv/tcg-target.opc.h
>>
>> --
>> 2.43.0
>>
>>


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

end of thread, other threads:[~2024-10-22  7:00 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-16 19:31 [PATCH v6 00/14] tcg/riscv: Add support for vector Richard Henderson
2024-10-16 19:31 ` [PATCH v6 01/14] tcg: Reset data_gen_ptr correctly Richard Henderson
2024-10-21  1:16   ` Alistair Francis
2024-10-21 17:31   ` Pierrick Bouvier
2024-10-22  2:48   ` LIU Zhiwei
2024-10-16 19:31 ` [PATCH v6 02/14] disas/riscv: Fix vsetivli disassembly Richard Henderson
2024-10-21  1:17   ` Alistair Francis
2024-10-21 17:41   ` Pierrick Bouvier
2024-10-22  3:12   ` LIU Zhiwei
2024-10-16 19:31 ` [PATCH v6 03/14] util: Add RISC-V vector extension probe in cpuinfo Richard Henderson
2024-10-21  1:20   ` Alistair Francis
2024-10-21 18:25   ` Daniel Henrique Barboza
2024-10-21 18:52     ` Richard Henderson
2024-10-21 19:16       ` Daniel Henrique Barboza
2024-10-16 19:31 ` [PATCH v6 04/14] tcg/riscv: Add basic support for vector Richard Henderson
2024-10-16 19:31 ` [PATCH v6 05/14] tcg/riscv: Implement vector mov/dup{m/i} Richard Henderson
2024-10-16 19:31 ` [PATCH v6 06/14] tcg/riscv: Add support for basic vector opcodes Richard Henderson
2024-10-16 19:31 ` [PATCH v6 07/14] tcg/riscv: Implement vector cmp/cmpsel ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 08/14] tcg/riscv: Implement vector neg ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 09/14] tcg/riscv: Accept constant first argument to sub_vec Richard Henderson
2024-10-22  6:31   ` LIU Zhiwei
2024-10-16 19:31 ` [PATCH v6 10/14] tcg/riscv: Implement vector sat/mul ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 11/14] tcg/riscv: Implement vector min/max ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 12/14] tcg/riscv: Implement vector shi/s/v ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 13/14] tcg/riscv: Implement vector roti/v/x ops Richard Henderson
2024-10-16 19:31 ` [PATCH v6 14/14] tcg/riscv: Enable native vector support for TCG host Richard Henderson
2024-10-21  1:42 ` [PATCH v6 00/14] tcg/riscv: Add support for vector Alistair Francis
2024-10-22  6:59   ` LIU Zhiwei
  -- strict thread matches above, loose matches on Subject: below --
2024-10-17  2:38 TangTianCheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).