[PATCH v5] target/riscv: Implement dynamic establishment of custom decoder

2024-05-05 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   RISCVCPU, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
   overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
Changes in v5:
- rebase on https://github.com/alistair23/qemu/tree/riscv-to-apply.next

Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
 target/riscv/cpu.c |  1 +
 target/riscv/cpu.h |  1 +
 target/riscv/tcg/tcg-cpu.c | 15 +++
 target/riscv/tcg/tcg-cpu.h | 15 +++
 target/riscv/translate.c   | 31 +++
 5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a74f0eb29c..2cb145121d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1134,6 +1134,7 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 error_propagate(errp, local_err);
 return;
 }
+riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
 } else if (kvm_enabled()) {
 riscv_kvm_cpu_finalize_features(cpu, _err);
 if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e0dd1828b5..2838d9640b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -455,6 +455,7 @@ struct ArchCPU {
 uint32_t pmu_avail_ctrs;
 /* Mapping of events to counters */
 GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
 };
 
 /**
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 4ebebebe09..3a4ec3662a 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -863,6 +863,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 }
 }
 
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].riscv_cpu_decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
 {
 return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp);
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
 
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 9ff09ebdb6..15e7123a68 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
 #include "exec/helper-info.c.inc"
 #undef  HELPER_H
 
+#include "tcg/tcg-cpu.h"
+
 /* global register indices */
 static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
@@ -116,6 +118,7 @@ typedef struct DisasContext {
 /* FRM is known to contain a valid value. */
 bool frm_valid;
 bool insn_start_updated;
+const

Re: [PATCH v4] target/riscv: Implement dynamic establishment of custom decoder

2024-04-29 Thread Huang Tao



On 2024/4/29 15:58, Huang Tao wrote:


On 2024/4/29 11:51, Alistair Francis wrote:
On Thu, Mar 14, 2024 at 7:23 PM Huang Tao 
 wrote:

In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add 
decoder in
    RISCVCPU, each cpu can have their own decoder, and the decoders 
can be

    different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if 
the decoder
    can be added to the dynamic_decoder when building up the 
decoder. Therefore,
    there is no need to run the guard_func when decoding each 
instruction. It can

    improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own 
decoder
    functions to improve decoding efficiency, especially when 
vendor-defined
    instruction sets increase. Because of dynamic building up, it 
can skip the other

    decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before 
decode_insn32() with minimal

    overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next?

Alistair


I will rebase this patch on the latest riscv-to-apply.next.

Thanks

I successfully applied this patch to the latest riscv-to-apply.next 
branch. I wonder what error you met on applying this patch to 
riscv-to-apply.next, so I can fix my patch.


Thanks


---
Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
  target/riscv/cpu.c |  1 +
  target/riscv/cpu.h |  1 +
  target/riscv/tcg/tcg-cpu.c | 15 +++
  target/riscv/tcg/tcg-cpu.h | 15 +++
  target/riscv/translate.c   | 31 +++
  5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c160b9216b..17070b82a7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1132,6 +1132,7 @@ void riscv_cpu_finalize_features(RISCVCPU 
*cpu, Error **errp)

  error_propagate(errp, local_err);
  return;
  }
+    riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
  } else if (kvm_enabled()) {
  riscv_kvm_cpu_finalize_features(cpu, _err);
  if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..48e67410e1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -457,6 +457,7 @@ struct ArchCPU {
  uint32_t pmu_avail_ctrs;
  /* Mapping of events to counters */
  GHashTable *pmu_event_ctr_map;
+    const GPtrArray *decoders;
  };

  /**
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ab6db817db..c9ab92ea2f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -853,6 +853,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU 
*cpu, Error **errp)

  }
  }

+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+    GPtrArray *dynamic_decoders;
+    dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+    for (size_t i = 0; i < decoder_table_size; ++i) {
+    if (decoder_table[i].guard_func &&
+    decoder_table[i].guard_func(>cfg)) {
+    g_ptr_array_add(dynamic_decoders,
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
+    }
+    }
+
+    cpu->decoders = dynamic_decoders;
+}
+
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
  {
  return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) 
== NULL;

diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp);

  void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);

+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+    bool (*guard_func)(const struct RISCVCPUConfig *);
+    bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
  #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea5d52b2ef..bce16d5054 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
  #include "exec/helpe

Re: [PATCH v4] target/riscv: Implement dynamic establishment of custom decoder

2024-04-29 Thread Huang Tao



On 2024/4/29 11:51, Alistair Francis wrote:

On Thu, Mar 14, 2024 at 7:23 PM Huang Tao  wrote:

In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
RISCVCPU, each cpu can have their own decoder, and the decoders can be
different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
can be added to the dynamic_decoder when building up the decoder. Therefore,
there is no need to run the guard_func when decoding each instruction. It 
can
improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
functions to improve decoding efficiency, especially when vendor-defined
instruction sets increase. Because of dynamic building up, it can skip the 
other
decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 

Do you mind rebasing this on
https://github.com/alistair23/qemu/tree/riscv-to-apply.next?

Alistair


I will rebase this patch on the latest riscv-to-apply.next.

Thanks


---
Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
  target/riscv/cpu.c |  1 +
  target/riscv/cpu.h |  1 +
  target/riscv/tcg/tcg-cpu.c | 15 +++
  target/riscv/tcg/tcg-cpu.h | 15 +++
  target/riscv/translate.c   | 31 +++
  5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c160b9216b..17070b82a7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1132,6 +1132,7 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
  error_propagate(errp, local_err);
  return;
  }
+riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
  } else if (kvm_enabled()) {
  riscv_kvm_cpu_finalize_features(cpu, _err);
  if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..48e67410e1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -457,6 +457,7 @@ struct ArchCPU {
  uint32_t pmu_avail_ctrs;
  /* Mapping of events to counters */
  GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
  };

  /**
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ab6db817db..c9ab92ea2f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -853,6 +853,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
  }
  }

+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].riscv_cpu_decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
  {
  return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp);
  void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);

+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
  #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea5d52b2ef..bce16d5054 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
  #include "exec/helper-info.c.inc"
  #undef  HELPER_H

+#include "tcg/tcg-cpu.h"
+
  /* global register indices */
  static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
  static TCGv_i64 cpu_fpr[32]; /* assume F

[PATCH 65/65] target/riscv: Enable XTheadVector extension for c906

2024-04-12 Thread Huang Tao
This patch enables XTheadVector for the c906.

Signed-off-by: Huang Tao 
---
 target/riscv/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 05652e8c87..e85aa51237 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -542,7 +542,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 cpu->cfg.ext_xtheadmemidx = true;
 cpu->cfg.ext_xtheadmempair = true;
 cpu->cfg.ext_xtheadsync = true;
-cpu->cfg.ext_xtheadvector = false;
+cpu->cfg.ext_xtheadvector = true;
 
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
-- 
2.44.0




[PATCH 64/65] target/riscv: Add vector compress instruction for XTheadVector

2024-04-12 Thread Huang Tao
The instruction has the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  5 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 36 ---
 target/riscv/xtheadvector_helper.c| 27 ++
 3 files changed, 63 insertions(+), 5 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b650e299cf..b46f9fc2c3 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2342,3 +2342,8 @@ DEF_HELPER_6(th_vrgather_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrgather_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vcompress_vm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index f6da1ff384..65b595d699 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2898,10 +2898,36 @@ static bool trans_th_vrgather_vi(DisasContext *s, 
arg_rmrr *a)
 return true;
 }
 
-#define TH_TRANS_STUB(NAME)\
-static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
-{  \
-return require_xtheadvector(s);\
+/* Vector Compress Instruction */
+static bool vcompress_vm_check_th(DisasContext *s, arg_r *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_overlap_group(a->rd, 1 << s->lmul, a->rs1, 1) &&
+(a->rd != a->rs2)) &&
+s->vstart_eq_zero;
 }
 
-TH_TRANS_STUB(th_vcompress_vm)
+static bool trans_th_vcompress_vm(DisasContext *s, arg_r *a)
+{
+if (vcompress_vm_check_th(s, a)) {
+uint32_t data = 0;
+static gen_helper_gvec_4_ptr * const fns[4] = {
+gen_helper_th_vcompress_vm_b, gen_helper_th_vcompress_vm_h,
+gen_helper_th_vcompress_vm_w, gen_helper_th_vcompress_vm_d,
+};
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs1), vreg_ofs(s, a->rs2),
+   tcg_env, s->cfg_ptr->vlenb,
+   s->cfg_ptr->vlenb, data,
+   fns[s->sew]);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 2598824bb3..656f83f408 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3865,3 +3865,30 @@ GEN_TH_VRGATHER_VX(th_vrgather_vx_b, uint8_t, H1, 
clearb_th)
 GEN_TH_VRGATHER_VX(th_vrgather_vx_h, uint16_t, H2, clearh_th)
 GEN_TH_VRGATHER_VX(th_vrgather_vx_w, uint32_t, H4, clearl_th)
 GEN_TH_VRGATHER_VX(th_vrgather_vx_d, uint64_t, H8, clearq_th)
+
+/* Vector Compress Instruction */
+#define GEN_TH_VCOMPRESS_VM(NAME, ETYPE, H, CLEAR_FN) \
+void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
+  CPURISCVState *env, uint32_t desc)  \
+{ \
+uint32_t mlen = th_mlen(desc);\
+uint32_t vlmax = (env_archcpu(env)->cfg.vlenb << 3) / mlen;   \
+uint32_t vl = env->vl;\
+uint32_t num = 0, i;  \
+  \
+for (i = env->vstart; i < vl; i++) {  \
+if (!th_elem_mask(vs1, mlen, i)) {\
+continue; \
+} \
+*((ETYPE *)vd + H(num)) = *((ETYPE *)vs2 + H(i)); \
+num++;\
+} \
+env->vstart = 0;  \
+CLEAR

[PATCH 63/65] target/riscv: Add vector register gather instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  9 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 85 ++-
 target/riscv/xtheadvector_helper.c| 64 ++
 3 files changed, 155 insertions(+), 3 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6ce0bcbba7..b650e299cf 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2333,3 +2333,12 @@ DEF_HELPER_6(th_vslide1down_vx_b, void, ptr, ptr, tl, 
ptr, env, i32)
 DEF_HELPER_6(th_vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrgather_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 46cfc51690..f6da1ff384 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2816,13 +2816,92 @@ GEN_OPIVX_TRANS_TH(th_vslidedown_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vslide1down_vx, opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vslidedown_vi, IMM_ZX, th_vslidedown_vx, opivx_check_th)
 
+/* Vector Register Gather Instruction */
+static bool vrgather_vv_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs1, false) &&
+th_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2) && (a->rd != a->rs1));
+}
+
+GEN_OPIVV_TRANS_TH(th_vrgather_vv, vrgather_vv_check_th)
+
+static bool vrgather_vx_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2));
+}
+
+/* vrgather.vx vd, vs2, rs1, vm # vd[i] = (x[rs1] >= VLMAX) ? 0 : vs2[rs1] */
+static bool trans_th_vrgather_vx(DisasContext *s, arg_rmrr *a)
+{
+if (!vrgather_vx_check_th(s, a)) {
+return false;
+}
+
+if (a->vm && s->vl_eq_vlmax) {
+int vlmax = (s->cfg_ptr->vlenb << 3) / s->mlen;
+TCGv_i64 dest = tcg_temp_new_i64();
+
+if (a->rs1 == 0) {
+th_element_loadi(s, dest, a->rs2, 0);
+} else {
+th_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
+}
+
+tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
+ MAXSZ(s), MAXSZ(s), dest);
+finalize_rvv_inst(s);
+} else {
+static gen_helper_opivx * const fns[4] = {
+gen_helper_th_vrgather_vx_b, gen_helper_th_vrgather_vx_h,
+gen_helper_th_vrgather_vx_w, gen_helper_th_vrgather_vx_d
+};
+return opivx_trans_th(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew], s);
+}
+return true;
+}
+
+/* vrgather.vi vd, vs2, imm, vm # vd[i] = (imm >= VLMAX) ? 0 : vs2[imm] */
+static bool trans_th_vrgather_vi(DisasContext *s, arg_rmrr *a)
+{
+if (!vrgather_vx_check_th(s, a)) {
+return false;
+}
+
+if (a->vm && s->vl_eq_vlmax) {
+if (a->rs1 >= (s->cfg_ptr->vlenb << 3) / s->mlen) {
+tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
+ MAXSZ(s), MAXSZ(s), 0);
+} else {
+tcg_gen_gvec_dup_mem(s->sew, vreg_ofs(s, a->rd),
+ endian_ofs(s, a->rs2, a->rs1),
+ MAXSZ(s), MAXSZ(s));
+}
+finalize_rvv_inst(s);
+} else {
+static gen_helper_opivx * const fns[4] = {
+gen_helper_th_vrgather_vx_b, gen_helper_th_vrgather_vx_h,
+gen_helper_th_vrgather_vx_w, gen_helper_th_vrgather_vx_d
+};
+return opivi_trans_th(a->rd, a->rs1, a->rs2, a->vm, fns[s->sew],
+  

[PATCH 62/65] target/riscv: Add vector slide instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  17 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  25 +++-
 target/riscv/xtheadvector_helper.c| 123 ++
 3 files changed, 159 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index fe264621ff..6ce0bcbba7 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2316,3 +2316,20 @@ DEF_HELPER_4(th_vid_v_b, void, ptr, ptr, env, i32)
 DEF_HELPER_4(th_vid_v_h, void, ptr, ptr, env, i32)
 DEF_HELPER_4(th_vid_v_w, void, ptr, ptr, env, i32)
 DEF_HELPER_4(th_vid_v_d, void, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vslideup_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslideup_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslideup_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslideup_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslidedown_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslidedown_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslidedown_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslidedown_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1up_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1up_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1up_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1up_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1down_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1down_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 54ccd933c0..46cfc51690 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2797,18 +2797,31 @@ static bool trans_th_vfmv_s_f(DisasContext *s, 
arg_th_vfmv_s_f *a)
 return false;
 }
 
+/* Vector Slide Instructions */
+static bool slideup_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, false) &&
+(a->rd != a->rs2));
+}
+
+GEN_OPIVX_TRANS_TH(th_vslideup_vx, slideup_check_th)
+GEN_OPIVX_TRANS_TH(th_vslide1up_vx, slideup_check_th)
+GEN_OPIVI_TRANS_TH(th_vslideup_vi, IMM_ZX, th_vslideup_vx, slideup_check_th)
+
+GEN_OPIVX_TRANS_TH(th_vslidedown_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vslide1down_vx, opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vslidedown_vi, IMM_ZX, th_vslidedown_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vslideup_vx)
-TH_TRANS_STUB(th_vslideup_vi)
-TH_TRANS_STUB(th_vslide1up_vx)
-TH_TRANS_STUB(th_vslidedown_vx)
-TH_TRANS_STUB(th_vslidedown_vi)
-TH_TRANS_STUB(th_vslide1down_vx)
 TH_TRANS_STUB(th_vrgather_vv)
 TH_TRANS_STUB(th_vrgather_vx)
 TH_TRANS_STUB(th_vrgather_vi)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 0743d57b12..73a15eb070 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3678,3 +3678,126 @@ GEN_TH_VID_V(th_vid_v_b, uint8_t, H1, clearb_th)
 GEN_TH_VID_V(th_vid_v_h, uint16_t, H2, clearh_th)
 GEN_TH_VID_V(th_vid_v_w, uint32_t, H4, clearl_th)
 GEN_TH_VID_V(th_vid_v_d, uint64_t, H8, clearq_th)
+
+/*
+ * Vector Permutation Instructions
+ */
+
+/* Vector Slide Instructions */
+#define GEN_TH_VSLIDEUP_VX(NAME, ETYPE, H, CLEAR_FN)  \
+void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
+  CPURISCVState *env, uint32_t desc)  \
+{ \
+uint32_t mlen = th_mlen(desc);\
+uint32_t vlmax = (env_archcpu(env)->cfg.vlenb << 3) / mlen;   \
+uint32_t vm = th_vm(desc);\
+uint32_t vl = env->vl;\
+target_ulong offset = s1, i_min, i;   \
+  \
+VSTART_CHECK_EARLY_EXIT(env); \
+i_min = MAX(env->vsta

[PATCH 61/65] target/riscv: Add floating-point scalar move instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector floating-point scalar move instructions diff from RVV1.0 in
the following points:
1. When src width < dst width, RVV1.0 checks whether the input value is a
   valid NaN-boxed value, in which case the least-significant dst-width bits
   are used, else the canonical NaN value is used. XTheadVector always use the
   least-significant bits.
2. different tail elements process policy.

Signed-off-by: Huang Tao 
---
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 59 ++-
 1 file changed, 57 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index a8a1ec7b3f..54ccd933c0 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2740,14 +2740,69 @@ static bool trans_th_vmv_s_x(DisasContext *s, 
arg_th_vmv_s_x *a)
 return false;
 }
 
+/* Floating-Point Scalar Move Instructions */
+static bool trans_th_vfmv_f_s(DisasContext *s, arg_th_vfmv_f_s *a)
+{
+if (require_xtheadvector(s) &&
+!s->vill && has_ext(s, RVF) &&
+(s->mstatus_fs != 0) &&
+(s->sew != 0)) {
+unsigned int len = 8 << s->sew;
+
+th_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0);
+if (len < 64) {
+tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+MAKE_64BIT_MASK(len, 64 - len));
+}
+
+mark_fs_dirty(s);
+tcg_gen_movi_tl(cpu_vstart, 0);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
+/* vfmv.s.f vd, rs1 # vd[0] = rs1 (vs2=0) */
+static bool trans_th_vfmv_s_f(DisasContext *s, arg_th_vfmv_s_f *a)
+{
+if (require_xtheadvector(s) &&
+!s->vill && has_ext(s, RVF) &&
+(s->sew != 0)) {
+TCGv_i64 t1;
+/* The instructions ignore LMUL and vector register group. */
+uint32_t vlmax = s->cfg_ptr->vlenb;
+
+/* if vl == 0, skip vector register write back */
+TCGLabel *over = gen_new_label();
+tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
+
+/* zeroed all elements */
+tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd), vlmax, vlmax, 0);
+
+/* NaN-box f[rs1] as necessary for SEW */
+t1 = tcg_temp_new_i64();
+if (s->sew == MO_64 && !has_ext(s, RVD)) {
+tcg_gen_ori_i64(t1, cpu_fpr[a->rs1], MAKE_64BIT_MASK(32, 32));
+} else {
+tcg_gen_mov_i64(t1, cpu_fpr[a->rs1]);
+}
+th_element_storei(s, a->rd, 0, t1);
+
+gen_set_label(over);
+tcg_gen_movi_tl(cpu_vstart, 0);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfmv_f_s)
-TH_TRANS_STUB(th_vfmv_s_f)
 TH_TRANS_STUB(th_vslideup_vx)
 TH_TRANS_STUB(th_vslideup_vi)
 TH_TRANS_STUB(th_vslide1up_vx)
-- 
2.44.0




[PATCH 60/65] target/riscv: Add integer extract and scalar move instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add integer extract and scalar move instructions to show the 
way we
implement XTheadVector permutation instructions.
XTheadVector integer scalar move instructions diff from RVV1.0 in the following
points:
1. th.vext.x.v can transfer any element in a vector register to a general
   register, while vmv.x.s can only transfer the first element in a vector
   register to a general register.
2. When SEW < XLEN, XTheadVector zero-extend the value, while RVV1.0
   sign-extend the value.
3. different tail element process policy.

Signed-off-by: Huang Tao 
---
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 154 +-
 1 file changed, 152 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 9a0ea606ab..a8a1ec7b3f 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2588,14 +2588,164 @@ static bool trans_th_vid_v(DisasContext *s, 
arg_th_vid_v *a)
 return false;
 }
 
+/*
+ * Vector Permutation Instructions
+ */
+
+/* Integer Extract Instruction */
+
+/*
+ * This function is almost the copy of load_element, except:
+ * 1) When SEW < XLEN, XTheadVector zero-extend the value, while
+ *RVV1.0 sign-extend the value.
+ */
+static void load_element_th(TCGv_i64 dest, TCGv_ptr base,
+int ofs, int sew)
+{
+switch (sew) {
+case MO_8:
+tcg_gen_ld8u_i64(dest, base, ofs);
+break;
+case MO_16:
+tcg_gen_ld16u_i64(dest, base, ofs);
+break;
+case MO_32:
+tcg_gen_ld32u_i64(dest, base, ofs);
+break;
+case MO_64:
+tcg_gen_ld_i64(dest, base, ofs);
+break;
+default:
+g_assert_not_reached();
+break;
+}
+}
+
+/* Load idx >= VLMAX ? 0 : vreg[idx] */
+static void th_element_loadx(DisasContext *s, TCGv_i64 dest,
+  int vreg, TCGv idx, int vlmax)
+{
+TCGv_i32 ofs = tcg_temp_new_i32();
+TCGv_ptr base = tcg_temp_new_ptr();
+TCGv_i64 t_idx = tcg_temp_new_i64();
+TCGv_i64 t_vlmax, t_zero;
+
+/*
+ * Mask the index to the length so that we do
+ * not produce an out-of-range load.
+ */
+tcg_gen_trunc_tl_i32(ofs, idx);
+tcg_gen_andi_i32(ofs, ofs, vlmax - 1);
+
+/* Convert the index to an offset. */
+endian_adjust(ofs, s->sew);
+tcg_gen_shli_i32(ofs, ofs, s->sew);
+
+/* Convert the index to a pointer. */
+tcg_gen_ext_i32_ptr(base, ofs);
+tcg_gen_add_ptr(base, base, tcg_env);
+
+/* Perform the load. */
+load_element_th(dest, base,
+vreg_ofs(s, vreg), s->sew);
+
+/* Flush out-of-range indexing to zero.  */
+t_vlmax = tcg_constant_i64(vlmax);
+t_zero = tcg_constant_i64(0);
+tcg_gen_extu_tl_i64(t_idx, idx);
+
+tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
+t_vlmax, dest, t_zero);
+
+}
+/*
+ * This function is almost the copy of vec_element_loadi, except
+ * we just change the function name to decouple and delete the
+ * unused parameter.
+ * We delete the arg "bool sign", because XTheadVector always
+ * zero-extend the value.
+ */
+static void th_element_loadi(DisasContext *s, TCGv_i64 dest,
+  int vreg, int idx)
+{
+load_element_th(dest, tcg_env, endian_ofs(s, vreg, idx), s->sew);
+}
+
+/*
+ * Compared to trans_vmv_x_s, th.vext.x.v can transfer any element
+ * in a vector register to a general register, while vmv.x.s can only
+ * transfer the first element in a vector register to a general register.
+ *
+ * So we use th_element_loadx to load the element. And we use th_element_loadi
+ * to deal with the special case when rs1 == 0, to accelerate.
+ */
+static bool trans_th_vext_x_v(DisasContext *s, arg_r *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s)) {
+TCGv_i64 tmp = tcg_temp_new_i64();
+TCGv dest = dest_gpr(s, a->rd);
+
+if (a->rs1 == 0) {
+/* Special case vmv.x.s rd, vs2. */
+th_element_loadi(s, tmp, a->rs2, 0);
+} else {
+/* This instruction ignores LMUL and vector register groups */
+int vlmax = s->cfg_ptr->vlenb >> s->sew;
+th_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
+}
+
+tcg_gen_trunc_i64_tl(dest, tmp);
+gen_set_gpr(s, a->rd, dest);
+tcg_gen_movi_tl(cpu_vstart, 0);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
+/* Integer Scalar Move Instruction */
+
+static void th_element_storei(DisasContext *s, int vreg,
+  int idx, TCGv_i64 val)
+{
+vec_element_storei(s, vreg, idx, val);
+}
+/* vmv.s.x vd, rs1 # vd[0] = rs1 */
+static bool trans_th_vmv_s_x(DisasContext *s, arg_th_vmv_s_x *a)
+{
+if (require_xtheadvector(s) &

[PATCH 59/65] target/riscv: Add vector element index instruction for XTheadVector

2024-04-12 Thread Huang Tao
The instruction has the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  5 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 27 ++-
 target/riscv/xtheadvector_helper.c| 26 ++
 3 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a1c85e5254..fe264621ff 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2311,3 +2311,8 @@ DEF_HELPER_5(th_viota_m_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_viota_m_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_viota_m_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_viota_m_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_4(th_vid_v_b, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vid_v_h, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vid_v_w, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vid_v_d, void, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 93f4ee4a12..9a0ea606ab 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2562,13 +2562,38 @@ static bool trans_th_viota_m(DisasContext *s, 
arg_th_viota_m *a)
 return false;
 }
 
+/* Vector Element Index Instruction */
+static bool trans_th_vid_v(DisasContext *s, arg_th_vid_v *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_overlap_mask(s, a->rd, a->vm, false)) {
+uint32_t data = 0;
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+static gen_helper_gvec_2_ptr * const fns[4] = {
+gen_helper_th_vid_v_b, gen_helper_th_vid_v_h,
+gen_helper_th_vid_v_w, gen_helper_th_vid_v_d,
+};
+tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   tcg_env, s->cfg_ptr->vlenb,
+   s->cfg_ptr->vlenb,
+   data, fns[s->sew]);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vid_v)
 TH_TRANS_STUB(th_vext_x_v)
 TH_TRANS_STUB(th_vmv_s_x)
 TH_TRANS_STUB(th_vfmv_f_s)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index b0ddb3b307..0743d57b12 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3652,3 +3652,29 @@ GEN_TH_VIOTA_M(th_viota_m_b, uint8_t, H1, clearb_th)
 GEN_TH_VIOTA_M(th_viota_m_h, uint16_t, H2, clearh_th)
 GEN_TH_VIOTA_M(th_viota_m_w, uint32_t, H4, clearl_th)
 GEN_TH_VIOTA_M(th_viota_m_d, uint64_t, H8, clearq_th)
+
+/* Vector Element Index Instruction */
+#define GEN_TH_VID_V(NAME, ETYPE, H, CLEAR_FN)\
+void HELPER(NAME)(void *vd, void *v0, CPURISCVState *env, uint32_t desc)  \
+{ \
+uint32_t mlen = th_mlen(desc);\
+uint32_t vlmax = (env_archcpu(env)->cfg.vlenb << 3) / mlen;   \
+uint32_t vm = th_vm(desc);\
+uint32_t vl = env->vl;\
+int i;\
+  \
+VSTART_CHECK_EARLY_EXIT(env); \
+for (i = env->vstart; i < vl; i++) {  \
+if (!vm && !th_elem_mask(v0, mlen, i)) {  \
+continue; \
+} \
+*((ETYPE *)vd + H(i)) = i;\
+} \
+env->vstart = 0;  \
+CLEAR_FN(vd, vl, vl * sizeof(ETYPE), vlmax * sizeof(ETYPE));  \
+}
+
+GEN_TH_VID_V(th_vid_v_b, uint8_t, H1, clearb_th)
+GEN_TH_VID_V(th_vid_v_h, uint16_t, H2, clearh_th)
+GEN_TH_VID_V(th_vid_v_w, uint32_t, H4, clearl_th)
+GEN_TH_VID_V(th_vid_v_d, uint64_t, H8, clearq_th)
-- 
2.44.0




[PATCH 58/65] target/riscv: Add vector iota instruction for XTheadVector

2024-04-12 Thread Huang Tao
The instruction has the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  5 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 29 +-
 target/riscv/xtheadvector_helper.c| 30 +++
 3 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 90a1ff2601..a1c85e5254 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2306,3 +2306,8 @@ DEF_HELPER_4(th_vmfirst_m, tl, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vmsbf_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vmsif_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vmsof_m, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(th_viota_m_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_viota_m_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_viota_m_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_viota_m_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d41c691c31..93f4ee4a12 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2534,13 +2534,40 @@ GEN_M_TRANS_TH(th_vmsbf_m)
 GEN_M_TRANS_TH(th_vmsif_m)
 GEN_M_TRANS_TH(th_vmsof_m)
 
+/* Vector Iota Instruction */
+static bool trans_th_viota_m(DisasContext *s, arg_th_viota_m *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_overlap_group(a->rd, 1 << s->lmul, a->rs2, 1) &&
+(a->vm != 0 || a->rd != 0) &&
+s->vstart_eq_zero) {
+uint32_t data = 0;
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+static gen_helper_gvec_3_ptr * const fns[4] = {
+gen_helper_th_viota_m_b, gen_helper_th_viota_m_h,
+gen_helper_th_viota_m_w, gen_helper_th_viota_m_d,
+};
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs2), tcg_env,
+   s->cfg_ptr->vlenb,
+   s->cfg_ptr->vlenb, data, fns[s->sew]);
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_viota_m)
 TH_TRANS_STUB(th_vid_v)
 TH_TRANS_STUB(th_vext_x_v)
 TH_TRANS_STUB(th_vmv_s_x)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index d4f1665bf3..b0ddb3b307 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3622,3 +3622,33 @@ void HELPER(th_vmsof_m)(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 {
 vmsetm(vd, v0, vs2, env, desc, ONLY_FIRST);
 }
+
+/* Vector Iota Instruction */
+#define GEN_TH_VIOTA_M(NAME, ETYPE, H, CLEAR_FN)  \
+void HELPER(NAME)(void *vd, void *v0, void *vs2, CPURISCVState *env,  \
+  uint32_t desc)  \
+{ \
+uint32_t mlen = th_mlen(desc);\
+uint32_t vlmax = (env_archcpu(env)->cfg.vlenb << 3) / mlen;   \
+uint32_t vm = th_vm(desc);\
+uint32_t vl = env->vl;\
+uint32_t sum = 0; \
+int i;\
+  \
+for (i = env->vstart; i < vl; i++) {  \
+if (!vm && !th_elem_mask(v0, mlen, i)) {  \
+continue; \
+} \
+*((ETYPE *)vd + H(i)) = sum;  \
+if (th_elem_mask(vs2, mlen, i)) { \
+sum++;\
+} \
+} \
+env->vstart = 0;  \
+CLEAR_FN(vd, vl, vl 

[PATCH 57/65] target/riscv: Add set-X-first mask bit instructrions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  4 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 36 ++-
 target/riscv/xtheadvector_helper.c| 64 +++
 3 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 2379a3431d..90a1ff2601 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2302,3 +2302,7 @@ DEF_HELPER_6(th_vmxnor_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_4(th_vmpopc_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_4(th_vmfirst_m, tl, ptr, ptr, env, i32)
+
+DEF_HELPER_5(th_vmsbf_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vmsif_m, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vmsof_m, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 45554c38fb..d41c691c31 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2500,6 +2500,39 @@ static bool trans_th_vmfirst_m(DisasContext *s, arg_rmr 
*a)
 }
 return false;
 }
+/*
+ * th.vmsbf.m set-before-first mask bit
+ * th.vmsif.m set-including-first mask bit
+ * th.vmsof.m set-only-first mask bit
+ */
+#define GEN_M_TRANS_TH(NAME)   \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (require_xtheadvector(s) && \
+vext_check_isa_ill(s) &&   \
+(a->rd != a->rs2) &&   \
+s->vstart_eq_zero) {   \
+uint32_t data = 0; \
+gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2),\
+   tcg_env, s->cfg_ptr->vlenb, \
+   s->cfg_ptr->vlenb,  \
+   data, fn);  \
+finalize_rvv_inst(s);  \
+return true;   \
+}  \
+return false;  \
+}
+
+GEN_M_TRANS_TH(th_vmsbf_m)
+GEN_M_TRANS_TH(th_vmsif_m)
+GEN_M_TRANS_TH(th_vmsof_m)
 
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
@@ -2507,9 +2540,6 @@ static bool trans_##NAME(DisasContext *s, arg_##NAME *a)  
 \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmsbf_m)
-TH_TRANS_STUB(th_vmsif_m)
-TH_TRANS_STUB(th_vmsof_m)
 TH_TRANS_STUB(th_viota_m)
 TH_TRANS_STUB(th_vid_v)
 TH_TRANS_STUB(th_vext_x_v)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 1860e47f4f..d4f1665bf3 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3558,3 +3558,67 @@ target_ulong HELPER(th_vmfirst_m)(void *v0, void *vs2, 
CPURISCVState *env,
 env->vstart = 0;
 return -1LL;
 }
+
+enum set_mask_type_th {
+ONLY_FIRST = 1,
+INCLUDE_FIRST,
+BEFORE_FIRST,
+};
+
+static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
+   uint32_t desc, enum set_mask_type_th type)
+{
+uint32_t mlen = th_mlen(desc);
+uint32_t vlmax = (env_archcpu(env)->cfg.vlenb << 3) / mlen;
+uint32_t vm = th_vm(desc);
+uint32_t vl = env->vl;
+int i;
+bool first_mask_bit = false;
+
+for (i = env->vstart; i < vl; i++) {
+if (!vm && !th_elem_mask(v0, mlen, i)) {
+continue;
+}
+/* write a zero to all following active elements */
+if (first_mask_bit) {
+th_set_elem_mask(vd, mlen, i, 0);
+continue;
+}
+if (th_elem_mask(vs2, mlen, i)) {
+first_mask_bit = true;
+if (type == BEFORE_FIRST) {
+th_set_elem_mask(vd, mlen, i, 0);
+} else {
+th_set_elem_mask(vd, mlen, i, 1);
+}
+   

[PATCH 56/65] target/riscv: Add th.vmfirst.m for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  2 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 31 ++-
 target/riscv/xtheadvector_helper.c| 20 
 3 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6ddecbbe65..2379a3431d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2300,3 +2300,5 @@ DEF_HELPER_6(th_vmornot_mm, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(th_vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_4(th_vmpopc_m, tl, ptr, ptr, env, i32)
+
+DEF_HELPER_4(th_vmfirst_m, tl, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index f8e8b321e4..45554c38fb 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2471,13 +2471,42 @@ static bool trans_th_vmpopc_m(DisasContext *s, arg_rmr 
*a)
 return false;
 }
 
+/* vmfirst find-first-set mask bit */
+static bool trans_th_vmfirst_m(DisasContext *s, arg_rmr *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s)) {
+TCGv_ptr src2, mask;
+TCGv dst;
+TCGv_i32 desc;
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+
+mask = tcg_temp_new_ptr();
+src2 = tcg_temp_new_ptr();
+dst = dest_gpr(s, a->rd);
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
+  s->cfg_ptr->vlenb, data));
+
+tcg_gen_addi_ptr(src2, tcg_env, vreg_ofs(s, a->rs2));
+tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
+
+gen_helper_th_vmfirst_m(dst, mask, src2, tcg_env, desc);
+gen_set_gpr(s, a->rd, dst);
+
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmfirst_m)
 TH_TRANS_STUB(th_vmsbf_m)
 TH_TRANS_STUB(th_vmsif_m)
 TH_TRANS_STUB(th_vmsof_m)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index ba1ab0435d..1860e47f4f 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3538,3 +3538,23 @@ target_ulong HELPER(th_vmpopc_m)(void *v0, void *vs2, 
CPURISCVState *env,
 env->vstart = 0;
 return cnt;
 }
+
+/* vmfirst find-first-set mask bit*/
+target_ulong HELPER(th_vmfirst_m)(void *v0, void *vs2, CPURISCVState *env,
+   uint32_t desc)
+{
+uint32_t mlen = th_mlen(desc);
+uint32_t vm = th_vm(desc);
+uint32_t vl = env->vl;
+int i;
+
+for (i = env->vstart; i < vl; i++) {
+if (vm || th_elem_mask(v0, mlen, i)) {
+if (th_elem_mask(vs2, mlen, i)) {
+return i;
+}
+}
+}
+env->vstart = 0;
+return -1LL;
+}
-- 
2.44.0




[PATCH 55/65] target/riscv: Add vector mask population count vmpopc for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  2 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 31 ++-
 target/riscv/xtheadvector_helper.c| 21 +
 3 files changed, 53 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 7d992ac3b1..6ddecbbe65 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2298,3 +2298,5 @@ DEF_HELPER_6(th_vmor_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(th_vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_4(th_vmpopc_m, tl, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index e9fa7f1ae2..f8e8b321e4 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2441,13 +2441,42 @@ GEN_MM_TRANS_TH(th_vmnor_mm)
 GEN_MM_TRANS_TH(th_vmornot_mm)
 GEN_MM_TRANS_TH(th_vmxnor_mm)
 
+/* Vector mask population count vmpopc */
+static bool trans_th_vmpopc_m(DisasContext *s, arg_rmr *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+s->vstart_eq_zero) {
+TCGv_ptr src2, mask;
+TCGv dst;
+TCGv_i32 desc;
+uint32_t data = 0;
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+
+mask = tcg_temp_new_ptr();
+src2 = tcg_temp_new_ptr();
+dst = dest_gpr(s, a->rd);
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
+  s->cfg_ptr->vlenb, data));
+
+tcg_gen_addi_ptr(src2, tcg_env, vreg_ofs(s, a->rs2));
+tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
+
+gen_helper_th_vmpopc_m(dst, mask, src2, tcg_env, desc);
+gen_set_gpr(s, a->rd, dst);
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmpopc_m)
 TH_TRANS_STUB(th_vmfirst_m)
 TH_TRANS_STUB(th_vmsbf_m)
 TH_TRANS_STUB(th_vmsif_m)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index b3f445eeb5..ba1ab0435d 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3517,3 +3517,24 @@ GEN_TH_MASK_VV(th_vmor_mm, TH_OR)
 GEN_TH_MASK_VV(th_vmnor_mm, TH_NOR)
 GEN_TH_MASK_VV(th_vmornot_mm, TH_ORNOT)
 GEN_TH_MASK_VV(th_vmxnor_mm, TH_XNOR)
+
+/* Vector mask population count vmpopc */
+target_ulong HELPER(th_vmpopc_m)(void *v0, void *vs2, CPURISCVState *env,
+  uint32_t desc)
+{
+target_ulong cnt = 0;
+uint32_t mlen = th_mlen(desc);
+uint32_t vm = th_vm(desc);
+uint32_t vl = env->vl;
+int i;
+
+for (i = env->vstart; i < vl; i++) {
+if (vm || th_elem_mask(v0, mlen, i)) {
+if (th_elem_mask(vs2, mlen, i)) {
+cnt++;
+}
+}
+}
+env->vstart = 0;
+return cnt;
+}
-- 
2.44.0




[PATCH 54/65] target/riscv: Add mask-register logical instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add mask-register logical instructions to show the way
we implement XTheadVector mask instructions.
XTheadVector mask-register logical instructions diff from RVV1.0 in the
following points:
1. Different mask reg layout. For mask bit of element i, XTheadVector locates it
   in bit[mlen], while RVV1.0 locates it in bit[i].

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  9 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 44 +++
 target/riscv/xtheadvector_helper.c| 42 ++
 3 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c39ee9a8e8..7d992ac3b1 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2289,3 +2289,12 @@ DEF_HELPER_6(th_vfredmin_vs_d, void, ptr, ptr, ptr, ptr, 
env, i32)
 
 DEF_HELPER_6(th_vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vmand_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmandnot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmxor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index b71875700b..e9fa7f1ae2 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2405,20 +2405,48 @@ GEN_OPFVV_TRANS_TH(th_vfredmin_vs, reduction_check_th)
 /* Vector Widening Floating-Point Reduction Instructions */
 GEN_OPFVV_WIDEN_TRANS_TH(th_vfwredsum_vs, reduction_check_th)
 
+/*
+ * Vector Mask Operations
+ */
+
+/* Vector Mask-Register Logical Instructions */
+#define GEN_MM_TRANS_TH(NAME)  \
+static bool trans_##NAME(DisasContext *s, arg_r *a)\
+{  \
+if (require_xtheadvector(s) && \
+vext_check_isa_ill(s)) {   \
+uint32_t data = 0; \
+gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs1),\
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   s->cfg_ptr->vlenb,  \
+   s->cfg_ptr->vlenb, data, fn);   \
+finalize_rvv_inst(s);  \
+return true;   \
+}  \
+return false;  \
+}
+
+GEN_MM_TRANS_TH(th_vmand_mm)
+GEN_MM_TRANS_TH(th_vmnand_mm)
+GEN_MM_TRANS_TH(th_vmandnot_mm)
+GEN_MM_TRANS_TH(th_vmxor_mm)
+GEN_MM_TRANS_TH(th_vmor_mm)
+GEN_MM_TRANS_TH(th_vmnor_mm)
+GEN_MM_TRANS_TH(th_vmornot_mm)
+GEN_MM_TRANS_TH(th_vmxnor_mm)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmand_mm)
-TH_TRANS_STUB(th_vmnand_mm)
-TH_TRANS_STUB(th_vmandnot_mm)
-TH_TRANS_STUB(th_vmxor_mm)
-TH_TRANS_STUB(th_vmor_mm)
-TH_TRANS_STUB(th_vmnor_mm)
-TH_TRANS_STUB(th_vmornot_mm)
-TH_TRANS_STUB(th_vmxnor_mm)
 TH_TRANS_STUB(th_vmpopc_m)
 TH_TRANS_STUB(th_vmfirst_m)
 TH_TRANS_STUB(th_vmsbf_m)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 8953207630..b3f445eeb5 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3475,3 +3475,45 @@ static uint64_t fwadd32(uint64_t a, uint32_t b, 
float_status *s)
 /* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
 GEN_TH_FRED(th_vfwredsum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16, clearl_th)
 GEN_TH_FRED(th_vfwredsum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32, clearq_th)
+
+/*
+ * Vector Mask Operations
+ */
+/* Vector Mask-Register Logical Instructions */
+#define GEN_TH_MASK_VV(NAME, OP) \
+v

[PATCH 53/65] target/riscv: Add widening floating-point reduction instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h|  3 +++
 target/riscv/insn_trans/trans_xtheadvector.c.inc |  4 +++-
 target/riscv/xtheadvector_helper.c   | 16 
 3 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 24bb8479a4..c39ee9a8e8 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2286,3 +2286,6 @@ DEF_HELPER_6(th_vfredmax_vs_d, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(th_vfredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index f77d76dc5e..b71875700b 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2402,13 +2402,15 @@ GEN_OPFVV_TRANS_TH(th_vfredsum_vs, reduction_check_th)
 GEN_OPFVV_TRANS_TH(th_vfredmax_vs, reduction_check_th)
 GEN_OPFVV_TRANS_TH(th_vfredmin_vs, reduction_check_th)
 
+/* Vector Widening Floating-Point Reduction Instructions */
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwredsum_vs, reduction_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfwredsum_vs)
 TH_TRANS_STUB(th_vmand_mm)
 TH_TRANS_STUB(th_vmnand_mm)
 TH_TRANS_STUB(th_vmandnot_mm)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 2a241aed65..8953207630 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3459,3 +3459,19 @@ GEN_TH_FRED(th_vfredmin_vs_w, uint32_t, uint32_t, H4, H4,
 float32_minnum, clearl_th)
 GEN_TH_FRED(th_vfredmin_vs_d, uint64_t, uint64_t, H8, H8,
 float64_minnum, clearq_th)
+
+/* Vector Widening Floating-Point Add functions */
+static uint32_t fwadd16(uint32_t a, uint16_t b, float_status *s)
+{
+return float32_add(a, float16_to_float32(b, true, s), s);
+}
+
+static uint64_t fwadd32(uint64_t a, uint32_t b, float_status *s)
+{
+return float64_add(a, float32_to_float64(b, s), s);
+}
+
+/* Vector Widening Floating-Point Reduction Instructions */
+/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
+GEN_TH_FRED(th_vfwredsum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16, clearl_th)
+GEN_TH_FRED(th_vfwredsum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32, clearq_th)
-- 
2.44.0




[PATCH 52/65] target/riscv: Add single-width floating-point reduction instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 10 
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  8 +--
 target/riscv/xtheadvector_helper.c| 49 +++
 3 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 2cd4a7401f..24bb8479a4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2276,3 +2276,13 @@ DEF_HELPER_6(th_vwredsumu_vs_w, void, ptr, ptr, ptr, 
ptr, env, i32)
 DEF_HELPER_6(th_vwredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vfredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 8a1f0e1e74..f77d76dc5e 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2397,15 +2397,17 @@ GEN_OPIVV_TRANS_TH(th_vredxor_vs, reduction_check_th)
 GEN_OPIVV_WIDEN_TRANS_TH(th_vwredsum_vs, reduction_check_th)
 GEN_OPIVV_WIDEN_TRANS_TH(th_vwredsumu_vs, reduction_check_th)
 
+/* Vector Single-Width Floating-Point Reduction Instructions */
+GEN_OPFVV_TRANS_TH(th_vfredsum_vs, reduction_check_th)
+GEN_OPFVV_TRANS_TH(th_vfredmax_vs, reduction_check_th)
+GEN_OPFVV_TRANS_TH(th_vfredmin_vs, reduction_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfredsum_vs)
-TH_TRANS_STUB(th_vfredmin_vs)
-TH_TRANS_STUB(th_vfredmax_vs)
 TH_TRANS_STUB(th_vfwredsum_vs)
 TH_TRANS_STUB(th_vmand_mm)
 TH_TRANS_STUB(th_vmnand_mm)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index f802b2c5ac..2a241aed65 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3410,3 +3410,52 @@ GEN_TH_RED(th_vwredsum_vs_w, int64_t, int32_t, H8, H4, 
TH_ADD, clearq_th)
 GEN_TH_RED(th_vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, TH_ADD, clearh_th)
 GEN_TH_RED(th_vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, TH_ADD, clearl_th)
 GEN_TH_RED(th_vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, TH_ADD, clearq_th)
+
+/* Vector Single-Width Floating-Point Reduction Instructions */
+#define GEN_TH_FRED(NAME, TD, TS2, HD, HS2, OP, CLEAR_FN)  \
+void HELPER(NAME)(void *vd, void *v0, void *vs1,   \
+  void *vs2, CPURISCVState *env,   \
+  uint32_t desc)   \
+{  \
+uint32_t mlen = th_mlen(desc); \
+uint32_t vm = th_vm(desc); \
+uint32_t vl = env->vl; \
+uint32_t i;\
+uint32_t tot = env_archcpu(env)->cfg.vlenb;\
+TD s1 =  *((TD *)vs1 + HD(0)); \
+   \
+for (i = env->vstart; i < vl; i++) {   \
+TS2 s2 = *((TS2 *)vs2 + HS2(i));   \
+if (!vm && !th_elem_mask(v0, mlen, i)) {   \
+continue;  \
+}  \
+s1 = OP(s1, (TD)s2, >fp_status);  \
+}  \
+*((TD *)vd + HD(0)) = s1;  \
+env->vstart = 0;   \
+CLEAR_FN(vd, 1, sizeof(TD), tot);  \
+}
+
+/* Unordered sum */
+GEN_TH_FRED(th_vfredsum_vs_h, uint16_t, uint16_t, H2, H2,
+float16_add, clearh_th)
+GEN_TH_FRED(th_vfredsum_vs_w, uint32_t, uint32_t, H4, H4,
+float32_add, clearl_th)
+GEN_TH_FRED(th_vfredsum_vs_d, uint64_t, uint64_t, H8, H8,
+float64_add, clearq_th)
+
+/* Maximum value */
+GEN_TH_FRED(th_vfredmax_vs_h, uint16_t, uint16_t, H2, H2,
+   

[PATCH 51/65] target/riscv: Add widening integer reduction instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h|  7 +++
 target/riscv/insn_trans/trans_xtheadvector.c.inc |  6 --
 target/riscv/xtheadvector_helper.c   | 11 +++
 3 files changed, 22 insertions(+), 2 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 84d2921945..2cd4a7401f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2269,3 +2269,10 @@ DEF_HELPER_6(th_vredxor_vs_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(th_vredxor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vredxor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vredxor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vwredsumu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwredsumu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwredsumu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 1fd66353ed..8a1f0e1e74 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2393,14 +2393,16 @@ GEN_OPIVV_TRANS_TH(th_vredand_vs, reduction_check_th)
 GEN_OPIVV_TRANS_TH(th_vredor_vs, reduction_check_th)
 GEN_OPIVV_TRANS_TH(th_vredxor_vs, reduction_check_th)
 
+/* Vector Widening Integer Reduction Instructions */
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwredsum_vs, reduction_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwredsumu_vs, reduction_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vwredsumu_vs)
-TH_TRANS_STUB(th_vwredsum_vs)
 TH_TRANS_STUB(th_vfredsum_vs)
 TH_TRANS_STUB(th_vfredmin_vs)
 TH_TRANS_STUB(th_vfredmax_vs)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index d041a81150..f802b2c5ac 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3399,3 +3399,14 @@ GEN_TH_RED(th_vredxor_vs_b, int8_t, int8_t, H1, H1, 
TH_XOR, clearb_th)
 GEN_TH_RED(th_vredxor_vs_h, int16_t, int16_t, H2, H2, TH_XOR, clearh_th)
 GEN_TH_RED(th_vredxor_vs_w, int32_t, int32_t, H4, H4, TH_XOR, clearl_th)
 GEN_TH_RED(th_vredxor_vs_d, int64_t, int64_t, H8, H8, TH_XOR, clearq_th)
+
+/* Vector Widening Integer Reduction Instructions */
+/* signed sum reduction into double-width accumulator */
+GEN_TH_RED(th_vwredsum_vs_b, int16_t, int8_t, H2, H1, TH_ADD, clearh_th)
+GEN_TH_RED(th_vwredsum_vs_h, int32_t, int16_t, H4, H2, TH_ADD, clearl_th)
+GEN_TH_RED(th_vwredsum_vs_w, int64_t, int32_t, H8, H4, TH_ADD, clearq_th)
+
+/* Unsigned sum reduction into double-width accumulator */
+GEN_TH_RED(th_vwredsumu_vs_b, uint16_t, uint8_t, H2, H1, TH_ADD, clearh_th)
+GEN_TH_RED(th_vwredsumu_vs_h, uint32_t, uint16_t, H4, H2, TH_ADD, clearl_th)
+GEN_TH_RED(th_vwredsumu_vs_w, uint64_t, uint32_t, H8, H4, TH_ADD, clearq_th)
-- 
2.44.0




[PATCH 50/65] target/riscv: Add single-width integer reduction instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add single-width integer reduction instructions to show
the way we implement XTheadVector reduction instructions.
XTheadVector single-width integer reduction instructions diff from RVV1.0
in the following points:
1. Different mask reg layout. For mask bit of element i, XTheadVector locates it
   in bit[mlen], while RVV1.0 locates it in bit[i].
2. Different tail elements process policy. XTheadVector clear the tail elements.
   While RVV1.0 has vta to set the processing policy, keeping value or overwrite
   it with 1s.
3. Different check policy. XTheadVector does not have fractional lmul, so we can
   use simpler check function.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 33 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 27 +--
 target/riscv/xtheadvector_helper.c| 76 +++
 3 files changed, 128 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c666a5a020..84d2921945 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2236,3 +2236,36 @@ DEF_HELPER_5(th_vfncvt_f_x_v_h, void, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_5(th_vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmaxu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmaxu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmaxu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmaxu_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmax_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredminu_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredminu_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredminu_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredminu_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmin_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredand_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredand_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredand_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredand_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredor_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredxor_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredxor_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredxor_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vredxor_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d2734c007a..1fd66353ed 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2374,20 +2374,31 @@ GEN_OPFV_NARROW_TRANS_TH(th_vfncvt_f_xu_v)
 GEN_OPFV_NARROW_TRANS_TH(th_vfncvt_f_x_v)
 GEN_OPFV_NARROW_TRANS_TH(th_vfncvt_f_f_v)
 
+/*
+ * Vector Reduction Operations
+ */
+
+/* Vector Single-Width Integer Reduction Instructions */
+static bool reduction_check_th(DisasContext *s, arg_rmrr *a)
+{
+return vext_check_isa_ill(s) && th_check_reg(s, a->rs2, false);
+}
+
+GEN_OPIVV_TRANS_TH(th_vredsum_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredmaxu_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredmax_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredminu_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredmin_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredand_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredor_vs, reduction_check_th)
+GEN_OPIVV_TRANS_TH(th_vredxor_vs, reduction_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vredsum_vs)
-TH_TRANS_STUB(th_vredand_vs)
-TH_TRANS_STUB(th_vredor_vs)
-TH_TRANS_STUB(th_vredxor_vs)
-TH

[PATCH 49/65] target/riscv: Add narrowing floating-point/integer type-convert instructions for XTheadVector

2024-04-12 Thread Huang Tao
Compared to RVV1.0, XTheadVector lacks .rtz and .rod instructions, which 
specify the
rounding mode.
Except of lack of similar instructions, the instructions have the same function
as RVV1.0. Overall there are only general differences between XTheadVector and 
RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 94 ++-
 target/riscv/vector_helper.c  |  5 +-
 target/riscv/vector_internals.h   |  3 +
 target/riscv/xtheadvector_helper.c| 41 
 5 files changed, 147 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e2d737c9c4..c666a5a020 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2223,3 +2223,16 @@ DEF_HELPER_5(th_vfwcvt_f_x_v_h, void, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_5(th_vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(th_vfncvt_xu_f_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_x_f_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 72643facb1..d2734c007a 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2285,17 +2285,101 @@ GEN_OPFV_WIDEN_TRANS_TH(th_vfwcvt_xu_f_v)
 GEN_OPFV_WIDEN_TRANS_TH(th_vfwcvt_x_f_v)
 GEN_OPFV_WIDEN_TRANS_TH(th_vfwcvt_f_f_v)
 
+/* Narrowing Floating-Point/Integer Type-Convert Instructions */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised
+ */
+static bool opfv_narrow_check_th(DisasContext *s, arg_rmr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, false) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, true) &&
+th_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
+   2 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
+}
+
+static bool opxfv_narrow_check_th(DisasContext *s, arg_rmr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, false) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, true) &&
+th_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
+   2 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3));
+}
+
+#define GEN_OPXFV_NARROW_TRANS_TH(NAME)\
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (opxfv_narrow_check_th(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[3] = {\
+gen_helper_##NAME##_b, \
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+}; \
+gen_set_rm(s, RISCV_FRM_DYN);  \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   s->cfg_ptr->vlenb,  

[PATCH 48/65] target/riscv: Add widening floating-point/integer type-convert instructions for XTheadVector

2024-04-12 Thread Huang Tao
Compared to RVV1.0, XTheadVector lacks .rtz instructions, which specify the
rounding mode of rounding to zero.
Except of lack of similar instructions, the instructions have the same function
as RVV1.0. Overall there are only general differences between XTheadVector and 
RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 93 ++-
 target/riscv/vector_helper.c  |  5 +-
 target/riscv/vector_internals.h   |  3 +
 target/riscv/xtheadvector_helper.c| 44 +
 5 files changed, 149 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 18640c4a1e..e2d737c9c4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2210,3 +2210,16 @@ DEF_HELPER_5(th_vfcvt_f_xu_v_d, void, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_5(th_vfcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfcvt_f_x_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(th_vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 27a06c2cac..72643facb1 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2197,17 +2197,100 @@ GEN_OPFV_TRANS_TH(th_vfcvt_x_f_v, opfv_check_th)
 GEN_OPFV_TRANS_TH(th_vfcvt_f_xu_v, opfv_check_th)
 GEN_OPFV_TRANS_TH(th_vfcvt_f_x_v, opfv_check_th)
 
+/* Widening Floating-Point/Integer Type-Convert Instructions */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised
+ */
+static bool opfv_widen_check_th(DisasContext *s, arg_rmr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, true) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_overlap_group(a->rd, 2 << s->lmul, a->rs2,
+   1 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
+}
+
+static bool opfxv_widen_check_th(DisasContext *s, arg_rmr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, true) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_overlap_group(a->rd, 2 << s->lmul, a->rs2,
+   1 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3));
+}
+
+#define GEN_OPFXV_WIDEN_TRANS_TH(NAME) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (opfxv_widen_check_th(s, a)) {  \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[3] = {\
+gen_helper_##NAME##_b, \
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+}; \
+gen_set_rm(s, RISCV_FRM_DYN);  \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   

[PATCH 47/65] target/riscv: Add single-width floating-point/integer type-convert instructions for XTheadVector

2024-04-12 Thread Huang Tao
Compared to RVV1.0, XTheadVector lacks .rtz instructions, which specify the
rounding mode of rounding to zero.
Except of lack of similar instructions, the instructions have the same function
as RVV1.0. Overall there are only general differences between XTheadVector and 
RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 10 +++---
 target/riscv/xtheadvector_helper.c| 33 +++
 3 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 886655899e..18640c4a1e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2197,3 +2197,16 @@ DEF_HELPER_5(th_vfclass_v_d, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(th_vfmerge_vfm_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfmerge_vfm_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfmerge_vfm_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_5(th_vfcvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_xu_f_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_x_f_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_xu_v_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfcvt_f_x_v_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 8e928febb7..27a06c2cac 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2191,16 +2191,18 @@ static bool trans_th_vfmv_v_f(DisasContext *s, 
arg_th_vfmv_v_f *a)
 return false;
 }
 
+/* Single-Width Floating-Point/Integer Type-Convert Instructions */
+GEN_OPFV_TRANS_TH(th_vfcvt_xu_f_v, opfv_check_th)
+GEN_OPFV_TRANS_TH(th_vfcvt_x_f_v, opfv_check_th)
+GEN_OPFV_TRANS_TH(th_vfcvt_f_xu_v, opfv_check_th)
+GEN_OPFV_TRANS_TH(th_vfcvt_f_x_v, opfv_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfcvt_xu_f_v)
-TH_TRANS_STUB(th_vfcvt_x_f_v)
-TH_TRANS_STUB(th_vfcvt_f_xu_v)
-TH_TRANS_STUB(th_vfcvt_f_x_v)
 TH_TRANS_STUB(th_vfwcvt_xu_f_v)
 TH_TRANS_STUB(th_vfwcvt_x_f_v)
 TH_TRANS_STUB(th_vfwcvt_f_xu_v)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index e31e13dff3..7e98c1ead2 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3205,3 +3205,36 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2, \
 GEN_VFMERGE_VF_TH(th_vfmerge_vfm_h, int16_t, H2, clearh_th)
 GEN_VFMERGE_VF_TH(th_vfmerge_vfm_w, int32_t, H4, clearl_th)
 GEN_VFMERGE_VF_TH(th_vfmerge_vfm_d, int64_t, H8, clearq_th)
+
+/* Single-Width Floating-Point/Integer Type-Convert Instructions */
+/* vfcvt.xu.f.v vd, vs2, vm # Convert float to unsigned integer. */
+THCALL(TH_OPFVV1, th_vfcvt_xu_f_v_h, OP_UU_H, H2, H2, float16_to_uint16)
+THCALL(TH_OPFVV1, th_vfcvt_xu_f_v_w, OP_UU_W, H4, H4, float32_to_uint32)
+THCALL(TH_OPFVV1, th_vfcvt_xu_f_v_d, OP_UU_D, H8, H8, float64_to_uint64)
+GEN_TH_V_ENV(th_vfcvt_xu_f_v_h, 2, 2, clearh_th)
+GEN_TH_V_ENV(th_vfcvt_xu_f_v_w, 4, 4, clearl_th)
+GEN_TH_V_ENV(th_vfcvt_xu_f_v_d, 8, 8, clearq_th)
+
+/* vfcvt.x.f.v vd, vs2, vm # Convert float to signed integer. */
+THCALL(TH_OPFVV1, th_vfcvt_x_f_v_h, OP_UU_H, H2, H2, float16_to_int16)
+THCALL(TH_OPFVV1, th_vfcvt_x_f_v_w, OP_UU_W, H4, H4, float32_to_int32)
+THCALL(TH_OPFVV1, th_vfcvt_x_f_v_d, OP_UU_D, H8, H8, float64_to_int64)
+GEN_TH_V_ENV(th_vfcvt_x_f_v_h, 2, 2, clearh_th)
+GEN_TH_V_ENV(th_vfcvt_x_f_v_w, 4, 4, clearl_th)
+GEN_TH_V_ENV(th_vfcvt_x_f_v_d, 8, 8, clearq_th)
+
+/* vfcvt.f.xu.v vd, vs2, vm # Convert unsigned integer to float. */
+THCALL(TH_OPFVV1, th_vfcvt_f_xu_v_h, OP_UU_H, H2, H2, uint16_to_float16)
+THCALL(TH_OPFVV1, th_vfcvt_f_xu_v_w, OP_UU_W, H4, H4, uint32_to_float32)
+THCALL(TH_OPFVV1, th_vfcvt_f_xu_v_d, OP_UU_D, H8, H8, uint64_to_float64)
+GEN_TH_V_ENV(th_vfcvt_f_xu_v_h, 2, 2, clearh_th)
+GEN_TH_V_ENV(th_vfcvt_f_xu_v_w, 4, 4, clearl_th)
+GEN_TH_V_ENV(th_vfcvt_f_xu_v_d, 8, 8, clearq_th)
+
+/* vfcvt.f.x.v vd, vs2, vm # Convert integer to float. */
+THCALL(TH_OPFVV1, th_vfcvt_f_x_v_h, OP_UU_H, H2, H2, int16_to_float16)
+THCALL(TH_OPFVV1, th_vfcvt_f_x_v_w, OP_UU_W, H4, H4, int32_to_float32)
+THCALL(TH_OPFVV1, th_vfcvt_f_x_v_d, OP_UU_D, H8

[PATCH 46/65] target/riscv: Add floating-point classify and merge instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  8 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 51 +++-
 target/riscv/xtheadvector_helper.c| 58 +++
 3 files changed, 114 insertions(+), 3 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 5771a4fa8a..886655899e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2189,3 +2189,11 @@ DEF_HELPER_6(th_vmford_vv_d, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(th_vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_5(th_vfclass_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfclass_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfclass_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vfmerge_vfm_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmerge_vfm_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmerge_vfm_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 1e773c673e..8e928febb7 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2143,15 +2143,60 @@ GEN_OPFVF_TRANS_TH(th_vmfgt_vf, opfvf_cmp_check_th)
 GEN_OPFVF_TRANS_TH(th_vmfge_vf, opfvf_cmp_check_th)
 GEN_OPFVF_TRANS_TH(th_vmford_vf, opfvf_cmp_check_th)
 
+/* Vector Floating-Point Classify Instruction */
+GEN_OPFV_TRANS_TH(th_vfclass_v, opfv_check_th)
+
+/* Vector Floating-Point Merge Instruction */
+GEN_OPFVF_TRANS_TH(th_vfmerge_vfm,  opfvf_check_th)
+
+/* Besides of check function, th_vfmv_v_f just reuse the helper_th_vmv_v_x */
+static bool trans_th_vfmv_v_f(DisasContext *s, arg_th_vfmv_v_f *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+(s->sew != 0)) {
+
+TCGv_i64 t1;
+
+if (s->vl_eq_vlmax) {
+t1 = tcg_temp_new_i64();
+/* NaN-box f[rs1] */
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+tcg_gen_gvec_dup_i64(s->sew, vreg_ofs(s, a->rd),
+ MAXSZ(s), MAXSZ(s), t1);
+} else {
+TCGv_ptr dest;
+TCGv_i32 desc;
+uint32_t data = FIELD_DP32(0, VDATA_TH, LMUL, s->lmul);
+static gen_helper_vmv_vx_th * const fns[3] = {
+gen_helper_th_vmv_v_x_h,
+gen_helper_th_vmv_v_x_w,
+gen_helper_th_vmv_v_x_d,
+};
+
+t1 = tcg_temp_new_i64();
+/* NaN-box f[rs1] */
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+
+dest = tcg_temp_new_ptr();
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
+  s->cfg_ptr->vlenb, data));
+tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, a->rd));
+fns[s->sew - 1](dest, t1, tcg_env, desc);
+}
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfclass_v)
-TH_TRANS_STUB(th_vfmerge_vfm)
-TH_TRANS_STUB(th_vfmv_v_f)
 TH_TRANS_STUB(th_vfcvt_xu_f_v)
 TH_TRANS_STUB(th_vfcvt_x_f_v)
 TH_TRANS_STUB(th_vfcvt_f_xu_v)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 603b34a094..e31e13dff3 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -3147,3 +3147,61 @@ GEN_TH_CMP_VV_ENV(th_vmford_vv_d, uint64_t, H8, 
!float64_unordered_quiet)
 GEN_TH_CMP_VF(th_vmford_vf_h, uint16_t, H2, !float16_unordered_quiet)
 GEN_TH_CMP_VF(th_vmford_vf_w, uint32_t, H4, !float32_unordered_quiet)
 GEN_TH_CMP_VF(th_vmford_vf_d, uint64_t, H8, !float64_unordered_quiet)
+
+/* Vector Floating-Point Classify Instruction */
+#define TH_OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
+OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP)
+
+#define GEN_TH_V(NAME, ESZ, DSZ, CLEAR_FN) \
+void HELPER(NAME)(void *vd, void *v0, void *vs2,   \
+  CPURISCVState *env, uint32_t desc)   \
+{  \
+uint32_t vlmax = th_maxsz(desc) / ESZ; \
+uint32_t mlen = th_mlen(desc); \
+uint32_t vm = th_vm(desc); \
+ui

[PATCH 45/65] target/riscv: Add floating-point compare instructions for XTheadVector

2024-04-12 Thread Huang Tao
There is no similar instruction in RVV1.0 as th.vmford in XTheadVector.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 37 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 49 +++---
 target/riscv/vector_helper.c  | 18 ++--
 target/riscv/vector_internals.h   | 10 ++
 target/riscv/xtheadvector_helper.c| 96 +++
 5 files changed, 189 insertions(+), 21 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 2b9d7fa2b6..5771a4fa8a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2152,3 +2152,40 @@ DEF_HELPER_6(th_vfsgnjn_vf_d, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfsgnjx_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfsgnjx_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfsgnjx_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vmfeq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfeq_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfeq_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmfeq_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfeq_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfeq_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfne_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmflt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfle_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfgt_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfgt_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 1374bad5b9..1e773c673e 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2106,24 +2106,49 @@ GEN_OPFVF_TRANS_TH(th_vfsgnj_vf, opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfsgnjn_vf, opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfsgnjx_vf, opfvf_check_th)
 
+/* Vector Floating-Point Compare Instructions */
+static bool opfvv_cmp_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_reg(s, a->rs1, false) &&
+(s->sew != 0) &&
+((th_check_overlap_group(a->rd, 1, a->rs1, 1 << s->lmul) &&
+  th_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul)) ||
+ (s->lmul == 0)));
+}
+
+GEN_OPFVV_TRANS_TH(th_vmfeq_vv, opfvv_cmp_check_th)
+GEN_OPFVV_TRANS_TH(th_vmfne_vv, opfvv_cmp_check_th)
+GEN_OPFVV_TRANS_TH(th_vmflt_vv, opfvv_cmp_check_th)
+GEN_OPFVV_TRANS_TH(th_vmfle_vv, opfvv_cmp_check_th)
+GEN_OPFVV_TRANS_TH(th_vmford_vv, opfvv_cmp_check_th)
+
+static bool opfvf_cmp_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rs2, false) &&
+(s->sew != 0) &&
+(th_check_overlap_group(a->rd, 1, a->rs2, 1 << s->lmul) ||
+ (s->lmul == 0)));
+}
+
+GEN_OPFVF_TRANS_TH(th_vmfeq_vf, opfvf_cmp_c

[PATCH 44/65] target/riscv: Add floating-point sign-injection instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 19 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 14 ---
 target/riscv/vector_helper.c  | 18 
 target/riscv/vector_internals.h   | 10 +
 target/riscv/xtheadvector_helper.c| 41 +++
 5 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 86ae984430..2b9d7fa2b6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2133,3 +2133,22 @@ DEF_HELPER_6(th_vfmin_vf_d, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfmax_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfmax_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfmax_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfsgnj_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnj_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnj_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnj_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnj_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnj_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjn_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsgnjx_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d3205ce2a0..1374bad5b9 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2098,18 +2098,20 @@ GEN_OPFVV_TRANS_TH(th_vfmax_vv, opfvv_check_th)
 GEN_OPFVF_TRANS_TH(th_vfmin_vf, opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfmax_vf, opfvf_check_th)
 
+/* Vector Floating-Point Sign-Injection Instructions */
+GEN_OPFVV_TRANS_TH(th_vfsgnj_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfsgnjn_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfsgnjx_vv, opfvv_check_th)
+GEN_OPFVF_TRANS_TH(th_vfsgnj_vf, opfvf_check_th)
+GEN_OPFVF_TRANS_TH(th_vfsgnjn_vf, opfvf_check_th)
+GEN_OPFVF_TRANS_TH(th_vfsgnjx_vf, opfvf_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfsgnj_vv)
-TH_TRANS_STUB(th_vfsgnj_vf)
-TH_TRANS_STUB(th_vfsgnjn_vv)
-TH_TRANS_STUB(th_vfsgnjn_vf)
-TH_TRANS_STUB(th_vfsgnjx_vv)
-TH_TRANS_STUB(th_vfsgnjx_vf)
 TH_TRANS_STUB(th_vmfeq_vv)
 TH_TRANS_STUB(th_vmfeq_vf)
 TH_TRANS_STUB(th_vmfne_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ef89794bdd..d0ebda5445 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3882,17 +3882,17 @@ GEN_VEXT_VF(vfmax_vf_w, 4)
 GEN_VEXT_VF(vfmax_vf_d, 8)
 
 /* Vector Floating-Point Sign-Injection Instructions */
-static uint16_t fsgnj16(uint16_t a, uint16_t b, float_status *s)
+uint16_t fsgnj16(uint16_t a, uint16_t b, float_status *s)
 {
 return deposit64(b, 0, 15, a);
 }
 
-static uint32_t fsgnj32(uint32_t a, uint32_t b, float_status *s)
+uint32_t fsgnj32(uint32_t a, uint32_t b, float_status *s)
 {
 return deposit64(b, 0, 31, a);
 }
 
-static uint64_t fsgnj64(uint64_t a, uint64_t b, float_status *s)
+uint64_t fsgnj64(uint64_t a, uint64_t b, float_status *s)
 {
 return deposit64(b, 0, 63, a);
 }
@@ -3910,17 +3910,17 @@ GEN_VEXT_VF(vfsgnj_vf_h, 2)
 GEN_VEXT_VF(vfsgnj_vf_w, 4)
 GEN_VEXT_VF(vfsgnj_vf_d, 8)
 
-static uint16_t fsgnjn16(uint16_t a, uint16_t b, float_status *s)
+uint16_t fsgnjn16(uint16_t a, uint16_t b, float_status *s)
 {
 return deposit64(~b, 0, 15, a);
 }
 
-static uint32_t fsgnjn32(uint32_t a, uint32_t b, float_status *s)
+uint32_t fsgnjn32(uint32_t a, uint32_t b, float_status *s)
 {
 return deposit64(~b, 0, 31, a);
 }
 
-static uint64_t fsgnjn64(uint64_t a, uint64_t b, float_status *s)
+uint64_t fsgnjn64(uint64_t a, uint64_t b, float_status *s)
 {
 return deposit64(~b, 0, 63, a);
 }
@@ -3938,17 +3938,17 @@ GEN_VEXT_VF(vfsgnjn_vf_h, 2)
 GEN_VEXT_VF(vfsgnjn_vf_w

[PATCH 43/65] target/riscv: Add floating-point MIN/MAX instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 10 ---
 target/riscv/xtheadvector_helper.c| 27 +++
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 5aa12f3719..86ae984430 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2120,3 +2120,16 @@ DEF_HELPER_6(th_vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_5(th_vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(th_vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_6(th_vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmin_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmin_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmin_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmax_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index e709444e9f..d3205ce2a0 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2092,16 +2092,18 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)   
   \
 
 GEN_OPFV_TRANS_TH(th_vfsqrt_v, opfv_check_th)
 
+/* Vector Floating-Point MIN/MAX Instructions */
+GEN_OPFVV_TRANS_TH(th_vfmin_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfmax_vv, opfvv_check_th)
+GEN_OPFVF_TRANS_TH(th_vfmin_vf, opfvf_check_th)
+GEN_OPFVF_TRANS_TH(th_vfmax_vf, opfvf_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfmin_vv)
-TH_TRANS_STUB(th_vfmin_vf)
-TH_TRANS_STUB(th_vfmax_vv)
-TH_TRANS_STUB(th_vfmax_vf)
 TH_TRANS_STUB(th_vfsgnj_vv)
 TH_TRANS_STUB(th_vfsgnj_vf)
 TH_TRANS_STUB(th_vfsgnjn_vv)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 7274e7aedb..5593cace78 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -2983,3 +2983,30 @@ THCALL(TH_OPFVV1, th_vfsqrt_v_d, OP_UU_D, H8, H8, 
float64_sqrt)
 GEN_TH_V_ENV(th_vfsqrt_v_h, 2, 2, clearh_th)
 GEN_TH_V_ENV(th_vfsqrt_v_w, 4, 4, clearl_th)
 GEN_TH_V_ENV(th_vfsqrt_v_d, 8, 8, clearq_th)
+
+/* Vector Floating-Point MIN/MAX Instructions */
+THCALL(TH_OPFVV2, th_vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum)
+THCALL(TH_OPFVV2, th_vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum)
+THCALL(TH_OPFVV2, th_vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum)
+GEN_TH_VV_ENV(th_vfmin_vv_h, 2, 2, clearh_th)
+GEN_TH_VV_ENV(th_vfmin_vv_w, 4, 4, clearl_th)
+GEN_TH_VV_ENV(th_vfmin_vv_d, 8, 8, clearq_th)
+THCALL(TH_OPFVF2, th_vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum)
+THCALL(TH_OPFVF2, th_vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum)
+THCALL(TH_OPFVF2, th_vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum)
+GEN_TH_VF(th_vfmin_vf_h, 2, 2, clearh_th)
+GEN_TH_VF(th_vfmin_vf_w, 4, 4, clearl_th)
+GEN_TH_VF(th_vfmin_vf_d, 8, 8, clearq_th)
+
+THCALL(TH_OPFVV2, th_vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum)
+THCALL(TH_OPFVV2, th_vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum)
+THCALL(TH_OPFVV2, th_vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum)
+GEN_TH_VV_ENV(th_vfmax_vv_h, 2, 2, clearh_th)
+GEN_TH_VV_ENV(th_vfmax_vv_w, 4, 4, clearl_th)
+GEN_TH_VV_ENV(th_vfmax_vv_d, 8, 8, clearq_th)
+THCALL(TH_OPFVF2, th_vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum)
+THCALL(TH_OPFVF2, th_vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum)
+THCALL(TH_OPFVF2, th_vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum)
+GEN_TH_VF(th_vfmax_vf_h, 2, 2, clearh_th)
+GEN_TH_VF(th_vfmax_vf_w, 4, 4, clearl_th)
+GEN_TH_VF(th_vfmax_vf_d, 8, 8, clearq_th)
-- 
2.44.0




[PATCH 42/65] target/riscv: Add floating-pointing square-root instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  4 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 46 ++-
 target/riscv/xtheadvector_helper.c| 41 +
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 12b5e4573a..5aa12f3719 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2116,3 +2116,7 @@ DEF_HELPER_6(th_vfwmsac_vf_h, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_5(th_vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(th_vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 7220b7d607..e709444e9f 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2047,13 +2047,57 @@ GEN_OPFVF_WIDEN_TRANS_TH(th_vfwnmacc_vf)
 GEN_OPFVF_WIDEN_TRANS_TH(th_vfwmsac_vf)
 GEN_OPFVF_WIDEN_TRANS_TH(th_vfwnmsac_vf)
 
+/* Vector Floating-Point Square-Root Instruction */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised
+ */
+static bool opfv_check_th(DisasContext *s, arg_rmr *a)
+{
+return require_xtheadvector(s) &&
+   vext_check_isa_ill(s) &&
+   th_check_overlap_mask(s, a->rd, a->vm, false) &&
+   th_check_reg(s, a->rd, false) &&
+   th_check_reg(s, a->rs2, false) &&
+   (s->sew != 0);
+}
+
+#define GEN_OPFV_TRANS_TH(NAME, CHECK) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+if (CHECK(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_3_ptr * const fns[3] = {\
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+gen_helper_##NAME##_d, \
+}; \
+gen_set_rm(s, RISCV_FRM_DYN);  \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   s->cfg_ptr->vlenb,  \
+   s->cfg_ptr->vlenb, data,\
+   fns[s->sew - 1]);   \
+finalize_rvv_inst(s);  \
+return true;   \
+}  \
+return false;  \
+}
+
+GEN_OPFV_TRANS_TH(th_vfsqrt_v, opfv_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfsqrt_v)
 TH_TRANS_STUB(th_vfmin_vv)
 TH_TRANS_STUB(th_vfmin_vf)
 TH_TRANS_STUB(th_vfmax_vv)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index ac8e576c49..7274e7aedb 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -2942,3 +2942,44 @@ THCALL(TH_OPFVF3, th_vfwnmsac_vf_h, WOP_UUU_H, H4, H2, 
fwnmsac16)
 THCALL(TH_OPFVF3, th_vfwnmsac_vf_w, WOP_UUU_W, H8, H4, fwnmsac32)
 GEN_TH_VF(th_vfwnmsac_vf_h, 2, 4, clearl_th)
 GEN_TH_VF(th_vfwnmsac_vf_w, 4, 8, clearq_th)
+
+/* Vector Floating-Point Square-Root Instruction */
+
+#define TH_OPFVV1(NAME, TD, T2, TX2, HD, HS2, OP)\
+static void do_##NAME(void *vd, void *vs2, int i,  \
+CPURISCVState *env)\
+{  \
+TX2 s2 = *((T2 *)vs2 + HS2(i));   

[PATCH 41/65] target/riscv: Add widening floating-point fused mul-add instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 17 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 18 +
 target/riscv/vector_helper.c  | 16 
 target/riscv/vector_internals.h   |  9 +
 target/riscv/xtheadvector_helper.c| 38 +++
 5 files changed, 82 insertions(+), 16 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 88e3a18e17..12b5e4573a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2099,3 +2099,20 @@ DEF_HELPER_6(th_vfmsub_vf_d, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index af512c489b..7220b7d607 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2037,20 +2037,22 @@ GEN_OPFVF_TRANS_TH(th_vfnmadd_vf, opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfmsub_vf, opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfnmsub_vf, opfvf_check_th)
 
+/* Vector Widening Floating-Point Fused Multiply-Add Instructions */
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwmacc_vv, opfvv_widen_check_th)
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwnmacc_vv, opfvv_widen_check_th)
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwmsac_vv, opfvv_widen_check_th)
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwnmsac_vv, opfvv_widen_check_th)
+GEN_OPFVF_WIDEN_TRANS_TH(th_vfwmacc_vf)
+GEN_OPFVF_WIDEN_TRANS_TH(th_vfwnmacc_vf)
+GEN_OPFVF_WIDEN_TRANS_TH(th_vfwmsac_vf)
+GEN_OPFVF_WIDEN_TRANS_TH(th_vfwnmsac_vf)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfwmacc_vv)
-TH_TRANS_STUB(th_vfwmacc_vf)
-TH_TRANS_STUB(th_vfwnmacc_vv)
-TH_TRANS_STUB(th_vfwnmacc_vf)
-TH_TRANS_STUB(th_vfwmsac_vv)
-TH_TRANS_STUB(th_vfwmsac_vf)
-TH_TRANS_STUB(th_vfwnmsac_vv)
-TH_TRANS_STUB(th_vfwnmsac_vf)
 TH_TRANS_STUB(th_vfsqrt_v)
 TH_TRANS_STUB(th_vfmin_vv)
 TH_TRANS_STUB(th_vfmin_vf)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 165221e08b..ef89794bdd 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3332,13 +3332,13 @@ GEN_VEXT_VF(vfnmsub_vf_w, 4)
 GEN_VEXT_VF(vfnmsub_vf_d, 8)
 
 /* Vector Widening Floating-Point Fused Multiply-Add Instructions */
-static uint32_t fwmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
+uint32_t fwmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
 {
 return float32_muladd(float16_to_float32(a, true, s),
   float16_to_float32(b, true, s), d, 0, s);
 }
 
-static uint64_t fwmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
+uint64_t fwmacc32(uint32_t a, uint32_t b, uint64_t d, float_status *s)
 {
 return float64_muladd(float32_to_float64(a, s),
   float32_to_float64(b, s), d, 0, s);
@@ -3364,7 +3364,7 @@ GEN_VEXT_VV_ENV(vfwmaccbf16_vv, 4)
 RVVCALL(OPFVF3, vfwmaccbf16_vf, WOP_UUU_H, H4, H2, fwmaccbf16)
 GEN_VEXT_VF(vfwmaccbf16_vf, 4)
 
-static uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
+uint32_t fwnmacc16(uint16_t a, uint16_t b, uint32_t d, float_status *s)
 {
 return float32_muladd(float16_to_float32(a, true, s),
   float16_to_float32(b, true, s), d,
@@ -3372,7 +3372,7 @@ static uint32_t fwnmacc16(uint16_t a, uint16_t b, 
uint32_t d, float_status *s

[PATCH 40/65] target/riscv: Add single-width floating-point fused multiply-add instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  49 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  34 ++---
 target/riscv/vector_helper.c  |  48 +++
 target/riscv/vector_internals.h   |  25 
 target/riscv/xtheadvector_helper.c| 125 ++
 5 files changed, 241 insertions(+), 40 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3102b078e4..88e3a18e17 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2050,3 +2050,52 @@ DEF_HELPER_6(th_vfwmul_vv_h, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(th_vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(th_vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmacc_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsac_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfnmsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 3d0370f220..af512c489b 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2019,28 +2019,30 @@ GEN_OPFVF_TRANS_TH(th_vfrdiv_vf,  opfvf_check_th)
 GEN_OPFVV_WIDEN_TRANS_TH(th_vfwmul_vv, opfvv_widen_check_th)
 GEN_OPFVF_WIDEN_TRANS_TH(th_vfwmul_vf)
 
+/* Vector Single-Width Floating-Point Fused Multiply-Add Instructions */
+GEN_OPFVV_TRANS_TH(th_vfmacc_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfnmacc_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfmsac_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfnmsac_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfmadd_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfnmadd_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH

[PATCH 39/65] target/riscv: Add widening floating-point multiply instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h|  5 +
 target/riscv/insn_trans/trans_xtheadvector.c.inc |  6 --
 target/riscv/vector_helper.c |  4 ++--
 target/riscv/vector_internals.h  |  3 +++
 target/riscv/xtheadvector_helper.c   | 11 +++
 5 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f63239676a..3102b078e4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2045,3 +2045,8 @@ DEF_HELPER_6(th_vfdiv_vf_d, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 940b212f5e..3d0370f220 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2015,14 +2015,16 @@ GEN_OPFVF_TRANS_TH(th_vfmul_vf,  opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfdiv_vf,  opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfrdiv_vf,  opfvf_check_th)
 
+/* Vector Widening Floating-Point Multiply */
+GEN_OPFVV_WIDEN_TRANS_TH(th_vfwmul_vv, opfvv_widen_check_th)
+GEN_OPFVF_WIDEN_TRANS_TH(th_vfwmul_vf)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfwmul_vv)
-TH_TRANS_STUB(th_vfwmul_vf)
 TH_TRANS_STUB(th_vfmacc_vv)
 TH_TRANS_STUB(th_vfnmacc_vv)
 TH_TRANS_STUB(th_vfnmacc_vf)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d65b32c584..aa7714d651 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3059,13 +3059,13 @@ GEN_VEXT_VF(vfrdiv_vf_w, 4)
 GEN_VEXT_VF(vfrdiv_vf_d, 8)
 
 /* Vector Widening Floating-Point Multiply */
-static uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s)
+uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s)
 {
 return float32_mul(float16_to_float32(a, true, s),
float16_to_float32(b, true, s), s);
 }
 
-static uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s)
+uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s)
 {
 return float64_mul(float32_to_float64(a, s),
float32_to_float64(b, s), s);
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 29263c6a53..8903a894d7 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -357,4 +357,7 @@ uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status 
*s);
 uint32_t float32_rdiv(uint32_t a, uint32_t b, float_status *s);
 uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s);
 
+uint32_t vfwmul16(uint16_t a, uint16_t b, float_status *s);
+uint64_t vfwmul32(uint32_t a, uint32_t b, float_status *s);
+
 #endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 770f36346f..dd01d66933 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -2768,3 +2768,14 @@ THCALL(TH_OPFVF2, th_vfrdiv_vf_d, OP_UUU_D, H8, H8, 
float64_rdiv)
 GEN_TH_VF(th_vfrdiv_vf_h, 2, 2, clearh_th)
 GEN_TH_VF(th_vfrdiv_vf_w, 4, 4, clearl_th)
 GEN_TH_VF(th_vfrdiv_vf_d, 8, 8, clearq_th)
+
+/* Vector Widening Floating-Point Multiply */
+
+THCALL(TH_OPFVV2, th_vfwmul_vv_h, WOP_UUU_H, H4, H2, H2, vfwmul16)
+THCALL(TH_OPFVV2, th_vfwmul_vv_w, WOP_UUU_W, H8, H4, H4, vfwmul32)
+GEN_TH_VV_ENV(th_vfwmul_vv_h, 2, 4, clearl_th)
+GEN_TH_VV_ENV(th_vfwmul_vv_w, 4, 8, clearq_th)
+THCALL(TH_OPFVF2, th_vfwmul_vf_h, WOP_UUU_H, H4, H2, vfwmul16)
+THCALL(TH_OPFVF2, th_vfwmul_vf_w, WOP_UUU_W, H8, H4, vfwmul32)
+GEN_TH_VF(th_vfwmul_vf_h, 2, 4, clearl_th)
+GEN_TH_VF(th_vfwmul_vf_w, 4, 8, clearq_th)
-- 
2.44.0




[PATCH 38/65] target/riscv: Add single-width floating-point multiply/divide instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 16 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 12 ---
 target/riscv/vector_helper.c  |  6 ++--
 target/riscv/vector_internals.h   |  4 +++
 target/riscv/xtheadvector_helper.c| 34 +++
 5 files changed, 64 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 21916e9e3c..f63239676a 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2029,3 +2029,19 @@ DEF_HELPER_6(th_vfwadd_wf_h, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfmul_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmul_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfmul_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrdiv_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrdiv_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrdiv_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 64d7a7fb76..940b212f5e 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -2008,17 +2008,19 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  
 \
 GEN_OPFWF_WIDEN_TRANS_TH(th_vfwadd_wf)
 GEN_OPFWF_WIDEN_TRANS_TH(th_vfwsub_wf)
 
+/* Vector Single-Width Floating-Point Multiply/Divide Instructions */
+GEN_OPFVV_TRANS_TH(th_vfmul_vv, opfvv_check_th)
+GEN_OPFVV_TRANS_TH(th_vfdiv_vv, opfvv_check_th)
+GEN_OPFVF_TRANS_TH(th_vfmul_vf,  opfvf_check_th)
+GEN_OPFVF_TRANS_TH(th_vfdiv_vf,  opfvf_check_th)
+GEN_OPFVF_TRANS_TH(th_vfrdiv_vf,  opfvf_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vfmul_vv)
-TH_TRANS_STUB(th_vfmul_vf)
-TH_TRANS_STUB(th_vfdiv_vv)
-TH_TRANS_STUB(th_vfdiv_vf)
-TH_TRANS_STUB(th_vfrdiv_vf)
 TH_TRANS_STUB(th_vfwmul_vv)
 TH_TRANS_STUB(th_vfwmul_vf)
 TH_TRANS_STUB(th_vfmacc_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 6d0358876a..d65b32c584 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3036,17 +3036,17 @@ GEN_VEXT_VF(vfdiv_vf_h, 2)
 GEN_VEXT_VF(vfdiv_vf_w, 4)
 GEN_VEXT_VF(vfdiv_vf_d, 8)
 
-static uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s)
+uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s)
 {
 return float16_div(b, a, s);
 }
 
-static uint32_t float32_rdiv(uint32_t a, uint32_t b, float_status *s)
+uint32_t float32_rdiv(uint32_t a, uint32_t b, float_status *s)
 {
 return float32_div(b, a, s);
 }
 
-static uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s)
+uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s)
 {
 return float64_div(b, a, s);
 }
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 0786f5a4e1..29263c6a53 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -353,4 +353,8 @@ uint64_t vfwaddw32(uint64_t a, uint32_t b, float_status *s);
 uint32_t vfwsubw16(uint32_t a, uint16_t b, float_status *s);
 uint64_t vfwsubw32(uint64_t a, uint32_t b, float_status *s);
 
+uint16_t float16_rdiv(uint16_t a, uint16_t b, float_status *s);
+uint32_t float32_rdiv(uint32_t a, uint32_t b, float_status *s);
+uint64_t float64_rdiv(uint64_t a, uint64_t b, float_status *s);
+
 #endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index cab489a4ae..770f36346f 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -2734,3 +2734,37 @@ THCALL(TH_OPFVF2, th_vfwsub_wf_h, WOP_WUUU_H, H4, H2, 
vfwsubw16)
 THCALL(TH_OPFVF2, th_vfwsub_wf_w, WOP_WUUU_W, H8, H4, vfwsubw32

[PATCH 37/65] target/riscv: Add widening floating-point add/sub instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  17 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 162 +-
 target/riscv/vector_helper.c  |  16 +-
 target/riscv/vector_internals.h   |   9 +
 target/riscv/xtheadvector_helper.c|  38 
 5 files changed, 226 insertions(+), 16 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 04bd363ac0..21916e9e3c 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -2012,3 +2012,20 @@ DEF_HELPER_6(th_vfsub_vf_d, void, ptr, ptr, i64, ptr, 
env, i32)
 DEF_HELPER_6(th_vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(th_vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
+DEF_HELPER_6(th_vfwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_wf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwadd_wf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_wf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfwsub_wf_w, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index a18c661f24..64d7a7fb76 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1854,20 +1854,166 @@ GEN_OPFVF_TRANS_TH(th_vfadd_vf,  opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfsub_vf,  opfvf_check_th)
 GEN_OPFVF_TRANS_TH(th_vfrsub_vf,  opfvf_check_th)
 
+/* Vector Widening Floating-Point Add/Subtract Instructions */
+static bool opfvv_widen_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, true) &&
+th_check_reg(s, a->rd, true) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_reg(s, a->rs1, false) &&
+th_check_overlap_group(a->rd, 2 << s->lmul, a->rs2,
+ 1 << s->lmul) &&
+th_check_overlap_group(a->rd, 2 << s->lmul, a->rs1,
+ 1 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3) && (s->sew != 0));
+}
+
+/* OPFVV with WIDEN */
+#define GEN_OPFVV_WIDEN_TRANS_TH(NAME, CHECK)   \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  \
+{   \
+if (CHECK(s, a)) {  \
+uint32_t data = 0;  \
+static gen_helper_gvec_4_ptr * const fns[2] = { \
+gen_helper_##NAME##_h, gen_helper_##NAME##_w,   \
+};  \
+gen_set_rm(s, RISCV_FRM_DYN);   \
+\
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);   \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);   \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);   \
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),  \
+   vreg_ofs(s, a->rs1), \
+   vreg_ofs(s, a->rs2), tcg_env,\
+   s->cfg_ptr->vlenb,   \
+   s->cfg_ptr->vlenb, data, \
+   fns[s->sew - 1]);\
+finalize_rvv_inst(s);   \
+return true;\
+}   \
+return false;  

[PATCH 36/65] target/riscv: Add single-width floating-point add/sub instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add single-width floating-point add/sub instructions
to show the way we implement XTheadVector floating-point arithmetic
instructions. XTheadVector diff from RVV1.0 in the following points:
1. Different mask reg layout.
2. Different tail/masked elements process policy.
3. Different check policy. XTheadVector does not have fractional lmul, so we can
   use simpler check function.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  16 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 113 +-
 target/riscv/vector_helper.c  |   6 +-
 target/riscv/vector_internals.h   |   4 +
 target/riscv/xtheadvector_helper.c| 106 
 5 files changed, 237 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6254be771f..04bd363ac0 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1996,3 +1996,19 @@ DEF_HELPER_6(th_vnclipu_vx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vfadd_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfadd_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfadd_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrsub_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrsub_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(th_vfrsub_vf_d, void, ptr, ptr, i64, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 108f3249d0..a18c661f24 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1746,17 +1746,120 @@ GEN_OPIVX_NARROW_TRANS_TH(th_vnclip_vx)
 GEN_OPIVI_NARROW_TRANS_TH(th_vnclipu_vi, IMM_ZX, th_vnclipu_vx)
 GEN_OPIVI_NARROW_TRANS_TH(th_vnclip_vi, IMM_ZX, th_vnclip_vx)
 
+/*
+ * Vector Float Point Arithmetic Instructions
+ */
+
+/* Vector Single-Width Floating-Point Add/Subtract Instructions */
+
+/*
+ * If the current SEW does not correspond to a supported IEEE floating-point
+ * type, an illegal instruction exception is raised.
+ */
+static bool opfvv_check_th(DisasContext *s, arg_rmrr *a)
+{
+return require_xtheadvector(s) &&
+   vext_check_isa_ill(s) &&
+   th_check_overlap_mask(s, a->rd, a->vm, false) &&
+   th_check_reg(s, a->rd, false) &&
+   th_check_reg(s, a->rs2, false) &&
+   th_check_reg(s, a->rs1, false) &&
+   (s->sew != 0);
+}
+
+/*
+ * The macro below including GEN_OPFVV_TRANS_TH and GEN_OPFVF_TRANS_TH,
+ * are just changed the data encoding compared to RVV1.0.
+ */
+
+/* OPFVV without GVEC IR */
+#define GEN_OPFVV_TRANS_TH(NAME, CHECK)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{  \
+if (CHECK(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_4_ptr * const fns[3] = {\
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+gen_helper_##NAME##_d, \
+}; \
+gen_set_rm(s, RISCV_FRM_DYN);  \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs1),\
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   s->cfg_ptr->vlenb,  \
+ 

[PATCH 35/65] target/riscv: Add narrowing fixed-point clip instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 14 +
 target/riscv/vector_helper.c  | 26 -
 target/riscv/vector_internals.h   | 14 +
 target/riscv/xtheadvector_helper.c| 29 +++
 5 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 70d3f34a59..6254be771f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1983,3 +1983,16 @@ DEF_HELPER_6(th_vssra_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vssra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vnclip_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclip_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclip_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d1f523832b..108f3249d0 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1738,18 +1738,20 @@ GEN_OPIVX_TRANS_TH(th_vssra_vx,  opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vssrl_vi, IMM_TRUNC_SEW, th_vssrl_vx, opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vssra_vi, IMM_TRUNC_SEW, th_vssra_vx, opivx_check_th)
 
+/* Vector Narrowing Fixed-Point Clip Instructions */
+GEN_OPIVV_NARROW_TRANS_TH(th_vnclipu_vv)
+GEN_OPIVV_NARROW_TRANS_TH(th_vnclip_vv)
+GEN_OPIVX_NARROW_TRANS_TH(th_vnclipu_vx)
+GEN_OPIVX_NARROW_TRANS_TH(th_vnclip_vx)
+GEN_OPIVI_NARROW_TRANS_TH(th_vnclipu_vi, IMM_ZX, th_vnclipu_vx)
+GEN_OPIVI_NARROW_TRANS_TH(th_vnclip_vi, IMM_ZX, th_vnclip_vx)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vnclipu_vv)
-TH_TRANS_STUB(th_vnclipu_vx)
-TH_TRANS_STUB(th_vnclipu_vi)
-TH_TRANS_STUB(th_vnclip_vv)
-TH_TRANS_STUB(th_vnclip_vx)
-TH_TRANS_STUB(th_vnclip_vi)
 TH_TRANS_STUB(th_vfadd_vv)
 TH_TRANS_STUB(th_vfadd_vf)
 TH_TRANS_STUB(th_vfsub_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index be1f1bc8e2..262cb28824 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -646,14 +646,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
  * Vector Integer Arithmetic Instructions
  */
 
-/* (TD, T1, T2, TX1, TX2) */
-#define NOP_SSS_B int8_t, int8_t, int16_t, int8_t, int16_t
-#define NOP_SSS_H int16_t, int16_t, int32_t, int16_t, int32_t
-#define NOP_SSS_W int32_t, int32_t, int64_t, int32_t, int64_t
-#define NOP_UUU_B uint8_t, uint8_t, uint16_t, uint8_t, uint16_t
-#define NOP_UUU_H uint16_t, uint16_t, uint32_t, uint16_t, uint32_t
-#define NOP_UUU_W uint32_t, uint32_t, uint64_t, uint32_t, uint64_t
-
 #define DO_SUB(N, M) (N - M)
 #define DO_RSUB(N, M) (M - N)
 
@@ -2677,8 +2669,7 @@ GEN_VEXT_VX_RM(vssra_vx_w, 4)
 GEN_VEXT_VX_RM(vssra_vx_d, 8)
 
 /* Vector Narrowing Fixed-Point Clip Instructions */
-static inline int8_t
-vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
+int8_t vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
 {
 uint8_t round, shift = b & 0xf;
 int16_t res;
@@ -2696,8 +2687,7 @@ vnclip8(CPURISCVState *env, int vxrm, int16_t a, int8_t b)
 }
 }
 
-static inline int16_t
-vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t b)
+int16_t vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t b)
 {
 uint8_t round, shift = b & 0x1f;
 int32_t res;
@@ -2715,8 +2705,7 @@ vnclip16(CPURISCVState *env, int vxrm, int32_t a, int16_t 
b)
 }
 }
 
-static inline int32_t
-vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b)
+int32_t vnclip32(CPURISCVState *env, int vxrm, int64_t a, int32_t b)
 {
 uint8_t round, shift = b & 0x3f;
 int64_t res;
@@ -2748,8 +2737,7 @@ GEN_VEXT_VX_RM(vnclip_wx_b, 1)
 GEN_VEXT_VX_RM(vnclip_wx_h, 2)
 GEN_VEXT_VX_RM(vnclip_wx_w, 4)
 
-static in

[PATCH 34/65] target/riscv: Add single-width scaling shift instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 17 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 14 ---
 target/riscv/vector_helper.c  | 24 
 target/riscv/vector_internals.h   | 10 +
 target/riscv/xtheadvector_helper.c| 38 +++
 5 files changed, 81 insertions(+), 22 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d45477ee1b..70d3f34a59 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1966,3 +1966,20 @@ DEF_HELPER_6(th_vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vssrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssrl_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 175516e3a7..d1f523832b 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1730,18 +1730,20 @@ GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmacc_vx, 
opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmaccsu_vx, opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmaccus_vx, opivx_widen_check_th)
 
+/* Vector Single-Width Scaling Shift Instructions */
+GEN_OPIVV_TRANS_TH(th_vssrl_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vssra_vv, opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vssrl_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vssra_vx,  opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vssrl_vi, IMM_TRUNC_SEW, th_vssrl_vx, opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vssra_vi, IMM_TRUNC_SEW, th_vssra_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vssrl_vv)
-TH_TRANS_STUB(th_vssrl_vx)
-TH_TRANS_STUB(th_vssrl_vi)
-TH_TRANS_STUB(th_vssra_vv)
-TH_TRANS_STUB(th_vssra_vx)
-TH_TRANS_STUB(th_vssra_vi)
 TH_TRANS_STUB(th_vnclipu_vv)
 TH_TRANS_STUB(th_vnclipu_vx)
 TH_TRANS_STUB(th_vnclipu_vi)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ec11acf487..be1f1bc8e2 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2581,8 +2581,7 @@ GEN_VEXT_VX_RM(vsmul_vx_w, 4)
 GEN_VEXT_VX_RM(vsmul_vx_d, 8)
 
 /* Vector Single-Width Scaling Shift Instructions */
-static inline uint8_t
-vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b)
+uint8_t vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t b)
 {
 uint8_t round, shift = b & 0x7;
 uint8_t res;
@@ -2591,24 +2590,21 @@ vssrl8(CPURISCVState *env, int vxrm, uint8_t a, uint8_t 
b)
 res = (a >> shift) + round;
 return res;
 }
-static inline uint16_t
-vssrl16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b)
+uint16_t vssrl16(CPURISCVState *env, int vxrm, uint16_t a, uint16_t b)
 {
 uint8_t round, shift = b & 0xf;
 
 round = get_round(vxrm, a, shift);
 return (a >> shift) + round;
 }
-static inline uint32_t
-vssrl32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b)
+uint32_t vssrl32(CPURISCVState *env, int vxrm, uint32_t a, uint32_t b)
 {
 uint8_t round, shift = b & 0x1f;
 
 round = get_round(vxrm, a, shift);
 return (a >> shift) + round;
 }
-static inline uint64_t
-vssrl64(CPURISCVState *env, int vxrm, uint64_t a, uint64_t b)
+uint64_t vssrl64(CPURISCVState *env, int vxrm, uint64_t a, uint64_t b)
 {
 uint8_t round, shift = b & 0x3f;
 
@@ -2633,32 +2629,28 @@ GEN_VEXT_VX_RM(vssrl_vx_h, 2)
 GEN_VEXT_VX_RM(vssrl_vx_w, 4)
 GEN_VEXT_VX_RM(vssrl_vx_d, 8)
 
-static inline

[PATCH 33/65] target/riscv: Add widening saturating scaled multiply-add instructions for XTheadVector

2024-04-12 Thread Huang Tao
There are no instructions similar to these instructions in RVV1.0. So we
implement them by writing their own functions instead of copying code from
RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  22 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  16 +-
 target/riscv/vector_helper.c  |   2 +-
 target/riscv/vector_internals.h   |   2 +
 target/riscv/xtheadvector_helper.c| 210 ++
 5 files changed, 244 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 85962f7253..d45477ee1b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1944,3 +1944,25 @@ DEF_HELPER_6(th_vsmul_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vwsmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index df653bd1c9..175516e3a7 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1721,19 +1721,21 @@ GEN_OPIVI_TRANS_TH(th_vaadd_vi, IMM_SX, th_vaadd_vx, 
opivx_check_th)
 GEN_OPIVV_TRANS_TH(th_vsmul_vv, opivv_check_th)
 GEN_OPIVX_TRANS_TH(th_vsmul_vx, opivx_check_th)
 
+/* Vector Widening Saturating Scaled Multiply-Add */
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwsmaccu_vv, opivv_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwsmacc_vv, opivv_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwsmaccsu_vv, opivv_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmaccu_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmacc_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmaccsu_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwsmaccus_vx, opivx_widen_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vwsmaccu_vv)
-TH_TRANS_STUB(th_vwsmaccu_vx)
-TH_TRANS_STUB(th_vwsmacc_vv)
-TH_TRANS_STUB(th_vwsmacc_vx)
-TH_TRANS_STUB(th_vwsmaccsu_vv)
-TH_TRANS_STUB(th_vwsmaccsu_vx)
-TH_TRANS_STUB(th_vwsmaccus_vx)
 TH_TRANS_STUB(th_vssrl_vv)
 TH_TRANS_STUB(th_vssrl_vx)
 TH_TRANS_STUB(th_vssrl_vi)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 331a9a9c7a..ec11acf487 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2296,7 +2296,7 @@ GEN_VEXT_VX_RM(vssub_vx_w, 4)
 GEN_VEXT_VX_RM(vssub_vx_d, 8)
 
 /* Vector Single-Width Averaging Add and Subtract */
-static inline uint8_t get_round(int vxrm, uint64_t v, uint8_t shift)
+uint8_t get_round(int vxrm, uint64_t v, uint8_t shift)
 {
 uint8_t d = extract64(v, shift, 1);
 uint8_t d1;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index c76ff5abac..99f69ef8fa 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -314,4 +314,6 @@ int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, 
int16_t b);
 int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b);
 int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b);
 
+uint8_t get_round(int vxrm, uint64_t v, uint8_t shift);
+
 #endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv

[PATCH 32/65] target/riscv: Add single-width fractional mul with rounding and saturation for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  9 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  6 --
 target/riscv/vector_helper.c  |  8 
 target/riscv/vector_internals.h   |  6 ++
 target/riscv/xtheadvector_helper.c| 19 +++
 5 files changed, 42 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index aab2979328..85962f7253 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1935,3 +1935,12 @@ DEF_HELPER_6(th_vasub_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsmul_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 59da1e4b3f..df653bd1c9 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1717,14 +1717,16 @@ GEN_OPIVX_TRANS_TH(th_vaadd_vx,  opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vasub_vx,  opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vaadd_vi, IMM_SX, th_vaadd_vx, opivx_check_th)
 
+/* Vector Single-Width Fractional Multiply with Rounding and Saturation */
+GEN_OPIVV_TRANS_TH(th_vsmul_vv, opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vsmul_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vsmul_vv)
-TH_TRANS_STUB(th_vsmul_vx)
 TH_TRANS_STUB(th_vwsmaccu_vv)
 TH_TRANS_STUB(th_vwsmaccu_vx)
 TH_TRANS_STUB(th_vwsmacc_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ea1e449174..331a9a9c7a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2474,7 +2474,7 @@ GEN_VEXT_VX_RM(vasubu_vx_w, 4)
 GEN_VEXT_VX_RM(vasubu_vx_d, 8)
 
 /* Vector Single-Width Fractional Multiply with Rounding and Saturation */
-static inline int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
+int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b)
 {
 uint8_t round;
 int16_t res;
@@ -2494,7 +2494,7 @@ static inline int8_t vsmul8(CPURISCVState *env, int vxrm, 
int8_t a, int8_t b)
 }
 }
 
-static int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
+int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b)
 {
 uint8_t round;
 int32_t res;
@@ -2514,7 +2514,7 @@ static int16_t vsmul16(CPURISCVState *env, int vxrm, 
int16_t a, int16_t b)
 }
 }
 
-static int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
+int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b)
 {
 uint8_t round;
 int64_t res;
@@ -2534,7 +2534,7 @@ static int32_t vsmul32(CPURISCVState *env, int vxrm, 
int32_t a, int32_t b)
 }
 }
 
-static int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
+int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b)
 {
 uint8_t round;
 uint64_t hi_64, lo_64;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 19f174f4c8..c76ff5abac 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -308,4 +308,10 @@ int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a, 
int32_t b);
 int64_t aadd64(CPURISCVState *env, int vxrm, int64_t a, int64_t b);
 int32_t asub32(CPURISCVState *env, int vxrm, int32_t a, int32_t b);
 int64_t asub64(CPURISCVState *env, int vxrm, int64_t a, int64_t b);
+
+int8_t vsmul8(CPURISCVState *env, int vxrm, int8_t a, int8_t b);
+int16_t vsmul16(CPURISCVState *env, int vxrm, int16_t a, int16_t b);
+int32_t vsmul32(CPURISCVState *env, int vxrm, int32_t a, int32_t b);
+int64_t vsmul64(CPURISCVState *env, int vxrm, int64_t a, int64_t b);
+
 #endif /* TARGET_RISCV_VECTOR_INTERNALS_H */
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 06ac5940b7..e4acb4d176 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -2294,3 +2294,22 @@ GEN_TH_VX_RM(th_vasub_vx_b

[PATCH 31/65] target/riscv: Add single-width average add and sub instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 17 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 12 ---
 target/riscv/vector_helper.c  |  8 ++---
 target/riscv/vector_internals.h   |  5 +++
 target/riscv/xtheadvector_helper.c| 36 +++
 5 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c5156d9939..aab2979328 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1918,3 +1918,20 @@ DEF_HELPER_6(th_vssub_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vssub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vssub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vssub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vaadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index e60da5b237..59da1e4b3f 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1710,17 +1710,19 @@ GEN_OPIVX_TRANS_TH(th_vssub_vx,  opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vsaddu_vi, IMM_ZX, th_vsaddu_vx, opivx_check_th)
 GEN_OPIVI_TRANS_TH(th_vsadd_vi, IMM_SX, th_vsadd_vx, opivx_check_th)
 
+/* Vector Single-Width Averaging Add and Subtract */
+GEN_OPIVV_TRANS_TH(th_vaadd_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vasub_vv, opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vaadd_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vasub_vx,  opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vaadd_vi, IMM_SX, th_vaadd_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vaadd_vv)
-TH_TRANS_STUB(th_vaadd_vx)
-TH_TRANS_STUB(th_vaadd_vi)
-TH_TRANS_STUB(th_vasub_vv)
-TH_TRANS_STUB(th_vasub_vx)
 TH_TRANS_STUB(th_vsmul_vv)
 TH_TRANS_STUB(th_vsmul_vx)
 TH_TRANS_STUB(th_vwsmaccu_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 8664a3d4ef..ea1e449174 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2323,7 +2323,7 @@ static inline uint8_t get_round(int vxrm, uint64_t v, 
uint8_t shift)
 return 0; /* round-down (truncate) */
 }
 
-static inline int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a,
+int32_t aadd32(CPURISCVState *env, int vxrm, int32_t a,
  int32_t b)
 {
 int64_t res = (int64_t)a + b;
@@ -2332,7 +2332,7 @@ static inline int32_t aadd32(CPURISCVState *env, int 
vxrm, int32_t a,
 return (res >> 1) + round;
 }
 
-static inline int64_t aadd64(CPURISCVState *env, int vxrm, int64_t a,
+int64_t aadd64(CPURISCVState *env, int vxrm, int64_t a,
  int64_t b)
 {
 int64_t res = a + b;
@@ -2398,7 +2398,7 @@ GEN_VEXT_VX_RM(vaaddu_vx_h, 2)
 GEN_VEXT_VX_RM(vaaddu_vx_w, 4)
 GEN_VEXT_VX_RM(vaaddu_vx_d, 8)
 
-static inline int32_t asub32(CPURISCVState *env, int vxrm, int32_t a,
+int32_t asub32(CPURISCVState *env, int vxrm, int32_t a,
  int32_t b)
 {
 int64_t res = (int64_t)a - b;
@@ -2407,7 +2407,7 @@ static inline int32_t asub32(CPURISCVState *env, int 
vxrm, int32_t a,
 return (res >> 1) + round;
 }
 
-static inline int64_t asub64(CPURISCVState *env, int vxrm, int64_t a,
+int64_t asub64(CPURISCVState *env, int vxrm, int64_t a,
  int64_t b)
 {
 int64_t res = (int64_t)a - b;
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index a70ebdabe4..19f174f4c8 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -303,4 +303,

[PATCH 30/65] target/riscv: Add single-width saturating add and sub instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add single-width saturating add and sub instructions to
show the way we implement XTheadVector fixed-point arithmetic instructions.
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  33 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  26 +-
 target/riscv/vector_helper.c  |  32 +--
 target/riscv/vector_internals.h   |  19 ++
 target/riscv/xtheadvector_helper.c| 231 ++
 5 files changed, 315 insertions(+), 26 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ba548ebdc9..c5156d9939 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1885,3 +1885,36 @@ DEF_HELPER_4(th_vmv_v_x_b, void, ptr, i64, env, i32)
 DEF_HELPER_4(th_vmv_v_x_h, void, ptr, i64, env, i32)
 DEF_HELPER_4(th_vmv_v_x_w, void, ptr, i64, env, i32)
 DEF_HELPER_4(th_vmv_v_x_d, void, ptr, i64, env, i32)
+
+DEF_HELPER_6(th_vsaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssubu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vssub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 6d0ce9f966..e60da5b237 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1694,22 +1694,28 @@ GEN_OPIVV_TRANS_TH(th_vmerge_vvm, opivv_vadc_check_th)
 GEN_OPIVX_TRANS_TH(th_vmerge_vxm, opivx_vadc_check_th)
 GEN_OPIVI_TRANS_TH(th_vmerge_vim, IMM_SX, th_vmerge_vxm, opivx_vadc_check_th)
 
+/*
+ * Vector Fixed-Point Arithmetic Instructions
+ */
+
+/* Vector Single-Width Saturating Add and Subtract */
+GEN_OPIVV_TRANS_TH(th_vsaddu_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vsadd_vv,  opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vssubu_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vssub_vv,  opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vsaddu_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vsadd_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vssubu_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vssub_vx,  opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vsaddu_vi, IMM_ZX, th_vsaddu_vx, opivx_check_th)
+GEN_OPIVI_TRANS_TH(th_vsadd_vi, IMM_SX, th_vsadd_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vsaddu_vv)
-TH_TRANS_STUB(th_vsaddu_vx)
-TH_TRANS_STUB(th_vsaddu_vi)
-TH_TRANS_STUB(th_vsadd_vv)
-TH_TRANS_STUB(th_vsadd_vx)
-TH_TRANS_STUB(th_vsadd_vi)
-TH_TRANS_STUB(th_vssubu_vv)
-TH_TRANS_STUB(th_vssubu_vx)
-TH_TRANS_STUB(th_vssub_vv)
-TH_TRANS_STUB(th_vssub_vx)
 TH_TRANS_STUB(th_vaadd_vv)
 TH_TRANS_STUB(th_vaadd_vx)
 TH_TRANS_STUB(th_vaadd_vi)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 06ca77691d..8664a3d4ef 100644

[PATCH 29/65] target/riscv: Add integer merge and move instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0. Except of
th.vmv.v.x, the difference is that XTheadVector has no limit of SEW
of 8 to 64, Therefore, it is not suitable to use acceleration when
xlen < SEW.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  17 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 124 +-
 target/riscv/xtheadvector_helper.c| 104 +++
 3 files changed, 239 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 8b8dd62761..ba548ebdc9 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1868,3 +1868,20 @@ DEF_HELPER_6(th_vwmaccsu_vx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vwmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vmerge_vvm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vvm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vvm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vvm_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vxm_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmerge_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_4(th_vmv_v_v_b, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vmv_v_v_h, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vmv_v_v_w, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vmv_v_v_d, void, ptr, ptr, env, i32)
+DEF_HELPER_4(th_vmv_v_x_b, void, ptr, i64, env, i32)
+DEF_HELPER_4(th_vmv_v_x_h, void, ptr, i64, env, i32)
+DEF_HELPER_4(th_vmv_v_x_w, void, ptr, i64, env, i32)
+DEF_HELPER_4(th_vmv_v_x_d, void, ptr, i64, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index bfa3a26f78..6d0ce9f966 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1576,18 +1576,130 @@ GEN_OPIVX_WIDEN_TRANS_TH(th_vwmacc_vx, 
opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwmaccsu_vx, opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwmaccus_vx, opivx_widen_check_th)
 
+/* Vector Integer Merge and Move Instructions */
+
+/*
+ * This function is almost the copy of trans_vmv_v_v, except:
+ * 1) XTheadVector simplifies the judgment logic of whether
+ *to accelerate or not for its lack of fractional LMUL and
+ *VTA.
+ */
+static bool trans_th_vmv_v_v(DisasContext *s, arg_th_vmv_v_v *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs1, false)) {
+
+if (s->vl_eq_vlmax) {
+tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd),
+ vreg_ofs(s, a->rs1),
+ MAXSZ(s), MAXSZ(s));
+} else {
+uint32_t data = FIELD_DP32(0, VDATA_TH, LMUL, s->lmul);
+static gen_helper_gvec_2_ptr * const fns[4] = {
+gen_helper_th_vmv_v_v_b, gen_helper_th_vmv_v_v_h,
+gen_helper_th_vmv_v_v_w, gen_helper_th_vmv_v_v_d,
+};
+
+tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
+   tcg_env, s->cfg_ptr->vlenb,
+   s->cfg_ptr->vlenb, data,
+   fns[s->sew]);
+}
+finalize_rvv_inst(s);
+return true;
+}
+return false;
+}
+
+
+#define gen_helper_vmv_vx_th gen_helper_vmv_vx
+/*
+ * This function is almost the copy of trans_vmv_v_x, except:
+ * 1) Simplier judgment logic of acceleration
+ * 2) XTheadVector has no limit of SEW of 8 to 64, Therefore, it is not
+ *suitable to use acceleration when xlen < SEW.
+ */
+static bool trans_th_vmv_v_x(DisasContext *s, arg_th_vmv_v_x *a)
+{
+if (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false)) {
+
+TCGv s1;
+s1 = get_gpr(s, a->rs1, EXT_SIGN);
+
+if (s->vl_eq_vlmax && (8 << s->sew) <= get_xlen(s)) {
+tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
+MAXSZ(s), MAXSZ(s), s1);
+} else {
+TCGv_i32 desc;
+TCGv_i64 s1_i64 = tcg_temp_new_i64();
+TCGv_ptr dest = tcg_temp_new_ptr();
+uint32_t data = FIELD_DP32(0, VDATA_TH, LMUL, s->lmul);
+static gen_helper_vmv_vx_th * const fns[4] = {
+gen_helper_th_vmv_v_x_b, gen_helper_th_vmv_v_x_h,
+gen_helper_th_vmv_v_x_w

[PATCH 28/65] target/riscv: Add widening integer multiply-add instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 22 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 16 ---
 target/riscv/vector_helper.c  |  3 --
 target/riscv/vector_internals.h   |  3 ++
 target/riscv/xtheadvector_helper.c| 45 +++
 5 files changed, 79 insertions(+), 10 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a6abb48b55..8b8dd62761 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1846,3 +1846,25 @@ DEF_HELPER_6(th_vnmsub_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vnmsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnmsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnmsub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vwmaccu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccus_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccus_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmaccus_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d84edd90ca..bfa3a26f78 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1567,19 +1567,21 @@ GEN_OPIVX_TRANS_TH(th_vnmsac_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vmadd_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vnmsub_vx, opivx_check_th)
 
+/* Vector Widening Integer Multiply-Add Instructions */
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmaccu_vv, opivx_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmacc_vv, opivx_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmaccsu_vv, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmaccu_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmacc_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmaccsu_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmaccus_vx, opivx_widen_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vwmaccu_vv)
-TH_TRANS_STUB(th_vwmaccu_vx)
-TH_TRANS_STUB(th_vwmacc_vv)
-TH_TRANS_STUB(th_vwmacc_vx)
-TH_TRANS_STUB(th_vwmaccsu_vv)
-TH_TRANS_STUB(th_vwmaccsu_vx)
-TH_TRANS_STUB(th_vwmaccus_vx)
 TH_TRANS_STUB(th_vmv_v_v)
 TH_TRANS_STUB(th_vmv_v_x)
 TH_TRANS_STUB(th_vmv_v_i)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b312d67f87..06ca77691d 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -647,9 +647,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
  */
 
 /* (TD, T1, T2, TX1, TX2) */
-#define WOP_SSU_B int16_t, int8_t, uint8_t, int16_t, uint16_t
-#define WOP_SSU_H int32_t, int16_t, uint16_t, int32_t, uint32_t
-#define WOP_SSU_W int64_t, int32_t, uint32_t, int64_t, uint64_t
 #define NOP_SSS_B int8_t, int8_t, int16_t, int8_t, int16_t
 #define NOP_SSS_H int16_t, int16_t, int32_t, int16_t, int32_t
 #define NOP_SSS_W int32_t, int32_t, int64_t, int32_t, int64_t
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index c3d9752e2e..e99caa8e2d 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -252,6 +252,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,\
 #define WOP_SUS_B int16_t, uint8_t, int8_t, uint16_t, int16_t
 #define WOP_SUS_H int32_t, uint16_t, int16_t, uint32_t, int32_t
 #define WOP_SUS_W int64_t, uint32_t, int32_t, uint64_t, int64_t
+#define WOP_SSU_B int16_t, int8_t, uint8_t

[PATCH 27/65] target/riscv: Add single-width integer multiply-add instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 33 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 18 ++--
 target/riscv/xtheadvector_helper.c| 87 +++
 3 files changed, 130 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 93e6a3f33d..a6abb48b55 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1813,3 +1813,36 @@ DEF_HELPER_6(th_vwmulu_vx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vwmulsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwmulsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwmulsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vmacc_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmacc_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsac_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnmsub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 681e967078..d84edd90ca 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1557,20 +1557,22 @@ GEN_OPIVX_WIDEN_TRANS_TH(th_vwmul_vx, 
opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwmulu_vx, opivx_widen_check_th)
 GEN_OPIVX_WIDEN_TRANS_TH(th_vwmulsu_vx, opivx_widen_check_th)
 
+/* Vector Single-Width Integer Multiply-Add Instructions */
+GEN_OPIVV_TRANS_TH(th_vmacc_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vnmsac_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vmadd_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vnmsub_vv, opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vmacc_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vnmsac_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmadd_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vnmsub_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmacc_vv)
-TH_TRANS_STUB(th_vmacc_vx)
-TH_TRANS_STUB(th_vnmsac_vv)
-TH_TRANS_STUB(th_vnmsac_vx)
-TH_TRANS_STUB(th_vmadd_vv)
-TH_TRANS_STUB(th_vmadd_vx)
-TH_TRANS_STUB(th_vnmsub_vv)
-TH_TRANS_STUB(th_vnmsub_vx)
 TH_TRANS_STUB(th_vwmaccu_vv)
 TH_TRANS_STUB(th_vwmaccu_vx)
 TH_TRANS_STUB(th_vwmacc_vv)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index b5b1e55452..ccf6eb8a43 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -1791,3 +1791,90 @@ GEN_TH_VX(th_vwmulu_vx_w, 4, 8, clearq_th)
 GEN_TH_VX(th_vwmulsu_vx_b, 1, 2, clearh_th)
 GEN_TH_VX(th_vwmulsu_vx_h, 2, 4, clearl_th)
 GEN_TH_VX(th_vwmulsu_vx_w, 4, 8, clearq_th)
+
+/* Vector Single-Width Integer Multiply-Add Instructions */
+#define TH_OPIVV3(NAME, TD, T1, T2, TX1, TX2, HD, HS1, HS2, OP)   \
+static void do_##NAME(void *vd, void

[PATCH 26/65] target/riscv: Add widening integer multiply instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 19 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 14 ---
 target/riscv/vector_helper.c  |  3 --
 target/riscv/vector_internals.h   |  3 ++
 target/riscv/xtheadvector_helper.c| 39 +++
 5 files changed, 69 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3d5ad2847e..93e6a3f33d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1794,3 +1794,22 @@ DEF_HELPER_6(th_vrem_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vrem_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrem_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrem_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vwmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwmul_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmul_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmul_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwmulsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index a609b7faf3..681e967078 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1549,18 +1549,20 @@ GEN_OPIVX_TRANS_TH(th_vdiv_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vremu_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vrem_vx, opivx_check_th)
 
+/* Vector Widening Integer Multiply Instructions */
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmul_vv, opivv_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmulu_vv, opivv_widen_check_th)
+GEN_OPIVV_WIDEN_TRANS_TH(th_vwmulsu_vv, opivv_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmul_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmulu_vx, opivx_widen_check_th)
+GEN_OPIVX_WIDEN_TRANS_TH(th_vwmulsu_vx, opivx_widen_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vwmulu_vv)
-TH_TRANS_STUB(th_vwmulu_vx)
-TH_TRANS_STUB(th_vwmulsu_vv)
-TH_TRANS_STUB(th_vwmulsu_vx)
-TH_TRANS_STUB(th_vwmul_vv)
-TH_TRANS_STUB(th_vwmul_vx)
 TH_TRANS_STUB(th_vmacc_vv)
 TH_TRANS_STUB(th_vmacc_vx)
 TH_TRANS_STUB(th_vnmsac_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 5aba3f238f..b312d67f87 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -647,9 +647,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
  */
 
 /* (TD, T1, T2, TX1, TX2) */
-#define WOP_SUS_B int16_t, uint8_t, int8_t, uint16_t, int16_t
-#define WOP_SUS_H int32_t, uint16_t, int16_t, uint32_t, int32_t
-#define WOP_SUS_W int64_t, uint32_t, int32_t, uint64_t, int64_t
 #define WOP_SSU_B int16_t, int8_t, uint8_t, int16_t, uint16_t
 #define WOP_SSU_H int32_t, int16_t, uint16_t, int32_t, uint32_t
 #define WOP_SSU_W int64_t, int32_t, uint32_t, int64_t, uint64_t
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index 4cbd7f972a..c3d9752e2e 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -249,6 +249,9 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1,\
 #define WOP_WSSS_B  int16_t, int8_t, int16_t, int16_t, int16_t
 #define WOP_WSSS_H  int32_t, int16_t, int32_t, int32_t, int32_t
 #define WOP_WSSS_W  int64_t, int32_t, int64_t, int64_t, int64_t
+#define WOP_SUS_B int16_t, uint8_t, int8_t, uint16_t, int16_t
+#define WOP_SUS_H int32_t, uint16_t, int16_t, uint32_t, int32_t
+#define WOP_SUS_W int64_t, uint32_t, int32_t, uint64_t, int64_t
 
 /* share functions */
 static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv

[PATCH 25/65] target/riscv: Add integer divide instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 33 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 18 +++--
 target/riscv/xtheadvector_helper.c| 74 +++
 3 files changed, 117 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index e678dd5385..3d5ad2847e 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1761,3 +1761,36 @@ DEF_HELPER_6(th_vmulhsu_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vmulhsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmulhsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmulhsu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vdivu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdivu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vdiv_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vremu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrem_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 15f36ba98a..a609b7faf3 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1539,20 +1539,22 @@ GEN_OPIVX_TRANS_TH(th_vmulh_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vmulhu_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vmulhsu_vx, opivx_check_th)
 
+/* Vector Integer Divide Instructions */
+GEN_OPIVV_TRANS_TH(th_vdivu_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vdiv_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vremu_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vrem_vv, opivv_check_th)
+GEN_OPIVX_TRANS_TH(th_vdivu_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vdiv_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vremu_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vrem_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vdivu_vv)
-TH_TRANS_STUB(th_vdivu_vx)
-TH_TRANS_STUB(th_vdiv_vv)
-TH_TRANS_STUB(th_vdiv_vx)
-TH_TRANS_STUB(th_vremu_vv)
-TH_TRANS_STUB(th_vremu_vx)
-TH_TRANS_STUB(th_vrem_vv)
-TH_TRANS_STUB(th_vrem_vx)
 TH_TRANS_STUB(th_vwmulu_vv)
 TH_TRANS_STUB(th_vwmulu_vx)
 TH_TRANS_STUB(th_vwmulsu_vv)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 9d8129750c..4af66b047a 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -1678,3 +1678,77 @@ GEN_TH_VX(th_vmulhsu_vx_b, 1, 1, clearb_th)
 GEN_TH_VX(th_vmulhsu_vx_h, 2, 2, clearh_th)
 GEN_TH_VX(th_vmulhsu_vx_w, 4, 4, clearl_th)
 GEN_TH_VX(th_vmulhsu_vx_d, 8, 8, clearq_th)
+
+/* Vector Integer Divide Instructions */
+#define TH_DIVU(N, M) (unlikely(M == 0) ? (__typeof(N))(-1) : N / M)
+#define TH_REMU(N, M) (unlikely(M == 0) ? N : N % M)
+#define TH_DIV(N, M)  (unlikely(M == 0) ? (__typeof(N))(-1) :\
+unlikely((N == -N) &

[PATCH 24/65] target/riscv: Add single-width integer multiply instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 33 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 18 ++---
 target/riscv/vector_helper.c  | 28 
 target/riscv/vector_internals.h   | 17 +
 target/riscv/xtheadvector_helper.c| 69 +++
 5 files changed, 141 insertions(+), 24 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f3e4ab0f1f..e678dd5385 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1728,3 +1728,36 @@ DEF_HELPER_6(th_vmax_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vmax_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmax_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmax_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmul_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulh_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmulhsu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index f19a771b61..15f36ba98a 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1529,20 +1529,22 @@ GEN_OPIVX_TRANS_TH(th_vmin_vx,  opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vmaxu_vx, opivx_check_th)
 GEN_OPIVX_TRANS_TH(th_vmax_vx,  opivx_check_th)
 
+/* Vector Single-Width Integer Multiply Instructions */
+GEN_OPIVV_GVEC_TRANS_TH(th_vmul_vv,  mul)
+GEN_OPIVV_TRANS_TH(th_vmulh_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vmulhu_vv, opivv_check_th)
+GEN_OPIVV_TRANS_TH(th_vmulhsu_vv, opivv_check_th)
+GEN_OPIVX_GVEC_TRANS_TH(th_vmul_vx,  muls)
+GEN_OPIVX_TRANS_TH(th_vmulh_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmulhu_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmulhsu_vx, opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vmul_vv)
-TH_TRANS_STUB(th_vmul_vx)
-TH_TRANS_STUB(th_vmulh_vv)
-TH_TRANS_STUB(th_vmulh_vx)
-TH_TRANS_STUB(th_vmulhu_vv)
-TH_TRANS_STUB(th_vmulhu_vx)
-TH_TRANS_STUB(th_vmulhsu_vv)
-TH_TRANS_STUB(th_vmulhsu_vx)
 TH_TRANS_STUB(th_vdivu_vv)
 TH_TRANS_STUB(th_vdivu_vx)
 TH_TRANS_STUB(th_vdiv_vv)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9774fc62c3..5aba3f238f 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -647,10 +647,6 @@ GEN_VEXT_ST_WHOLE(vs8r_v, int8_t, ste_b)
  */
 
 /* (TD, T1, T2, TX1, TX2) */
-#define OP_SUS_B int8_t, uint8_t, int8_t, uint8_t, int8_t
-#define OP_SUS_H int16_t, uint16_t, int16_t, uint16_t, int16_t
-#define OP_SUS_W int32_t, uint32_t, int32_t, uint32_t, int32_t
-#define OP_SUS_D int64_t, uint64_t, int64_t, uint64_t

[PATCH 23/65] target/riscv: Add integer min/max instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 33 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 18 ++---
 target/riscv/xtheadvector_helper.c| 67 +++
 3 files changed, 110 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 8f2dec158b..f3e4ab0f1f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1695,3 +1695,36 @@ DEF_HELPER_6(th_vmsgt_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vmsgt_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmsgt_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmsgt_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vminu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vminu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmin_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmaxu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmax_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 049d9da0a5..f19a771b61 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1519,20 +1519,22 @@ GEN_OPIVI_TRANS_TH(th_vmsle_vi, IMM_SX, th_vmsle_vx, 
opivx_cmp_check_th)
 GEN_OPIVI_TRANS_TH(th_vmsgtu_vi, IMM_ZX, th_vmsgtu_vx, opivx_cmp_check_th)
 GEN_OPIVI_TRANS_TH(th_vmsgt_vi, IMM_SX, th_vmsgt_vx, opivx_cmp_check_th)
 
+/* Vector Integer Min/Max Instructions */
+GEN_OPIVV_GVEC_TRANS_TH(th_vminu_vv, umin)
+GEN_OPIVV_GVEC_TRANS_TH(th_vmin_vv,  smin)
+GEN_OPIVV_GVEC_TRANS_TH(th_vmaxu_vv, umax)
+GEN_OPIVV_GVEC_TRANS_TH(th_vmax_vv,  smax)
+GEN_OPIVX_TRANS_TH(th_vminu_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmin_vx,  opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmaxu_vx, opivx_check_th)
+GEN_OPIVX_TRANS_TH(th_vmax_vx,  opivx_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vminu_vv)
-TH_TRANS_STUB(th_vminu_vx)
-TH_TRANS_STUB(th_vmin_vv)
-TH_TRANS_STUB(th_vmin_vx)
-TH_TRANS_STUB(th_vmaxu_vv)
-TH_TRANS_STUB(th_vmaxu_vx)
-TH_TRANS_STUB(th_vmax_vv)
-TH_TRANS_STUB(th_vmax_vx)
 TH_TRANS_STUB(th_vmul_vv)
 TH_TRANS_STUB(th_vmul_vx)
 TH_TRANS_STUB(th_vmulh_vv)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index 827650b325..da869e1069 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -1542,3 +1542,70 @@ GEN_TH_CMP_VX(th_vmsgt_vx_b, int8_t,  H1, TH_MSGT)
 GEN_TH_CMP_VX(th_vmsgt_vx_h, int16_t, H2, TH_MSGT)
 GEN_TH_CMP_VX(th_vmsgt_vx_w, int32_t, H4, TH_MSGT)
 GEN_TH_CMP_VX(th_vmsgt_vx_d, int64_t, H8, TH_MSGT)
+
+/* Vector Integer Min/Max Instructions */
+THCALL(TH_OPIVV2, th_vminu_vv_b, OP_UUU_B, H1, H1, H1, TH_MIN)
+THCALL(TH_OPIVV2, th_vminu_vv_h, OP_UUU_H, H2, H2, H2, TH_MIN)
+THCALL(TH_OPIVV2

[PATCH 22/65] target/riscv: Add integer compare instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  57 
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  69 +++---
 target/riscv/xtheadvector_helper.c| 127 ++
 3 files changed, 233 insertions(+), 20 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d3170ba91f..8f2dec158b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1638,3 +1638,60 @@ DEF_HELPER_6(th_vnsrl_vx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vmseq_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmseq_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsne_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsltu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmslt_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsleu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsle_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgtu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgtu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgtu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgtu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgt_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgt_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgt_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsgt_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 68810ff0ec..049d9da0a5 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1470,32 +1470,61 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  
 \
 GEN_OPIVI_NARROW_TRANS_TH(th_vnsra_vi, IMM_ZX, th_vnsra_vx)
 GEN_OPIVI_NARROW_TRANS_TH(th_vnsrl_vi, IMM_ZX, th_vnsrl_vx)
 
+/* Vector Integer Comparison Instructions

[PATCH 21/65] target/riscv: Add narrowing integer right shift instructions for XTheadVector

2024-04-12 Thread Huang Tao
The instructions have the same function as RVV1.0. Overall there are only
general differences between XTheadVector and RVV1.0.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 99 +--
 target/riscv/xtheadvector_helper.c| 26 +
 3 files changed, 132 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 77251af8c9..d3170ba91f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1625,3 +1625,16 @@ DEF_HELPER_6(th_vsra_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vnsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vnsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index d72320699c..68810ff0ec 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1377,18 +1377,105 @@ GEN_OPIVI_GVEC_TRANS_TH(th_vsll_vi, IMM_TRUNC_SEW, 
th_vsll_vx,  shli)
 GEN_OPIVI_GVEC_TRANS_TH(th_vsrl_vi, IMM_TRUNC_SEW, th_vsrl_vx,  shri)
 GEN_OPIVI_GVEC_TRANS_TH(th_vsra_vi, IMM_TRUNC_SEW, th_vsra_vx,  sari)
 
+/* Vector Narrowing Integer Right Shift Instructions */
+static bool opivv_narrow_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, false) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, true) &&
+th_check_reg(s, a->rs1, false) &&
+th_check_overlap_group(a->rd, 1 << s->lmul, a->rs2,
+   2 << s->lmul) &&
+(s->lmul < 0x3) && (s->sew < 0x3));
+}
+
+/* OPIVV with NARROW */
+#define GEN_OPIVV_NARROW_TRANS_TH(NAME)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{  \
+if (opivv_narrow_check_th(s, a)) { \
+uint32_t data = 0; \
+static gen_helper_gvec_4_ptr * const fns[3] = {\
+gen_helper_##NAME##_b, \
+gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, \
+}; \
+   \
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);  \
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);  \
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);  \
+tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), \
+   vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs1),\
+   vreg_ofs(s, a->rs2), tcg_env,   \
+   s->cfg_ptr->vlenb,  \
+   s->cfg_ptr->vlenb, data,\
+   fns[s->sew]);   \
+finalize_rvv_inst(s);  \
+return true;   \
+}  \
+return false;  \
+}
+GEN_OPIVV_NARROW_TRANS_TH(th_vnsra_vv)
+GEN_OPIVV_NARROW_TRANS_TH(th_vnsrl_vv)
+
+static bool opivx_narrow_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, false) &&
+th_check_reg(s, a->rd, false) &&
+th_chec

[PATCH 20/65] target/riscv: Add single-width bit shift instructions for XTheadVector

2024-04-12 Thread Huang Tao
The difference between XTheadVector and RVV1.0 is same as the other patchs:
1. Different mask reg layout.
2. Different tail/masked elements process policy.
3. Simpler acceleration judgment logic.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  25 
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  61 --
 target/riscv/xtheadvector_helper.c| 115 ++
 3 files changed, 192 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6599b2f2f5..77251af8c9 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1600,3 +1600,28 @@ DEF_HELPER_6(th_vxor_vx_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vxor_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vxor_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vxor_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vsll_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsll_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsrl_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 2b7b2cfe20..d72320699c 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1325,21 +1325,64 @@ GEN_OPIVI_GVEC_TRANS_TH(th_vand_vi, IMM_SX, th_vand_vx, 
andi)
 GEN_OPIVI_GVEC_TRANS_TH(th_vor_vi, IMM_SX, th_vor_vx,  ori)
 GEN_OPIVI_GVEC_TRANS_TH(th_vxor_vi, IMM_SX, th_vxor_vx, xori)
 
+/* Vector Single-Width Bit Shift Instructions */
+GEN_OPIVV_GVEC_TRANS_TH(th_vsll_vv,  shlv)
+GEN_OPIVV_GVEC_TRANS_TH(th_vsrl_vv,  shrv)
+GEN_OPIVV_GVEC_TRANS_TH(th_vsra_vv,  sarv)
+
+#define GVecGen2sFn32_Th GVecGen2sFn32
+
+/*
+ * This function is almost the copy of do_opivx_gvec_shift, except:
+ * 1) XTheadVector simplifies the judgment logic of whether
+ *to accelerate or not for its lack of fractional LMUL and
+ *VTA.
+ */
+static inline bool
+do_opivx_gvec_shift_th(DisasContext *s, arg_rmrr *a, GVecGen2sFn32_Th *gvec_fn,
+   gen_helper_opivx_th *fn)
+{
+if (a->vm && s->vl_eq_vlmax) {
+TCGv_i32 src1 = tcg_temp_new_i32();
+
+tcg_gen_trunc_tl_i32(src1, get_gpr(s, a->rs1, EXT_NONE));
+tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
+gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
+src1, MAXSZ(s), MAXSZ(s));
+
+finalize_rvv_inst(s);
+return true;
+}
+return opivx_trans_th(a->rd, a->rs1, a->rs2, a->vm, fn, s);
+}
+
+#define GEN_OPIVX_GVEC_SHIFT_TRANS_TH(NAME, SUF)  \
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a)\
+{ \
+static gen_helper_opivx * const fns[4] = {\
+gen_helper_##NAME##_b, gen_helper_##NAME##_h, \
+gen_helper_##NAME##_w, gen_helper_##NAME##_d, \
+};\
+if (!opivx_check_th(s, a)) {  \
+return false; \
+} \
+return do_opivx_gvec_shift_th(s, a, tcg_gen_gvec_##SUF, fns[s->sew]); \
+}
+
+GEN_OPIVX_GVEC_SHIFT_TRANS_TH(th_vsll_vx,  shls)
+GEN_OPIVX_GVEC_SHIFT_TRANS_TH(th_vsrl_vx,  shrs)
+GEN_OPIVX_GVEC_SHIFT_TRANS_TH(th_vsra_vx,  sars)
+
+GEN_O

[PATCH 19/65] target/riscv: Add bitwise logical instructions for XTheadVector

2024-04-12 Thread Huang Tao
Add bitwise logical instructions by resuing macros define before,
Therefore, the difference depending on the macros which commited
in other patchs.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 25 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 20 
 target/riscv/xtheadvector_helper.c| 51 +++
 3 files changed, 87 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 25fb8f81c7..6599b2f2f5 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1575,3 +1575,28 @@ DEF_HELPER_6(th_vmsbc_vxm_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vmsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vmsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vand_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vand_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vand_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vand_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vor_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vor_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vor_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vor_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vand_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vand_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vand_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vand_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vor_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vor_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vor_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vor_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vxor_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index a9e20a6dcb..2b7b2cfe20 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1314,21 +1314,23 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  
 \
 GEN_OPIVI_TRANS_TH(th_vadc_vim, IMM_SX, th_vadc_vxm, opivx_vadc_check_th)
 GEN_OPIVI_TRANS_TH(th_vmadc_vim, IMM_SX, th_vmadc_vxm, opivx_vmadc_check_th)
 
+/* Vector Bitwise Logical Instructions */
+GEN_OPIVV_GVEC_TRANS_TH(th_vand_vv, and)
+GEN_OPIVV_GVEC_TRANS_TH(th_vor_vv,  or)
+GEN_OPIVV_GVEC_TRANS_TH(th_vxor_vv, xor)
+GEN_OPIVX_GVEC_TRANS_TH(th_vand_vx, ands)
+GEN_OPIVX_GVEC_TRANS_TH(th_vor_vx,  ors)
+GEN_OPIVX_GVEC_TRANS_TH(th_vxor_vx, xors)
+GEN_OPIVI_GVEC_TRANS_TH(th_vand_vi, IMM_SX, th_vand_vx, andi)
+GEN_OPIVI_GVEC_TRANS_TH(th_vor_vi, IMM_SX, th_vor_vx,  ori)
+GEN_OPIVI_GVEC_TRANS_TH(th_vxor_vi, IMM_SX, th_vxor_vx, xori)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vand_vv)
-TH_TRANS_STUB(th_vand_vx)
-TH_TRANS_STUB(th_vand_vi)
-TH_TRANS_STUB(th_vor_vv)
-TH_TRANS_STUB(th_vor_vx)
-TH_TRANS_STUB(th_vor_vi)
-TH_TRANS_STUB(th_vxor_vv)
-TH_TRANS_STUB(th_vxor_vx)
-TH_TRANS_STUB(th_vxor_vi)
 TH_TRANS_STUB(th_vsll_vv)
 TH_TRANS_STUB(th_vsll_vx)
 TH_TRANS_STUB(th_vsll_vi)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index e5058d09f6..85fa69dd82 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -1223,3 +1223,54 @@ GEN_TH_VMADC_VXM(th_vmsbc_vxm_b, uint8_t,  H1, TH_MSBC)
 GEN_TH_VMADC_VXM(th_vmsbc_vxm_h, uint16_t, H2, TH_MSBC)
 GEN_TH_VMADC_VXM(th_vmsbc_vxm_w, uint32_t, H4, TH_MSBC)
 GEN_TH_VMADC_VXM(th_vmsbc_vxm_d, uint64_t, H8, TH_MSBC)
+
+/* Vector Bitwise Logical Instructions */
+THCALL(TH_OPIVV2, th_vand_vv_b, OP_SSS_B, H1, H1, H1, TH_AND)
+THCALL(TH_OPIVV2, th_vand_vv_h, OP_SSS_H, H2, H2, H2, TH_AND)
+THCALL(TH_OPIVV2, th_vand_vv_w, OP_SSS_W, H4, H4, H4, TH_AND)
+THCALL(TH_OPIVV2, th_vand_vv_d, OP_SSS_D, H8, H8, H8, TH_AND)
+THCALL(TH_OPIVV2, th_vor_vv_b, OP_SSS_B, H1, H1, H1, TH_OR)
+THCALL(TH_OPIVV2, th_vor_vv_h, OP_SSS_H, H2, H2, H2, TH_OR)
+THCALL(TH_OPIVV2, th_vor_vv_w, OP_SSS_W, H4, H4, H4, TH_OR)
+THCALL(TH_OPIVV2, th_vor_vv_d, OP_SSS_D, H8, H8, H8, TH_OR)
+THCALL(TH_OPIVV2, th_vxor_vv_b, OP_SSS_B, H1, H1

[PATCH 18/65] target/riscv: Add integer add-with-carry/sub-with-borrow instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector adc/sbc instructions diff from RVV1.0 in the following points:
1. Different mask reg layout.
2. Different tail elements process policy.
3. Different check policy.
4. When vm = 1, RVV1.0 vmadc and vmsbc perform the computation without
   carry-in/borrow-in. While XTheadVector does not have this kind of situation.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  33 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 139 +-
 target/riscv/xtheadvector_helper.c| 173 ++
 3 files changed, 335 insertions(+), 10 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3906f17079..25fb8f81c7 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1542,3 +1542,36 @@ DEF_HELPER_6(th_vwadd_wx_w, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vwsub_wx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwsub_wx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vwsub_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vadc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vvm_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vvm_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vvm_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vvm_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vxm_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadc_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vxm_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vxm_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmadc_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vxm_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vxm_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vxm_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vmsbc_vxm_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index f6aea9deff..a9e20a6dcb 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1185,22 +1185,141 @@ GEN_OPIWX_WIDEN_TRANS_TH(th_vwadd_wx)
 GEN_OPIWX_WIDEN_TRANS_TH(th_vwsubu_wx)
 GEN_OPIWX_WIDEN_TRANS_TH(th_vwsub_wx)
 
+/* Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions */
+
+/*
+ * This function is almost the copy of opivv_trans, except:
+ * 1) XTheadVector using different data encoding, add MLEN,
+ *delete VTA and VMA.
+ */
+static bool opivv_trans_th(uint32_t vd, uint32_t vs1, uint32_t vs2, uint32_t 
vm,
+   gen_helper_gvec_4_ptr *fn, DisasContext *s)
+{
+uint32_t data = 0;
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+tcg_gen_gvec_4_ptr(vreg_ofs(s, vd), vreg_ofs(s, 0),
+   vreg_ofs(s, vs1), vreg_ofs(s, vs2),
+   tcg_env, s->cfg_ptr->vlenb,
+   s->cfg_ptr->vlenb, data, fn);
+finalize_rvv_inst(s);
+return true;
+}
+
+/* OPIVV without GVEC IR */
+#define GEN_OPIVV_TRANS_TH(NAME, CHECK)\
+static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
+{  \
+if (CHECK(s, a)) { \
+static gen_helper_gvec_4_ptr * const fns[4] = {\
+gen_helper_##NAME##_b, gen_helper_##NAME##_h,  \
+gen_helper_##NAME##_w, gen_helper_##NAME##_d,  \
+}; \
+ret

[PATCH 17/65] target/riscv: Add widening integer add/subtract instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we reuse lots of funtions of single-width operations,
except do_opivv_th. The reason why do_opivv_widen_th does not call
do_opivv_th is that widen operation is not applicable to using GVEC
to accerlate the vector operations.

The difference between XTheadVector and RVV1.0 is as same as the single-
width operation patch mentions.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  49 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 197 --
 target/riscv/vector_helper.c  |  15 --
 target/riscv/vector_internals.h   |   9 +
 target/riscv/xtheadvector_helper.c| 100 +
 5 files changed, 339 insertions(+), 31 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 6a7d2c0a78..3906f17079 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1493,3 +1493,52 @@ DEF_HELPER_6(th_vrsub_vx_b, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vrsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vrsub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vwaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwaddu_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsubu_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwadd_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vwsub_wx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 6836e9a3b7..f6aea9deff 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -1004,28 +1004,193 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a) 
\
 GEN_OPIVI_GVEC_TRANS_TH(th_vadd_vi, IMM_SX, th_vadd_vx, addi)
 GEN_OPIVI_GVEC_TRANS_TH(th_vrsub_vi, IMM_SX, th_vrsub_vx, rsubi)
 
+/* Vector Widening Integer Add/Subtract */
+
+/* OPIVV with WIDEN */
+static bool opivv_widen_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_i

[PATCH 16/65] target/riscv: Add single-width integer add and subtract instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add single-width integer add and subtract instructions,
including th.vadd.vv/vx/vi, th.vsub.vv/vx and th.vrsub.vx/vi, also show
the way we implement XTheadVector integer arithmetic instructions.
These instructions diff from RVV1.0 in the following points:
1. Different mask reg layout. For mask bit of element i, XTheadVector
   locates it in bit[mlen], while RVV1.0 locates it in bit[i].
2. Different tail/masked elements process policy. XTheadVector keep the
   masked element value and clear the tail elements. While RVV1.0 has vta
   and vma to set the processing policy, keeping value or overwrite it
   with 1s.
3. Different check policy. XTheadVector does not have fractional lmul, so
   we can use simpler check function.
4. XTheadVector simplifies the judgment logic of whether to accelerate or
   not for its lack of fractional LMUL and vta.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  21 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 242 +-
 target/riscv/vector_helper.c  |   4 -
 target/riscv/vector_internals.h   |   4 +
 target/riscv/xtheadvector_helper.c| 153 +++
 5 files changed, 413 insertions(+), 11 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c2a26acabc..6a7d2c0a78 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1472,3 +1472,24 @@ DEF_HELPER_6(th_vamominw_v_w,  void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(th_vamomaxw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+
+DEF_HELPER_6(th_vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrsub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrsub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrsub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vrsub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 2bcd9b0832..6836e9a3b7 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -769,19 +769,247 @@ GEN_TH_TRANS(th_vamomaxd_v, 15, rwdvm, amo_op_th, 
amo_check64_th)
 GEN_TH_TRANS(th_vamominud_v, 16, rwdvm, amo_op_th, amo_check64_th)
 GEN_TH_TRANS(th_vamomaxud_v, 17, rwdvm, amo_op_th, amo_check64_th)
 
+/*
+ * Vector Integer Arithmetic Instructions
+ */
+
+/*
+ * check function
+ * 1) check overlap mask, XTheadVector can overlap mask reg v0 when
+ *lmul == 1, while RVV1.0 can not.
+ * 2) check reg, XTheadVector Vector register numbers are multiples
+ *of integral LMUL, while RVV1.0 has fractional LMUL, which allows
+ *any vector register.
+ */
+static bool opivv_check_th(DisasContext *s, arg_rmrr *a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_overlap_mask(s, a->rd, a->vm, false) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_reg(s, a->rs1, false));
+}
+
+#define GVecGen3Fn_Th GVecGen3Fn
+/*
+ * This function is almost the copy of do_opivv_gvec, except:
+ * 1) XTheadVector using different data encoding, add MLEN,
+ *delete VTA and VMA.
+ * 2) XTheadVector simplifies the judgment logic of whether
+ *to accelerate or not for its lack of fractional LMUL and
+ *VTA.
+ */
+static inline bool
+do_opivv_gvec_th(DisasContext *s, arg_rmrr *a, GVecGen3Fn_Th *gvec_fn,
+ gen_helper_gvec_4_ptr *fn)
+{
+if (a->vm && s->vl_eq_vlmax) {
+gvec_fn(s->sew, vreg_ofs(s, a->rd),
+vreg_ofs(s, a->rs2), vreg_ofs(s, a->rs1),
+MAXSZ(s), MAXSZ(s));
+} else {
+uint32_t data = 0;
+/* Need extra mlen to find the mask bit */
+   

[PATCH 15/65] target/riscv: Add vector amo operations for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add the vector amo instructions(Zvamo) for XTheadVector.
Zvamo is unsupported by RVV1.0.
The action of Zvamo is similar to Zaamo(atomic operations from the standard
A extension).

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  28 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 155 --
 target/riscv/xtheadvector_helper.c| 136 +++
 3 files changed, 301 insertions(+), 18 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1bf4c38c4b..c2a26acabc 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1444,3 +1444,31 @@ DEF_HELPER_5(th_vlhuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlhuff_v_d, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlwuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlwuff_v_d, void, ptr, ptr, tl, env, i32)
+
+DEF_HELPER_6(th_vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoaddw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoaddd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoxorw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoxord_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoandw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoandd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoorw_v_d,   void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoord_v_d,   void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamominw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomind_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoaddw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoxorw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoandw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamoorw_v_w,   void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamominw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 3548a6c2cc..2bcd9b0832 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -632,30 +632,149 @@ GEN_TH_TRANS(th_vlbuff_v, 4, r2nfvm, ldff_op_th, 
ld_us_check_th)
 GEN_TH_TRANS(th_vlhuff_v, 5, r2nfvm, ldff_op_th, ld_us_check_th)
 GEN_TH_TRANS(th_vlwuff_v, 6, r2nfvm, ldff_op_th, ld_us_check_th)
 
+
+/*
+ * vector atomic operation
+ */
+typedef void gen_helper_amo(TCGv_ptr, TCGv_ptr, TCGv, TCGv_ptr,
+TCGv_env, TCGv_i32);
+static bool amo_trans_th(uint32_t vd, uint32_t rs1, uint32_t vs2,
+ uint32_t data, gen_helper_amo *fn, DisasContext *s)
+{
+TCGv_ptr dest, mask, index;
+TCGv base;
+TCGv_i32 desc;
+
+dest = tcg_temp_new_ptr();
+mask = tcg_temp_new_ptr();
+index = tcg_temp_new_ptr();
+base = get_gpr(s, rs1, EXT_NONE);
+desc = tcg_constant_i32(simd_desc(s->cfg_ptr->vlenb,
+  s->cfg_ptr->vlenb, data));
+
+tcg_gen_addi_ptr(dest, tcg_env, vreg_ofs(s, vd));
+tcg_gen_addi_ptr(index, tcg_env, vreg_ofs(s, vs2));
+tcg_gen_addi_ptr(mask, tcg_env, vreg_ofs(s, 0));
+
+mark_vs_dirty(s);
+
+fn(dest, mask, base, index, tcg_env, desc);
+
+finalize_rvv_inst(s);
+return true;
+}
+
+static bool amo_op_th(DisasContext *s, arg_rwdvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_amo *fn;
+static gen_helper_amo *const fnsw[9] = {
+/* no atomic operation */
+gen_helper_th_vamoswapw_v_w,
+gen_helper_th_vamoaddw_v_w,
+gen_helper_th_vamoxorw_v_w,
+gen_helper_th_vamoandw_v_w,
+gen_helper_th_vamoorw_v_w,
+gen_helper_th_vamominw_v_w,
+gen_helper_th_vamomaxw_v_w,
+gen_helper_th_vamominuw_v_w,
+gen_helper_th_vamomaxuw_v_w
+};
+static gen_helper_amo *const fnsd[18] = {
+gen_helper_th_vamoswapw_v_d,
+gen_helper_th_vamoaddw_v_d,
+gen_helper_th_vamoxorw_v_d,
+gen_helper_th_vamoandw_v_d,
+gen_helper_th_vamoorw_v_d,
+gen_helper_th_vamominw_v_d,
+gen_helper_th_vamomaxw_v_d,
+gen_helper_th_v

[PATCH 14/65] target/riscv: Add unit-stride fault-only-first instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector unit-stride fault-only-first instructions diff from RVV1.0 in
the following points:
1. Different mask reg layout.
2. Different vector reg element width.
3. Different tail/masked elements process policy.
4. Different check policy.
The detials of the difference are the same as unit-stride load instructions,
as unit-stride fault-only-first instructions are the he special cases of
unit-stride load operations.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  22 
 .../riscv/insn_trans/trans_xtheadvector.c.inc |  57 +++--
 target/riscv/vector_helper.c  |   2 +-
 target/riscv/vector_internals.h   |   5 +
 target/riscv/xtheadvector_helper.c| 119 ++
 5 files changed, 197 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index fd81db2f74..1bf4c38c4b 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1422,3 +1422,25 @@ DEF_HELPER_6(th_vsxe_v_b, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_5(th_vlbff_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbff_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhff_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vleff_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vleff_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vleff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vleff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbuff_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbuff_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbuff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbuff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhuff_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhuff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhuff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwuff_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwuff_v_d, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 68a2a9a0cf..3548a6c2cc 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -582,19 +582,62 @@ GEN_TH_TRANS(th_vsxh_v, 1, rnfvm, st_index_op_th, 
st_index_check_th)
 GEN_TH_TRANS(th_vsxw_v, 2, rnfvm, st_index_op_th, st_index_check_th)
 GEN_TH_TRANS(th_vsxe_v, 3, rnfvm, st_index_op_th, st_index_check_th)
 
+/*
+ * unit stride fault-only-first load
+ */
+
+/*
+ * This function is almost the copy of ldff_op, except:
+ * 1) different data encoding.
+ * 2) XTheadVector has more insns to handle zero/sign-extended.
+ */
+static bool ldff_op_th(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_us_th *fn;
+static gen_helper_ldst_us_th * const fns[7][4] = {
+{ gen_helper_th_vlbff_v_b,  gen_helper_th_vlbff_v_h,
+  gen_helper_th_vlbff_v_w,  gen_helper_th_vlbff_v_d },
+{ NULL, gen_helper_th_vlhff_v_h,
+  gen_helper_th_vlhff_v_w,  gen_helper_th_vlhff_v_d },
+{ NULL, NULL,
+  gen_helper_th_vlwff_v_w,  gen_helper_th_vlwff_v_d },
+{ gen_helper_th_vleff_v_b,  gen_helper_th_vleff_v_h,
+  gen_helper_th_vleff_v_w,  gen_helper_th_vleff_v_d },
+{ gen_helper_th_vlbuff_v_b, gen_helper_th_vlbuff_v_h,
+  gen_helper_th_vlbuff_v_w, gen_helper_th_vlbuff_v_d },
+{ NULL, gen_helper_th_vlhuff_v_h,
+  gen_helper_th_vlhuff_v_w, gen_helper_th_vlhuff_v_d },
+{ NULL, NULL,
+  gen_helper_th_vlwuff_v_w, gen_helper_th_vlwuff_v_d }
+};
+
+fn =  fns[seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA_TH, NF, a->nf);
+return ldff_trans(a->rd, a->rs1, data, fn, s);
+}
+
+GEN_TH_TRANS(th_vlbff_v, 0, r2nfvm, ldff_op_th, ld_us_check_th)
+GEN_TH_TRANS(th_vlhff_v, 1, r2nfvm, ldff_op_th, ld_us_check_th)
+GEN_TH_TRANS(th_vlwff_v, 2, r2nfvm, ldff_op_th, ld_us_check_th)
+GEN_TH_TRANS(th_vleff_v, 3, r2nfvm, ldff_op_th, ld_us_check_th)
+GEN_TH_TRANS(th_vlbuff_v, 4, r2nfvm, ldff_op_th, ld_us_check_th)
+GEN_TH_TRANS(th_vlhuff_v, 

[PATCH 13/65] target/riscv: Add indexed store instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector indexed store instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout.
2. Different access width. As same as XTheadVector indexed load instructions,
   except store does not need to distinguish between zero and sign extended.
3. Different masked elements process policy.
4. Different check policy.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 49 +--
 target/riscv/xtheadvector_helper.c| 24 +
 3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 733071bdc6..fd81db2f74 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1409,3 +1409,16 @@ DEF_HELPER_6(th_vlxhu_v_w, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(th_vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(th_vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 8148097de3..68a2a9a0cf 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -537,6 +537,51 @@ GEN_TH_TRANS(th_vlxbu_v, 4, rnfvm, ld_index_op_th, 
ld_index_check_th)
 GEN_TH_TRANS(th_vlxhu_v, 5, rnfvm, ld_index_op_th, ld_index_check_th)
 GEN_TH_TRANS(th_vlxwu_v, 6, rnfvm, ld_index_op_th, ld_index_check_th)
 
+/*
+ * This function is almost the copy of st_index_op, except:
+ * 1) different data encoding.
+ */
+static bool st_index_op_th(DisasContext *s, arg_rnfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_index_th *fn;
+static gen_helper_ldst_index_th * const fns[4][4] = {
+{ gen_helper_th_vsxb_v_b,  gen_helper_th_vsxb_v_h,
+  gen_helper_th_vsxb_v_w,  gen_helper_th_vsxb_v_d },
+{ NULL,gen_helper_th_vsxh_v_h,
+  gen_helper_th_vsxh_v_w,  gen_helper_th_vsxh_v_d },
+{ NULL,NULL,
+  gen_helper_th_vsxw_v_w,  gen_helper_th_vsxw_v_d },
+{ gen_helper_th_vsxe_v_b,  gen_helper_th_vsxe_v_h,
+  gen_helper_th_vsxe_v_w,  gen_helper_th_vsxe_v_d }
+};
+
+fn =  fns[seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA_TH, NF, a->nf);
+return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s);
+}
+
+static bool st_index_check_th(DisasContext *s, arg_rnfvm* a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_reg(s, a->rs2, false) &&
+th_check_nf(s, a->rd, a->nf));
+}
+
+GEN_TH_TRANS(th_vsxb_v, 0, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxh_v, 1, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxw_v, 2, rnfvm, st_index_op_th, st_index_check_th)
+GEN_TH_TRANS(th_vsxe_v, 3, rnfvm, st_index_op_th, st_index_check_th)
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
@@ -550,10 +595,6 @@ TH_TRANS_STUB(th_vleff_v)
 TH_TRANS_STUB(th_vlbuff_v)
 TH_TRANS_STUB(th_vlhuff_v)
 TH_TRANS_STUB(th_vlwuff_v)
-TH_TRANS_STUB(th_vsxb_v)
-TH_TRANS_STUB(th_vsxh_v)
-TH_TRANS_STUB(th_vsxw_v)
-TH_TRANS_STUB(th_vsxe_v)
 TH_TRANS_STUB(th_vamoswapw_v)
 TH_TRANS_STUB(th_vamoaddw_v)
 TH_TRANS_STUB(th_vamoxorw_v)
diff --git a/target/riscv/xtheadvector_helper.c 
b/target/riscv/xtheadvector_helper.c
index a9ae157296..22af4774df 100644
--- a/target/riscv/xtheadvector_helper.c
+++ b/target/riscv/xtheadvector_helper.c
@@ -518,3 +518,27 @@ GEN_TH_LD_INDEX(th_vlxhu_v_w, uint16_t, uint32_t, idx_w, 
ldhu_w, clearl_th)
 GEN_TH_LD_INDEX(th_vlxhu_v_d, uint16_t, uint64_t, idx_d, ldhu_d,

[PATCH 12/65] target/riscv: Add indexed load instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector indexed load instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout.
2. Different access width. XTheadVector has 7 instructions, th.vlx{b,h,w}.v,
   th.vlx{b,h,w}u.v and th.vlxe.v. Their index element width and reg data
   element width are all SEW-bit. The difference between b,h,w,e is memory
   access width. {b,h,w,e} stands for 8/16/32/SEW-bit. Therefore, it leads to
   the difference of zero and sign extend. "u" stands for zero-extened, the
   lack of "u" stands for the other.
   RVV1.0 instructions vlxei{8,16,32,64}.v. {8,16,32,64} are the width of
   index element, while the memory and data reg element width are both SEW-bit.
3. Different tail/masked elements process policy.
4. Different check policy. In RVV1.0, in some situations, the destination
   vector register group can overlap the source vector register group of a
   different element width. While XTheadVector not.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 22 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 91 +--
 target/riscv/vector_helper.c  |  4 +-
 target/riscv/vector_internals.h   |  4 +
 target/riscv/xtheadvector_helper.c| 82 +
 5 files changed, 194 insertions(+), 9 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index eb31784e18..733071bdc6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1387,3 +1387,25 @@ DEF_HELPER_5(th_vse_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vse_v_w_mask, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vse_v_d, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vse_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_6(th_vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(th_vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 9b88ea2fa4..8148097de3 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -179,6 +179,20 @@ static bool th_check_nf(DisasContext *s, uint32_t vd, 
uint32_t nf)
 return size <= 8 && vd + size <= 32;
 }
 
+/*
+ * The destination vector register group cannot overlap a source vector 
register
+ * group of a different element width.
+ *
+ * The overlap check rule is different from RVV1.0. The function
+ * "require_noover" describes the check rule in RVV1.0. In general, in some
+ * situations, the destination vector register group can overlap the source
+ * vector register group of a different element width. While XTheadVector not.
+ */
+static inline bool th_check_overlap_group(int rd, int dlen, int rs, int slen)
+{
+return ((rd >= rs + slen) || (rs >= rd + dlen));
+}
+
 /*
  * common translation macro
  *
@@ -453,6 +467,76 @@ GEN_TH_TRANS(th_vsh_v, 1, r2nfvm, st_us_op_th, 
st_us_check_th)
 GEN_TH_TRANS(th_vsw_v, 2, r2nfvm, st_us_op_th, st_us_check_th)
 GEN_TH_TRANS(th_vse_v, 3, r2nfvm, st_us_op_th, st_us_check_th)
 
+/*
+ * index load and store
+ */
+
+#define gen_helper_ldst_index_th gen_helper_ldst_index
+
+/*
+ * This function is almost the copy of ld_index_op, except:
+ * 1) different data encoding
+ * 2) XTheadVector has more insns to handle zero/sign-extended.
+ */
+static bool ld_index_op_th(DisasContext *s, arg_rnfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_index_th *fn;
+static gen_helper_ldst_index_th * const fns[7][4] = {
+{ gen_helper_th_vlxb_v_b,  gen_helper_th_vlxb_v_h,
+  gen_helper_th_vlxb_v_w,  gen_helper_th_vlxb_v_d },
+   

[PATCH 11/65] target/riscv: Add unit-stride store instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector unit-stride store instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout.
2. Different vector reg element width.
3. Different tail/masked elements process policy.
4. Different check policy.

The detials of the difference are the same as strided store instruction, as
unit-stride is the special case of strided operations.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 26 
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 59 +--
 target/riscv/xtheadvector_helper.c| 31 ++
 3 files changed, 112 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f2fa8425b3..eb31784e18 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1361,3 +1361,29 @@ DEF_HELPER_5(th_vlwu_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlwu_v_w_mask, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlwu_v_d, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(th_vlwu_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_b_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsb_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsh_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsw_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsw_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsw_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vsw_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_b_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vse_v_d_mask, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index eb910acf40..9b88ea2fa4 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -398,6 +398,61 @@ GEN_TH_TRANS(th_vlbu_v, 4, r2nfvm, ld_us_op_th, 
ld_us_check_th)
 GEN_TH_TRANS(th_vlhu_v, 5, r2nfvm, ld_us_op_th, ld_us_check_th)
 GEN_TH_TRANS(th_vlwu_v, 6, r2nfvm, ld_us_op_th, ld_us_check_th)
 
+/*
+ * This function is almost the copy of st_us_op, except:
+ * 1) different data encoding.
+ * 2) XTheadVector has more situations, depending on SEW.
+ */
+static bool st_us_op_th(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_us_th *fn;
+static gen_helper_ldst_us_th * const fns[2][4][4] = {
+/* masked unit stride load and store */
+{ { gen_helper_th_vsb_v_b_mask,  gen_helper_th_vsb_v_h_mask,
+gen_helper_th_vsb_v_w_mask,  gen_helper_th_vsb_v_d_mask },
+  { NULL,gen_helper_th_vsh_v_h_mask,
+gen_helper_th_vsh_v_w_mask,  gen_helper_th_vsh_v_d_mask },
+  { NULL,NULL,
+gen_helper_th_vsw_v_w_mask,  gen_helper_th_vsw_v_d_mask },
+  { gen_helper_th_vse_v_b_mask,  gen_helper_th_vse_v_h_mask,
+gen_helper_th_vse_v_w_mask,  gen_helper_th_vse_v_d_mask } },
+/* unmasked unit stride store */
+{ { gen_helper_th_vsb_v_b,  gen_helper_th_vsb_v_h,
+gen_helper_th_vsb_v_w,  gen_helper_th_vsb_v_d },
+  { NULL,   gen_helper_th_vsh_v_h,
+gen_helper_th_vsh_v_w,  gen_helper_th_vsh_v_d },
+  { NULL,   NULL,
+gen_helper_th_vsw_v_w,  gen_helper_th_vsw_v_d },
+  { gen_helper_th_vse_v_b,  gen_helper_th_vse_v_h,
+gen_helper_th_vse_v_w,  gen_helper_th_vse_v_d } }
+};
+
+fn =  fns[a->vm][seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA_TH, NF, a->nf);
+return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
+}
+
+static bool st_us_check_th(DisasContext *s, arg_r2nfvm* a)
+{
+return

[PATCH 10/65] target/riscv: Add unit-stride load instructions for XTheadVector

2024-04-12 Thread Huang Tao
TheadVector unit-stride load instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout.
2. Different vector reg element width.
3. Different tail/masked elements process policy.
4. Different check function.

The detials of the difference are the same as strided load instruction, as
unit-stride is the special case of strided operations.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 44 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 84 --
 target/riscv/xtheadvector_helper.c| 86 +++
 3 files changed, 207 insertions(+), 7 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index bfd6bd9b13..f2fa8425b3 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1317,3 +1317,47 @@ DEF_HELPER_6(th_vsse_v_b, void, ptr, ptr, tl, tl, env, 
i32)
 DEF_HELPER_6(th_vsse_v_h, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(th_vsse_v_w, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(th_vsse_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlb_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlh_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlw_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlw_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlw_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlw_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_b_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vle_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_b, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_b_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlbu_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_h, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_h_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlhu_v_d_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwu_v_w, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwu_v_w_mask, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwu_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(th_vlwu_v_d_mask, void, ptr, ptr, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 48004bf0d6..eb910acf40 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -321,19 +321,89 @@ GEN_TH_TRANS(th_vssh_v, 1, rnfvm, st_stride_op_th, 
st_stride_check_th)
 GEN_TH_TRANS(th_vssw_v, 2, rnfvm, st_stride_op_th, st_stride_check_th)
 GEN_TH_TRANS(th_vsse_v, 3, rnfvm, st_stride_op_th, st_stride_check_th)
 
+/*
+ * unit stride load and store
+ */
+
+#define gen_helper_ldst_us_th gen_helper_ldst_us
+
+/*
+ * This function is almost the copy of ld_us_op, except:
+ * 1) different data encoding
+ * 2) XTheadVector has more insns to handle zero/sign-extended.
+ */
+static bool ld_us_op_th(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_us_th *fn;
+static gen_helper_ldst_us_th * const fns[2][7][4] = {
+/* masked unit stride load */
+{ { gen_helper_th_vlb_v_b_mask,  gen_helper_th_vlb_v_h_mask,
+gen_helper_th_vlb_v_w_mask,  gen_helper_th_vlb_v_d_mask },
+  { NULL,gen_helper_th_vlh_v_h_mask,
+gen_helper_th_vlh_v_w_mask,  gen_helper_th_vlh_v_d_mask },
+  { NULL,NULL

[PATCH 09/65] target/riscv: Add strided store instructions for XTheadVector

2024-04-12 Thread Huang Tao
XTheadVector strided store instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout. The difference is same as strided load 
instructions.
2. Different vector reg element width. XTheadVector has 4 instructions,
   th.vss{b,h,w,e}.v. They store SEW-bit reg data to 8/16/32/SEW-bit memory 
loaction.
   RVV1.0 has 4 instructions, vsse{8,16,32,64}.v. They store 8/16/32/64-bit reg 
data
   to 8/16/32/64-bit memory location.
3. Different tail/masked elements process policy. The difference is same as 
strided
   load instructions.
4. Different check policy. XTheadVector does not have fractional lmul and emul,
   so we can use simpler check function.

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h | 13 +
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 56 +--
 target/riscv/xtheadvector_helper.c| 50 +
 3 files changed, 115 insertions(+), 4 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 8decfc20cc..bfd6bd9b13 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1304,3 +1304,16 @@ DEF_HELPER_6(th_vlshu_v_w, void, ptr, ptr, tl, tl, env, 
i32)
 DEF_HELPER_6(th_vlshu_v_d, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(th_vlswu_v_w, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(th_vlswu_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssb_v_b, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssb_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssb_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssb_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssh_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssh_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssh_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssw_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vssw_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vsse_v_b, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vsse_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vsse_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vsse_v_d, void, ptr, ptr, tl, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 72481fdd5f..48004bf0d6 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -269,6 +269,58 @@ GEN_TH_TRANS(th_vlsbu_v, 4, rnfvm, ld_stride_op_th, 
ld_stride_check_th)
 GEN_TH_TRANS(th_vlshu_v, 5, rnfvm, ld_stride_op_th, ld_stride_check_th)
 GEN_TH_TRANS(th_vlswu_v, 6, rnfvm, ld_stride_op_th, ld_stride_check_th)
 
+/*
+ * This function is almost the copy of st_stride_op, except:
+ * 1) XTheadVector using different data encoding, add MLEN,
+ *delete VTA and VMA.
+ * 2) XTheadVector has more situations. vss{8,16,32,64}.v decide the
+ *reg and mem width both equal 8/16/32/64. As for th.vss{b,h,w}.v, the
+ *reg width equals SEW, and the mem width equals 8/16/32. The reg and
+ *mem width of th.vsse.v both equal SEW. Therefore, we need to add more
+ *helper functions depending on SEW.
+ */
+static bool st_stride_op_th(DisasContext *s, arg_rnfvm *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_ldst_stride_th *fn;
+static gen_helper_ldst_stride_th * const fns[4][4] = {
+/* masked stride store */
+{ gen_helper_th_vssb_v_b,  gen_helper_th_vssb_v_h,
+  gen_helper_th_vssb_v_w,  gen_helper_th_vssb_v_d },
+{ NULL,gen_helper_th_vssh_v_h,
+  gen_helper_th_vssh_v_w,  gen_helper_th_vssh_v_d },
+{ NULL,NULL,
+  gen_helper_th_vssw_v_w,  gen_helper_th_vssw_v_d },
+{ gen_helper_th_vsse_v_b,  gen_helper_th_vsse_v_h,
+  gen_helper_th_vsse_v_w,  gen_helper_th_vsse_v_d }
+};
+
+data = FIELD_DP32(data, VDATA_TH, MLEN, s->mlen);
+data = FIELD_DP32(data, VDATA_TH, VM, a->vm);
+data = FIELD_DP32(data, VDATA_TH, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA_TH, NF, a->nf);
+fn =  fns[seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
+}
+
+/* store does not need to check overlap */
+static bool st_stride_check_th(DisasContext *s, arg_rnfvm* a)
+{
+return (require_xtheadvector(s) &&
+vext_check_isa_ill(s) &&
+th_check_reg(s, a->rd, false) &&
+th_check_nf(s, a->rd, a->nf));
+}
+
+GEN_TH_TRANS(th_vssb_v, 0, rnfvm, st_stride_op_th, st_stride_check_th)
+GEN_TH_TRANS(th_vssh_v, 1, rnfvm, st_stride_op_th, st_stride_check_th)
+GEN_TH_TRANS(th_vssw_v, 2, rnfvm, st_stride_op_th, st_stride_check_th)
+GEN_TH_TRANS(th_vsse_v, 3, rnfvm, st_stride_op_th, st_stride_check_th)
+
 #define TH_TRANS_STUB(NAME)  

[PATCH 08/65] target/riscv: Add strided load instructions for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we add one strided load instructions to show the way
we implement XTheadVector load/store instructions. We use independent
functions to achieve decoupling.

XTheadVector strided load instructions diff from RVV1.0 in the following
points:
1. Different mask reg layout. For mask bit of element i, XTheadVector
   locates it in bit[mlen*i] (mlen = SEW/LMUL), while RVV1.0 locates it
   in bit[i].
2. Different vector reg element width. XTheadVector has 7 instructions,
   th.vls{b,h,w}.v, th.vls{b,h,w}u.v and th.vlse.v. "b/h/w" represents
   byte/halfword, "u" represents unsigned. The insn th.vls{b,h,w}.v
   strided load 8/16/32-bit memory data and sign-extended to SEW-bit vector
   element if SEW > 8/16/32. The insn th.vls{b,h,w}u.v strided load
   8/16/32-bit memory data and zero-extended to SEW-bit vector element
   if SEW > 8/16/32. The insn th.vlse strided load SEW-bit memory data
   to SEW-bit vector element.
   RVV1.0 has 4 instructions, vlse{8,16,32,64}.v. They load 8/16/32/64-bit
   memory data to 8/16/32/64-bit vector element.
   So XTheadVector has more instructions to handle zero/sign-extened.
3. Different tail/masked elements process policy. XTheadVector keep the
   masked element value and clear the tail elements. While RVV1.0 has vta
   and vma to set the processing policy, keeping value or overwrite it with
   1s.
4. Different check policy. XTheadVector does not have fractional lmul, so we
   can use simpler check function

Signed-off-by: Huang Tao 
---
 target/riscv/helper.h |  24 ++
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 160 ++-
 target/riscv/internals.h  |  12 +
 target/riscv/meson.build  |   1 +
 target/riscv/vector_helper.c  |   5 -
 target/riscv/vector_internals.h   |   6 +
 target/riscv/xtheadvector_helper.c| 271 ++
 7 files changed, 467 insertions(+), 12 deletions(-)
 create mode 100644 target/riscv/xtheadvector_helper.c

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 8a63523851..8decfc20cc 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1280,3 +1280,27 @@ DEF_HELPER_4(vgmul_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_5(vsm4k_vi, void, ptr, ptr, i32, env, i32)
 DEF_HELPER_4(vsm4r_vv, void, ptr, ptr, env, i32)
 DEF_HELPER_4(vsm4r_vs, void, ptr, ptr, env, i32)
+
+ /* XTheadVector functions */
+DEF_HELPER_6(th_vlsb_v_b, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsb_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsb_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsb_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsh_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsh_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsh_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsw_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsw_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlse_v_b, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlse_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlse_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlse_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsbu_v_b, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsbu_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsbu_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlsbu_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlshu_v_h, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlshu_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlshu_v_d, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlswu_v_w, void, ptr, ptr, tl, tl, env, i32)
+DEF_HELPER_6(th_vlswu_v_d, void, ptr, ptr, tl, tl, env, i32)
diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 0461b53893..72481fdd5f 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -116,6 +116,159 @@ static bool trans_th_vsetvli(DisasContext *s, 
arg_th_vsetvli *a)
 return th_vsetvl(s, a->rd, a->rs1, s2);
 }
 
+/* check functions */
+
+/*
+ * There are two rules check here.
+ * 1. Vector register numbers are multiples of LMUL.
+ * 2. For all widening instructions, the destination LMUL value must also be
+ *a supported LMUL value.
+ *
+ * This function is the combination of require_align and 
vext_wide_check_common,
+ * except:
+ * 1) In require_align, if LMUL < 0, i.e. fractional LMUL, any vector register
+ *is allowed, we do not need to check this situation.
+ * 2) In vext_wide_check_common, RVV check all the constraints of widen
+ *instruction, including SEW < 64, 2*SEW lmul : 1 << s->lmul;
+
+return !((s->lmul == 0x3 && widen) || (reg % legal));
+}
+
+/*
+ * There are two rules check here.
+ * 1. The destination vector register gro

[PATCH 07/65] target/riscv: implement th.vsetvl{i} for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we implement the th.vetvl{i} instructions. In the th_vsetvl
function, some work has been done according to the difference between RVV1.0
and XTheadVector.

th.vsetvl{i} differs from vsetvl{i} in the following points:
1. th.vsetvl{i} does not have the option to maintain the existing vl.
2. XTheadVector has different vtype encoding from RVV1.0.

Signed-off-by: Huang Tao 
---
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 93 ++-
 1 file changed, 91 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
index 2dd77d74ab..0461b53893 100644
--- a/target/riscv/insn_trans/trans_xtheadvector.c.inc
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -25,14 +25,103 @@ static bool require_xtheadvector(DisasContext *s)
s->mstatus_vs != EXT_STATUS_DISABLED;
 }
 
+/*
+ * XTheadVector has different vtype encoding from RVV1.0.
+ * We recode the value in RVV1.0 vtype format to reuse the RVV1.0 functions.
+ * In RVV1.0:
+ *   vtype[7] -> vma
+ *   vtype[6] -> vta
+ *   vtype[5:3] -> vsew
+ *   vtype[2:0] -> vlmul
+ * In XTheadVector:
+ *   vtype[6:5] -> vediv (reserved)
+ *   vtype[4:2] -> vsew
+ *   vtype[1:0] -> vlmul
+ *
+ * Also th_vsetvl does not have feature of keeping existing vl when
+ * (rd == 0 && rs1 == 0)
+ */
+static bool th_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
+{
+TCGv temp = tcg_temp_new();
+TCGv dst_s2 = tcg_temp_new();
+/* illegal value check*/
+TCGLabel *legal = gen_new_label();
+tcg_gen_shri_tl(temp, s2, 5);
+tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, legal);
+/*
+ * if illegal, set unsupported value
+ * s2[8:5] == 0b111, which is reserved field in XTheadVector
+ */
+tcg_gen_movi_tl(s2, 0xff);
+gen_set_label(legal);
+/* get vlmul, s2[1:0] -> dst_s2[2:0] */
+tcg_gen_andi_tl(dst_s2, s2, 0x3);
+/* get vsew, s2[4:2] -> dst_s2[5:3] */
+tcg_gen_andi_tl(temp, s2, 0x1c);
+tcg_gen_shli_tl(temp, temp, 1);
+tcg_gen_or_tl(dst_s2, dst_s2, temp);
+/*
+ * get reserved field when illegal, s2[7:5] -> dst_s2[10:8]
+ * avoid dst_s2[7:6], because dst_s2[7:6] are vma and vta.
+ *
+ * Make the dst_s2 an illegal value for RVV1.0, leads to the illegal
+ * operation processing flow.
+ */
+tcg_gen_andi_tl(temp, s2, 0xe0);
+tcg_gen_shli_tl(temp, temp, 3);
+tcg_gen_or_tl(dst_s2, dst_s2, temp);
+
+/*
+ * We can't reuse do_vsetvl for we don't have ext_zve32f
+ * The code below is almost copied from rvv do_vsetvl
+ * delete zve32f check and the situation when rd = rs1 = 0
+ */
+TCGv s1, dst;
+dst = dest_gpr(s, rd);
+if (rs1 == 0) {
+/* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
+s1 = tcg_constant_tl(RV_VLEN_MAX);
+} else {
+s1 = get_gpr(s, rs1, EXT_ZERO);
+}
+
+gen_helper_vsetvl(dst, tcg_env, s1, dst_s2);
+gen_set_gpr(s, rd, dst);
+mark_vs_dirty(s);
+
+gen_update_pc(s, s->cur_insn_len);
+lookup_and_goto_ptr(s);
+s->base.is_jmp = DISAS_NORETURN;
+return true;
+}
+
+static bool trans_th_vsetvl(DisasContext *s, arg_th_vsetvl *a)
+{
+if (!require_xtheadvector(s)) {
+return false;
+}
+
+TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO);
+return th_vsetvl(s, a->rd, a->rs1, s2);
+}
+
+static bool trans_th_vsetvli(DisasContext *s, arg_th_vsetvli *a)
+{
+if (!require_xtheadvector(s)) {
+return false;
+}
+
+TCGv s2 = tcg_constant_tl(a->zimm);
+return th_vsetvl(s, a->rd, a->rs1, s2);
+}
+
 #define TH_TRANS_STUB(NAME)\
 static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
 {  \
 return require_xtheadvector(s);\
 }
 
-TH_TRANS_STUB(th_vsetvli)
-TH_TRANS_STUB(th_vsetvl)
 TH_TRANS_STUB(th_vlb_v)
 TH_TRANS_STUB(th_vlh_v)
 TH_TRANS_STUB(th_vlw_v)
-- 
2.44.0




[PATCH 06/65] target/riscv: Implement insns decode rules for XTheadVector

2024-04-12 Thread Huang Tao
In this patch, we implement the XTheadVector instructions decode rules
in xtheadvector.decode. In order to avoid compile failure, we add
trans_ functions in trans_xtheadvector.c.inc as placeholders.
Also, we add decode_xtheadvector in decoder_table to support dynamic
building of deocders. There is no performance impact on standard decoding
because the decode_xtheadvector will not be added to decode function array
when ext_xtheadvector is false.

Signed-off-by: Huang Tao 
---
 .../riscv/insn_trans/trans_xtheadvector.c.inc | 384 +
 target/riscv/meson.build  |   1 +
 target/riscv/translate.c  |   3 +
 target/riscv/xtheadvector.decode  | 390 ++
 4 files changed, 778 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_xtheadvector.c.inc
 create mode 100644 target/riscv/xtheadvector.decode

diff --git a/target/riscv/insn_trans/trans_xtheadvector.c.inc 
b/target/riscv/insn_trans/trans_xtheadvector.c.inc
new file mode 100644
index 00..2dd77d74ab
--- /dev/null
+++ b/target/riscv/insn_trans/trans_xtheadvector.c.inc
@@ -0,0 +1,384 @@
+/*
+ * RISC-V translation routines for the XTheadVector Extension.
+ *
+ * Copyright (c) 2024 Alibaba Group. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "tcg/tcg-op-gvec.h"
+#include "tcg/tcg-gvec-desc.h"
+#include "internals.h"
+
+static bool require_xtheadvector(DisasContext *s)
+{
+return s->cfg_ptr->ext_xtheadvector &&
+   s->mstatus_vs != EXT_STATUS_DISABLED;
+}
+
+#define TH_TRANS_STUB(NAME)\
+static bool trans_##NAME(DisasContext *s, arg_##NAME *a)   \
+{  \
+return require_xtheadvector(s);\
+}
+
+TH_TRANS_STUB(th_vsetvli)
+TH_TRANS_STUB(th_vsetvl)
+TH_TRANS_STUB(th_vlb_v)
+TH_TRANS_STUB(th_vlh_v)
+TH_TRANS_STUB(th_vlw_v)
+TH_TRANS_STUB(th_vle_v)
+TH_TRANS_STUB(th_vlbu_v)
+TH_TRANS_STUB(th_vlhu_v)
+TH_TRANS_STUB(th_vlwu_v)
+TH_TRANS_STUB(th_vlbff_v)
+TH_TRANS_STUB(th_vlhff_v)
+TH_TRANS_STUB(th_vlwff_v)
+TH_TRANS_STUB(th_vleff_v)
+TH_TRANS_STUB(th_vlbuff_v)
+TH_TRANS_STUB(th_vlhuff_v)
+TH_TRANS_STUB(th_vlwuff_v)
+TH_TRANS_STUB(th_vsb_v)
+TH_TRANS_STUB(th_vsh_v)
+TH_TRANS_STUB(th_vsw_v)
+TH_TRANS_STUB(th_vse_v)
+TH_TRANS_STUB(th_vlsb_v)
+TH_TRANS_STUB(th_vlsh_v)
+TH_TRANS_STUB(th_vlsw_v)
+TH_TRANS_STUB(th_vlse_v)
+TH_TRANS_STUB(th_vlsbu_v)
+TH_TRANS_STUB(th_vlshu_v)
+TH_TRANS_STUB(th_vlswu_v)
+TH_TRANS_STUB(th_vssb_v)
+TH_TRANS_STUB(th_vssh_v)
+TH_TRANS_STUB(th_vssw_v)
+TH_TRANS_STUB(th_vsse_v)
+TH_TRANS_STUB(th_vlxb_v)
+TH_TRANS_STUB(th_vlxh_v)
+TH_TRANS_STUB(th_vlxw_v)
+TH_TRANS_STUB(th_vlxe_v)
+TH_TRANS_STUB(th_vlxbu_v)
+TH_TRANS_STUB(th_vlxhu_v)
+TH_TRANS_STUB(th_vlxwu_v)
+TH_TRANS_STUB(th_vsxb_v)
+TH_TRANS_STUB(th_vsxh_v)
+TH_TRANS_STUB(th_vsxw_v)
+TH_TRANS_STUB(th_vsxe_v)
+TH_TRANS_STUB(th_vamoswapw_v)
+TH_TRANS_STUB(th_vamoaddw_v)
+TH_TRANS_STUB(th_vamoxorw_v)
+TH_TRANS_STUB(th_vamoandw_v)
+TH_TRANS_STUB(th_vamoorw_v)
+TH_TRANS_STUB(th_vamominw_v)
+TH_TRANS_STUB(th_vamomaxw_v)
+TH_TRANS_STUB(th_vamominuw_v)
+TH_TRANS_STUB(th_vamomaxuw_v)
+TH_TRANS_STUB(th_vamoswapd_v)
+TH_TRANS_STUB(th_vamoaddd_v)
+TH_TRANS_STUB(th_vamoxord_v)
+TH_TRANS_STUB(th_vamoandd_v)
+TH_TRANS_STUB(th_vamoord_v)
+TH_TRANS_STUB(th_vamomind_v)
+TH_TRANS_STUB(th_vamomaxd_v)
+TH_TRANS_STUB(th_vamominud_v)
+TH_TRANS_STUB(th_vamomaxud_v)
+TH_TRANS_STUB(th_vadd_vv)
+TH_TRANS_STUB(th_vadd_vx)
+TH_TRANS_STUB(th_vadd_vi)
+TH_TRANS_STUB(th_vsub_vv)
+TH_TRANS_STUB(th_vsub_vx)
+TH_TRANS_STUB(th_vrsub_vx)
+TH_TRANS_STUB(th_vrsub_vi)
+TH_TRANS_STUB(th_vwaddu_vv)
+TH_TRANS_STUB(th_vwaddu_vx)
+TH_TRANS_STUB(th_vwadd_vv)
+TH_TRANS_STUB(th_vwadd_vx)
+TH_TRANS_STUB(th_vwsubu_vv)
+TH_TRANS_STUB(th_vwsubu_vx)
+TH_TRANS_STUB(th_vwsub_vv)
+TH_TRANS_STUB(th_vwsub_vx)
+TH_TRANS_STUB(th_vwaddu_wv)
+TH_TRANS_STUB(th_vwaddu_wx)
+TH_TRANS_STUB(th_vwadd_wv)
+TH_TRANS_STUB(th_vwadd_wx)
+TH_TRANS_STUB(th_vwsubu_wv)
+TH_TRANS_STUB(th_vwsubu_wx)
+TH_TRANS_STUB(th_vwsub_wv)
+TH_TRANS_STUB(th_vwsub_wx)
+TH_TRANS_STUB(th_vadc_vvm)
+TH_TRANS_STUB(th_vadc_vxm)
+TH_TRANS_STUB(th_vadc_vim)
+TH_TRANS_STUB(th_vmadc_vvm)
+TH_TRANS_STUB(th_vmadc_vxm)
+TH_TRANS_STUB(th_vmadc_vim)
+TH_TRANS_STUB(th_vsbc_vvm)
+TH_TRANS_STUB(th_vsbc_vxm)
+TH_TRANS_STUB(th_vmsbc_vvm)
+

[PATCH 05/65] target/riscv: Add mlen in DisasContext

2024-04-12 Thread Huang Tao
The mask register layout of XTheadVector is different from that of RVV1.0.
For RVV1.0, the mask bits for element i are located in bit[i] of the mask
register. While for XTheadVector, the mask bits for element i are located
bit[MLEN*i] of the mask register. (MLEN = SEW/LMUL)
So we add mlen in DisasContext to indicate the mask bit and reduce the
calculation of mlen.

Signed-off-by: Huang Tao 
---
 target/riscv/translate.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7eb8c9cd31..a22fdb59df 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -106,6 +106,7 @@ typedef struct DisasContext {
 bool cfg_vta_all_1s;
 bool vstart_eq_zero;
 bool vl_eq_vlmax;
+uint16_t mlen;
 CPUState *cs;
 TCGv zero;
 /* PointerMasking extension */
@@ -1207,6 +1208,9 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->zero = tcg_constant_tl(0);
 ctx->virt_inst_excp = false;
 ctx->decoders = cpu->decoders;
+if (cpu->cfg.ext_xtheadvector) {
+ctx->mlen = 1 << (ctx->sew  + 3 - ctx->lmul);
+}
 }
 
 static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
-- 
2.44.0




[PATCH 04/65] target/riscv: Override some csr ops for XTheadVector

2024-04-12 Thread Huang Tao
Some CSR operations have different behavior when XTheadVector is enabled.
In this patch, we override the RISC-V standard implementation of these
CSRs with a vendor implementation. Additionally, we attempt to use the
decorator pattern to explicitly list the different behaviors between
xtheadvector and the RISC-V standard.

Signed-off-by: Huang Tao 
---
 target/riscv/cpu.h  |  36 +
 target/riscv/cpu_bits.h |  18 +
 target/riscv/csr.c  |  42 +-
 target/riscv/th_csr.c   | 169 +++-
 4 files changed, 243 insertions(+), 22 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8d0b500758..6558e652df 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -813,6 +813,42 @@ void riscv_add_satp_mode_properties(Object *obj);
 bool riscv_cpu_accelerator_compatible(RISCVCPU *cpu);
 
 /* CSR function table */
+RISCVException fs(CPURISCVState *env, int csrno);
+RISCVException vs(CPURISCVState *env, int csrno);
+RISCVException any(CPURISCVState *env, int csrno);
+RISCVException smode(CPURISCVState *env, int csrno);
+RISCVException read_fcsr(CPURISCVState *env, int csrno,
+ target_ulong *val);
+RISCVException write_fcsr(CPURISCVState *env, int csrno,
+  target_ulong val);
+RISCVException read_vtype(CPURISCVState *env, int csrno,
+  target_ulong *val);
+RISCVException read_vl(CPURISCVState *env, int csrno,
+   target_ulong *val);
+RISCVException read_vlenb(CPURISCVState *env, int csrno,
+  target_ulong *val);
+RISCVException read_vxrm(CPURISCVState *env, int csrno,
+ target_ulong *val);
+RISCVException write_vxrm(CPURISCVState *env, int csrno,
+  target_ulong val);
+RISCVException read_vxsat(CPURISCVState *env, int csrno,
+  target_ulong *val);
+RISCVException write_vxsat(CPURISCVState *env, int csrno,
+   target_ulong val);
+RISCVException read_vstart(CPURISCVState *env, int csrno,
+   target_ulong *val);
+RISCVException write_vstart(CPURISCVState *env, int csrno,
+target_ulong val);
+RISCVException read_mstatus(CPURISCVState *env, int csrno,
+target_ulong *val);
+RISCVException write_mstatus(CPURISCVState *env, int csrno,
+ target_ulong val);
+RISCVException write_sstatus(CPURISCVState *env, int csrno,
+ target_ulong val);
+RISCVException read_sstatus(CPURISCVState *env, int csrno,
+target_ulong *val);
+RISCVException read_vcsr(CPURISCVState *env, int csrno, target_ulong *val);
+RISCVException write_vcsr(CPURISCVState *env, int csrno, target_ulong val);
 extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
 
 extern const bool valid_vm_1_10_32[], valid_vm_1_10_64[];
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index fc2068ee4d..5a5e0ed444 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -904,4 +904,22 @@ typedef enum RISCVException {
 #define MCONTEXT64 0x1FFFULL
 #define MCONTEXT32_HCONTEXT0x007F
 #define MCONTEXT64_HCONTEXT0x3FFFULL
+
+/* Xuantie custom CSRs */
+#define TH_MSTATUS_VS 0x0180
+
+#define TH_FSR_VXRM_SHIFT  9
+#define TH_FSR_VXRM(0x3 << TH_FSR_VXRM_SHIFT)
+
+#define TH_FSR_VXSAT_SHIFT 8
+#define TH_FSR_VXSAT   (0x1 << TH_FSR_VXSAT_SHIFT)
+
+#define TH_VTYPE_LMUL_SHIFT0
+#define TH_VTYPE_LMUL  (0x3 << TH_VTYPE_LMUL_SHIFT)
+
+#define TH_VTYPE_SEW_SHIFT 2
+#define TH_VTYPE_SEW   (0x7 << TH_VTYPE_SEW_SHIFT)
+
+#define TH_VTYPE_CLEAR_SHIFT   5
+#define TH_VTYPE_CLEAR (0x7 << TH_VTYPE_CLEAR_SHIFT)
 #endif
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 726096444f..797929d5b9 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -76,7 +76,7 @@ RISCVException smstateen_acc_ok(CPURISCVState *env, int 
index, uint64_t bit)
 }
 #endif
 
-static RISCVException fs(CPURISCVState *env, int csrno)
+RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
 if (!env->debugger && !riscv_cpu_fp_enabled(env) &&
@@ -91,7 +91,7 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 return RISCV_EXCP_NONE;
 }
 
-static RISCVException vs(CPURISCVState *env, int csrno)
+RISCVException vs(CPURISCVState *env, int csrno)
 {
 if (riscv_cpu_cfg(env)->ext_zve32f) {
 #if !defined(CONFIG_USER_ONLY)
@@ -227,7 +227,7 @@ static RISCVException sscofpmf(CPURISCVState *env, int 
csrno)
 return RISCV_EXCP_NONE;
 }
 
-static RISCVException any(CPURISCVState *env, int csrno)
+RISCVException any(CPURISCVState *env, int csrno)
 {
 return RISCV_EXCP_NONE;
 }
@@ -260,7 +260,7 @@ static RIS

[PATCH 03/65] target/riscv: Add properties for XTheadVector extension

2024-04-12 Thread Huang Tao
Add ext_xtheadvector properties.
In this patch, we add ext_xtheadvector in RISCVCPUConfig
for XTheadVector as a start. In rv64_thead_c906_cpu_init,
we make ext_xtheadvector equals false to avoid affecting
other extensions when it is not fully implemented.

Signed-off-by: Huang Tao 
---
 target/riscv/cpu.c |  3 +++
 target/riscv/cpu_cfg.h |  2 ++
 target/riscv/cpu_helper.c  |  2 +-
 target/riscv/tcg/tcg-cpu.c | 33 +
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3f21c976ba..05652e8c87 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -201,6 +201,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(xtheadmemidx, PRIV_VERSION_1_11_0, ext_xtheadmemidx),
 ISA_EXT_DATA_ENTRY(xtheadmempair, PRIV_VERSION_1_11_0, ext_xtheadmempair),
 ISA_EXT_DATA_ENTRY(xtheadsync, PRIV_VERSION_1_11_0, ext_xtheadsync),
+ISA_EXT_DATA_ENTRY(xtheadvector, PRIV_VERSION_1_11_0, ext_xtheadvector),
 ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, 
ext_XVentanaCondOps),
 
 DEFINE_PROP_END_OF_LIST(),
@@ -541,6 +542,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 cpu->cfg.ext_xtheadmemidx = true;
 cpu->cfg.ext_xtheadmempair = true;
 cpu->cfg.ext_xtheadsync = true;
+cpu->cfg.ext_xtheadvector = false;
 
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
@@ -1567,6 +1569,7 @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
 MULTI_EXT_CFG_BOOL("xtheadmemidx", ext_xtheadmemidx, false),
 MULTI_EXT_CFG_BOOL("xtheadmempair", ext_xtheadmempair, false),
 MULTI_EXT_CFG_BOOL("xtheadsync", ext_xtheadsync, false),
+MULTI_EXT_CFG_BOOL("xtheadvector", ext_xtheadvector, false),
 MULTI_EXT_CFG_BOOL("xventanacondops", ext_XVentanaCondOps, false),
 
 DEFINE_PROP_END_OF_LIST(),
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
index cb750154bd..da85e94e04 100644
--- a/target/riscv/cpu_cfg.h
+++ b/target/riscv/cpu_cfg.h
@@ -149,6 +149,7 @@ struct RISCVCPUConfig {
 bool ext_xtheadmemidx;
 bool ext_xtheadmempair;
 bool ext_xtheadsync;
+bool ext_xtheadvector;
 bool ext_XVentanaCondOps;
 
 uint32_t pmu_mask;
@@ -205,6 +206,7 @@ MATERIALISE_EXT_PREDICATE(xtheadmac)
 MATERIALISE_EXT_PREDICATE(xtheadmemidx)
 MATERIALISE_EXT_PREDICATE(xtheadmempair)
 MATERIALISE_EXT_PREDICATE(xtheadsync)
+MATERIALISE_EXT_PREDICATE(xtheadvector)
 MATERIALISE_EXT_PREDICATE(XVentanaCondOps)
 
 #endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index fc090d729a..5882b65321 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -72,7 +72,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
 *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
 *cs_base = 0;
 
-if (cpu->cfg.ext_zve32f) {
+if (cpu->cfg.ext_zve32f || cpu->cfg.ext_xtheadvector) {
 /*
  * If env->vl equals to VLMAX, we can use generic vector operation
  * expanders (GVEC) to accerlate the vector operations.
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index 483774e4f8..f7a105b30e 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -281,6 +281,25 @@ static void riscv_cpu_validate_v(CPURISCVState *env, 
RISCVCPUConfig *cfg,
 }
 }
 
+static void th_cpu_validate_v(CPURISCVState *env, RISCVCPUConfig *cfg,
+  Error **errp)
+{
+uint32_t vlen = cfg->vlenb << 3;
+
+if (vlen < 32) {
+error_setg(errp,
+   "In XTheadVector extension, VLEN must be "
+   "greater than or equal to 32");
+}
+
+if (vlen < cfg->elen) {
+error_setg(errp,
+   "In XTheadVector extension, VLEN must be "
+   "greater than or equal to ELEN");
+return;
+}
+}
+
 static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
 {
 CPURISCVState *env = >env;
@@ -485,6 +504,20 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, 
Error **errp)
 return;
 }
 
+if (cpu->cfg.ext_xtheadvector && riscv_has_ext(env, RVV)) {
+error_setg(errp, "XTheadVector extension is incompatible with "
+ "RVV extension");
+return;
+}
+
+if (cpu->cfg.ext_xtheadvector) {
+th_cpu_validate_v(env, >cfg, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+}
+
 if (riscv_has_ext(env, RVV)) {
 riscv_cpu_validate_v(env, >cfg, _err);
 if (local_err != NULL) {
-- 
2.44.0




[PATCH 02/65] target/riscv: Reuse th_csr.c to add user-mode csrs

2024-04-12 Thread Huang Tao
The former patch added th_csr.c to add th.sxstatus csr for XTheadMaee.
However, it can only support system-mode vendor csrs.
In this patch, I change the way of compiling th_csr.c and calling the
function th_register_custom_csrs, using '#if !defined(CONFIG_USER_ONLY)' in
th_csr.c to support both user-mode and system-mode vendor csrs.

Signed-off-by: Huang Tao 
---
 target/riscv/cpu.c   |  2 +-
 target/riscv/meson.build |  2 +-
 target/riscv/th_csr.c| 21 +
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 46a66cdbbb..3f21c976ba 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -545,8 +545,8 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
-th_register_custom_csrs(cpu);
 #endif
+th_register_custom_csrs(cpu);
 
 /* inherited from parent obj via riscv_cpu_init() */
 cpu->cfg.pmp = true;
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a4bd61e52a..b01a6cfb23 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -12,6 +12,7 @@ riscv_ss.add(files(
   'cpu.c',
   'cpu_helper.c',
   'csr.c',
+  'th_csr.c',
   'fpu_helper.c',
   'gdbstub.c',
   'op_helper.c',
@@ -33,7 +34,6 @@ riscv_system_ss.add(files(
   'monitor.c',
   'machine.c',
   'pmu.c',
-  'th_csr.c',
   'time_helper.c',
   'riscv-qmp-cmds.c',
 ))
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
index 66d260cabd..dc087b1ffa 100644
--- a/target/riscv/th_csr.c
+++ b/target/riscv/th_csr.c
@@ -33,6 +33,15 @@ typedef struct {
 riscv_csr_operations csr_ops;
 } riscv_csr;
 
+static int test_thead_mvendorid(RISCVCPU *cpu)
+{
+if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
+return -1;
+}
+return 0;
+}
+
+#if !defined(CONFIG_USER_ONLY)
 static RISCVException s_mode_csr(CPURISCVState *env, int csrno)
 {
 if (env->debugger)
@@ -44,13 +53,6 @@ static RISCVException s_mode_csr(CPURISCVState *env, int 
csrno)
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
-static int test_thead_mvendorid(RISCVCPU *cpu)
-{
-if (cpu->cfg.mvendorid != THEAD_VENDOR_ID)
-return -1;
-return 0;
-}
-
 static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
target_ulong *val)
 {
@@ -58,13 +60,16 @@ static RISCVException read_th_sxstatus(CPURISCVState *env, 
int csrno,
 *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
 return RISCV_EXCP_NONE;
 }
+#endif
 
 static riscv_csr th_csr_list[] = {
+#if !defined(CONFIG_USER_ONLY)
 {
 .csrno = CSR_TH_SXSTATUS,
 .insertion_test = test_thead_mvendorid,
 .csr_ops = { "th.sxstatus", s_mode_csr, read_th_sxstatus }
-}
+},
+#endif
 };
 
 void th_register_custom_csrs(RISCVCPU *cpu)
-- 
2.44.0




[PATCH 01/65] riscv: thead: Add th.sxstatus CSR emulation

2024-04-12 Thread Huang Tao
From: Christoph Müllner 

The th.sxstatus CSR can be used to identify available custom extension
on T-Head CPUs. The CSR is documented here:
  https://github.com/T-head-Semi/thead-extension-spec/pull/46

An important property of this patch is, that the th.sxstatus MAEE field
is not set (indicating that XTheadMaee is not available).
XTheadMaee is a memory attribute extension (similar to Svpbmt) which is
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
in PTEs that are marked as reserved. QEMU maintainers prefer to not
implement XTheadMaee, so we need give kernels a mechanism to identify
if XTheadMaee is available in a system or not. And this patch introduces
this mechanism in QEMU in a way that's compatible with real HW
(i.e., probing the th.sxstatus.MAEE bit).

Further context can be found on the list:
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html

Signed-off-by: Christoph Müllner 
---
 target/riscv/cpu.c   |  1 +
 target/riscv/cpu.h   |  3 ++
 target/riscv/meson.build |  1 +
 target/riscv/th_csr.c| 78 
 4 files changed, 83 insertions(+)
 create mode 100644 target/riscv/th_csr.c

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 193dbf7fe8..46a66cdbbb 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -545,6 +545,7 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 cpu->cfg.mvendorid = THEAD_VENDOR_ID;
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(cpu, VM_1_10_SV39);
+th_register_custom_csrs(cpu);
 #endif
 
 /* inherited from parent obj via riscv_cpu_init() */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 48e67410e1..8d0b500758 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -825,4 +825,7 @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
 uint8_t satp_mode_max_from_map(uint32_t map);
 const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
 
+/* Implemented in th_csr.c */
+void th_register_custom_csrs(RISCVCPU *cpu);
+
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index a5e0734e7f..a4bd61e52a 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -33,6 +33,7 @@ riscv_system_ss.add(files(
   'monitor.c',
   'machine.c',
   'pmu.c',
+  'th_csr.c',
   'time_helper.c',
   'riscv-qmp-cmds.c',
 ))
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
new file mode 100644
index 00..66d260cabd
--- /dev/null
+++ b/target/riscv/th_csr.c
@@ -0,0 +1,78 @@
+/*
+ * T-Head-specific CSRs.
+ *
+ * Copyright (c) 2024 VRULL GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see .
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "cpu_vendorid.h"
+
+#define CSR_TH_SXSTATUS 0x5c0
+
+/* TH_SXSTATUS bits */
+#define TH_SXSTATUS_UCMEBIT(16)
+#define TH_SXSTATUS_MAEEBIT(21)
+#define TH_SXSTATUS_THEADISAEE  BIT(22)
+
+typedef struct {
+int csrno;
+int (*insertion_test)(RISCVCPU *cpu);
+riscv_csr_operations csr_ops;
+} riscv_csr;
+
+static RISCVException s_mode_csr(CPURISCVState *env, int csrno)
+{
+if (env->debugger)
+return RISCV_EXCP_NONE;
+
+if (env->priv >= PRV_S)
+return RISCV_EXCP_NONE;
+
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+static int test_thead_mvendorid(RISCVCPU *cpu)
+{
+if (cpu->cfg.mvendorid != THEAD_VENDOR_ID)
+return -1;
+return 0;
+}
+
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
+   target_ulong *val)
+{
+/* We don't set MAEE here, because QEMU does not implement MAEE. */
+*val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
+return RISCV_EXCP_NONE;
+}
+
+static riscv_csr th_csr_list[] = {
+{
+.csrno = CSR_TH_SXSTATUS,
+.insertion_test = test_thead_mvendorid,
+.csr_ops = { "th.sxstatus", s_mode_csr, read_th_sxstatus }
+}
+};
+
+void th_register_custom_csrs(RISCVCPU *cpu)
+{
+for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
+int csrno = th_csr_list[i].csrno;
+riscv_csr_operations *csr_ops = _csr_list[i].csr_ops;
+if (!th_csr_list[i].insertion_test(cpu))
+riscv_set_csr_ops(csrno, csr_ops);
+}
+}
-- 
2.44.0




[PATCH 00/65]target/riscv: Support XTheadVector extension

2024-04-12 Thread Huang Tao
This patchset implements the XTheadVector extension for RISC-V on QEMU.

You can find the full description of the XTheadVector extension at:
https://github.com/RISCV-SPEC/thead-extension-spec/blob/master/xtheadvector.adoc

The XTheadvector extension is a non-standard extension for RISC-V. The
encoding space of the XTheadVector instructions overlaps with those of
the V extension.

The XTheadVector is similar to the V extension v0.7.1, so it has several
differences with the current V extension v1.0 which is supported by
QEMU.

Here is a simple list of the differences:
  * Different instructions
  * Different CSR behaviors
  * Different mask register layout
  * Different overlap policy
  * Different masked/tail element processing policy
  * Same instructions have different behaviors in detail

This patchset is based on 
https://github.com/alistair23/qemu/tree/riscv-to-apply.next,
relay on some former patches which are not merged into upstream yet:
  * target/riscv: Implement dynamic establishment of custom decoder
  
(https://patchew.org/QEMU/20240314092158.65866-1-eric.hu...@linux.alibaba.com/)
  * riscv: set vstart_eq_zero on vector insns
  (https://patchew.org/QEMU/20240313220141.427730-1-dbarb...@ventanamicro.com/)
  * riscv: thead: Add th.sxstatus CSR emulation
  
(https://patchew.org/QEMU/20240329120427.684677-1-christoph.muell...@vrull.eu/)


The patch 'riscv: thead: Add th.sxstatus CSR emulation' is included in the 
patchset
for we need to change it to support XTheadVector csrs.

Christoph Müllner (1):
  riscv: thead: Add th.sxstatus CSR emulation

Huang Tao (64):
  target/riscv: Reuse th_csr.c to add user-mode csrs
  target/riscv: Add properties for XTheadVector extension
  target/riscv: Override some csr ops for XTheadVector
  target/riscv: Add mlen in DisasContext
  target/riscv: Implement insns decode rules for XTheadVector
  target/riscv: implement th.vsetvl{i} for XTheadVector
  target/riscv: Add strided load instructions for XTheadVector
  target/riscv: Add strided store instructions for XTheadVector
  target/riscv: Add unit-stride load instructions for XTheadVector
  target/riscv: Add unit-stride store instructions for XTheadVector
  target/riscv: Add indexed load instructions for XTheadVector
  target/riscv: Add indexed store instructions for XTheadVector
  target/riscv: Add unit-stride fault-only-first instructions for
XTheadVector
  target/riscv: Add vector amo operations for XTheadVector
  target/riscv: Add single-width integer add and subtract instructions
for XTheadVector
  target/riscv: Add widening integer add/subtract instructions for
XTheadVector
  target/riscv: Add integer add-with-carry/sub-with-borrow instructions
for XTheadVector
  target/riscv: Add bitwise logical instructions for XTheadVector
  target/riscv: Add single-width bit shift instructions for XTheadVector
  target/riscv: Add narrowing integer right shift instructions for
XTheadVector
  target/riscv: Add integer compare instructions for XTheadVector
  target/riscv: Add integer min/max instructions for XTheadVector
  target/riscv: Add single-width integer multiply instructions for
XTheadVector
  target/riscv: Add integer divide instructions for XTheadVector
  target/riscv: Add widening integer multiply instructions for
XTheadVector
  target/riscv: Add single-width integer multiply-add instructions for
XTheadVector
  target/riscv: Add widening integer multiply-add instructions for
XTheadVector
  target/riscv: Add integer merge and move instructions for XTheadVector
  target/riscv: Add single-width saturating add and sub instructions for
XTheadVector
  target/riscv: Add single-width average add and sub instructions for
XTheadVector
  target/riscv: Add single-width fractional mul with rounding and
saturation for XTheadVector
  target/riscv: Add widening saturating scaled multiply-add instructions
for XTheadVector
  target/riscv: Add single-width scaling shift instructions for
XTheadVector
  target/riscv: Add narrowing fixed-point clip instructions for
XTheadVector
  target/riscv: Add single-width floating-point add/sub instructions for
XTheadVector
  target/riscv: Add widening floating-point add/sub instructions for
XTheadVector
  target/riscv: Add single-width floating-point multiply/divide
instructions for XTheadVector
  target/riscv: Add widening floating-point multiply instructions for
XTheadVector
  target/riscv: Add single-width floating-point fused multiply-add
instructions for XTheadVector
  target/riscv: Add widening floating-point fused mul-add instructions
for XTheadVector
  target/riscv: Add floating-pointing square-root instructions for
XTheadVector
  target/riscv: Add floating-point MIN/MAX instructions for XTheadVector
  target/riscv: Add floating-point sign-injection instructions for
XTheadVector
  target/riscv: Add floating-point compare instructions for XTheadVector
  target/riscv: Add floating-point classify

Re: [PATCH v3] target/riscv: Fix the element agnostic function problem

2024-04-02 Thread Huang Tao

This is a ping to the patch below.

https://patchew.org/QEMU/20240325021654.6594-1-eric.hu...@linux.alibaba.com/ 



On 2024/3/25 10:16, Huang Tao wrote:

In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. This patch fixes
the problem by adding handling of such case.

Signed-off-by: Huang Tao
Suggested-by: Richard Henderson
Reviewed-by: LIU Zhiwei
---
Changes in v3:
- use "if (HOST_BIG_ENDIAN)" instead of "#if HOST_BIG_ENDIAN"

Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
  target/riscv/vector_internals.c | 22 ++
  1 file changed, 22 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 12f5964fbb..36635a1138 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
  if (tot - cnt == 0) {
  return ;
  }
+
+if (HOST_BIG_ENDIAN) {
+/*
+ * Deal the situation when the elements are insdie
+ * only one uint64 block including setting the
+ * masked-off element.
+ */
+if (((tot - 1) ^ cnt) < 8) {
+memset(base + H1(tot - 1), -1, tot - cnt);
+return;
+}
+/*
+ * Otherwise, at least cross two uint64_t blocks.
+ * Set first unaligned block.
+ */
+if (cnt % 8 != 0) {
+uint32_t j = ROUND_UP(cnt, 8);
+memset(base + H1(j - 1), -1, j - cnt);
+cnt = j;
+}
+/* Set other 64bit aligend blocks */
+}
  memset(base + cnt, -1, tot - cnt);
  }
  

Re: [PATCH v4] target/riscv: Implement dynamic establishment of custom decoder

2024-04-02 Thread Huang Tao

This is a ping to the patch below.

https://patchew.org/QEMU/20240314092158.65866-1-eric.hu...@linux.alibaba.com/

On 2024/3/14 17:21, Huang Tao wrote:

In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
RISCVCPU, each cpu can have their own decoder, and the decoders can be
different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
can be added to the dynamic_decoder when building up the decoder. Therefore,
there is no need to run the guard_func when decoding each instruction. It 
can
improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
functions to improve decoding efficiency, especially when vendor-defined
instruction sets increase. Because of dynamic building up, it can skip the 
other
decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao
Suggested-by: Christoph Muellner
Co-authored-by: LIU Zhiwei
Reviewed-by: Richard Henderson
---
Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
  target/riscv/cpu.c |  1 +
  target/riscv/cpu.h |  1 +
  target/riscv/tcg/tcg-cpu.c | 15 +++
  target/riscv/tcg/tcg-cpu.h | 15 +++
  target/riscv/translate.c   | 31 +++
  5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c160b9216b..17070b82a7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1132,6 +1132,7 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
  error_propagate(errp, local_err);
  return;
  }
+riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
  } else if (kvm_enabled()) {
  riscv_kvm_cpu_finalize_features(cpu, _err);
  if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..48e67410e1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -457,6 +457,7 @@ struct ArchCPU {
  uint32_t pmu_avail_ctrs;
  /* Mapping of events to counters */
  GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
  };
  
  /**

diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ab6db817db..c9ab92ea2f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -853,6 +853,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
  }
  }
  
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)

+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].riscv_cpu_decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
  {
  return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp);
  void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
  bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
  
+struct DisasContext;

+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
  #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea5d52b2ef..bce16d5054 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
  #include "exec/helper-info.c.inc"
  #undef  HELPER_H
  
+#include "tcg/tcg-cpu.h"

+
  /* global register indices */
  static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
  static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
@@ -117,6 +119,7 @@ typedef struct DisasContext {
  bool frm_valid;
  /* TCG of 

[PATCH v3] target/riscv: Fix the element agnostic function problem

2024-03-24 Thread Huang Tao
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. This patch fixes
the problem by adding handling of such case.

Signed-off-by: Huang Tao 
Suggested-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
---
Changes in v3:
- use "if (HOST_BIG_ENDIAN)" instead of "#if HOST_BIG_ENDIAN"

Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
 target/riscv/vector_internals.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 12f5964fbb..36635a1138 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
 if (tot - cnt == 0) {
 return ;
 }
+
+if (HOST_BIG_ENDIAN) {
+/*
+ * Deal the situation when the elements are insdie
+ * only one uint64 block including setting the
+ * masked-off element.
+ */
+if (((tot - 1) ^ cnt) < 8) {
+memset(base + H1(tot - 1), -1, tot - cnt);
+return;
+}
+/*
+ * Otherwise, at least cross two uint64_t blocks.
+ * Set first unaligned block.
+ */
+if (cnt % 8 != 0) {
+uint32_t j = ROUND_UP(cnt, 8);
+memset(base + H1(j - 1), -1, j - cnt);
+cnt = j;
+}
+/* Set other 64bit aligend blocks */
+}
 memset(base + cnt, -1, tot - cnt);
 }
 
-- 
2.41.0




Re: [PATCH v2] target/riscv: Fix the element agnostic function problem

2024-03-21 Thread Huang Tao



On 2024/3/21 16:18, Richard Henderson wrote:

On 3/20/24 17:58, Huang Tao wrote:
In RVV and vcrypto instructions, the masked and tail elements are set 
to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the 
element

agnostic policy.

However, this function can't deal the big endian situation. This 
patch fixes

the problem by adding handling of such case.

Signed-off-by: Huang Tao 
Suggested-by: Richard Henderson 
---
Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
  target/riscv/vector_internals.c | 22 ++
  1 file changed, 22 insertions(+)

diff --git a/target/riscv/vector_internals.c 
b/target/riscv/vector_internals.c

index 12f5964fbb..3e45b9b4a7 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t 
is_agnostic, uint32_t cnt,

  if (tot - cnt == 0) {
  return ;
  }
+
+#if HOST_BIG_ENDIAN
+    /*
+ * Deal the situation when the elements are insdie
+ * only one uint64 block including setting the
+ * masked-off element.
+ */
+    if ((tot - 1) ^ cnt < 8) {
+    memset(base + H1(tot - 1), -1, tot - cnt);
+    return;
+    }


(1) tot will always be a multiple of 8, afaik, so there's no need for 
this first block.
(2) Using if not #if means that the code is always compile-tested, 
even if it is eliminated.



r~


tot is not always be a multiple of 8. In the vector instructions, the 
helper fuinctions will use vext_set_elems_1s to set one masked-off 
element. In that case, tot = cnt + esz, and tot is not the end of a 
vector register.


There is an example in GEN_VEXT_SHIFT_VV:

    for (i = env->vstart; i < vl; i++) {
    if (!vm && !vext_elem_mask(v0, i)) {
    /* set masked-off elements to 1s */
    vext_set_elems_1s(vd, vma, i * esz, (i + 1) * esz);
    continue;
    }

As for the second point, I will use if instead of #if in the next version.

Thanks,

Huang Tao





[PATCH v2] target/riscv: Fix the element agnostic function problem

2024-03-20 Thread Huang Tao
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. This patch fixes
the problem by adding handling of such case.

Signed-off-by: Huang Tao 
Suggested-by: Richard Henderson 
---
Changes in v2:
- Keep the api of vext_set_elems_1s
- Reduce the number of patches.
---
 target/riscv/vector_internals.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 12f5964fbb..3e45b9b4a7 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -30,6 +30,28 @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, 
uint32_t cnt,
 if (tot - cnt == 0) {
 return ;
 }
+
+#if HOST_BIG_ENDIAN
+/*
+ * Deal the situation when the elements are insdie
+ * only one uint64 block including setting the
+ * masked-off element.
+ */
+if ((tot - 1) ^ cnt < 8) {
+memset(base + H1(tot - 1), -1, tot - cnt);
+return;
+}
+/*
+ * Otherwise, at least cross two uint64_t blocks.
+ * Set first unaligned block.
+ */
+if (cnt % 8 != 0) {
+uint32_t j = ROUND_UP(cnt, 8);
+memset(base + H1(j - 1), -1, j - cnt);
+cnt = j;
+}
+/* Set other 64bit aligend blocks */
+#endif
 memset(base + cnt, -1, tot - cnt);
 }
 
-- 
2.41.0




Re: [PATCH 2/4] target/riscv: Add right functions to set agnostic elements

2024-03-19 Thread Huang Tao

I will rewrite the patch, and send a new version soon.

Thanks,

Huang Tao

On 2024/3/20 07:32, Richard Henderson wrote:

On 3/19/24 11:57, Daniel Henrique Barboza wrote:
This seems correct but a bit over complicated at first glance. I 
wonder if we have

something simpler already done somewhere.

Richard, does ARM (or any other arch) do anything of the sort? Aside 
from more trivial

byte swaps using bswap64() I didn't find anything similar.


No, nothing quite like.


We recently posted a big endian related fix here:

[PATCH for 9.0 v15 03/10] target/riscv/vector_helper.c: fix 'vmvr_v' 
memcpy endianess


But not sure how to apply it here.


It's almost exactly the same, only with memset instead of memcpy.

    if (HOST_BIG_ENDIAN && idx % 8 != 0) {
    uint32_t j = ROUND_UP(idx, 8);
    memset(vd + H(j - 1), -1, j - idx);
    idx = j;
    }
    memset(vd + idx, -1, tot - idx);


I'll note that you don't need to change the api of vext_set_elems_1s 
-- so most of these patches are not required.



r~




[PATCH v4] target/riscv: Implement dynamic establishment of custom decoder

2024-03-14 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   RISCVCPU, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
   overhead for users that don't need this particular vendor decoder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
Reviewed-by: Richard Henderson 
---
Changes in v4:
- fix typo
- rename function
- add 'if tcg_enable()'
- move function to tcg-cpu.c and declarations to tcg-cpu.h

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
 target/riscv/cpu.c |  1 +
 target/riscv/cpu.h |  1 +
 target/riscv/tcg/tcg-cpu.c | 15 +++
 target/riscv/tcg/tcg-cpu.h | 15 +++
 target/riscv/translate.c   | 31 +++
 5 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index c160b9216b..17070b82a7 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1132,6 +1132,7 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 error_propagate(errp, local_err);
 return;
 }
+riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
 } else if (kvm_enabled()) {
 riscv_kvm_cpu_finalize_features(cpu, _err);
 if (local_err != NULL) {
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3b1a02b944..48e67410e1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -457,6 +457,7 @@ struct ArchCPU {
 uint32_t pmu_avail_ctrs;
 /* Mapping of events to counters */
 GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
 };
 
 /**
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
index ab6db817db..c9ab92ea2f 100644
--- a/target/riscv/tcg/tcg-cpu.c
+++ b/target/riscv/tcg/tcg-cpu.c
@@ -853,6 +853,21 @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 }
 }
 
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].riscv_cpu_decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
 {
 return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
index f7b32417f8..ce94253fe4 100644
--- a/target/riscv/tcg/tcg-cpu.h
+++ b/target/riscv/tcg/tcg-cpu.h
@@ -26,4 +26,19 @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error 
**errp);
 void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
 bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
 
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
+
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ea5d52b2ef..bce16d5054 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -37,6 +37,8 @@
 #include "exec/helper-info.c.inc"
 #undef  HELPER_H
 
+#include "tcg/tcg-cpu.h"
+
 /* global register indices */
 static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
 static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
@@ -117,6 +119,7 @@ typedef struct DisasContext {
 bool frm_valid;
 /* TCG of the current insn_start */
 TCGOp *insn_start;
+const GPtrArray *decoders;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -1120,21 +1123,16 @@ static in

Re: [PATCH v3] target/riscv: Implement dynamic establishment of custom decoder

2024-03-14 Thread Huang Tao

Hi,

On 2024/3/13 18:47, Philippe Mathieu-Daudé wrote:



+{
+    GPtrArray *dynamic_decoders;
+    dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+    for (size_t i = 0; i < decoder_table_size; ++i) {
+    if (decoder_table[i].guard_func &&
+    decoder_table[i].guard_func(>cfg)) {
+    g_ptr_array_add(dynamic_decoders,
+ (gpointer)decoder_table[i].decode_fn);
+    }
+    }
+
+    cpu->decoders = dynamic_decoders;
+}


Move this function to translate.c and make decoder_table[] static.
Then we don't need the "cpu_decoder.h", it is specific to TCG and
declarations go in "target/riscv/tcg/tcg-cpu.h".

This function is about finalizing the feature of cpu, it is not suitable 
to move it to translate.c from the perspective of code structure and 
readability.


I will try to move the function to tcg-cpu.c, and the declarations to 
tcg-cpu.h according to your suggestion.



diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 177418b2b9..332f0bfd4e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -115,6 +115,7 @@ typedef struct DisasContext {
  bool frm_valid;
  /* TCG of the current insn_start */
  TCGOp *insn_start;
+    const GPtrArray *decoders;


Why do we need this reference? We can use env_archcpu(env)->decoders.


As Richard said before:

> We try to avoid placing env into DisasContext, so that it is much 
harder to make the mistake of referencing env fields at 
translation-time, when you really needed to generate tcg code to 
reference the fields at runtime.


It also applies to the ArchCPU case.


Thanks to your review, I will adopt the other suggestions in the next 
version.



Thanks,

Huang Tao






[PATCH v3] target/riscv: Implement dynamic establishment of custom decoder

2024-03-13 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   RISCVCPU, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
   overhead for users that don't need this particular vendor deocder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
---

Changes in v3:
- use GPtrArray to save decode function poionter list.
---
 target/riscv/cpu.c | 18 ++
 target/riscv/cpu.h |  2 ++
 target/riscv/cpu_decoder.h | 34 ++
 target/riscv/translate.c   | 29 +
 4 files changed, 67 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/cpu_decoder.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5ff0192c52..9aedd93cf6 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -38,6 +38,7 @@
 #include "kvm/kvm_riscv.h"
 #include "tcg/tcg-cpu.h"
 #include "tcg/tcg.h"
+#include "cpu_decoder.h"
 
 /* RISC-V CPU definitions */
 static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -1102,6 +1103,21 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
Error **errp)
 }
 #endif
 
+static void riscv_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+GPtrArray *dynamic_decoders;
+dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+g_ptr_array_add(dynamic_decoders,
+(gpointer)decoder_table[i].decode_fn);
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
 void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 Error *local_err = NULL;
@@ -1127,6 +1143,8 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 return;
 }
 }
+
+riscv_cpu_finalize_dynamic_decoder(cpu);
 }
 
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d291a7092..923721e67a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -30,6 +30,7 @@
 #include "qemu/int128.h"
 #include "cpu_bits.h"
 #include "cpu_cfg.h"
+#include "cpu_decoder.h"
 #include "qapi/qapi-types-common.h"
 #include "cpu-qom.h"
 
@@ -457,6 +458,7 @@ struct ArchCPU {
 uint32_t pmu_avail_ctrs;
 /* Mapping of events to counters */
 GHashTable *pmu_event_ctr_map;
+const GPtrArray *decoders;
 };
 
 /**
diff --git a/target/riscv/cpu_decoder.h b/target/riscv/cpu_decoder.h
new file mode 100644
index 00..549414ce4c
--- /dev/null
+++ b/target/riscv/cpu_decoder.h
@@ -0,0 +1,34 @@
+/*
+ * QEMU RISC-V CPU Decoder
+ *
+ * Copyright (c) 2023-2024 Alibaba Group
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_CPU_DECODER_H
+#define RISCV_CPU_DECODER_H
+
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 177418b2b9..332f0bfd4e 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@

Re: [PATCH v2] target/riscv: Implement dynamic establishment of custom decoder

2024-03-13 Thread Huang Tao

I'm sorry for making this mistake and thank you for your patience.

In the next version, I will use GPtrArray you mentioned earlier to solve 
the problem.


Thanks,

Huang Tao

On 2024/3/12 21:57, Richard Henderson wrote:

On 3/11/24 19:45, Huang Tao wrote:

+static void riscv_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+    decode_fn *dynamic_decoders;
+    dynamic_decoders = g_new0(decode_fn, decoder_table_size);


Allocating ARRAY_SIZE(decoder_table)...


+    int j = 0;
+    for (size_t i = 0; i < decoder_table_size; ++i) {
+    if (decoder_table[i].guard_func &&
+    decoder_table[i].guard_func(>cfg)) {
+    dynamic_decoders[j] = decoder_table[i].decode_fn;
+    j++;
+    }


Potentially enabling all elements...


+    for (size_t i = 0; ctx->decoders[i]; ++i) {


Reading past the end of the array expecting an extra NULL entry.


r~




[PATCH v2] target/riscv: Implement dynamic establishment of custom decoder

2024-03-11 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   RISCVCPU, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with 
minimal
   overhead for users that don't need this particular vendor deocder.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
---
 target/riscv/cpu.c | 19 +++
 target/riscv/cpu.h |  2 ++
 target/riscv/cpu_decoder.h | 34 ++
 target/riscv/translate.c   | 28 
 4 files changed, 67 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/cpu_decoder.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5ff0192c52..5ea5232ed8 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -38,6 +38,7 @@
 #include "kvm/kvm_riscv.h"
 #include "tcg/tcg-cpu.h"
 #include "tcg/tcg.h"
+#include "cpu_decoder.h"
 
 /* RISC-V CPU definitions */
 static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -1102,6 +1103,22 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
Error **errp)
 }
 #endif
 
+static void riscv_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+decode_fn *dynamic_decoders;
+dynamic_decoders = g_new0(decode_fn, decoder_table_size);
+int j = 0;
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+dynamic_decoders[j] = decoder_table[i].decode_fn;
+j++;
+}
+}
+
+cpu->decoders = dynamic_decoders;
+}
+
 void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 Error *local_err = NULL;
@@ -1127,6 +1144,8 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 return;
 }
 }
+
+riscv_cpu_finalize_dynamic_decoder(cpu);
 }
 
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d291a7092..bb96af97f9 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -30,6 +30,7 @@
 #include "qemu/int128.h"
 #include "cpu_bits.h"
 #include "cpu_cfg.h"
+#include "cpu_decoder.h"
 #include "qapi/qapi-types-common.h"
 #include "cpu-qom.h"
 
@@ -457,6 +458,7 @@ struct ArchCPU {
 uint32_t pmu_avail_ctrs;
 /* Mapping of events to counters */
 GHashTable *pmu_event_ctr_map;
+const decode_fn *decoders;
 };
 
 /**
diff --git a/target/riscv/cpu_decoder.h b/target/riscv/cpu_decoder.h
new file mode 100644
index 00..549414ce4c
--- /dev/null
+++ b/target/riscv/cpu_decoder.h
@@ -0,0 +1,34 @@
+/*
+ * QEMU RISC-V CPU Decoder
+ *
+ * Copyright (c) 2023-2024 Alibaba Group
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_CPU_DECODER_H
+#define RISCV_CPU_DECODER_H
+
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 177418b2b9..3f50737a50 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -115,6 +115,7 @@ typedef struct DisasContext {
 bool frm_valid;
 /* TCG of the current i

Re: [PATCH] target/riscv: Implement dynamic establishment of custom decoder

2024-03-08 Thread Huang Tao

Hello, Richard and Daniel,

Thanks to your review, the suggestions about decoder_table_size and 
decoder's place will be adopted in the next version of the patch.


But I would not agree that this patch is a wash or worse. On average, 
though, the two approaches may be comparable. However, as more and more 
vendors join in, this approach will have scalability issues.


For example, if you add 10 vendors, it is not fair to treat the 10th 
vendor with the lowest performance. Our approach works for most 
scenarios, which are basic RV extensions + vendor-specific extensions.


Thanks,

Huang Tao


在 2024/3/8 04:35, Richard Henderson 写道:

-    for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
-    if (decoders[i].guard_func(ctx->cfg_ptr) &&
-    decoders[i].decode_func(ctx, opcode32)) {
+    for (size_t i = 0; i < decoder_table_size; ++i) {
+    if (ctx->decoder[i](ctx, opcode32)) {
  return;


By the way, you're adding layers of pointer chasing, so I suspect 
you'll find all of this is a wash or worse, performance-wise.


Indeed, since some of the predicates are trivial, going the other way 
might help: allow everything to be inlined:


    if (decode_insn32(...)) {
    return;
    }
    if (has_xthead_p(...) && decode_xthead(...)) {
    return;
    }
    ...

Even if there are 10 entries here, so what?  All of the code has to be 
compiled into QEMU.  You're not going to somehow add truly dynamic 
code that you've loaded from a module.


You could perhaps streamline predicates such as has_xthead_p to not 
test 11 variables by adding an artificial "ext_xthead_any" 
configuration entry that is the sum of all of those.



r~





[PATCH 3/4] target/riscv: Replace element agnostic for vector instructions

2024-03-06 Thread Huang Tao
Replace vext_set_elems_1s_le with vext_set_elems_1s for RVV and
vcrypto.

Signed-off-by: Huang Tao 
---
 target/riscv/vcrypto_helper.c   | 32 ++--
 target/riscv/vector_helper.c| 92 -
 target/riscv/vector_internals.c |  8 +--
 target/riscv/vector_internals.h |  4 +-
 4 files changed, 68 insertions(+), 68 deletions(-)

diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index f818749a63..d6c52c1fd0 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -235,7 +235,7 @@ static inline void xor_round_key(AESState *round_state, 
AESState *round_key)
 } \
 env->vstart = 0;  \
 /* set tail elements to 1s */ \
-vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);  \
+vext_set_elems_1s(vd, vta, 4, vl, total_elems * 4);   \
 }
 
 #define GEN_ZVKNED_HELPER_VS(NAME, ...)   \
@@ -259,7 +259,7 @@ static inline void xor_round_key(AESState *round_state, 
AESState *round_key)
 } \
 env->vstart = 0;  \
 /* set tail elements to 1s */ \
-vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);  \
+vext_set_elems_1s(vd, vta, 4, vl, total_elems * 4);   \
 }
 
 GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(_state,
@@ -339,7 +339,7 @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 }
 env->vstart = 0;
 /* set tail elements to 1s */
-vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);
+vext_set_elems_1s(vd, vta, 4, vl, total_elems * 4);
 }
 
 void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
@@ -396,7 +396,7 @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 }
 env->vstart = 0;
 /* set tail elements to 1s */
-vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);
+vext_set_elems_1s(vd, vta, 4, vl, total_elems * 4);
 }
 
 static inline uint32_t sig0_sha256(uint32_t x)
@@ -469,7 +469,7 @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 }
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -579,7 +579,7 @@ void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -597,7 +597,7 @@ void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -615,7 +615,7 @@ void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -633,7 +633,7 @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -672,7 +672,7 @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void 
*vs2_vptr,
 vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
 }
 }
-vext_set_elems_1s_le(vd_vptr, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd_vptr, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -767,7 +767,7 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 vd[i * 8 + k] = bswap32(v1[H4(k)]);
 }
 }
-vext_set_elems_1s_le(vd_vptr, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s(vd_vptr, vta, esz, env->vl, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -805,7 +805,7 @@ void HELPER(vghsh_vv)(void *vd_vptr, void *vs1_vptr, void 
*vs2_vptr,
 vd[i * 2 + 1] = brev8(Z[1]);

[PATCH 0/4] target/riscv: Fix the element agnostic function problem

2024-03-06 Thread Huang Tao
In RVV and vcrypto instructions, the element agnostic function vext_set_elems_1s
can't deal with the big endian host environment.
This patchset fixes the problem by implementing the right function to set 
agnostic
elements.

Huang Tao (4):
  target/riscv: Rename vext_set_elems_1s function
  target/riscv: Add right functions to set agnostic elements
  target/riscv: Replace element agnostic for vector instructions
  target/riscv: Delete the former element agnostic function

 target/riscv/vcrypto_helper.c   | 32 ++--
 target/riscv/vector_helper.c| 92 -
 target/riscv/vector_internals.c | 58 +
 target/riscv/vector_internals.h |  8 +--
 4 files changed, 115 insertions(+), 75 deletions(-)

-- 
2.41.0




[PATCH 2/4] target/riscv: Add right functions to set agnostic elements

2024-03-06 Thread Huang Tao
We add vext_set_elems_1s to set agnostic elements to 1s in both big
and little endian situation.
In the function vext_set_elems_1s. We using esz argument to get the first
element to set. 'cnt' is just idx * esz.

Signed-off-by: Huang Tao 
---
 target/riscv/vector_internals.c | 53 +
 target/riscv/vector_internals.h |  2 ++
 2 files changed, 55 insertions(+)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 349b24f4ae..455be96996 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -20,6 +20,59 @@
 #include "vector_internals.h"
 
 /* set agnostic elements to 1s */
+#if HOST_BIG_ENDIAN
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+   uint32_t idx, uint32_t tot)
+{
+if (is_agnostic == 0) {
+/* policy undisturbed */
+return;
+}
+void *base = NULL;
+switch (esz) {
+case 1:
+base = ((int8_t *)vd + H1(idx));
+break;
+case 2:
+base = ((int16_t *)vd + H2(idx));
+break;
+case 4:
+base = ((int32_t *)vd + H4(idx));
+break;
+case 8:
+base = ((int64_t *)vd + H8(idx));
+break;
+default:
+g_assert_not_reached();
+break;
+}
+/*
+ * spilt the elements into 2 parts
+ * part_begin: the memory need to be set in the first uint64_t unit
+ * part_allign: the memory need to be set begins from next uint64_t
+ *  unit and alligned to 8
+ */
+uint32_t cnt = idx * esz;
+int part_begin, part_allign;
+part_begin = MIN(tot - cnt, 8 - (cnt % 8));
+part_allign = ((tot - cnt - part_begin) / 8) * 8;
+
+memset(base - part_begin + 1, -1, part_begin);
+memset(QEMU_ALIGN_PTR_UP(base, 8), -1, part_allign);
+}
+#else
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+   uint32_t idx, uint32_t tot)
+{
+if (is_agnostic == 0) {
+/* policy undisturbed */
+return;
+}
+uint32_t cnt = idx * esz;
+memset(vd + cnt, -1, tot - cnt);
+}
+#endif
+
 void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
uint32_t tot)
 {
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index fa599f60ca..c96e52f926 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -114,6 +114,8 @@ static inline uint32_t vext_get_total_elems(CPURISCVState 
*env, uint32_t desc,
 }
 
 /* set agnostic elements to 1s */
+void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
+   uint32_t idx, uint32_t tot);
 void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
uint32_t tot);
 
-- 
2.41.0




[PATCH] target/riscv: Implement dynamic establishment of custom decoder

2024-03-06 Thread Huang Tao
In this patch, we modify the decoder to be a freely composable data
structure instead of a hardcoded one. It can be dynamically builded up
according to the extensions.
This approach has several benefits:
1. Provides support for heterogeneous cpu architectures. As we add decoder in
   CPUArchState, each cpu can have their own decoder, and the decoders can be
   different due to cpu's features.
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
   can be added to the dynamic_decoder when building up the decoder. Therefore,
   there is no need to run the guard_func when decoding each instruction. It can
   improve the decoding efficiency
3. For vendor or dynamic cpus, it allows them to customize their own decoder
   functions to improve decoding efficiency, especially when vendor-defined
   instruction sets increase. Because of dynamic building up, it can skip the 
other
   decoder guard functions when decoding.

Signed-off-by: Huang Tao 
Suggested-by: Christoph Muellner 
Co-authored-by: LIU Zhiwei 
---
 target/riscv/cpu.c | 20 
 target/riscv/cpu.h |  2 ++
 target/riscv/cpu_decoder.h | 34 ++
 target/riscv/translate.c   | 28 
 4 files changed, 68 insertions(+), 16 deletions(-)
 create mode 100644 target/riscv/cpu_decoder.h

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5ff0192c52..cadcd51b4f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -38,6 +38,7 @@
 #include "kvm/kvm_riscv.h"
 #include "tcg/tcg-cpu.h"
 #include "tcg/tcg.h"
+#include "cpu_decoder.h"
 
 /* RISC-V CPU definitions */
 static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
@@ -1102,6 +1103,23 @@ static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, 
Error **errp)
 }
 #endif
 
+static void riscv_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
+{
+CPURISCVState *env = >env;
+decode_fn *dynamic_decoder;
+dynamic_decoder = g_new0(decode_fn, decoder_table_size);
+int j = 0;
+for (size_t i = 0; i < decoder_table_size; ++i) {
+if (decoder_table[i].guard_func &&
+decoder_table[i].guard_func(>cfg)) {
+dynamic_decoder[j] = decoder_table[i].decode_fn;
+j++;
+}
+}
+
+env->decoder = dynamic_decoder;
+}
+
 void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
 {
 Error *local_err = NULL;
@@ -1127,6 +1145,8 @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error 
**errp)
 return;
 }
 }
+
+riscv_cpu_finalize_dynamic_decoder(cpu);
 }
 
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5d291a7092..42bfed065c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -30,6 +30,7 @@
 #include "qemu/int128.h"
 #include "cpu_bits.h"
 #include "cpu_cfg.h"
+#include "cpu_decoder.h"
 #include "qapi/qapi-types-common.h"
 #include "cpu-qom.h"
 
@@ -433,6 +434,7 @@ struct CPUArchState {
 uint64_t kvm_timer_state;
 uint64_t kvm_timer_frequency;
 #endif /* CONFIG_KVM */
+const decode_fn *decoder;
 };
 
 /*
diff --git a/target/riscv/cpu_decoder.h b/target/riscv/cpu_decoder.h
new file mode 100644
index 00..549414ce4c
--- /dev/null
+++ b/target/riscv/cpu_decoder.h
@@ -0,0 +1,34 @@
+/*
+ * QEMU RISC-V CPU Decoder
+ *
+ * Copyright (c) 2023-2024 Alibaba Group
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_CPU_DECODER_H
+#define RISCV_CPU_DECODER_H
+
+struct DisasContext;
+struct RISCVCPUConfig;
+typedef struct RISCVDecoder {
+bool (*guard_func)(const struct RISCVCPUConfig *);
+bool (*decode_fn)(struct DisasContext *, uint32_t);
+} RISCVDecoder;
+
+typedef bool (*decode_fn)(struct DisasContext *, uint32_t);
+
+extern const size_t decoder_table_size;
+
+extern const RISCVDecoder decoder_table[];
+#endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 177418b2b9..23c5321bce 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -115,6 +115,7 @@ typedef struct DisasContext {
 bool frm_valid;
 /* TCG of the current insn_start */
 TCGOp *insn_start;
+const decode_fn *decoder;
 } DisasContext;
 
 static inline bool has_ext(DisasConte

[PATCH 4/4] target/riscv: Delete the former element agnostic function

2024-03-06 Thread Huang Tao
Delete vext_set_elems_1s_le.

Signed-off-by: Huang Tao 
---
 target/riscv/vector_internals.c | 13 -
 target/riscv/vector_internals.h |  2 --
 2 files changed, 15 deletions(-)

diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
index 0166e81e02..4f24bd8516 100644
--- a/target/riscv/vector_internals.c
+++ b/target/riscv/vector_internals.c
@@ -73,19 +73,6 @@ void vext_set_elems_1s(void *vd, uint32_t is_agnostic, 
uint32_t esz,
 }
 #endif
 
-void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
-   uint32_t tot)
-{
-if (is_agnostic == 0) {
-/* policy undisturbed */
-return;
-}
-if (tot - cnt == 0) {
-return ;
-}
-memset(base + cnt, -1, tot - cnt);
-}
-
 void do_vext_vv(void *vd, void *v0, void *vs1, void *vs2,
 CPURISCVState *env, uint32_t desc,
 opivv2_fn *fn, uint32_t esz)
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
index de7d2681e6..45168d4cfc 100644
--- a/target/riscv/vector_internals.h
+++ b/target/riscv/vector_internals.h
@@ -116,8 +116,6 @@ static inline uint32_t vext_get_total_elems(CPURISCVState 
*env, uint32_t desc,
 /* set agnostic elements to 1s */
 void vext_set_elems_1s(void *vd, uint32_t is_agnostic, uint32_t esz,
uint32_t idx, uint32_t tot);
-void vext_set_elems_1s_le(void *base, uint32_t is_agnostic, uint32_t cnt,
-   uint32_t tot);
 
 /* expand macro args before macro */
 #define RVVCALL(macro, ...)  macro(__VA_ARGS__)
-- 
2.41.0




[PATCH 1/4] target/riscv: Rename vext_set_elems_1s function

2024-03-06 Thread Huang Tao
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
agnostic policy.

However, this function can't deal the big endian situation. We rename the
function, adding '_le' to the end of the name, to indicate that it only
suits little endian situation.

Signed-off-by: Huang Tao 
---
 target/riscv/vcrypto_helper.c   | 32 ++--
 target/riscv/vector_helper.c| 92 -
 target/riscv/vector_internals.c | 10 ++--
 target/riscv/vector_internals.h |  6 +--
 4 files changed, 70 insertions(+), 70 deletions(-)

diff --git a/target/riscv/vcrypto_helper.c b/target/riscv/vcrypto_helper.c
index e2d719b13b..f818749a63 100644
--- a/target/riscv/vcrypto_helper.c
+++ b/target/riscv/vcrypto_helper.c
@@ -235,7 +235,7 @@ static inline void xor_round_key(AESState *round_state, 
AESState *round_key)
 } \
 env->vstart = 0;  \
 /* set tail elements to 1s */ \
-vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);  \
+vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);  \
 }
 
 #define GEN_ZVKNED_HELPER_VS(NAME, ...)   \
@@ -259,7 +259,7 @@ static inline void xor_round_key(AESState *round_state, 
AESState *round_key)
 } \
 env->vstart = 0;  \
 /* set tail elements to 1s */ \
-vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);  \
+vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);  \
 }
 
 GEN_ZVKNED_HELPER_VV(vaesef_vv, aesenc_SB_SR_AK(_state,
@@ -339,7 +339,7 @@ void HELPER(vaeskf1_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 }
 env->vstart = 0;
 /* set tail elements to 1s */
-vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
+vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);
 }
 
 void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, uint32_t uimm,
@@ -396,7 +396,7 @@ void HELPER(vaeskf2_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 }
 env->vstart = 0;
 /* set tail elements to 1s */
-vext_set_elems_1s(vd, vta, vl * 4, total_elems * 4);
+vext_set_elems_1s_le(vd, vta, vl * 4, total_elems * 4);
 }
 
 static inline uint32_t sig0_sha256(uint32_t x)
@@ -469,7 +469,7 @@ void HELPER(vsha2ms_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 }
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -579,7 +579,7 @@ void HELPER(vsha2ch32_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -597,7 +597,7 @@ void HELPER(vsha2ch64_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -615,7 +615,7 @@ void HELPER(vsha2cl32_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -633,7 +633,7 @@ void HELPER(vsha2cl64_vv)(void *vd, void *vs1, void *vs2, 
CPURISCVState *env,
 
 /* set tail elements to 1s */
 total_elems = vext_get_total_elems(env, desc, esz);
-vext_set_elems_1s(vd, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -672,7 +672,7 @@ void HELPER(vsm3me_vv)(void *vd_vptr, void *vs1_vptr, void 
*vs2_vptr,
 vd[(i * 8) + j] = bswap32(w[H4(j + 16)]);
 }
 }
-vext_set_elems_1s(vd_vptr, vta, env->vl * esz, total_elems * esz);
+vext_set_elems_1s_le(vd_vptr, vta, env->vl * esz, total_elems * esz);
 env->vstart = 0;
 }
 
@@ -767,7 +767,7 @@ void HELPER(vsm3c_vi)(void *vd_vptr, void *vs2_vptr, 
uint32_t uimm,
 vd[i * 8 + k] = bswap32(v1[H4(k)]);
 }
 }
-