Re: [PATCH 5/8] q800: wire up auxmode GPIO to GLUE

2021-10-15 Thread Laurent Vivier
Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :
> This enables the GLUE logic to change its CPU level IRQ routing depending upon
> whether the hardware has been configured for A/UX mode.
> 
> Signed-off-by: Mark Cave-Ayland 
> ---
>  hw/m68k/q800.c | 14 ++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c
> index 81c335bf16..0093872d89 100644
> --- a/hw/m68k/q800.c
> +++ b/hw/m68k/q800.c
> @@ -100,6 +100,7 @@ struct GLUEState {
>  SysBusDevice parent_obj;
>  M68kCPU *cpu;
>  uint8_t ipr;
> +uint8_t auxmode;
>  };
>  
>  #define GLUE_IRQ_IN_VIA1   0
> @@ -145,11 +146,19 @@ static void GLUE_set_irq(void *opaque, int irq, int 
> level)
>  m68k_set_irq_level(s->cpu, 0, 0);
>  }
>  
> +static void glue_auxmode_set_irq(void *opaque, int irq, int level)
> +{
> +GLUEState *s = GLUE(opaque);
> +
> +s->auxmode = level;
> +}
> +
>  static void glue_reset(DeviceState *dev)
>  {
>  GLUEState *s = GLUE(dev);
>  
>  s->ipr = 0;
> +s->auxmode = 0;
>  }
>  
>  static const VMStateDescription vmstate_glue = {
> @@ -158,6 +167,7 @@ static const VMStateDescription vmstate_glue = {
>  .minimum_version_id = 0,
>  .fields = (VMStateField[]) {
>  VMSTATE_UINT8(ipr, GLUEState),
> +VMSTATE_UINT8(auxmode, GLUEState),
>  VMSTATE_END_OF_LIST(),
>  },
>  };
> @@ -178,6 +188,7 @@ static void glue_init(Object *obj)
>  DeviceState *dev = DEVICE(obj);
>  
>  qdev_init_gpio_in(dev, GLUE_set_irq, 8);
> +qdev_init_gpio_in_named(dev, glue_auxmode_set_irq, "auxmode", 1);
>  }
>  
>  static void glue_class_init(ObjectClass *klass, void *data)
> @@ -308,6 +319,9 @@ static void q800_init(MachineState *machine)
>  sysbus_realize_and_unref(sysbus, &error_fatal);
>  sysbus_mmio_map(sysbus, 1, VIA_BASE);
>  sysbus_connect_irq(sysbus, 0, qdev_get_gpio_in(glue, GLUE_IRQ_IN_VIA1));
> +/* A/UX mode */
> +qdev_connect_gpio_out(via1_dev, 0,
> +  qdev_get_gpio_in_named(glue, "auxmode", 0));
>  
>  adb_bus = qdev_get_child_bus(via1_dev, "adb.0");
>  dev = qdev_new(TYPE_ADB_KEYBOARD);
> 

Reviewed-by: Laurent Vivier 



[PATCH v2 4/6] target/riscv: zfh: half-precision floating-point compare

2021-10-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Chih-Min Chao 
Signed-off-by: Frank Chang 
---
 target/riscv/fpu_helper.c | 21 +
 target/riscv/helper.h |  3 ++
 target/riscv/insn32.decode|  3 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc | 37 +++
 4 files changed, 64 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index d40bc590e6a..12e84aed41e 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -449,6 +449,27 @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
 return nanbox_h(float16_sqrt(frs1, &env->fp_status));
 }
 
+target_ulong helper_fle_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return float16_le(frs1, frs2, &env->fp_status);
+}
+
+target_ulong helper_flt_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return float16_lt(frs1, frs2, &env->fp_status);
+}
+
+target_ulong helper_feq_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return float16_eq_quiet(frs1, frs2, &env->fp_status);
+}
+
 target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
 {
 float16 frs1 = check_nanbox_h(rs1);
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b50672d1684..9c89521d4ad 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -74,6 +74,9 @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, 
i64)
 DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_3(fle_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
+DEF_HELPER_FLAGS_3(flt_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
+DEF_HELPER_FLAGS_3(feq_h, TCG_CALL_NO_RWG, tl, env, i64, i64)
 DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
 DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
 DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ba40f3e7f89..3906c9fb201 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -751,6 +751,9 @@ fcvt_d_h   011  00010 . ... . 1010011 @r2_rm
 fcvt_w_h   1100010  0 . ... . 1010011 @r2_rm
 fcvt_wu_h  1100010  1 . ... . 1010011 @r2_rm
 fmv_x_h1110010  0 . 000 . 1010011 @r2
+feq_h  1010010  . . 010 . 1010011 @r
+flt_h  1010010  . . 001 . 1010011 @r
+fle_h  1010010  . . 000 . 1010011 @r
 fcvt_h_w   1101010  0 . ... . 1010011 @r2_rm
 fcvt_h_wu  1101010  1 . ... . 1010011 @r2_rm
 fmv_h_x010  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
index fff34e2c8a4..8b469348ce9 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -334,6 +334,43 @@ static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d 
*a)
 return true;
 }
 
+static bool trans_feq_h(DisasContext *ctx, arg_feq_h *a)
+{
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+TCGv dest = dest_gpr(ctx, a->rd);
+
+gen_helper_feq_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+gen_set_gpr(ctx, a->rd, dest);
+return true;
+}
+
+static bool trans_flt_h(DisasContext *ctx, arg_flt_h *a)
+{
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+TCGv dest = dest_gpr(ctx, a->rd);
+
+gen_helper_flt_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+gen_set_gpr(ctx, a->rd, dest);
+
+return true;
+}
+
+static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a)
+{
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+TCGv dest = dest_gpr(ctx, a->rd);
+
+gen_helper_fle_h(dest, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
+gen_set_gpr(ctx, a->rd, dest);
+return true;
+}
+
 static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v2 0/6] target/riscv: support Zfh, Zfhmin extension v0.1

2021-10-15 Thread frank . chang
From: Frank Chang 

Zfh - Half width floating point
Zfhmin - Subset of half width floating point

Zfh, Zfhmin v0.1 is now in public review period and is required by
RVV extension:
https://groups.google.com/a/groups.riscv.org/g/isa-dev/c/63gDCinXTwE/m/871Wm9XIBQAJ

Zfh, Zfhmin can be enabled with -cpu option: Zfh=true and Zfhmin=true
respectively.

The port is available at:
https://github.com/sifive/qemu/tree/zfh-upstream-v2

Note: This patchset depends on another patchset listed in Based-on
  section below so it is not able to be built unless the patchset
  is applied.

Changelog:

v2:
  * Use {get,dest}_gpr APIs.
  * Add Zfhmin extension.

Based-on: <20211015065500.3850513-1-frank.ch...@sifive.com>

Frank Chang (1):
  target/riscv: zfh: implement zfhmin extension

Kito Cheng (5):
  target/riscv: zfh: half-precision load and store
  target/riscv: zfh: half-precision computational
  target/riscv: zfh: half-precision convert and move
  target/riscv: zfh: half-precision floating-point compare
  target/riscv: zfh: half-precision floating-point classify

 target/riscv/cpu.c|   2 +
 target/riscv/cpu.h|   2 +
 target/riscv/fpu_helper.c | 176 +++
 target/riscv/helper.h |  29 ++
 target/riscv/insn32.decode|  38 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc | 535 ++
 target/riscv/internals.h  |  16 +
 target/riscv/translate.c  |  20 +
 8 files changed, 818 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc

--
2.25.1




[PATCH v2 1/6] target/riscv: zfh: half-precision load and store

2021-10-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Chih-Min Chao 
Signed-off-by: Frank Chang 
---
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h|  1 +
 target/riscv/insn32.decode|  4 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc | 64 +++
 target/riscv/translate.c  |  8 +++
 5 files changed, 78 insertions(+)
 create mode 100644 target/riscv/insn_trans/trans_rvzfh.c.inc

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 1d69d1887e6..992cfc3ab0b 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -591,6 +591,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
+DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
 /* This is experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false),
 DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9e55b2f5b17..88684e72be1 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -297,6 +297,7 @@ struct RISCVCPU {
 bool ext_counters;
 bool ext_ifencei;
 bool ext_icsr;
+bool ext_zfh;
 
 char *priv_spec;
 char *user_spec;
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 2f251dac1bb..b36a3d8dbf8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -726,3 +726,7 @@ binv   0110100 .. 001 . 0110011 @r
 binvi  01101. ... 001 . 0010011 @sh
 bset   0010100 .. 001 . 0110011 @r
 bseti  00101. ... 001 . 0010011 @sh
+
+# *** RV32 Zfh Extension ***
+flh   . 001 . 111 @i
+fsh...  . . 001 . 0100111 @s
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
new file mode 100644
index 000..1d0ad07f03b
--- /dev/null
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -0,0 +1,64 @@
+/*
+ * RISC-V translation routines for the RV64Zfh Standard Extension.
+ *
+ * Copyright (c) 2020 Chih-Min Chao, chihmin.c...@sifive.com
+ *
+ * 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 .
+ */
+
+#define REQUIRE_ZFH(ctx) do { \
+if (!ctx->ext_zfh)\
+return false; \
+} while (0)
+
+static bool trans_flh(DisasContext *ctx, arg_flh *a)
+{
+TCGv_i64 dest;
+TCGv t0;
+
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+t0 = get_gpr(ctx, a->rs1, EXT_NONE);
+if (a->imm) {
+TCGv temp = temp_new(ctx);
+tcg_gen_addi_tl(temp, t0, a->imm);
+t0 = temp;
+}
+
+dest = cpu_fpr[a->rd];
+tcg_gen_qemu_ld_i64(dest, t0, ctx->mem_idx, MO_TEUW);
+gen_nanbox_h(dest, dest);
+
+mark_fs_dirty(ctx);
+return true;
+}
+
+static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
+{
+TCGv t0;
+
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+t0 = get_gpr(ctx, a->rs1, EXT_NONE);
+if (a->imm) {
+TCGv temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, t0, a->imm);
+t0 = temp;
+}
+
+tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUW);
+
+return true;
+}
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d2442f0cf5d..75048149f5a 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -69,6 +69,7 @@ typedef struct DisasContext {
 bool w;
 bool virt_enabled;
 bool ext_ifencei;
+bool ext_zfh;
 bool hlsx;
 /* vector extension */
 bool vill;
@@ -118,6 +119,11 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
 tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(32, 32));
 }
 
+static void gen_nanbox_h(TCGv_i64 out, TCGv_i64 in)
+{
+tcg_gen_ori_i64(out, in, MAKE_64BIT_MASK(16, 48));
+}
+
 /*
  * A narrow n-bit operation, where n < FLEN, checks that input operands
  * are correctly Nan-boxed, i.e., all upper FLEN - n bits are 1.
@@ -489,6 +495,7 @@ static uint32_t opcode_at(DisasContextBase *dcbase, 
target_ulong pc)
 #include "insn_trans/trans_rvh.c.inc"
 #include "insn_trans/trans_rvv.c.inc"
 #include "insn_trans/trans_rvb.c.inc"
+#include "insn_trans/trans_rvzfh.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
 
 /* Include the auto-generated deco

[PATCH v2 3/6] target/riscv: zfh: half-precision convert and move

2021-10-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Chih-Min Chao 
Signed-off-by: Frank Chang 
---
 target/riscv/fpu_helper.c |  67 +
 target/riscv/helper.h |  12 +
 target/riscv/insn32.decode|  19 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc | 288 ++
 target/riscv/translate.c  |  10 +
 5 files changed, 396 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index ec9ccba18c0..d40bc590e6a 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -448,3 +448,70 @@ uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
 float16 frs1 = check_nanbox_h(rs1);
 return nanbox_h(float16_sqrt(frs1, &env->fp_status));
 }
+
+target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return float16_to_int32(frs1, &env->fp_status);
+}
+
+target_ulong helper_fcvt_wu_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return (int32_t)float16_to_uint32(frs1, &env->fp_status);
+}
+
+target_ulong helper_fcvt_l_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return float16_to_int64(frs1, &env->fp_status);
+}
+
+target_ulong helper_fcvt_lu_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return float16_to_uint64(frs1, &env->fp_status);
+}
+
+uint64_t helper_fcvt_h_w(CPURISCVState *env, target_ulong rs1)
+{
+return nanbox_h(int32_to_float16((int32_t)rs1, &env->fp_status));
+}
+
+uint64_t helper_fcvt_h_wu(CPURISCVState *env, target_ulong rs1)
+{
+return nanbox_h(uint32_to_float16((uint32_t)rs1, &env->fp_status));
+}
+
+uint64_t helper_fcvt_h_l(CPURISCVState *env, target_ulong rs1)
+{
+return nanbox_h(int64_to_float16(rs1, &env->fp_status));
+}
+
+uint64_t helper_fcvt_h_lu(CPURISCVState *env, target_ulong rs1)
+{
+return nanbox_h(uint64_to_float16(rs1, &env->fp_status));
+}
+
+uint64_t helper_fcvt_h_s(CPURISCVState *env, uint64_t rs1)
+{
+float32 frs1 = check_nanbox_s(rs1);
+return nanbox_h(float32_to_float16(frs1, true, &env->fp_status));
+}
+
+uint64_t helper_fcvt_s_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return nanbox_s(float16_to_float32(frs1, true, &env->fp_status));
+}
+
+uint64_t helper_fcvt_h_d(CPURISCVState *env, uint64_t rs1)
+{
+return nanbox_h(float64_to_float16(rs1, true, &env->fp_status));
+}
+
+uint64_t helper_fcvt_d_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return float16_to_float64(frs1, true, &env->fp_status);
+}
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c6c0323fafc..b50672d1684 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -74,6 +74,18 @@ DEF_HELPER_FLAGS_3(fdiv_h, TCG_CALL_NO_RWG, i64, env, i64, 
i64)
 DEF_HELPER_FLAGS_3(fmin_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_3(fmax_h, TCG_CALL_NO_RWG, i64, env, i64, i64)
 DEF_HELPER_FLAGS_2(fsqrt_h, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_s_h, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_h_s, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_d_h, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_h_d, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_w_h, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_wu_h, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_l_h, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_lu_h, TCG_CALL_NO_RWG, tl, env, i64)
+DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
 
 /* Special functions */
 DEF_HELPER_2(csrr, tl, env, int)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 66c231a3010..ba40f3e7f89 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -739,5 +739,24 @@ fsub_h 110  . . ... . 1010011 @r_rm
 fmul_h 0001010  . . ... . 1010011 @r_rm
 fdiv_h 0001110  . . ... . 1010011 @r_rm
 fsqrt_h0101110  0 . ... . 1010011 @r2_rm
+fsgnj_h0010010  . . 000 . 1010011 @r
+fsgnjn_h   0010010  . . 001 . 1010011 @r
+fsgnjx_h   0010010  . . 010 . 1010011 @r
 fmin_h 0010110  . . 000 . 1010011 @r
 fmax_h 0010110  . . 001 . 1010011 @r
+fcvt_h_s   0100010  0 . ... . 1010011 @r2_rm
+fcvt_s_h   010  00010 . ... . 1010011 @r2_rm
+fcvt_h_d   0100010  1 . ... . 1010011 @r2_rm
+fcvt_d_h   011  00010 . ... . 1010011 @r2_rm
+fcvt_w_h   1100010  0 . ... . 1010011 @r2_rm
+fcvt_wu_h  1100010  1 . ... . 1010011 @r2_rm
+fmv_x_h1110010  0 . 000 . 101001

Re: [PATCH 6/6] ppc/pegasos2: Implement power-off RTAS function with VOF

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> This only helps Linux guests as only that seems to use it.
> 
> Signed-off-by: BALATON Zoltan 

Applied, thanks.

> ---
>  hw/ppc/pegasos2.c | 11 +++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index 39e96d323f..e427ac2fe0 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -22,6 +22,7 @@
>  #include "hw/i2c/smbus_eeprom.h"
>  #include "hw/qdev-properties.h"
>  #include "sysemu/reset.h"
> +#include "sysemu/runstate.h"
>  #include "hw/boards.h"
>  #include "hw/loader.h"
>  #include "hw/fw-path-provider.h"
> @@ -429,6 +430,16 @@ static target_ulong pegasos2_rtas(PowerPCCPU *cpu, 
> Pegasos2MachineState *pm,
>  qemu_log_mask(LOG_UNIMP, "%c", ldl_be_phys(as, args));
>  stl_be_phys(as, rets, 0);
>  return H_SUCCESS;
> +case RTAS_POWER_OFF:
> +{
> +if (nargs != 2 || nrets != 1) {
> +stl_be_phys(as, rets, -1);
> +return H_PARAMETER;
> +}
> +qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
> +stl_be_phys(as, rets, 0);
> +return H_SUCCESS;
> +}
>  default:
>  qemu_log_mask(LOG_UNIMP, "Unknown RTAS token %u (args=%u, 
> rets=%u)\n",
>token, nargs, nrets);

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


[PATCH v2 2/6] target/riscv: zfh: half-precision computational

2021-10-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Chih-Min Chao 
Signed-off-by: Frank Chang 
---
 target/riscv/fpu_helper.c |  82 ++
 target/riscv/helper.h |  13 +++
 target/riscv/insn32.decode|  11 ++
 target/riscv/insn_trans/trans_rvzfh.c.inc | 129 ++
 target/riscv/internals.h  |  16 +++
 5 files changed, 251 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 1472ead2528..ec9ccba18c0 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -81,6 +81,15 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
rm)
 set_float_rounding_mode(softrm, &env->fp_status);
 }
 
+static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
+   uint64_t rs3, int flags)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+float16 frs3 = check_nanbox_h(rs3);
+return nanbox_h(float16_muladd(frs1, frs2, frs3, flags, &env->fp_status));
+}
+
 static uint64_t do_fmadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
uint64_t rs3, int flags)
 {
@@ -102,6 +111,12 @@ uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, 
uint64_t frs2,
 return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status);
 }
 
+uint64_t helper_fmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+uint64_t frs3)
+{
+return do_fmadd_h(env, frs1, frs2, frs3, 0);
+}
+
 uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
 uint64_t frs3)
 {
@@ -115,6 +130,12 @@ uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, 
uint64_t frs2,
   &env->fp_status);
 }
 
+uint64_t helper_fmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+uint64_t frs3)
+{
+return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_c);
+}
+
 uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  uint64_t frs3)
 {
@@ -128,6 +149,12 @@ uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t 
frs1, uint64_t frs2,
   &env->fp_status);
 }
 
+uint64_t helper_fnmsub_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+ uint64_t frs3)
+{
+return do_fmadd_h(env, frs1, frs2, frs3, float_muladd_negate_product);
+}
+
 uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
  uint64_t frs3)
 {
@@ -142,6 +169,13 @@ uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t 
frs1, uint64_t frs2,
   float_muladd_negate_product, &env->fp_status);
 }
 
+uint64_t helper_fnmadd_h(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
+ uint64_t frs3)
+{
+return do_fmadd_h(env, frs1, frs2, frs3,
+  float_muladd_negate_c | float_muladd_negate_product);
+}
+
 uint64_t helper_fadd_s(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
 {
 float32 frs1 = check_nanbox_s(rs1);
@@ -366,3 +400,51 @@ target_ulong helper_fclass_d(uint64_t frs1)
 {
 return fclass_d(frs1);
 }
+
+uint64_t helper_fadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_add(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fsub_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_sub(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fmul_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_mul(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fdiv_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_div(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fmin_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_minnum_noprop(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fmax_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2)
+{
+float16 frs1 = check_nanbox_h(rs1);
+float16 frs2 = check_nanbox_h(rs2);
+return nanbox_h(float16_maxnum_noprop(frs1, frs2, &env->fp_status));
+}
+
+uint64_t helper_fsqrt_h(CPURISCVState *env, uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return nanbox_h(float16_sqrt(frs1, &env->fp_status));
+}
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index c7a53762277..c6c0323fafc 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -7,12 +7,16 @@ DEF_HELPER_FLAGS_2(set_rounding_mode, 

Re: [PATCH 4/6] ppc/pegasos2: Access MV64361 registers via their memory region

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> Instead of relying on the mapped address of the MV64361 registers
> access them via their memory region. This is not a problem at reset
> time when these registers are mapped at the default address but the
> guest could change this later and then the RTAS calls accessing PCI
> config registers could fail. None of the guests actually do this so
> this only avoids a theoretical problem not seen in practice.
> 
> Signed-off-by: BALATON Zoltan 

Applied, thanks.

> ---
>  hw/pci-host/mv64361.c |   1 +
>  hw/ppc/pegasos2.c | 117 --
>  2 files changed, 56 insertions(+), 62 deletions(-)
> 
> diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c
> index 92b0f5d047..00b3ff7d90 100644
> --- a/hw/pci-host/mv64361.c
> +++ b/hw/pci-host/mv64361.c
> @@ -869,6 +869,7 @@ static void mv64361_realize(DeviceState *dev, Error 
> **errp)
>  s->base_addr_enable = 0x1f;
>  memory_region_init_io(&s->regs, OBJECT(s), &mv64361_ops, s,
>TYPE_MV64361, 0x1);
> +sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs);
>  for (i = 0; i < 2; i++) {
>  g_autofree char *name = g_strdup_printf("pcihost%d", i);
>  object_initialize_child(OBJECT(dev), name, &s->pci[i],
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index a9e3625f56..a861bf16b8 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -205,56 +205,49 @@ static void pegasos2_init(MachineState *machine)
>  }
>  }
>  
> -static uint32_t pegasos2_pci_config_read(AddressSpace *as, int bus,
> +static uint32_t pegasos2_mv_reg_read(Pegasos2MachineState *pm,
> + uint32_t addr, uint32_t len)
> +{
> +MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->mv), 0);
> +uint64_t val = 0xULL;
> +memory_region_dispatch_read(r, addr, &val, size_memop(len) | MO_LE,
> +MEMTXATTRS_UNSPECIFIED);
> +return val;
> +}
> +
> +static void pegasos2_mv_reg_write(Pegasos2MachineState *pm, uint32_t addr,
> +  uint32_t len, uint32_t val)
> +{
> +MemoryRegion *r = sysbus_mmio_get_region(SYS_BUS_DEVICE(pm->mv), 0);
> +memory_region_dispatch_write(r, addr, val, size_memop(len) | MO_LE,
> + MEMTXATTRS_UNSPECIFIED);
> +}
> +
> +static uint32_t pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
>   uint32_t addr, uint32_t len)
>  {
> -hwaddr pcicfg = (bus ? 0xf1000c78 : 0xf1000cf8);
> -uint32_t val = 0x;
> -
> -stl_le_phys(as, pcicfg, addr | BIT(31));
> -switch (len) {
> -case 4:
> -val = ldl_le_phys(as, pcicfg + 4);
> -break;
> -case 2:
> -val = lduw_le_phys(as, pcicfg + 4);
> -break;
> -case 1:
> -val = ldub_phys(as, pcicfg + 4);
> -break;
> -default:
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid length\n", __func__);
> -break;
> +hwaddr pcicfg = bus ? 0xc78 : 0xcf8;
> +uint64_t val = 0xULL;
> +
> +if (len <= 4) {
> +pegasos2_mv_reg_write(pm, pcicfg, 4, addr | BIT(31));
> +val = pegasos2_mv_reg_read(pm, pcicfg + 4, len);
>  }
>  return val;
>  }
>  
> -static void pegasos2_pci_config_write(AddressSpace *as, int bus, uint32_t 
> addr,
> -  uint32_t len, uint32_t val)
> +static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
> +  uint32_t addr, uint32_t len, uint32_t 
> val)
>  {
> -hwaddr pcicfg = (bus ? 0xf1000c78 : 0xf1000cf8);
> -
> -stl_le_phys(as, pcicfg, addr | BIT(31));
> -switch (len) {
> -case 4:
> -stl_le_phys(as, pcicfg + 4, val);
> -break;
> -case 2:
> -stw_le_phys(as, pcicfg + 4, val);
> -break;
> -case 1:
> -stb_phys(as, pcicfg + 4, val);
> -break;
> -default:
> -qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid length\n", __func__);
> -break;
> -}
> +hwaddr pcicfg = bus ? 0xc78 : 0xcf8;
> +
> +pegasos2_mv_reg_write(pm, pcicfg, 4, addr | BIT(31));
> +pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);
>  }
>  
>  static void pegasos2_machine_reset(MachineState *machine)
>  {
>  Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
> -AddressSpace *as = CPU(pm->cpu)->as;
>  void *fdt;
>  uint64_t d[2];
>  int sz;
> @@ -265,51 +258,51 @@ static void pegasos2_machine_reset(MachineState 
> *machine)
>  }
>  
>  /* Otherwise, set up devices that board firmware would normally do */
> -stl_le_phys(as, 0xf100, 0x28020ff);
> -stl_le_phys(as, 0xf1000278, 0xa31fc);
> -stl_le_phys(as, 0xf100f300, 0x11ff0400);
> -stl_le_phys(as, 0xf100f10c, 0x8000);
> -stl_le_phys(as, 0xf11c, 0x800);
> -pegasos2_pci_config_writ

[PATCH v2 5/6] target/riscv: zfh: half-precision floating-point classify

2021-10-15 Thread frank . chang
From: Kito Cheng 

Signed-off-by: Kito Cheng 
Signed-off-by: Chih-Min Chao 
Signed-off-by: Frank Chang 
---
 target/riscv/fpu_helper.c |  6 ++
 target/riscv/helper.h |  1 +
 target/riscv/insn32.decode|  1 +
 target/riscv/insn_trans/trans_rvzfh.c.inc | 12 
 4 files changed, 20 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 12e84aed41e..f90f7dca59c 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -470,6 +470,12 @@ target_ulong helper_feq_h(CPURISCVState *env, uint64_t 
rs1, uint64_t rs2)
 return float16_eq_quiet(frs1, frs2, &env->fp_status);
 }
 
+target_ulong helper_fclass_h(uint64_t rs1)
+{
+float16 frs1 = check_nanbox_h(rs1);
+return fclass_h(frs1);
+}
+
 target_ulong helper_fcvt_w_h(CPURISCVState *env, uint64_t rs1)
 {
 float16 frs1 = check_nanbox_h(rs1);
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 9c89521d4ad..d25cf725c57 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -89,6 +89,7 @@ DEF_HELPER_FLAGS_2(fcvt_h_w, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fcvt_h_wu, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fcvt_h_l, TCG_CALL_NO_RWG, i64, env, tl)
 DEF_HELPER_FLAGS_2(fcvt_h_lu, TCG_CALL_NO_RWG, i64, env, tl)
+DEF_HELPER_FLAGS_1(fclass_h, TCG_CALL_NO_RWG_SE, tl, i64)
 
 /* Special functions */
 DEF_HELPER_2(csrr, tl, env, int)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3906c9fb201..6c4cde216bc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -754,6 +754,7 @@ fmv_x_h1110010  0 . 000 . 1010011 @r2
 feq_h  1010010  . . 010 . 1010011 @r
 flt_h  1010010  . . 001 . 1010011 @r
 fle_h  1010010  . . 000 . 1010011 @r
+fclass_h   1110010  0 . 001 . 1010011 @r2
 fcvt_h_w   1101010  0 . ... . 1010011 @r2_rm
 fcvt_h_wu  1101010  1 . ... . 1010011 @r2_rm
 fmv_h_x010  0 . 000 . 1010011 @r2
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 8b469348ce9..837a8002b7f 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -371,6 +371,18 @@ static bool trans_fle_h(DisasContext *ctx, arg_fle_h *a)
 return true;
 }
 
+static bool trans_fclass_h(DisasContext *ctx, arg_fclass_h *a)
+{
+REQUIRE_FPU;
+REQUIRE_ZFH(ctx);
+
+TCGv dest = dest_gpr(ctx, a->rd);
+
+gen_helper_fclass_h(dest, cpu_fpr[a->rs1]);
+gen_set_gpr(ctx, a->rd, dest);
+return true;
+}
+
 static bool trans_fcvt_w_h(DisasContext *ctx, arg_fcvt_w_h *a)
 {
 REQUIRE_FPU;
-- 
2.25.1




[PATCH v2 6/6] target/riscv: zfh: implement zfhmin extension

2021-10-15 Thread frank . chang
From: Frank Chang 

Zfhmin extension is a subset of Zfh extension, consisting only of data
transfer and conversion instructions.

If enabled, only the following instructions from Zfh extension are
included:
  * flh, fsh, fmv.x.h, fmv.h.x, fcvt.s.h, fcvt.h.s
  * If D extension is present: fcvt.d.h, fcvt.h.d

Signed-off-by: Frank Chang 
---
 target/riscv/cpu.c|  1 +
 target/riscv/cpu.h|  1 +
 target/riscv/insn_trans/trans_rvzfh.c.inc | 21 +
 target/riscv/translate.c  |  2 ++
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 992cfc3ab0b..89a612f7606 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -592,6 +592,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
+DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 /* This is experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false),
 DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 88684e72be1..d70f63ddfe6 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -298,6 +298,7 @@ struct RISCVCPU {
 bool ext_ifencei;
 bool ext_icsr;
 bool ext_zfh;
+bool ext_zfhmin;
 
 char *priv_spec;
 char *user_spec;
diff --git a/target/riscv/insn_trans/trans_rvzfh.c.inc 
b/target/riscv/insn_trans/trans_rvzfh.c.inc
index 837a8002b7f..69aebe52107 100644
--- a/target/riscv/insn_trans/trans_rvzfh.c.inc
+++ b/target/riscv/insn_trans/trans_rvzfh.c.inc
@@ -21,13 +21,18 @@
 return false; \
 } while (0)
 
+#define REQUIRE_ZFH_OR_ZFHMIN(ctx) do { \
+if (!(ctx->ext_zfh || ctx->ext_zfhmin)) \
+return false;   \
+} while (0)
+
 static bool trans_flh(DisasContext *ctx, arg_flh *a)
 {
 TCGv_i64 dest;
 TCGv t0;
 
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 t0 = get_gpr(ctx, a->rs1, EXT_NONE);
 if (a->imm) {
@@ -49,7 +54,7 @@ static bool trans_fsh(DisasContext *ctx, arg_fsh *a)
 TCGv t0;
 
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 t0 = get_gpr(ctx, a->rs1, EXT_NONE);
 if (a->imm) {
@@ -282,7 +287,7 @@ static bool trans_fmax_h(DisasContext *ctx, arg_fmax_h *a)
 static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 gen_set_rm(ctx, a->rm);
 gen_helper_fcvt_s_h(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
@@ -295,7 +300,7 @@ static bool trans_fcvt_s_h(DisasContext *ctx, arg_fcvt_s_h 
*a)
 static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 REQUIRE_EXT(ctx, RVD);
 
 gen_set_rm(ctx, a->rm);
@@ -310,7 +315,7 @@ static bool trans_fcvt_d_h(DisasContext *ctx, arg_fcvt_d_h 
*a)
 static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 gen_set_rm(ctx, a->rm);
 gen_helper_fcvt_h_s(cpu_fpr[a->rd], cpu_env, cpu_fpr[a->rs1]);
@@ -323,7 +328,7 @@ static bool trans_fcvt_h_s(DisasContext *ctx, arg_fcvt_h_s 
*a)
 static bool trans_fcvt_h_d(DisasContext *ctx, arg_fcvt_h_d *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 REQUIRE_EXT(ctx, RVD);
 
 gen_set_rm(ctx, a->rm);
@@ -440,7 +445,7 @@ static bool trans_fcvt_h_wu(DisasContext *ctx, 
arg_fcvt_h_wu *a)
 static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 TCGv dest = dest_gpr(ctx, a->rd);
 
@@ -460,7 +465,7 @@ static bool trans_fmv_x_h(DisasContext *ctx, arg_fmv_x_h *a)
 static bool trans_fmv_h_x(DisasContext *ctx, arg_fmv_h_x *a)
 {
 REQUIRE_FPU;
-REQUIRE_ZFH(ctx);
+REQUIRE_ZFH_OR_ZFHMIN(ctx);
 
 TCGv t0 = get_gpr(ctx, a->rs1, EXT_ZERO);
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 442ef42f441..f23bc919c08 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -70,6 +70,7 @@ typedef struct DisasContext {
 bool virt_enabled;
 bool ext_ifencei;
 bool ext_zfh;
+bool ext_zfhmin;
 bool hlsx;
 /* vector extension */
 bool vill;
@@ -559,6 +560,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->frm = -1;  /* unknown rounding mode */
 ctx->ext_ifencei = cpu->cfg.ext_ifencei;
 ctx->ext_zfh = cpu->cfg.ext_zfh;
+ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
 ctx->vlen = cpu->cfg.vlen;
 ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
 ctx->hlsx = FIELD_EX32(tb_f

Re: [PATCH 3/6] ppc/pegasos2: Implement get-time-of-day RTAS function with VOF

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> This is needed for Linux to access RTC time.
> 
> Signed-off-by: BALATON Zoltan 
> ---
>  hw/ppc/pegasos2.c | 25 +
>  1 file changed, 25 insertions(+)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index a1dd1f6752..a9e3625f56 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -31,6 +31,8 @@
>  #include "sysemu/kvm.h"
>  #include "kvm_ppc.h"
>  #include "exec/address-spaces.h"
> +#include "qom/qom-qobject.h"
> +#include "qapi/qmp/qdict.h"
>  #include "trace.h"
>  #include "qemu/datadir.h"
>  #include "sysemu/device_tree.h"
> @@ -369,6 +371,29 @@ static target_ulong pegasos2_rtas(PowerPCCPU *cpu, 
> Pegasos2MachineState *pm,
>  return H_PARAMETER;
>  }
>  switch (token) {
> +case RTAS_GET_TIME_OF_DAY:
> +{
> +QObject *qo = object_property_get_qobject(qdev_get_machine(),
> +  "rtc-time", &error_fatal);
> +QDict *qd = qobject_to(QDict, qo);
> +
> +if (nargs != 0 || nrets != 8 || !qd) {
> +stl_be_phys(as, rets, -1);
> +qobject_unref(qo);
> +return H_PARAMETER;
> +}
> +
> +stl_be_phys(as, rets, 0);
> +stl_be_phys(as, rets + 4, qdict_get_int(qd, "tm_year") + 1900);
> +stl_be_phys(as, rets + 8, qdict_get_int(qd, "tm_mon") + 1);
> +stl_be_phys(as, rets + 12, qdict_get_int(qd, "tm_mday"));
> +stl_be_phys(as, rets + 16, qdict_get_int(qd, "tm_hour"));
> +stl_be_phys(as, rets + 20, qdict_get_int(qd, "tm_min"));
> +stl_be_phys(as, rets + 24, qdict_get_int(qd, "tm_sec"));

Doing a separate dictionary lookup for every component seems like it
might be pretty expensive.  You might want to look at how spapr does
this.

However, you're maintainer for pegasos, so really it's your call -
applied, thanks.

> +stl_be_phys(as, rets + 28, 0);
> +qobject_unref(qo);
> +return H_SUCCESS;
> +}
>  case RTAS_READ_PCI_CONFIG:
>  {
>  uint32_t addr, len, val;

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH 0/6] Misc pegasos2 patches

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> Some small clean ups and improvements for the pegasos2 machine.
> 
> BALATON Zoltan (6):
>   ppc/pegasos2: Restrict memory to 2 gigabytes
>   ppc/pegasos2: Warn when using VOF but no kernel is specified
>   ppc/pegasos2: Implement get-time-of-day RTAS function with VOF
>   ppc/pegasos2: Access MV64361 registers via their memory region
>   ppc/pegasos2: Add constants for PCI config addresses
>   ppc/pegasos2: Implement power-off RTAS function with VOF

Do you use git send-email to send out your patches, or something else?

For some reason your patchsets, unlike most people's end up with the
order completely jumbled in my inbox, which makes applying them a bit
annoying.

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH 2/6] ppc/pegasos2: Warn when using VOF but no kernel is specified

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> Issue a warning when using VOF (which is the default) but no -kernel
> option given to let users know that it will likely fail as the guest
> has nothing to run. It is not a hard error because it may still be
> useful to start the machine without further options for testing or
> inspecting it from monitor without actually booting it.
> 
> Signed-off-by: BALATON Zoltan 

Applied, thanks.

> ---
>  hw/ppc/pegasos2.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index 474cfdeabf..a1dd1f6752 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -194,7 +194,10 @@ static void pegasos2_init(MachineState *machine)
>  if (!pm->vof) {
>  warn_report("Option -kernel may be ineffective with -bios.");
>  }
> +} else if (pm->vof) {
> +warn_report("Using Virtual OpenFirmware but no -kernel option.");
>  }
> +
>  if (!pm->vof && machine->kernel_cmdline && machine->kernel_cmdline[0]) {
>  warn_report("Option -append may be ineffective with -bios.");
>  }

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH v2] hw/elf_ops.h: switch to ssize_t for elf loader return type

2021-10-15 Thread Stefano Garzarella

On Thu, Oct 14, 2021 at 09:43:25PM +0200, Luc Michel wrote:

Until now, int was used as the return type for all the ELF
loader related functions. The returned value is the sum of all loaded
program headers "MemSize" fields.

Because of the overflow check in elf_ops.h, trying to load an ELF bigger
than INT_MAX will fail. Switch to ssize_t to remove this limitation.

Reviewed-by: Philippe Mathieu-Daudé 
Signed-off-by: Luc Michel 
---
v2:
 - Turn load_elf ret local variable to ssize_t [Stefano]
 - Add Phil's R-B
---
include/hw/elf_ops.h | 27 ++--
include/hw/loader.h  | 60 ++--
hw/core/loader.c | 60 +++-
3 files changed, 75 insertions(+), 72 deletions(-)


Reviewed-by: Stefano Garzarella 




Re: [PATCH v2 09/15] softmmu/qdev-monitor: add error handling in qdev_set_id

2021-10-15 Thread Kevin Wolf
Am 13.10.2021 um 23:37 hat Eric Blake geschrieben:
> On Wed, Oct 13, 2021 at 03:10:38PM +0200, Damien Hedde wrote:
> > > > @@ -691,7 +703,13 @@ DeviceState *qdev_device_add(QemuOpts *opts, Error 
> > > > **errp)
> > > >   }
> > > >   }
> > > > -qdev_set_id(dev, g_strdup(qemu_opts_id(opts)));
> > > > +/*
> > > > + * set dev's parent and register its id.
> > > > + * If it fails it means the id is already taken.
> > > > + */
> > > > +if (!qdev_set_id(dev, g_strdup(qemu_opts_id(opts)), errp)) {
> > > > +goto err_del_dev;
> > > 
> > > ...nor on this, which means the g_strdup() leaks on failure.
> > > 
> > 
> > Since we strdup the id just before calling qdev_set_id.
> > Maybe we should do the the strdup in qdev_set_id (and free things on error
> > there too). It seems simplier than freeing things on the callee side just in
> > case of an error.
> 
> Indeed.  If we expected qdev_set_id() to be passed something that it
> can later free, we would have used 'char *'; but because we used
> 'const char *' for that parameter, it really does make more sense for
> the callers to pass in any string and for qdev_set_id() to do the
> necessary strdup()ing, as well as clean up on error.

Since this seems to be the only thing in the series that needs to be
addressed, I'll do the minimal fix while applying (adding g_free() to
the error path in qemu_opts_id()) and then we can clean up on top.

Kevin




Re: [PATCH 1/6] ppc/pegasos2: Restrict memory to 2 gigabytes

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> The CHRP spec this board confirms to only allows 2 GiB of system
> memory below 4 GiB as the high 2 GiB is allocated to IO and system
> resources. To avoid problems with memory overlapping these areas
> restrict RAM to 2 GiB similar to mac_newworld.
> 
> Signed-off-by: BALATON Zoltan 

Applied, thanks.

> ---
>  hw/ppc/pegasos2.c | 4 
>  1 file changed, 4 insertions(+)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index b8ce859f1a..474cfdeabf 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -117,6 +117,10 @@ static void pegasos2_init(MachineState *machine)
>  qemu_register_reset(pegasos2_cpu_reset, pm->cpu);
>  
>  /* RAM */
> +if (machine->ram_size > 2 * GiB) {
> +error_report("RAM size more than 2 GiB is not supported");
> +exit(1);
> +}
>  memory_region_add_subregion(get_system_memory(), 0, machine->ram);
>  
>  /* allocate and load firmware */

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [RFC PATCH v4 20/20] vdpa: Add custom IOTLB translations to SVQ

2021-10-15 Thread Eugenio Perez Martin
On Wed, Oct 13, 2021 at 7:34 AM Jason Wang  wrote:
>
>
> 在 2021/10/1 下午3:06, Eugenio Pérez 写道:
> > Use translations added in VhostIOVATree in SVQ.
> >
> > Now every element needs to store the previous address also, so VirtQueue
> > can consume the elements properly. This adds a little overhead per VQ
> > element, having to allocate more memory to stash them. As a possible
> > optimization, this allocation could be avoided if the descriptor is not
> > a chain but a single one, but this is left undone.
> >
> > TODO: iova range should be queried before, and add logic to fail when
> > GPA is outside of its range and memory listener or svq add it.
> >
> > Signed-off-by: Eugenio Pérez
> > ---
> >   hw/virtio/vhost-shadow-virtqueue.h |   4 +-
> >   hw/virtio/vhost-shadow-virtqueue.c | 130 -
> >   hw/virtio/vhost-vdpa.c |  40 -
> >   hw/virtio/trace-events |   1 +
> >   4 files changed, 152 insertions(+), 23 deletions(-)
>
>
> Think hard about the whole logic. This is safe since qemu memory map
> will fail if guest submits a invalidate IOVA.
>

Can you expand on this? What you mean is that VirtQueue already
protects SVQ code if the guest sets an invalid buffer address (GPA),
isn't it?

> Then I wonder if we do something much more simpler:
>
> 1) Using qemu VA as IOVA but only maps the VA that belongs to guest
> 2) Then we don't need any IOVA tree here, what we need is to just map
> vring and use qemu VA without any translation
>

That would be great, but either qemu's SVQ vring or guest translated
buffers address (in qemu VA form) were already in high addresses,
outside of the device's iova range (in my test).

I didn't try remapping tricks to make them fit in the range, but I
think it does complicate the solution relatively fast if there was
already memory in that range owned by qemu before enabling SVQ:

* Guest memory must be contiguous in VA address space, but it "must"
support hotplug/unplug (although vDPA currently pins it). Hotplug
memory could always overlap with SVQ vring, so we would need to move
it.
* Duplicating mapped memory for writing? (Not sure if guest memory is
actually movable in qemu).
* Indirect descriptors will need to allocate and free memory more or
less frequently, increasing the possibility of overlapping.

If we can move guest memory, however, I can see how we can track it in
a tree *but* mark when the tree is 1:1 with qemu's VA, so buffers
forwarding does not take the translation penalty. When guest memory
cannot be map 1:1, we can resort to tree, and come back to 1:1
translation if the offending tree node(s) get deleted.

However I think this puts the solution a little bit farther than
"starting simple" :).

Does it make sense?

Thanks!

> Thanks
>




Re: [PATCH v3 00/22] target/ppc: DFP instructions using decodetree

2021-10-15 Thread da...@gibson.dropbear.id.au
On Thu, Oct 14, 2021 at 05:02:59PM +, Luis Fernando Fujita Pires wrote:
> Ping?

I'm not sure who you're asking for what.  From my PoV, I'm waiting for reviews.

> 
> > -Original Message-
> > From: Luis Fernando Fujita Pires 
> > Sent: segunda-feira, 20 de setembro de 2021 15:51
> > To: Luis Fernando Fujita Pires ; qemu-
> > de...@nongnu.org; qemu-...@nongnu.org
> > Cc: da...@gibson.dropbear.id.au; gr...@kaod.org;
> > richard.hender...@linaro.org
> > Subject: RE: [PATCH v3 00/22] target/ppc: DFP instructions using decodetree
> > 
> > Ping.
> > 
> > Patches 1-4 were already applied, and patches 5-8, 12, 15, 18 are missing
> > reviews.
> > 
> > Thanks,
> > 
> 

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [PATCH 5/6] ppc/pegasos2: Add constants for PCI config addresses

2021-10-15 Thread David Gibson
On Thu, Oct 14, 2021 at 09:50:19PM +0200, BALATON Zoltan wrote:
> Define a constant for PCI config addresses to make it clearer what
> these numbers are.
> 
> Signed-off-by: BALATON Zoltan 

Applied, thanks.

> ---
>  hw/ppc/pegasos2.c | 6 --
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
> index a861bf16b8..39e96d323f 100644
> --- a/hw/ppc/pegasos2.c
> +++ b/hw/ppc/pegasos2.c
> @@ -54,11 +54,13 @@
>  
>  #define BUS_FREQ_HZ 1
>  
> +#define PCI0_CFG_ADDR 0xcf8
>  #define PCI0_MEM_BASE 0xc000
>  #define PCI0_MEM_SIZE 0x2000
>  #define PCI0_IO_BASE  0xf800
>  #define PCI0_IO_SIZE  0x1
>  
> +#define PCI1_CFG_ADDR 0xc78
>  #define PCI1_MEM_BASE 0x8000
>  #define PCI1_MEM_SIZE 0x4000
>  #define PCI1_IO_BASE  0xfe00
> @@ -226,7 +228,7 @@ static void pegasos2_mv_reg_write(Pegasos2MachineState 
> *pm, uint32_t addr,
>  static uint32_t pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
>   uint32_t addr, uint32_t len)
>  {
> -hwaddr pcicfg = bus ? 0xc78 : 0xcf8;
> +hwaddr pcicfg = bus ? PCI1_CFG_ADDR : PCI0_CFG_ADDR;
>  uint64_t val = 0xULL;
>  
>  if (len <= 4) {
> @@ -239,7 +241,7 @@ static uint32_t 
> pegasos2_pci_config_read(Pegasos2MachineState *pm, int bus,
>  static void pegasos2_pci_config_write(Pegasos2MachineState *pm, int bus,
>uint32_t addr, uint32_t len, uint32_t 
> val)
>  {
> -hwaddr pcicfg = bus ? 0xc78 : 0xcf8;
> +hwaddr pcicfg = bus ? PCI1_CFG_ADDR : PCI0_CFG_ADDR;
>  
>  pegasos2_mv_reg_write(pm, pcicfg, 4, addr | BIT(31));
>  pegasos2_mv_reg_write(pm, pcicfg + 4, len, val);

-- 
David Gibson| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au  | minimalist, thank you.  NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson


signature.asc
Description: PGP signature


Re: [RFC PATCH v4 20/20] vdpa: Add custom IOTLB translations to SVQ

2021-10-15 Thread Jason Wang
On Fri, Oct 15, 2021 at 3:28 PM Eugenio Perez Martin
 wrote:
>
> On Wed, Oct 13, 2021 at 7:34 AM Jason Wang  wrote:
> >
> >
> > 在 2021/10/1 下午3:06, Eugenio Pérez 写道:
> > > Use translations added in VhostIOVATree in SVQ.
> > >
> > > Now every element needs to store the previous address also, so VirtQueue
> > > can consume the elements properly. This adds a little overhead per VQ
> > > element, having to allocate more memory to stash them. As a possible
> > > optimization, this allocation could be avoided if the descriptor is not
> > > a chain but a single one, but this is left undone.
> > >
> > > TODO: iova range should be queried before, and add logic to fail when
> > > GPA is outside of its range and memory listener or svq add it.
> > >
> > > Signed-off-by: Eugenio Pérez
> > > ---
> > >   hw/virtio/vhost-shadow-virtqueue.h |   4 +-
> > >   hw/virtio/vhost-shadow-virtqueue.c | 130 -
> > >   hw/virtio/vhost-vdpa.c |  40 -
> > >   hw/virtio/trace-events |   1 +
> > >   4 files changed, 152 insertions(+), 23 deletions(-)
> >
> >
> > Think hard about the whole logic. This is safe since qemu memory map
> > will fail if guest submits a invalidate IOVA.
> >
>
> Can you expand on this? What you mean is that VirtQueue already
> protects SVQ code if the guest sets an invalid buffer address (GPA),
> isn't it?

Yes.

>
> > Then I wonder if we do something much more simpler:
> >
> > 1) Using qemu VA as IOVA but only maps the VA that belongs to guest
> > 2) Then we don't need any IOVA tree here, what we need is to just map
> > vring and use qemu VA without any translation
> >
>
> That would be great, but either qemu's SVQ vring or guest translated
> buffers address (in qemu VA form) were already in high addresses,
> outside of the device's iova range (in my test).

You're right. I miss that and that's why we need e.g iova tree and allocator.

What I proposed only makes sense when shared virtual memory (SVA) is
implemented. In the case of SVA, the valid iova range should be the
full VA range.

>
> I didn't try remapping tricks to make them fit in the range, but I
> think it does complicate the solution relatively fast if there was
> already memory in that range owned by qemu before enabling SVQ:
>
> * Guest memory must be contiguous in VA address space, but it "must"
> support hotplug/unplug (although vDPA currently pins it). Hotplug
> memory could always overlap with SVQ vring, so we would need to move
> it.
> * Duplicating mapped memory for writing? (Not sure if guest memory is
> actually movable in qemu).
> * Indirect descriptors will need to allocate and free memory more or
> less frequently, increasing the possibility of overlapping.

I'm not sure I get the problem, but overlapping is not an issue since
we're using VA.

>
> If we can move guest memory,

I'm not sure we can do this or it looks very tricky.

> however, I can see how we can track it in
> a tree *but* mark when the tree is 1:1 with qemu's VA, so buffers
> forwarding does not take the translation penalty. When guest memory
> cannot be map 1:1, we can resort to tree, and come back to 1:1
> translation if the offending tree node(s) get deleted.
>
> However I think this puts the solution a little bit farther than
> "starting simple" :).
>
> Does it make sense?

Yes. So I think I will review the IOVA tree codes and get back to you.

THanks

>
> Thanks!
>
> > Thanks
> >
>




Re: [PATCH 4/8] mac_via: add GPIO for A/UX mode

2021-10-15 Thread Laurent Vivier
Le 13/10/2021 à 23:21, Mark Cave-Ayland a écrit :
> Add a new auxmode GPIO that is updated when port B bit 6 is changed indicating
> whether the hardware is configured for A/UX mode.
> 

Stupid question: why do you use GPIO to pass the auxmode information between 
VIA and GLUE?

Can't we use object_property_set_link() to set a pointer to the GLUE object?

Thanks,
Laurent



Re: [PATCH v3] tests: qtest: Add virtio-iommu test

2021-10-15 Thread Eric Auger
Hi Jean,

On 10/14/21 2:11 PM, Jean-Philippe Brucker wrote:
> Hi Eric,
>
> On Thu, Oct 14, 2021 at 04:34:05AM -0400, Eric Auger wrote:
>> Add the framework to test the virtio-iommu-pci device
>> and tests exercising the attach/detach, map/unmap API.
>>
>> Signed-off-by: Eric Auger 
>> Acked-by: Thomas Huth 
>>
>> ---
>>
>> This applies on top of jean-Philippe's
>> [PATCH v4 00/11] virtio-iommu: Add ACPI support
>> branch can be found at:
>> https://github.com/eauger/qemu.git
>> branch qtest-virtio-iommu-v3
>>
>> To run the tests:
>> make tests/qtest/qos-test
>> cd build
>> QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon 
>> QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64  tests/qtest/qos-test
> Looks like some archs cannot run the test:
>
> $ make check  # built with all targets
> qemu-system-arm: -device virtio-iommu-device: VIRTIO-IOMMU is not attached to 
> any PCI bus!
> Broken pipe
> ERROR qtest-arm/qos-test - too few tests run (expected 80, got 75)
>
> Also, should the test run on aarch64?

I don't think it is possible to run on aarch64 because there is some
test infrastructure missing (in the past I started to work on this
enablement but struggled on some libqos subtleties and surrendered due
to lack of time
) and
that must be the same for arm. However I would have expected make check
to work and sort out the tests according to the arch. I need to further
look at it then.

I will address your other virtio-iommu specific comments below asap.
Thank you for the detailed review!

Eric
>
>
> [...]
>> diff --git a/tests/qtest/virtio-iommu-test.c 
>> b/tests/qtest/virtio-iommu-test.c
>> new file mode 100644
>> index 00..ac4d38c779
>> --- /dev/null
>> +++ b/tests/qtest/virtio-iommu-test.c
>> @@ -0,0 +1,299 @@
>> +/*
>> + * QTest testcase for VirtIO IOMMU
>> + *
>> + * Copyright (c) 2021 Red Hat, Inc.
>> + *
>> + * Authors:
>> + *  Eric Auger 
>> + *
>> + * This work is licensed under the terms of the GNU GPL, version 2 or (at 
>> your
>> + * option) any later version.  See the COPYING file in the top-level 
>> directory.
>> + *
>> + */
>> +
>> +#include "qemu/osdep.h"
>> +#include "libqtest-single.h"
>> +#include "qemu/module.h"
>> +#include "libqos/qgraph.h"
>> +#include "libqos/virtio-iommu.h"
>> +#include "hw/virtio/virtio-iommu.h"
>> +
>> +#define PCI_SLOT_HP 0x06
>> +#define QVIRTIO_IOMMU_TIMEOUT_US (30 * 1000 * 1000)
>> +
>> +static QGuestAllocator *alloc;
>> +
>> +static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
>> +{
>> +QVirtioIOMMU *v_iommu = obj;
>> +QVirtioDevice *dev = v_iommu->vdev;
>> +uint64_t input_range_start = qvirtio_config_readq(dev, 8);
>> +uint64_t input_range_end = qvirtio_config_readq(dev, 16);
>> +uint32_t domain_range_start = qvirtio_config_readl(dev, 24);
>> +uint32_t domain_range_end = qvirtio_config_readl(dev, 28);
>> +
>> +g_assert_cmpint(input_range_start, ==, 0);
>> +g_assert_cmphex(input_range_end, ==, UINT64_MAX);
>> +g_assert_cmpint(domain_range_start, ==, 0);
>> +g_assert_cmpint(domain_range_end, ==, 32);
> By the way, this value seems to be left from when the config declared a
> number of domain bits. It's now a range so the value could be UINT32_MAX.
> Right now the driver can't manage more than 32 endpoints at a time.
> I have a patch changing that but planning to send later, it doesn't feel
> urgent.
>
>> +}
>> +
>> +/**
>> + * send_attach_detach - Send an attach/detach command to the device
>> + * @type: VIRTIO_IOMMU_T_ATTACH/VIRTIO_IOMMU_T_DETACH
>> + * @domain: domain the end point is attached to
>> + * @ep: end-point
> ("endpoint"?)
>
>> + */
>> +static int send_attach_detach(QTestState *qts, QVirtioIOMMU *v_iommu,
>> +  uint8_t type, uint32_t domain, uint32_t ep)
>> +{
>> +QVirtioDevice *dev = v_iommu->vdev;
>> +QVirtQueue *vq = v_iommu->vq;
>> +uint64_t ro_addr, wr_addr;
>> +uint32_t free_head;
>> +struct virtio_iommu_req_attach req; /* same layout as detach */
> Should the reserved fields be initialized to zero?
>
> The test fails here with my recent bypass patch, which sanity-checks the
> new flags field. But I could change the test in the bypass series, since
> the test doesn't fail as is.
>
> On a related note, the spec says that the device MUST reject the request
> if field reserved is not zero. I can also send a patch for that.
>
>> +size_t ro_size = sizeof(req) - sizeof(struct virtio_iommu_req_tail);
>> +size_t wr_size = sizeof(struct virtio_iommu_req_tail);
>> +struct virtio_iommu_req_tail buffer;
>> +int ret;
>> +
>> +req.head.type = type;
>> +req.domain = domain;
>> +req.endpoint = ep;
> A driver would explicitly write little-endian in there with cpu_to_le*().
> I guess that also matters here if the test could run on a big-endian host?
>
>> +
>> +ro_addr = guest_alloc(alloc, ro_size);
>> +wr_addr 

[PATCH v8 03/78] target/riscv: Use FIELD_EX32() to extract wd field

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 12c31aa4b4d..70f589813ed 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -98,7 +98,7 @@ static inline uint32_t vext_lmul(uint32_t desc)
 
 static uint32_t vext_wd(uint32_t desc)
 {
-return (simd_data(desc) >> 11) & 0x1;
+return FIELD_EX32(simd_data(desc), VDATA, WD);
 }
 
 /*
-- 
2.25.1




[PATCH v8 00/78] support vector extension v1.0

2021-10-15 Thread frank . chang
From: Frank Chang 

This patchset implements the vector extension v1.0 for RISC-V on QEMU.

RVV v1.0 spec is now fronzen for public review:
https://github.com/riscv/riscv-v-spec/releases/tag/v1.0

The port is available here:
https://github.com/sifive/qemu/tree/rvv-1.0-upstream-v8

RVV v1.0 can be enabled with -cpu option: v=true and specify vext_spec
option to v1.0 (i.e. vext_spec=v1.0)

Note: This patchset depends on other patchsets listed in Based-on
  section below so it is not able to be built unless those patchsets
  are applied.

Changelog:

v8
  * Use {get,dest}_gpr APIs.
  * remove vector AMO instructions.
  * rename vpopc.m to vcpop.m.
  * rename vle1.v and vse1.v to vlm.v and vsm.v.
  * rename vmandnot.mm and vmornot.mm to vmandn.mm and vmorn.mm.

v7
  * remove hardcoded GDB vector registers list.
  * add vsetivli instruction.
  * add vle1.v and vse1.v instructions.

v6
  * add vector floating-point reciprocal estimate instruction.
  * add vector floating-point reciprocal square-root estimate instruction.
  * update check rules for segment register groups, each segment register
group has to follow overlap rules.
  * update viota.m instruction check rules.

v5
  * refactor RVV v1.0 check functions.
(Thanks to Richard Henderson's bitwise tricks.)
  * relax RV_VLEN_MAX to 1024-bits.
  * implement vstart CSR's behaviors.
  * trigger illegal instruction exception if frm is not valid for
vector floating-point instructions.
  * rebase on riscv-to-apply.next.

v4
  * remove explicit float flmul variable in DisasContext.
  * replace floating-point calculations with shift operations to
improve performance.
  * relax RV_VLEN_MAX to 512-bits.

v3
  * apply nan-box helpers from Richard Henderson.
  * remove fp16 api changes as they are sent independently in another
pathcset by Chih-Min Chao.
  * remove all tail elements clear functions as tail elements can
retain unchanged for either VTA set to undisturbed or agnostic.
  * add fp16 nan-box check generator function.
  * add floating-point rounding mode enum.
  * replace flmul arithmetic with shifts to avoid floating-point
conversions.
  * add Zvqmac extension.
  * replace gdbstub vector register xml files with dynamic generator.
  * bumped to RVV v1.0.
  * RVV v1.0 related changes:
* add vlre.v and vsr.v vector whole register
  load/store instructions
* add vrgatherei16 instruction.
* rearranged bits in vtype to make vlmul bits into a contiguous
  field.

v2
  * drop v0.7.1 support.
  * replace invisible return check macros with functions.
  * move mark_vs_dirty() to translators.
  * add SSTATUS_VS flag for s-mode.
  * nan-box scalar fp register for floating-point operations.
  * add gdbstub files for vector registers to allow system-mode
debugging with GDB.

Based-on: <20211015065500.3850513-1-frank.ch...@sifive.com>
Based-on: <20211015070307.3860984-1-frank.ch...@sifive.com>

Frank Chang (73):
  target/riscv: fix TB_FLAGS bits overlapping bug for rvv/rvh
  target/riscv: drop vector 0.7.1 and add 1.0 support
  target/riscv: Use FIELD_EX32() to extract wd field
  target/riscv: rvv-1.0: introduce writable misa.v field
  target/riscv: rvv-1.0: add translation-time vector context status
  target/riscv: rvv-1.0: remove rvv related codes from fcsr registers
  target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr
registers
  target/riscv: rvv-1.0: remove MLEN calculations
  target/riscv: rvv-1.0: add fractional LMUL
  target/riscv: rvv-1.0: add VMA and VTA
  target/riscv: rvv-1.0: update check functions
  target/riscv: introduce more imm value modes in translator functions
  target/riscv: rvv:1.0: add translation-time nan-box helper function
  target/riscv: rvv-1.0: remove amo operations instructions
  target/riscv: rvv-1.0: configure instructions
  target/riscv: rvv-1.0: stride load and store instructions
  target/riscv: rvv-1.0: index load and store instructions
  target/riscv: rvv-1.0: fix address index overflow bug of indexed
load/store insns
  target/riscv: rvv-1.0: fault-only-first unit stride load
  target/riscv: rvv-1.0: load/store whole register instructions
  target/riscv: rvv-1.0: update vext_max_elems() for load/store insns
  target/riscv: rvv-1.0: take fractional LMUL into vector max elements
calculation
  target/riscv: rvv-1.0: floating-point square-root instruction
  target/riscv: rvv-1.0: floating-point classify instructions
  target/riscv: rvv-1.0: count population in mask instruction
  target/riscv: rvv-1.0: find-first-set mask bit instruction
  target/riscv: rvv-1.0: set-X-first mask bit instructions
  target/riscv: rvv-1.0: iota instruction
  target/riscv: rvv-1.0: element index instruction
  target/riscv: rvv-1.0: allow load element with sign-extended
  target/riscv: rvv-1.0: register gather instructions
  target/riscv: rvv-1.0: integer scalar move instructions
  target/riscv: rvv-1.0: floating-point move instruction
  target/riscv: rvv-1.0: floating-point scalar

[PATCH v8 02/78] target/riscv: drop vector 0.7.1 and add 1.0 support

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.c | 10 +-
 target/riscv/cpu.h |  2 +-
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 89a612f7606..36448e61572 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -492,7 +492,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 target_misa |= RVH;
 }
 if (cpu->cfg.ext_v) {
-int vext_version = VEXT_VERSION_0_07_1;
+int vext_version = VEXT_VERSION_1_00_0;
 target_misa |= RVV;
 if (!is_power_of_2(cpu->cfg.vlen)) {
 error_setg(errp,
@@ -517,8 +517,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 return;
 }
 if (cpu->cfg.vext_spec) {
-if (!g_strcmp0(cpu->cfg.vext_spec, "v0.7.1")) {
-vext_version = VEXT_VERSION_0_07_1;
+if (!g_strcmp0(cpu->cfg.vext_spec, "v1.0")) {
+vext_version = VEXT_VERSION_1_00_0;
 } else {
 error_setg(errp,
"Unsupported vector spec version '%s'",
@@ -527,7 +527,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 }
 } else {
 qemu_log("vector version is not specified, "
-"use the default value v0.7.1\n");
+ "use the default value v1.0\n");
 }
 set_vext_version(env, vext_version);
 }
@@ -591,6 +591,7 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
 DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
 DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
+DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
 DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
 /* This is experimental so mark with 'x-' */
@@ -599,7 +600,6 @@ static Property riscv_cpu_properties[] = {
 DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false),
 DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
 DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
-DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
 DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d63a08b6e4c..8ded9da5623 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -82,7 +82,7 @@ enum {
 #define PRIV_VERSION_1_10_0 0x00011000
 #define PRIV_VERSION_1_11_0 0x00011100
 
-#define VEXT_VERSION_0_07_1 0x0701
+#define VEXT_VERSION_1_00_0 0x0001
 
 enum {
 TRANSLATE_SUCCESS,
-- 
2.25.1




[PATCH v8 04/78] target/riscv: rvv-1.0: add mstatus VS field

2021-10-15 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h|  7 +++
 target/riscv/cpu_bits.h   |  1 +
 target/riscv/cpu_helper.c | 15 ++-
 target/riscv/csr.c| 25 -
 4 files changed, 46 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8ded9da5623..b951e39602c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -338,6 +338,7 @@ int riscv_cpu_write_elf32_note(WriteCoreDumpFunction f, 
CPUState *cs,
 int riscv_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
 int riscv_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
 bool riscv_cpu_fp_enabled(CPURISCVState *env);
+bool riscv_cpu_vector_enabled(CPURISCVState *env);
 bool riscv_cpu_virt_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
 bool riscv_cpu_force_hs_excep_enabled(CPURISCVState *env);
@@ -383,6 +384,7 @@ void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 #define TB_FLAGS_PRIV_MMU_MASK3
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
+#define TB_FLAGS_MSTATUS_VS MSTATUS_VS
 
 typedef CPURISCVState CPUArchState;
 typedef RISCVCPU ArchCPU;
@@ -439,6 +441,7 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, 
target_ulong *pc,
 
 #ifdef CONFIG_USER_ONLY
 flags |= TB_FLAGS_MSTATUS_FS;
+flags |= TB_FLAGS_MSTATUS_VS;
 #else
 flags |= cpu_mmu_index(env, 0);
 if (riscv_cpu_fp_enabled(env)) {
@@ -456,6 +459,10 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
get_field(env->mstatus_hs, MSTATUS_FS));
 }
+
+if (riscv_cpu_vector_enabled(env)) {
+flags |= env->mstatus & MSTATUS_VS;
+}
 #endif
 
 *pflags = flags;
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 999187a9ee2..8c2fd35d2ef 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -343,6 +343,7 @@
 #define MSTATUS_UBE 0x0040
 #define MSTATUS_MPIE0x0080
 #define MSTATUS_SPP 0x0100
+#define MSTATUS_VS  0x0600
 #define MSTATUS_MPP 0x1800
 #define MSTATUS_FS  0x6000
 #define MSTATUS_XS  0x00018000
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index d41d5cd27c1..fedde9ea0de 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -104,12 +104,25 @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
 return false;
 }
 
+/* Return true is vector support is currently enabled */
+bool riscv_cpu_vector_enabled(CPURISCVState *env)
+{
+if (env->mstatus & MSTATUS_VS) {
+if (riscv_cpu_virt_enabled(env) && !(env->mstatus_hs & MSTATUS_VS)) {
+return false;
+}
+return true;
+}
+
+return false;
+}
+
 void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
 {
 uint64_t sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
 uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
 MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
-MSTATUS64_UXL | sd;
+MSTATUS64_UXL | MSTATUS_VS | sd;
 bool current_virt = riscv_cpu_virt_enabled(env);
 
 g_assert(riscv_has_ext(env, RVH));
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 23fbbd32162..cc0131d7962 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -263,6 +263,7 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
 {
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_FS;
+env->mstatus |= MSTATUS_VS;
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 if (vs(env, csrno) >= 0) {
@@ -297,6 +298,13 @@ static RISCVException read_vxrm(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxrm(CPURISCVState *env, int csrno,
  target_ulong val)
 {
+#if !defined(CONFIG_USER_ONLY)
+if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+env->mstatus |= MSTATUS_VS;
+#endif
+
 env->vxrm = val;
 return RISCV_EXCP_NONE;
 }
@@ -311,6 +319,13 @@ static RISCVException read_vxsat(CPURISCVState *env, int 
csrno,
 static RISCVException write_vxsat(CPURISCVState *env, int csrno,
   target_ulong val)
 {
+#if !defined(CONFIG_USER_ONLY)
+if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+env->mstatus |= MSTATUS_VS;
+#endif
+
 env->vxsat = val;
 return RISCV_EXCP_NONE;
 }
@@ -325,6 +340,13 @@ static RISCVException read_vstart(CPURISCVState *env, int 
csrno,
 static RISCVException write_vstart(CPURISCVState *env, int csrno,
   

[PATCH v8 01/78] target/riscv: fix TB_FLAGS bits overlapping bug for rvv/rvh

2021-10-15 Thread frank . chang
From: Frank Chang 

TB_FLAGS mem_idx bits was extended from 2 bits to 3 bits in
commit: c445593, but other TB_FLAGS bits for rvv and rvh were
not shift as well so these bits may overlap with each other when
rvv is enabled.

Signed-off-by: Frank Chang 
---
 target/riscv/cpu.h   | 14 +++---
 target/riscv/translate.c |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d70f63ddfe6..d63a08b6e4c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -380,7 +380,6 @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
 target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
 void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 
-#define TB_FLAGS_MMU_MASK   7
 #define TB_FLAGS_PRIV_MMU_MASK3
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
@@ -389,13 +388,14 @@ typedef CPURISCVState CPUArchState;
 typedef RISCVCPU ArchCPU;
 #include "exec/cpu-all.h"
 
-FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
-FIELD(TB_FLAGS, LMUL, 3, 2)
-FIELD(TB_FLAGS, SEW, 5, 3)
-FIELD(TB_FLAGS, VILL, 8, 1)
+FIELD(TB_FLAGS, MEM_IDX, 0, 3)
+FIELD(TB_FLAGS, VL_EQ_VLMAX, 3, 1)
+FIELD(TB_FLAGS, LMUL, 4, 2)
+FIELD(TB_FLAGS, SEW, 6, 3)
+FIELD(TB_FLAGS, VILL, 9, 1)
 /* Is a Hypervisor instruction load/store allowed? */
-FIELD(TB_FLAGS, HLSX, 9, 1)
-FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
+FIELD(TB_FLAGS, HLSX, 10, 1)
+FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
 
 bool riscv_cpu_is_32bit(CPURISCVState *env);
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index f23bc919c08..a7a66cf9db1 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -544,7 +544,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 uint32_t tb_flags = ctx->base.tb->flags;
 
 ctx->pc_succ_insn = ctx->base.pc_first;
-ctx->mem_idx = tb_flags & TB_FLAGS_MMU_MASK;
+ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
 ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
 ctx->priv_ver = env->priv_ver;
 #if !defined(CONFIG_USER_ONLY)
-- 
2.25.1




[PATCH v8 08/78] target/riscv: rvv-1.0: remove rvv related codes from fcsr registers

2021-10-15 Thread frank . chang
From: Frank Chang 

* Remove VXRM and VXSAT fields from FCSR register as they are only
  presented in VCSR register.
* Remove RVV loose check in fs() predicate function.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 13 -
 1 file changed, 13 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 2734c223369..c71f3f34e88 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -38,10 +38,6 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
 static RISCVException fs(CPURISCVState *env, int csrno)
 {
 #if !defined(CONFIG_USER_ONLY)
-/* loose check condition for fcsr in vector extension */
-if ((csrno == CSR_FCSR) && (env->misa & RVV)) {
-return RISCV_EXCP_NONE;
-}
 if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
 return RISCV_EXCP_ILLEGAL_INST;
 }
@@ -251,10 +247,6 @@ static RISCVException read_fcsr(CPURISCVState *env, int 
csrno,
 {
 *val = (riscv_cpu_get_fflags(env) << FSR_AEXC_SHIFT)
 | (env->frm << FSR_RD_SHIFT);
-if (vs(env, csrno) >= 0) {
-*val |= (env->vxrm << FSR_VXRM_SHIFT)
-| (env->vxsat << FSR_VXSAT_SHIFT);
-}
 return RISCV_EXCP_NONE;
 }
 
@@ -263,13 +255,8 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
 {
 #if !defined(CONFIG_USER_ONLY)
 env->mstatus |= MSTATUS_FS;
-env->mstatus |= MSTATUS_VS;
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
-if (vs(env, csrno) >= 0) {
-env->vxrm = (val & FSR_VXRM) >> FSR_VXRM_SHIFT;
-env->vxsat = (val & FSR_VXSAT) >> FSR_VXSAT_SHIFT;
-}
 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
 return RISCV_EXCP_NONE;
 }
-- 
2.25.1




[PATCH v8 15/78] target/riscv: rvv-1.0: update check functions

2021-10-15 Thread frank . chang
From: Frank Chang 

Update check functions with RVV 1.0 rules.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 715 +---
 1 file changed, 507 insertions(+), 208 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ddf20f02dfa..a03cc8e0781 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -19,11 +19,112 @@
 #include "tcg/tcg-gvec-desc.h"
 #include "internals.h"
 
+static inline bool is_overlapped(const int8_t astart, int8_t asize,
+ const int8_t bstart, int8_t bsize)
+{
+const int8_t aend = astart + asize;
+const int8_t bend = bstart + bsize;
+
+return MAX(aend, bend) - MIN(astart, bstart) < asize + bsize;
+}
+
+static bool require_rvv(DisasContext *s)
+{
+return s->mstatus_vs != 0;
+}
+
+static bool require_rvf(DisasContext *s)
+{
+if (s->mstatus_fs == 0) {
+return false;
+}
+
+switch (s->sew) {
+case MO_16:
+case MO_32:
+return has_ext(s, RVF);
+case MO_64:
+return has_ext(s, RVD);
+default:
+return false;
+}
+}
+
+static bool require_scale_rvf(DisasContext *s)
+{
+if (s->mstatus_fs == 0) {
+return false;
+}
+
+switch (s->sew) {
+case MO_8:
+case MO_16:
+return has_ext(s, RVF);
+case MO_32:
+return has_ext(s, RVD);
+default:
+return false;
+}
+}
+
+/* Destination vector register group cannot overlap source mask register. */
+static bool require_vm(int vm, int vd)
+{
+return (vm != 0 || vd != 0);
+}
+
+/*
+ * Vector register should aligned with the passed-in LMUL (EMUL).
+ * If LMUL < 0, i.e. fractional LMUL, any vector register is allowed.
+ */
+static bool require_align(const int8_t val, const int8_t lmul)
+{
+return lmul <= 0 || extract32(val, 0, lmul) == 0;
+}
+
+/*
+ * A destination vector register group can overlap a source vector
+ * register group only if one of the following holds:
+ *  1. The destination EEW equals the source EEW.
+ *  2. The destination EEW is smaller than the source EEW and the overlap
+ * is in the lowest-numbered part of the source register group.
+ *  3. The destination EEW is greater than the source EEW, the source EMUL
+ * is at least 1, and the overlap is in the highest-numbered part of
+ * the destination register group.
+ * (Section 5.2)
+ *
+ * This function returns true if one of the following holds:
+ *  * Destination vector register group does not overlap a source vector
+ *register group.
+ *  * Rule 3 met.
+ * For rule 1, overlap is allowed so this function doesn't need to be called.
+ * For rule 2, (vd == vs). Caller has to check whether: (vd != vs) before
+ * calling this function.
+ */
+static bool require_noover(const int8_t dst, const int8_t dst_lmul,
+   const int8_t src, const int8_t src_lmul)
+{
+int8_t dst_size = dst_lmul <= 0 ? 1 : 1 << dst_lmul;
+int8_t src_size = src_lmul <= 0 ? 1 : 1 << src_lmul;
+
+/* Destination EEW is greater than the source EEW, check rule 3. */
+if (dst_size > src_size) {
+if (dst < src &&
+src_lmul >= 0 &&
+is_overlapped(dst, dst_size, src, src_size) &&
+!is_overlapped(dst, dst_size, src + src_size, src_size)) {
+return true;
+}
+}
+
+return !is_overlapped(dst, dst_size, src, src_size);
+}
+
 static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
 {
 TCGv s1, s2, dst;
 
-if (!has_ext(ctx, RVV)) {
+if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
 return false;
 }
 
@@ -51,7 +152,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
 {
 TCGv s1, s2, dst;
 
-if (!has_ext(ctx, RVV)) {
+if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
 return false;
 }
 
@@ -82,6 +183,237 @@ static uint32_t vreg_ofs(DisasContext *s, int reg)
 
 /* check functions */
 
+static bool vext_check_ss(DisasContext *s, int vd, int vs, int vm)
+{
+return require_vm(vm, vd) &&
+require_align(vd, s->lmul) &&
+require_align(vs, s->lmul);
+}
+
+/*
+ * Check function for vector instruction with format:
+ * single-width result and single-width sources (SEW = SEW op SEW)
+ *
+ * Rules to be checked here:
+ *   1. Destination vector register group for a masked vector
+ *  instruction cannot overlap the source mask register (v0).
+ *  (Section 5.3)
+ *   2. Destination vector register number is multiples of LMUL.
+ *  (Section 3.4.2)
+ *   3. Source (vs2, vs1) vector register number are multiples of LMUL.
+ *  (Section 3.4.2)
+ */
+static bool vext_check_sss(DisasContext *s, int vd, int vs1, int vs2, int vm)
+{
+return vext_check_ss(s, vd, vs2, vm) &&
+require_align(vs1, s->lmul);
+}
+
+static bool vext_check_ms(DisasContext *s, int vd, int vs)
+{
+bool ret = re

[PATCH v8 13/78] target/riscv: rvv-1.0: add fractional LMUL

2021-10-15 Thread frank . chang
From: Frank Chang 

Introduce the concepts of fractional LMUL for RVV 1.0.
In RVV 1.0, LMUL bits are contiguous in vtype register.

Also rearrange rvv bits in TB_FLAGS to skip MSTATUS_VS (0x600)
and MSTATUS_FS (0x6000) bits.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h   | 22 --
 target/riscv/translate.c | 16 ++--
 target/riscv/vector_helper.c | 16 ++--
 3 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fb41c1cea7c..1bd9b4123da 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -103,10 +103,10 @@ typedef struct CPURISCVState CPURISCVState;
 
 #define RV_VLEN_MAX 256
 
-FIELD(VTYPE, VLMUL, 0, 2)
-FIELD(VTYPE, VSEW, 2, 3)
-FIELD(VTYPE, VEDIV, 5, 2)
-FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
+FIELD(VTYPE, VLMUL, 0, 3)
+FIELD(VTYPE, VSEW, 3, 3)
+FIELD(VTYPE, VEDIV, 8, 2)
+FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
 FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
 
 struct CPURISCVState {
@@ -391,14 +391,16 @@ typedef RISCVCPU ArchCPU;
 #include "exec/cpu-all.h"
 
 FIELD(TB_FLAGS, MEM_IDX, 0, 3)
-FIELD(TB_FLAGS, VL_EQ_VLMAX, 3, 1)
-FIELD(TB_FLAGS, LMUL, 4, 2)
+FIELD(TB_FLAGS, LMUL, 3, 3)
 FIELD(TB_FLAGS, SEW, 6, 3)
-FIELD(TB_FLAGS, VILL, 9, 1)
+/* Skip MSTATUS_VS (0x600) bits */
+FIELD(TB_FLAGS, VL_EQ_VLMAX, 11, 1)
+FIELD(TB_FLAGS, VILL, 12, 1)
+/* Skip MSTATUS_FS (0x6000) bits */
 /* Is a Hypervisor instruction load/store allowed? */
-FIELD(TB_FLAGS, HLSX, 10, 1)
-FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
-FIELD(TB_FLAGS, MSTATUS_HS_VS, 13, 2)
+FIELD(TB_FLAGS, HLSX, 15, 1)
+FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
+FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 
 bool riscv_cpu_is_32bit(CPURISCVState *env);
 
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 174ef0564e6..6a3f105d431 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -76,7 +76,19 @@ typedef struct DisasContext {
 bool hlsx;
 /* vector extension */
 bool vill;
-uint8_t lmul;
+/*
+ * Encode LMUL to lmul as follows:
+ * LMULvlmullmul
+ *  1   000   0
+ *  2   001   1
+ *  4   010   2
+ *  8   011   3
+ *  -   100   -
+ * 1/8  101  -3
+ * 1/4  110  -2
+ * 1/2  111  -1
+ */
+int8_t lmul;
 uint8_t sew;
 uint16_t vlen;
 bool vl_eq_vlmax;
@@ -606,7 +618,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX);
 ctx->vill = FIELD_EX32(tb_flags, TB_FLAGS, VILL);
 ctx->sew = FIELD_EX32(tb_flags, TB_FLAGS, SEW);
-ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
+ctx->lmul = sextract32(FIELD_EX32(tb_flags, TB_FLAGS, LMUL), 0, 3);
 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 ctx->cs = cs;
 ctx->w = false;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index ac6c7298bc0..866bfb35714 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -86,9 +86,21 @@ static inline uint32_t vext_vm(uint32_t desc)
 return FIELD_EX32(simd_data(desc), VDATA, VM);
 }
 
-static inline uint32_t vext_lmul(uint32_t desc)
+/*
+ * Encode LMUL to lmul as following:
+ * LMULvlmullmul
+ *  1   000   0
+ *  2   001   1
+ *  4   010   2
+ *  8   011   3
+ *  -   100   -
+ * 1/8  101  -3
+ * 1/4  110  -2
+ * 1/2  111  -1
+ */
+static inline int32_t vext_lmul(uint32_t desc)
 {
-return FIELD_EX32(simd_data(desc), VDATA, LMUL);
+return sextract32(FIELD_EX32(simd_data(desc), VDATA, LMUL), 0, 3);
 }
 
 static uint32_t vext_wd(uint32_t desc)
-- 
2.25.1




[PATCH v8 06/78] target/riscv: rvv-1.0: introduce writable misa.v field

2021-10-15 Thread frank . chang
From: Frank Chang 

Implementations may have a writable misa.v field. Analogous to the way
in which the floating-point unit is handled, the mstatus.vs field may
exist even if misa.v is clear.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d8a3010140e..2734c223369 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -610,7 +610,7 @@ static RISCVException write_misa(CPURISCVState *env, int 
csrno,
 val &= env->misa_mask;
 
 /* Mask extensions that are not supported by QEMU */
-val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU | RVV);
 
 /* 'D' depends on 'F', so clear 'D' if 'F' is not present */
 if ((val & RVD) && !(val & RVF)) {
-- 
2.25.1




[PATCH v8 05/78] target/riscv: rvv-1.0: add sstatus VS field

2021-10-15 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 8c2fd35d2ef..ca3ddd313b0 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -375,6 +375,7 @@
 #define SSTATUS_UPIE0x0010
 #define SSTATUS_SPIE0x0020
 #define SSTATUS_SPP 0x0100
+#define SSTATUS_VS  0x0600
 #define SSTATUS_FS  0x6000
 #define SSTATUS_XS  0x00018000
 #define SSTATUS_SUM 0x0004 /* since: priv-1.10 */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index cc0131d7962..d8a3010140e 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -465,7 +465,7 @@ static const target_ulong vs_delegable_excps = 
DELEGABLE_EXCPS &
   (1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
 static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
 SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
-SSTATUS_SUM | SSTATUS_MXR;
+SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
 static const target_ulong hip_writable_mask = MIP_VSSIP;
 static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | 
MIP_VSEIP;
-- 
2.25.1




[PATCH v8 07/78] target/riscv: rvv-1.0: add translation-time vector context status

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  |  4 ++
 target/riscv/insn_trans/trans_rvv.c.inc | 75 +
 target/riscv/translate.c| 41 ++
 3 files changed, 108 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index b951e39602c..fb41c1cea7c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -398,6 +398,7 @@ FIELD(TB_FLAGS, VILL, 9, 1)
 /* Is a Hypervisor instruction load/store allowed? */
 FIELD(TB_FLAGS, HLSX, 10, 1)
 FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
+FIELD(TB_FLAGS, MSTATUS_HS_VS, 13, 2)
 
 bool riscv_cpu_is_32bit(CPURISCVState *env);
 
@@ -458,6 +459,9 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, 
target_ulong *pc,
 
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
get_field(env->mstatus_hs, MSTATUS_FS));
+
+flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
+   get_field(env->mstatus_hs, MSTATUS_VS));
 }
 
 if (riscv_cpu_vector_enabled(env)) {
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index fa451938f1e..47fdd438609 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -39,6 +39,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
 }
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(ctx, a->rd, dst);
+mark_vs_dirty(ctx);
 
 tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
 lookup_and_goto_ptr(ctx);
@@ -66,6 +67,7 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
 }
 gen_helper_vsetvl(dst, cpu_env, s1, s2);
 gen_set_gpr(ctx, a->rd, dst);
+mark_vs_dirty(ctx);
 
 gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
 ctx->base.is_jmp = DISAS_NORETURN;
@@ -154,7 +156,8 @@ typedef void gen_helper_ldst_us(TCGv_ptr, TCGv_ptr, TCGv,
 TCGv_env, TCGv_i32);
 
 static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
-  gen_helper_ldst_us *fn, DisasContext *s)
+  gen_helper_ldst_us *fn, DisasContext *s,
+  bool is_store)
 {
 TCGv_ptr dest, mask;
 TCGv base;
@@ -183,6 +186,11 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
 gen_set_label(over);
 return true;
 }
@@ -233,7 +241,7 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
-return ldst_us_trans(a->rd, a->rs1, data, fn, s);
+return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
 
 static bool ld_us_check(DisasContext *s, arg_r2nfvm* a)
@@ -286,7 +294,7 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
-return ldst_us_trans(a->rd, a->rs1, data, fn, s);
+return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
 }
 
 static bool st_us_check(DisasContext *s, arg_r2nfvm* a)
@@ -309,7 +317,7 @@ typedef void gen_helper_ldst_stride(TCGv_ptr, TCGv_ptr, 
TCGv,
 
 static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
   uint32_t data, gen_helper_ldst_stride *fn,
-  DisasContext *s)
+  DisasContext *s, bool is_store)
 {
 TCGv_ptr dest, mask;
 TCGv base, stride;
@@ -331,6 +339,11 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, 
uint32_t rs2,
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
 gen_set_label(over);
 return true;
 }
@@ -365,7 +378,7 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
-return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
+return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
 
 static bool ld_stride_check(DisasContext *s, arg_rnfvm* a)
@@ -409,7 +422,7 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s);
+return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, true);
 }
 
 static bool st_stride_check(DisasContext *s, arg_rnfvm* a)
@@ -432,7 +445,7 @@ typedef void gen_helper_ldst_index(TCGv_ptr, TCGv_ptr, TCGv,
 
 static

[PATCH v8 10/78] target/riscv: rvv-1.0: add vlenb register

2021-10-15 Thread frank . chang
From: Greentime Hu 

Signed-off-by: Greentime Hu 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h | 1 +
 target/riscv/csr.c  | 7 +++
 2 files changed, 8 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index b8816822b81..849b100b3b7 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -63,6 +63,7 @@
 #define CSR_VCSR0x00f
 #define CSR_VL  0xc20
 #define CSR_VTYPE   0xc21
+#define CSR_VLENB   0xc22
 
 /* VCSR fields */
 #define VCSR_VXSAT_SHIFT0
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 57591753059..0fb71875654 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -275,6 +275,12 @@ static RISCVException read_vl(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+static int read_vlenb(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = env_archcpu(env)->cfg.vlen >> 3;
+return RISCV_EXCP_NONE;
+}
+
 static RISCVException read_vxrm(CPURISCVState *env, int csrno,
 target_ulong *val)
 {
@@ -1555,6 +1561,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
 [CSR_VL]   = { "vl",   vs, read_vl},
 [CSR_VTYPE]= { "vtype",vs, read_vtype },
+[CSR_VLENB]= { "vlenb",vs, read_vlenb },
 /* User Timers and Counters */
 [CSR_CYCLE]= { "cycle",ctr,read_instret  },
 [CSR_INSTRET]  = { "instret",  ctr,read_instret  },
-- 
2.25.1




[PATCH v8 20/78] target/riscv: rvv-1.0: stride load and store instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 129 ++--
 target/riscv/insn32.decode  |  43 ++-
 target/riscv/insn_trans/trans_rvv.c.inc | 376 
 target/riscv/vector_helper.c| 199 +
 4 files changed, 300 insertions(+), 447 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index ecb6af6cd99..5a760fa4a32 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -112,111 +112,30 @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
 
 /* Vector functions */
 DEF_HELPER_3(vsetvl, tl, env, tl, tl)
-DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_6(vlsb_v_b, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsw_v_w, void, pt

[PATCH 18/76] target/riscv: rvv-1.0: configure instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 64 +++--
 target/riscv/vector_helper.c| 14 +-
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 69caa5a036b..7d247656e51 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -126,59 +126,51 @@ static bool require_noover(const int8_t dst, const int8_t 
dst_lmul,
 return !is_overlapped(dst, dst_size, src, src_size);
 }
 
-static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
+static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
 {
-TCGv s1, s2, dst;
+TCGv s1, dst;
 
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
+if (!require_rvv(s) || !has_ext(s, RVV)) {
 return false;
 }
 
-s2 = get_gpr(ctx, a->rs2, EXT_ZERO);
-dst = dest_gpr(ctx, a->rd);
+dst = dest_gpr(s, rd);
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->rs1 == 0) {
+if (rd == 0 && rs1 == 0) {
+s1 = tcg_temp_new();
+tcg_gen_mov_tl(s1, cpu_vl);
+} else 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(ctx, a->rs1, EXT_ZERO);
+s1 = get_gpr(s, rs1, EXT_ZERO);
 }
-gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
 
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-lookup_and_goto_ptr(ctx);
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
-}
+gen_helper_vsetvl(dst, cpu_env, s1, s2);
+gen_set_gpr(s, rd, dst);
+mark_vs_dirty(s);
 
-static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
-{
-TCGv s1, s2, dst;
+tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+lookup_and_goto_ptr(s);
+s->base.is_jmp = DISAS_NORETURN;
 
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
-return false;
+if (rd == 0 && rs1 == 0) {
+tcg_temp_free(s1);
 }
 
-s2 = tcg_constant_tl(a->zimm);
-dst = dest_gpr(ctx, a->rd);
+return true;
+}
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->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(ctx, a->rs1, EXT_ZERO);
-}
-gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
+static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
+{
+TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO);
+return do_vsetvl(s, a->rd, a->rs1, s2);
+}
 
-gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
+static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a)
+{
+TCGv s2 = tcg_constant_tl(a->zimm);
+return do_vsetvl(s, a->rd, a->rs1, s2);
 }
 
 /* vector register offset from env */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d0a10a926f4..f6ece48e250 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -31,12 +31,24 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
target_ulong s1,
 {
 int vlmax, vl;
 RISCVCPU *cpu = env_archcpu(env);
+uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
 uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
 uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
 bool vill = FIELD_EX64(s2, VTYPE, VILL);
 target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
 
-if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+if (lmul & 4) {
+/* Fractional LMUL. */
+if (lmul == 4 ||
+cpu->cfg.elen >> (8 - lmul) < sew) {
+vill = true;
+}
+}
+
+if ((sew > cpu->cfg.elen)
+|| vill
+|| (ediv != 0)
+|| (reserved != 0)) {
 /* only set vill bit. */
 env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
 env->vl = 0;
-- 
2.25.1




[PATCH v8 09/78] target/riscv: rvv-1.0: add vcsr register

2021-10-15 Thread frank . chang
From: LIU Zhiwei 

Signed-off-by: LIU Zhiwei 
Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h |  7 +++
 target/riscv/csr.c  | 21 +
 2 files changed, 28 insertions(+)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index ca3ddd313b0..b8816822b81 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -60,9 +60,16 @@
 #define CSR_VSTART  0x008
 #define CSR_VXSAT   0x009
 #define CSR_VXRM0x00a
+#define CSR_VCSR0x00f
 #define CSR_VL  0xc20
 #define CSR_VTYPE   0xc21
 
+/* VCSR fields */
+#define VCSR_VXSAT_SHIFT0
+#define VCSR_VXSAT  (0x1 << VCSR_VXSAT_SHIFT)
+#define VCSR_VXRM_SHIFT 1
+#define VCSR_VXRM   (0x3 << VCSR_VXRM_SHIFT)
+
 /* User Timers and Counters */
 #define CSR_CYCLE   0xc00
 #define CSR_TIME0xc01
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index c71f3f34e88..57591753059 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -338,6 +338,26 @@ static RISCVException write_vstart(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
+static int read_vcsr(CPURISCVState *env, int csrno, target_ulong *val)
+{
+*val = (env->vxrm << VCSR_VXRM_SHIFT) | (env->vxsat << VCSR_VXSAT_SHIFT);
+return RISCV_EXCP_NONE;
+}
+
+static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
+{
+#if !defined(CONFIG_USER_ONLY)
+if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+env->mstatus |= MSTATUS_VS;
+#endif
+
+env->vxrm = (val & VCSR_VXRM) >> VCSR_VXRM_SHIFT;
+env->vxsat = (val & VCSR_VXSAT) >> VCSR_VXSAT_SHIFT;
+return RISCV_EXCP_NONE;
+}
+
 /* User Timers and Counters */
 static RISCVException read_instret(CPURISCVState *env, int csrno,
target_ulong *val)
@@ -1532,6 +1552,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 [CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart },
 [CSR_VXSAT]= { "vxsat",vs, read_vxsat,   write_vxsat  },
 [CSR_VXRM] = { "vxrm", vs, read_vxrm,write_vxrm   },
+[CSR_VCSR] = { "vcsr", vs, read_vcsr,write_vcsr   },
 [CSR_VL]   = { "vl",   vs, read_vl},
 [CSR_VTYPE]= { "vtype",vs, read_vtype },
 /* User Timers and Counters */
-- 
2.25.1




[PATCH v8 16/78] target/riscv: introduce more imm value modes in translator functions

2021-10-15 Thread frank . chang
From: Frank Chang 

Immediate value in translator function is extended not only
zero-extended and sign-extended but with more modes to be applicable
with multiple formats of vector instructions.

* IMM_ZX: Zero-extended
* IMM_SX: Sign-extended
* IMM_TRUNC_SEW:  Truncate to log(SEW) bit
* IMM_TRUNC_2SEW: Truncate to log(2*SEW) bit

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 115 ++--
 1 file changed, 66 insertions(+), 49 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index a03cc8e0781..c33ded385d7 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1310,8 +1310,32 @@ static void tcg_gen_gvec_rsubs(unsigned vece, uint32_t 
dofs, uint32_t aofs,
 
 GEN_OPIVX_GVEC_TRANS(vrsub_vx, rsubs)
 
+typedef enum {
+IMM_ZX, /* Zero-extended */
+IMM_SX, /* Sign-extended */
+IMM_TRUNC_SEW,  /* Truncate to log(SEW) bits */
+IMM_TRUNC_2SEW, /* Truncate to log(2*SEW) bits */
+} imm_mode_t;
+
+static int64_t extract_imm(DisasContext *s, uint32_t imm, imm_mode_t imm_mode)
+{
+switch (imm_mode) {
+case IMM_ZX:
+return extract64(imm, 0, 5);
+case IMM_SX:
+return sextract64(imm, 0, 5);
+case IMM_TRUNC_SEW:
+return extract64(imm, 0, s->sew + 3);
+case IMM_TRUNC_2SEW:
+return extract64(imm, 0, s->sew + 4);
+default:
+g_assert_not_reached();
+}
+}
+
 static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
-gen_helper_opivx *fn, DisasContext *s, int zx)
+gen_helper_opivx *fn, DisasContext *s,
+imm_mode_t imm_mode)
 {
 TCGv_ptr dest, src2, mask;
 TCGv src1;
@@ -1324,11 +1348,8 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 dest = tcg_temp_new_ptr();
 mask = tcg_temp_new_ptr();
 src2 = tcg_temp_new_ptr();
-if (zx) {
-src1 = tcg_constant_tl(imm);
-} else {
-src1 = tcg_constant_tl(sextract64(imm, 0, 5));
-}
+src1 = tcg_constant_tl(extract_imm(s, imm, imm_mode));
+
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1352,28 +1373,23 @@ typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, 
int64_t,
 
 static inline bool
 do_opivi_gvec(DisasContext *s, arg_rmrr *a, GVecGen2iFn *gvec_fn,
-  gen_helper_opivx *fn, int zx)
+  gen_helper_opivx *fn, imm_mode_t imm_mode)
 {
 if (!opivx_check(s, a)) {
 return false;
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-if (zx) {
-gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
-extract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s));
-} else {
-gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
-sextract64(a->rs1, 0, 5), MAXSZ(s), MAXSZ(s));
-}
+gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
+extract_imm(s, a->rs1, imm_mode), MAXSZ(s), MAXSZ(s));
 mark_vs_dirty(s);
 return true;
 }
-return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, zx);
+return opivi_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s, imm_mode);
 }
 
 /* OPIVI with GVEC IR */
-#define GEN_OPIVI_GVEC_TRANS(NAME, ZX, OPIVX, SUF) \
+#define GEN_OPIVI_GVEC_TRANS(NAME, IMM_MODE, OPIVX, SUF) \
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
 {  \
 static gen_helper_opivx * const fns[4] = { \
@@ -1381,10 +1397,10 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)  
   \
 gen_helper_##OPIVX##_w, gen_helper_##OPIVX##_d,\
 }; \
 return do_opivi_gvec(s, a, tcg_gen_gvec_##SUF, \
- fns[s->sew], ZX); \
+ fns[s->sew], IMM_MODE);   \
 }
 
-GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
+GEN_OPIVI_GVEC_TRANS(vadd_vi, IMM_SX, vadd_vx, addi)
 
 static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
int64_t c, uint32_t oprsz, uint32_t maxsz)
@@ -1393,7 +1409,7 @@ static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t 
dofs, uint32_t aofs,
 tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
 }
 
-GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
+GEN_OPIVI_GVEC_TRANS(vrsub_vi, IMM_SX, vrsub_vx, rsubi)
 
 /* Vector Widening Integer Add/Subtract */
 
@@ -1649,7 +1665,7 @@ GEN_OPIVX_TRANS(vmadc_vxm, opivx_vmadc_check)
 GEN_OPIVX_TRANS(vmsbc_vxm, opivx_vmadc_check)
 
 /*

[PATCH v8 17/78] target/riscv: rvv:1.0: add translation-time nan-box helper function

2021-10-15 Thread frank . chang
From: Frank Chang 

* Add fp16 nan-box check generator function, if a 16-bit input is not
  properly nanboxed, then the input is replaced with the default qnan.
* Add do_nanbox() helper function to utilize gen_check_nanbox_X() to
  generate the NaN-boxed floating-point values based on SEW setting.
* Apply nanbox helper in opfvf_trans().

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 35 -
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index c33ded385d7..50834bb8a39 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2094,6 +2094,33 @@ GEN_OPIVI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx)
 /*
  *** Vector Float Point Arithmetic Instructions
  */
+
+/*
+ * As RVF-only cpus always have values NaN-boxed to 64-bits,
+ * RVF and RVD can be treated equally.
+ * We don't have to deal with the cases of: SEW > FLEN.
+ *
+ * If SEW < FLEN, check whether input fp register is a valid
+ * NaN-boxed value, in which case the least-significant SEW bits
+ * of the f regsiter are used, else the canonical NaN value is used.
+ */
+static void do_nanbox(DisasContext *s, TCGv_i64 out, TCGv_i64 in)
+{
+switch (s->sew) {
+case 1:
+gen_check_nanbox_h(out, in);
+break;
+case 2:
+gen_check_nanbox_s(out, in);
+break;
+case 3:
+tcg_gen_mov_i64(out, in);
+break;
+default:
+g_assert_not_reached();
+}
+}
+
 /* Vector Single-Width Floating-Point Add/Subtract Instructions */
 
 /*
@@ -2147,6 +2174,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 {
 TCGv_ptr dest, src2, mask;
 TCGv_i32 desc;
+TCGv_i64 t1;
 
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -2160,11 +2188,16 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, 
uint32_t vs2,
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-fn(dest, mask, cpu_fpr[rs1], src2, cpu_env, desc);
+/* NaN-box f[rs1] */
+t1 = tcg_temp_new_i64();
+do_nanbox(s, t1, cpu_fpr[rs1]);
+
+fn(dest, mask, t1, src2, cpu_env, desc);
 
 tcg_temp_free_ptr(dest);
 tcg_temp_free_ptr(mask);
 tcg_temp_free_ptr(src2);
+tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
 gen_set_label(over);
 return true;
-- 
2.25.1




[PATCH v8 30/78] target/riscv: rvv-1.0: find-first-set mask bit instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 2 +-
 target/riscv/insn32.decode  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 3f30882aec4..7646567eb27 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1022,7 +1022,7 @@ DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, 
i32)
 
 DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32)
 
-DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
+DEF_HELPER_4(vfirst_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_5(vmsbf_m, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vmsif_m, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e748f7ca714..4df2aa9cddc 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -628,7 +628,7 @@ vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vcpop_m 01 . . 1 010 . 1010111 @r2_vm
-vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
+vfirst_m01 . . 10001 010 . 1010111 @r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index fc17e57d0f7..5376adca60c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2695,7 +2695,7 @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 }
 
 /* vmfirst find-first-set mask bit */
-static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
+static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s)) {
@@ -2714,7 +2714,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
+gen_helper_vfirst_m(dst, mask, src2, cpu_env, desc);
 gen_set_gpr(s, a->rd, dst);
 
 tcg_temp_free_ptr(mask);
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9451112b3da..f97783acf05 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4233,9 +4233,9 @@ target_ulong HELPER(vcpop_m)(void *v0, void *vs2, 
CPURISCVState *env,
 return cnt;
 }
 
-/* vmfirst find-first-set mask bit*/
-target_ulong HELPER(vmfirst_m)(void *v0, void *vs2, CPURISCVState *env,
-   uint32_t desc)
+/* vfirst find-first-set mask bit*/
+target_ulong HELPER(vfirst_m)(void *v0, void *vs2, CPURISCVState *env,
+  uint32_t desc)
 {
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
-- 
2.25.1




[PATCH v8 12/78] target/riscv: rvv-1.0: remove MLEN calculations

2021-10-15 Thread frank . chang
From: Frank Chang 

As in RVV 1.0 design, MLEN is hardcoded with value 1 (Section 4.5).
Thus, remove all MLEN related calculations.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc |  35 +---
 target/riscv/internals.h|   9 +-
 target/riscv/translate.c|   2 -
 target/riscv/vector_helper.c| 252 ++--
 4 files changed, 111 insertions(+), 187 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 47fdd438609..ddf20f02dfa 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -237,7 +237,6 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -290,7 +289,6 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -374,7 +372,6 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -413,7 +410,6 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
   gen_helper_vsse_v_w,  gen_helper_vsse_v_d }
 };
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -504,7 +500,6 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -556,7 +551,6 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -632,7 +626,6 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t 
seq)
 return false;
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
@@ -738,7 +731,6 @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t 
seq)
 }
 }
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 data = FIELD_DP32(data, VDATA, WD, a->wd);
@@ -820,7 +812,6 @@ do_opivv_gvec(DisasContext *s, arg_rmrr *a, GVecGen3Fn 
*gvec_fn,
 } else {
 uint32_t data = 0;
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
@@ -865,7 +856,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t 
vs2, uint32_t vm,
 src2 = tcg_temp_new_ptr();
 src1 = get_gpr(s, rs1, EXT_NONE);
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1009,7 +999,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, 
uint32_t vs2, uint32_t vm,
 } else {
 src1 = tcg_constant_tl(sextract64(imm, 0, 5));
 }
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
@@ -1102,7 +1091,6 @@ static bool do_opivv_widen(DisasContext *s, arg_rmrr *a,
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
 tcg_gen_gvec_4_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
@@ -1191,7 +1179,6 @@ static bool do_opiwv_widen(DisasContext *s, arg_rmrr *a,
 TCGLabel *over = gen_new_label();

[PATCH v8 18/78] target/riscv: rvv-1.0: remove amo operations instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Vector AMOs are removed from standard vector extensions. Will be added
later as separate Zvamo extension, but will need a different encoding
from earlier proposal.

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |  27 -
 target/riscv/insn32.decode  |  24 -
 target/riscv/insn_trans/trans_rvv.c.inc | 137 
 target/riscv/vector_helper.c| 125 -
 4 files changed, 313 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index d25cf725c57..ecb6af6cd99 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -274,33 +274,6 @@ DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxord_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoord_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomind_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_w,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 6c4cde216bc..3d57255fffb 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -49,7 +49,6 @@
 &atomicaq rl rs2 rs1 rd
 &rmrr  vm rd rs1 rs2
 &rmr   vm rd rs2
-&rwdvm vm wd rd rs1 rs2
 &r2nfvmvm rd rs1 nf
 &rnfvm vm rd rs1 rs2 nf
 
@@ -79,7 +78,6 @@
 @r_vm.. vm:1 . . ... . ... &rmrr %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
-@r_wdvm  . wd:1 vm:1 . . ... . ... &rwdvm %rs2 %rs1 %rd
 @r2_zimm . zimm:11  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
 
@@ -340,17 +338,6 @@ vsxh_v ... -11 . . . 101 . 0100111 @r_nfvm
 vsxw_v ... -11 . . . 110 . 0100111 @r_nfvm
 vsxe_v ... -11 . . . 111 . 0100111 @r_nfvm
 
-#*** Vector AMO operations are encoded under the standard AMO major opcode ***
-vamoswapw_v 1 . . . . 110 . 010 @r_wdvm
-vamoaddw_v  0 . . . . 110 . 010 @r_wdvm
-vamoxorw_v  00100 . . . . 110 . 010 @r_wdvm
-vamoandw_v  01100 . . . . 110 . 010 @r_wdvm
-vamoorw_v   01000 . . . . 110 . 010 @r_wdvm
-vamominw_v  1 . . . . 110 . 010 @r_wdvm
-vamomaxw_v  10100 . . . . 110 . 010 @r_wdvm
-vamominuw_v 11000 . . . . 110 . 010 @r_wdvm
-vamomaxuw_v 11100 . . . . 110 . 010 @r_wdvm
-
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
@@ -649,17 +636,6 @@ vcompress_vm010111 - . . 010 . 1010111 @r
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
 
-#*** Vector AMO operations (in addition to Zvamo) ***
-vamoswapd_v 1 . . . . 111 . 010 @r_wdvm
-vamoaddd_v  0 . . . . 111 . 010 @r_wdvm
-vamoxord_v  00100 . . . . 111 .

[PATCH 19/76] target/riscv: rvv-1.0: stride load and store instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 129 +++---
 target/riscv/insn32.decode  |  43 +++--
 target/riscv/insn_trans/trans_rvv.c.inc | 227 +++-
 target/riscv/vector_helper.c| 190 ++--
 4 files changed, 194 insertions(+), 395 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 460eee9988e..80f2d1aee83 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -85,111 +85,30 @@ DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
 
 /* Vector functions */
 DEF_HELPER_3(vsetvl, tl, env, tl, tl)
-DEF_HELPER_5(vlb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vle_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwu_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsb_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsh_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vsw_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_b_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_h_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_w_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vse_v_d_mask, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_6(vlsb_v_b, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsb_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_h, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_w, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsh_v_d, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlsw_

[PATCH v8 19/78] target/riscv: rvv-1.0: configure instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 64 +++--
 target/riscv/vector_helper.c| 14 +-
 2 files changed, 41 insertions(+), 37 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ddea578d0ba..ddc5f602768 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -120,59 +120,51 @@ static bool require_noover(const int8_t dst, const int8_t 
dst_lmul,
 return !is_overlapped(dst, dst_size, src, src_size);
 }
 
-static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
+static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
 {
-TCGv s1, s2, dst;
+TCGv s1, dst;
 
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
+if (!require_rvv(s) || !has_ext(s, RVV)) {
 return false;
 }
 
-s2 = get_gpr(ctx, a->rs2, EXT_ZERO);
-dst = dest_gpr(ctx, a->rd);
+dst = dest_gpr(s, rd);
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->rs1 == 0) {
+if (rd == 0 && rs1 == 0) {
+s1 = tcg_temp_new();
+tcg_gen_mov_tl(s1, cpu_vl);
+} else 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(ctx, a->rs1, EXT_ZERO);
+s1 = get_gpr(s, rs1, EXT_ZERO);
 }
-gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
 
-tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
-lookup_and_goto_ptr(ctx);
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
-}
+gen_helper_vsetvl(dst, cpu_env, s1, s2);
+gen_set_gpr(s, rd, dst);
+mark_vs_dirty(s);
 
-static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
-{
-TCGv s1, s2, dst;
+tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
+lookup_and_goto_ptr(s);
+s->base.is_jmp = DISAS_NORETURN;
 
-if (!require_rvv(ctx) || !has_ext(ctx, RVV)) {
-return false;
+if (rd == 0 && rs1 == 0) {
+tcg_temp_free(s1);
 }
 
-s2 = tcg_constant_tl(a->zimm);
-dst = dest_gpr(ctx, a->rd);
+return true;
+}
 
-/* Using x0 as the rs1 register specifier, encodes an infinite AVL */
-if (a->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(ctx, a->rs1, EXT_ZERO);
-}
-gen_helper_vsetvl(dst, cpu_env, s1, s2);
-gen_set_gpr(ctx, a->rd, dst);
-mark_vs_dirty(ctx);
+static bool trans_vsetvl(DisasContext *s, arg_vsetvl *a)
+{
+TCGv s2 = get_gpr(s, a->rs2, EXT_ZERO);
+return do_vsetvl(s, a->rd, a->rs1, s2);
+}
 
-gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
-ctx->base.is_jmp = DISAS_NORETURN;
-return true;
+static bool trans_vsetvli(DisasContext *s, arg_vsetvli *a)
+{
+TCGv s2 = tcg_constant_tl(a->zimm);
+return do_vsetvl(s, a->rd, a->rs1, s2);
 }
 
 /* vector register offset from env */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index bf976d364f1..78fae782840 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -31,12 +31,24 @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, 
target_ulong s1,
 {
 int vlmax, vl;
 RISCVCPU *cpu = env_archcpu(env);
+uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
 uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
 uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
 bool vill = FIELD_EX64(s2, VTYPE, VILL);
 target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
 
-if ((sew > cpu->cfg.elen) || vill || (ediv != 0) || (reserved != 0)) {
+if (lmul & 4) {
+/* Fractional LMUL. */
+if (lmul == 4 ||
+cpu->cfg.elen >> (8 - lmul) < sew) {
+vill = true;
+}
+}
+
+if ((sew > cpu->cfg.elen)
+|| vill
+|| (ediv != 0)
+|| (reserved != 0)) {
 /* only set vill bit. */
 env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
 env->vl = 0;
-- 
2.25.1




[PATCH v8 31/78] target/riscv: rvv-1.0: set-X-first mask bit instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode  | 6 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 5 -
 target/riscv/vector_helper.c| 4 
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4df2aa9cddc..d139c0aade7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -629,9 +629,9 @@ vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
 vcpop_m 01 . . 1 010 . 1010111 @r2_vm
 vfirst_m01 . . 10001 010 . 1010111 @r2_vm
-vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
-vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
-vmsof_m 010110 . . 00010 010 . 1010111 @r2_vm
+vmsbf_m 010100 . . 1 010 . 1010111 @r2_vm
+vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
+vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010110 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5376adca60c..538a32a605a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2730,7 +2730,10 @@ static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 #define GEN_M_TRANS(NAME)  \
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
-if (vext_check_isa_ill(s)) {   \
+if (require_rvv(s) &&  \
+vext_check_isa_ill(s) &&   \
+require_vm(a->vm, a->rd) &&\
+(a->rd != a->rs2)) {   \
 uint32_t data = 0; \
 gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f97783acf05..b0dc971a860 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4260,7 +4260,6 @@ enum set_mask_type {
 static void vmsetm(void *vd, void *v0, void *vs2, CPURISCVState *env,
uint32_t desc, enum set_mask_type type)
 {
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;
 uint32_t vm = vext_vm(desc);
 uint32_t vl = env->vl;
 int i;
@@ -4290,9 +4289,6 @@ static void vmsetm(void *vd, void *v0, void *vs2, 
CPURISCVState *env,
 }
 }
 }
-for (; i < vlmax; i++) {
-vext_set_elem_mask(vd, i, 0);
-}
 }
 
 void HELPER(vmsbf_m)(void *vd, void *v0, void *vs2, CPURISCVState *env,
-- 
2.25.1




[PATCH v8 11/78] target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr registers

2021-10-15 Thread frank . chang
From: Frank Chang 

If VS field is off, accessing vector csr registers should raise an
illegal-instruction exception.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/csr.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0fb71875654..688dc1533b6 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -48,6 +48,11 @@ static RISCVException fs(CPURISCVState *env, int csrno)
 static RISCVException vs(CPURISCVState *env, int csrno)
 {
 if (env->misa & RVV) {
+#if !defined(CONFIG_USER_ONLY)
+if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+#endif
 return RISCV_EXCP_NONE;
 }
 return RISCV_EXCP_ILLEGAL_INST;
-- 
2.25.1




[PATCH v8 22/78] target/riscv: rvv-1.0: fix address index overflow bug of indexed load/store insns

2021-10-15 Thread frank . chang
From: Frank Chang 

Replace ETYPE from signed int to unsigned int to prevent index overflow
issue, which would lead to wrong index address.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index df45c1620c1..3da4f3b1e62 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -374,10 +374,10 @@ static target_ulong NAME(target_ulong base,\
 return (base + *((ETYPE *)vs2 + H(idx)));  \
 }
 
-GEN_VEXT_GET_INDEX_ADDR(idx_b, int8_t,  H1)
-GEN_VEXT_GET_INDEX_ADDR(idx_h, int16_t, H2)
-GEN_VEXT_GET_INDEX_ADDR(idx_w, int32_t, H4)
-GEN_VEXT_GET_INDEX_ADDR(idx_d, int64_t, H8)
+GEN_VEXT_GET_INDEX_ADDR(idx_b, uint8_t,  H1)
+GEN_VEXT_GET_INDEX_ADDR(idx_h, uint16_t, H2)
+GEN_VEXT_GET_INDEX_ADDR(idx_w, uint32_t, H4)
+GEN_VEXT_GET_INDEX_ADDR(idx_d, uint64_t, H8)
 
 static inline void
 vext_ldst_index(void *vd, void *v0, target_ulong base,
-- 
2.25.1




[PATCH v8 33/78] target/riscv: rvv-1.0: element index instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 3ac5162aeb7..ab274dcde12 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -633,7 +633,7 @@ vmsbf_m 010100 . . 1 010 . 1010111 
@r2_vm
 vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010100 . . 1 010 . 1010111 @r2_vm
-vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
+vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
-- 
2.25.1




[PATCH 20/76] target/riscv: rvv-1.0: index load and store instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  67 
 target/riscv/insn32.decode  |  21 ++-
 target/riscv/insn_trans/trans_rvv.c.inc | 203 
 target/riscv/vector_helper.c|  89 +--
 4 files changed, 222 insertions(+), 158 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 80f2d1aee83..597646893ca 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -109,41 +109,38 @@ DEF_HELPER_6(vsse8_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse16_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse32_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse64_v, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlbff_v_w, void, ptr

[PATCH 21/76] target/riscv: rvv-1.0: fix address index overflow bug of indexed load/store insns

2021-10-15 Thread frank . chang
From: Frank Chang 

Replace ETYPE from signed int to unsigned int to prevent index overflow
issue, which would lead to wrong index address.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/vector_helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d0c4be2ecc9..366a4476916 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -361,10 +361,10 @@ static target_ulong NAME(target_ulong base,\
 return (base + *((ETYPE *)vs2 + H(idx)));  \
 }
 
-GEN_VEXT_GET_INDEX_ADDR(idx_b, int8_t,  H1)
-GEN_VEXT_GET_INDEX_ADDR(idx_h, int16_t, H2)
-GEN_VEXT_GET_INDEX_ADDR(idx_w, int32_t, H4)
-GEN_VEXT_GET_INDEX_ADDR(idx_d, int64_t, H8)
+GEN_VEXT_GET_INDEX_ADDR(idx_b, uint8_t,  H1)
+GEN_VEXT_GET_INDEX_ADDR(idx_h, uint16_t, H2)
+GEN_VEXT_GET_INDEX_ADDR(idx_w, uint32_t, H4)
+GEN_VEXT_GET_INDEX_ADDR(idx_d, uint64_t, H8)
 
 static inline void
 vext_ldst_index(void *vd, void *v0, target_ulong base,
-- 
2.25.1




[PATCH 22/76] target/riscv: rvv-1.0: fault-only-first unit stride load

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 27 +++-
 target/riscv/insn32.decode  | 14 +++
 target/riscv/insn_trans/trans_rvv.c.inc | 33 ---
 target/riscv/vector_helper.c| 56 +
 4 files changed, 39 insertions(+), 91 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 597646893ca..f74fa7188f0 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -141,28 +141,11 @@ DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle8ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
+
 DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vamoaddw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ff3071066db..e4f975b49b6 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -316,14 +316,6 @@ vsse16_v... 010 . . . 101 . 0100111 @r_nfvm
 vsse32_v... 010 . . . 110 . 0100111 @r_nfvm
 vsse64_v... 010 . . . 111 . 0100111 @r_nfvm
 
-vlbff_v... 100 . 1 . 000 . 111 @r2_nfvm
-vlhff_v... 100 . 1 . 101 . 111 @r2_nfvm
-vlwff_v... 100 . 1 . 110 . 111 @r2_nfvm
-vleff_v... 000 . 1 . 111 . 111 @r2_nfvm
-vlbuff_v   ... 000 . 1 . 000 . 111 @r2_nfvm
-vlhuff_v   ... 000 . 1 . 101 . 111 @r2_nfvm
-vlwuff_v   ... 000 . 1 . 110 . 111 @r2_nfvm
-
 # Vector ordered-indexed and unordered-indexed load insns.
 vlxei8_v  ... 0-1 . . . 000 . 111 @r_nfvm
 vlxei16_v ... 0-1 . . . 101 . 111 @r_nfvm
@@ -336,6 +328,12 @@ vsxei16_v ... 0-1 . . . 101 . 0100111 
@r_nfvm
 vsxei32_v ... 0-1 . . . 110 . 0100111 @r_nfvm
 vsxei64_v ... 0-1 . . . 111 . 0100111 @r_nfvm
 
+# Vector unit-stride fault-only-first load insns.
+vle8ff_v  ... 000 . 1 . 000 . 111 @r2_nfvm
+vle16ff_v ... 000 . 1 . 101 . 111 @r2_nfvm
+vle32ff_v ... 000 . 1 . 110 . 111 @r2_nfvm
+vle64ff_v ... 000 . 1 . 111 . 111 @r2_nfvm
+
 #*** Vector AMO operations are encoded under the standard AMO major opcode ***
 vamoswapw_v 1 . . . . 110 . 010 @r_wdvm
 vamoaddw_v  0 . . . . 110 . 010 @r_wdvm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 6aa75de802e..4aef8bb2a76 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -935,28 +935,16 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 return true;
 }
 
-static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
 {
 uint32_t data = 0;
 gen_helper_ldst_us *fn;
-static gen_helper_ldst_us * const fns[7][4] = {
-{ gen_helper_vlbff_v_b,  gen_helper_vlbff_v_h,
-  gen_helper_vlbff_v_w,  gen_helper_vlbff_v_d },
-{ NULL,  gen_helper_vlhff_v_h,
-  gen_helper_vlhff_v_w,  gen_helper_vlhff_v_d

[PATCH v8 27/78] target/riscv: rvv-1.0: floating-point square-root instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7d8441d1f21..92a0e6fe51e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -563,7 +563,7 @@ vfwmsac_vv  10 . . . 001 . 1010111 @r_vm
 vfwmsac_vf  10 . . . 101 . 1010111 @r_vm
 vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm
 vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm
-vfsqrt_v100011 . . 0 001 . 1010111 @r2_vm
+vfsqrt_v010011 . . 0 001 . 1010111 @r2_vm
 vfmin_vv000100 . . . 001 . 1010111 @r_vm
 vfmin_vf000100 . . . 101 . 1010111 @r_vm
 vfmax_vv000110 . . . 001 . 1010111 @r_vm
-- 
2.25.1




[PATCH v8 36/78] target/riscv: rvv-1.0: integer scalar move instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

* Remove "vmv.s.x: dothing if rs1 == 0" constraint.
* Add vmv.x.s instruction.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode  |  3 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 43 -
 2 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 4653a9679ef..e33ec82fdf8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -634,8 +634,9 @@ vmsif_m 010100 . . 00011 010 . 1010111 
@r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
 viota_m 010100 . . 1 010 . 1010111 @r2_vm
 vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
+vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
+vmv_s_x 01 1 0 . 110 . 1010111 @r2
 vext_x_v001100 1 . . 010 . 1010111 @r
-vmv_s_x 001101 1 0 . 110 . 1010111 @r2
 vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
 vfmv_s_f001101 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 43da36f4200..42a9f2764d5 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2977,27 +2977,54 @@ static void vec_element_storei(DisasContext *s, int 
vreg,
 store_element(val, cpu_env, endian_ofs(s, vreg, idx), s->sew);
 }
 
+/* vmv.x.s rd, vs2 # x[rd] = vs2[0] */
+static bool trans_vmv_x_s(DisasContext *s, arg_vmv_x_s *a)
+{
+if (require_rvv(s) &&
+vext_check_isa_ill(s)) {
+TCGv_i64 t1;
+TCGv dest;
+
+t1 = tcg_temp_new_i64();
+dest = tcg_temp_new();
+/*
+ * load vreg and sign-extend to 64 bits,
+ * then truncate to XLEN bits before storing to gpr.
+ */
+vec_element_loadi(s, t1, a->rs2, 0, true);
+tcg_gen_trunc_i64_tl(dest, t1);
+gen_set_gpr(s, a->rd, dest);
+tcg_temp_free_i64(t1);
+tcg_temp_free(dest);
+
+return true;
+}
+return false;
+}
+
 /* vmv.s.x vd, rs1 # vd[0] = rs1 */
 static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x *a)
 {
-if (vext_check_isa_ill(s)) {
+if (require_rvv(s) &&
+vext_check_isa_ill(s)) {
 /* This instruction ignores LMUL and vector register groups */
-int maxsz = s->vlen >> 3;
 TCGv_i64 t1;
+TCGv s1;
 TCGLabel *over = gen_new_label();
 
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), maxsz, maxsz, 0);
-if (a->rs1 == 0) {
-goto done;
-}
 
 t1 = tcg_temp_new_i64();
-tcg_gen_extu_tl_i64(t1, cpu_gpr[a->rs1]);
+
+/*
+ * load gpr and sign-extend to 64 bits,
+ * then truncate to SEW bits when storing to vreg.
+ */
+s1 = get_gpr(s, a->rs1, EXT_NONE);
+tcg_gen_ext_tl_i64(t1, s1);
 vec_element_storei(s, a->rd, 0, t1);
 tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
-done:
 gen_set_label(over);
 return true;
 }
-- 
2.25.1




[PATCH v8 21/78] target/riscv: rvv-1.0: index load and store instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  67 +++
 target/riscv/insn32.decode  |  21 +++--
 target/riscv/insn_trans/trans_rvv.c.inc | 110 +---
 target/riscv/vector_helper.c|  98 +
 4 files changed, 145 insertions(+), 151 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 5a760fa4a32..1beca6dc0d7 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -136,41 +136,38 @@ DEF_HELPER_6(vsse8_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse16_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse32_v, void, ptr, ptr, tl, tl, env, i32)
 DEF_HELPER_6(vsse64_v, void, ptr, ptr, tl, tl, env, i32)
-DEF_HELPER_6(vlxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxbu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxhu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vlxwu_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxb_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxh_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vsxe_v_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vlxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(v

[PATCH 29/76] target/riscv: rvv-1.0: mask population count instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 2 +-
 target/riscv/insn32.decode  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 7 ---
 target/riscv/vector_helper.c| 6 +++---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 780cd6d995a..3b6b4788818 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1066,7 +1066,7 @@ DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
+DEF_HELPER_4(vpopc_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
 
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 64c2a533b42..f12096d67de 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -669,7 +669,7 @@ vmor_mm 011010 - . . 010 . 1010111 @r
 vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
-vmpopc_m010100 . . - 010 . 1010111 @r2_vm
+vpopc_m 01 . . 1 010 . 1010111 @r2_vm
 vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ec205bfd63c..80d23e3f447 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2864,8 +2864,8 @@ GEN_MM_TRANS(vmnor_mm)
 GEN_MM_TRANS(vmornot_mm)
 GEN_MM_TRANS(vmxnor_mm)
 
-/* Vector mask population count vmpopc */
-static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
+/* Vector mask population count vpopc */
+static bool trans_vpopc_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s)) {
@@ -2884,11 +2884,12 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
+gen_helper_vpopc_m(dst, mask, src2, cpu_env, desc);
 gen_set_gpr(s, a->rd, dst);
 
 tcg_temp_free_ptr(mask);
 tcg_temp_free_ptr(src2);
+
 return true;
 }
 return false;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 1ef98de6b63..18c26c45731 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4416,9 +4416,9 @@ GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
 GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT)
 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
 
-/* Vector mask population count vmpopc */
-target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env,
-  uint32_t desc)
+/* Vector mask population count vpopc */
+target_ulong HELPER(vpopc_m)(void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
 {
 target_ulong cnt = 0;
 uint32_t vm = vext_vm(desc);
-- 
2.25.1




[PATCH v8 38/78] target/riscv: rvv-1.0: floating-point scalar move instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

NaN-boxed the scalar floating-point register based on RVV 1.0's rules.

Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  |  4 +--
 target/riscv/insn_trans/trans_rvv.c.inc | 38 -
 target/riscv/internals.h|  5 
 3 files changed, 21 insertions(+), 26 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index e33ec82fdf8..ab5fdbf9be8 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -637,8 +637,8 @@ vid_v   010100 . 0 10001 010 . 1010111 
@r1_vm
 vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
 vmv_s_x 01 1 0 . 110 . 1010111 @r2
 vext_x_v001100 1 . . 010 . 1010111 @r
-vfmv_f_s001100 1 . 0 001 . 1010111 @r2rd
-vfmv_s_f001101 1 0 . 101 . 1010111 @r2
+vfmv_f_s01 1 . 0 001 . 1010111 @r2rd
+vfmv_s_f01 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
 vslideup_vi 001110 . . . 011 . 1010111 @r_vm
 vslide1up_vx001110 . . . 110 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 1340ce56806..aec0316fba4 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3046,14 +3046,19 @@ static bool trans_vmv_s_x(DisasContext *s, arg_vmv_s_x 
*a)
 /* Floating-Point Scalar Move Instructions */
 static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
 {
-if (!s->vill && has_ext(s, RVF) &&
-(s->mstatus_fs != 0) && (s->sew != 0)) {
-unsigned int len = 8 << s->sew;
+if (require_rvv(s) &&
+require_rvf(s) &&
+vext_check_isa_ill(s)) {
+unsigned int ofs = (8 << s->sew);
+unsigned int len = 64 - ofs;
+TCGv_i64 t_nan;
 
 vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
-if (len < 64) {
-tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
-MAKE_64BIT_MASK(len, 64 - len));
+/* NaN-box f[rd] as necessary for SEW */
+if (len) {
+t_nan = tcg_constant_i64(UINT64_MAX);
+tcg_gen_deposit_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
+t_nan, ofs, len);
 }
 
 mark_fs_dirty(s);
@@ -3065,25 +3070,20 @@ static bool trans_vfmv_f_s(DisasContext *s, 
arg_vfmv_f_s *a)
 /* vfmv.s.f vd, rs1 # vd[0] = rs1 (vs2=0) */
 static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
 {
-if (!s->vill && has_ext(s, RVF) && (s->sew != 0)) {
-TCGv_i64 t1;
+if (require_rvv(s) &&
+require_rvf(s) &&
+vext_check_isa_ill(s)) {
 /* The instructions ignore LMUL and vector register group. */
-uint32_t vlmax = s->vlen >> 3;
+TCGv_i64 t1;
+TCGLabel *over = gen_new_label();
 
 /* if vl == 0, skip vector register write back */
-TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-/* zeroed all elements */
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd), vlmax, vlmax, 0);
-
-/* NaN-box f[rs1] as necessary for SEW */
+/* NaN-box f[rs1] */
 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]);
-}
+do_nanbox(s, t1, cpu_fpr[a->rs1]);
+
 vec_element_storei(s, a->rd, 0, t1);
 tcg_temp_free_i64(t1);
 mark_vs_dirty(s);
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 81f5dfa477a..ac062dc0b4e 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -32,11 +32,6 @@ target_ulong fclass_h(uint64_t frs1);
 target_ulong fclass_s(uint64_t frs1);
 target_ulong fclass_d(uint64_t frs1);
 
-#define SEW8  0
-#define SEW16 1
-#define SEW32 2
-#define SEW64 3
-
 #ifndef CONFIG_USER_ONLY
 extern const VMStateDescription vmstate_riscv_cpu;
 #endif
-- 
2.25.1




[PATCH 23/76] target/riscv: rvv-1.0: amo operations

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  99 +++---
 target/riscv/insn32.decode  |  58 --
 target/riscv/insn_trans/trans_rvv.c.inc | 230 ++-
 target/riscv/vector_helper.c| 232 
 4 files changed, 413 insertions(+), 206 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f74fa7188f0..25bc6140587 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -146,33 +146,78 @@ DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
 
-DEF_HELPER_6(vamoswapw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapd_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxord_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoord_v_d,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomind_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxd_v_d,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxud_v_d, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoswapw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoaddw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoxorw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoandw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamoorw_v_w,   void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxw_v_w,  void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamominuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vamomaxuw_v_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoswapei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoaddei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoxorei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoandei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamoorei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei16_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei16_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei32_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamominei32_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamomaxei8_32_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vamomaxei8_64_v, void, ptr, ptr, tl, ptr, env, i32)
+DEF_

[PATCH v8 23/78] target/riscv: rvv-1.0: fault-only-first unit stride load

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 26 ++---
 target/riscv/insn32.decode  | 14 ++---
 target/riscv/insn_trans/trans_rvv.c.inc | 33 +++
 target/riscv/vector_helper.c| 74 +++--
 4 files changed, 38 insertions(+), 109 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1beca6dc0d7..57560b8c04d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -168,28 +168,10 @@ DEF_HELPER_6(vsxei64_8_v, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vsxei64_16_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_32_v, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsxei64_64_v, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_5(vlbff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vleff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_b, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlbuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_h, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlhuff_v_d, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_w, void, ptr, ptr, tl, env, i32)
-DEF_HELPER_5(vlwuff_v_d, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle8ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
+DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
 
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f34194d31c4..180d97ecba3 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -314,14 +314,6 @@ vsse16_v... 010 . . . 101 . 0100111 @r_nfvm
 vsse32_v... 010 . . . 110 . 0100111 @r_nfvm
 vsse64_v... 010 . . . 111 . 0100111 @r_nfvm
 
-vlbff_v... 100 . 1 . 000 . 111 @r2_nfvm
-vlhff_v... 100 . 1 . 101 . 111 @r2_nfvm
-vlwff_v... 100 . 1 . 110 . 111 @r2_nfvm
-vleff_v... 000 . 1 . 111 . 111 @r2_nfvm
-vlbuff_v   ... 000 . 1 . 000 . 111 @r2_nfvm
-vlhuff_v   ... 000 . 1 . 101 . 111 @r2_nfvm
-vlwuff_v   ... 000 . 1 . 110 . 111 @r2_nfvm
-
 # Vector ordered-indexed and unordered-indexed load insns.
 vlxei8_v  ... 0-1 . . . 000 . 111 @r_nfvm
 vlxei16_v ... 0-1 . . . 101 . 111 @r_nfvm
@@ -334,6 +326,12 @@ vsxei16_v ... 0-1 . . . 101 . 0100111 
@r_nfvm
 vsxei32_v ... 0-1 . . . 110 . 0100111 @r_nfvm
 vsxei64_v ... 0-1 . . . 111 . 0100111 @r_nfvm
 
+# Vector unit-stride fault-only-first load insns.
+vle8ff_v  ... 000 . 1 . 000 . 111 @r2_nfvm
+vle16ff_v ... 000 . 1 . 101 . 111 @r2_nfvm
+vle32ff_v ... 000 . 1 . 110 . 111 @r2_nfvm
+vle64ff_v ... 000 . 1 . 111 . 111 @r2_nfvm
+
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 954a8636063..d7c04fa2a62 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -935,28 +935,16 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 return true;
 }
 
-static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t seq)
+static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t eew)
 {
 uint32_t data = 0;
 gen_helper_ldst_us *fn;
-static gen_helper_ldst_us * const fns[7][4] = {
-{ gen_helper_vlbff_v_b,  gen_helper_vlbff_v_h,
-  gen_helper_vlbff_v_w,  gen_helper_vlbff_v_d },
-{ NULL,  gen_helper_vlhff_v_h,
-  gen_helper_vlhff_v_w,  gen_helper_vlhff_v_d },
-{ NULL,  NULL,
-  gen_helper_vlwff_v_w,  gen_helper_vlwff_v_d },
-{ gen_helper_vleff_v

[PATCH v8 28/78] target/riscv: rvv-1.0: floating-point classify instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn32.decode | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 92a0e6fe51e..f61eaf7c6ba 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -586,7 +586,7 @@ vmfgt_vf011101 . . . 101 . 1010111 @r_vm
 vmfge_vf01 . . . 101 . 1010111 @r_vm
 vmford_vv   011010 . . . 001 . 1010111 @r_vm
 vmford_vf   011010 . . . 101 . 1010111 @r_vm
-vfclass_v   100011 . . 1 001 . 1010111 @r2_vm
+vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
 vfcvt_xu_f_v100010 . . 0 001 . 1010111 @r2_vm
-- 
2.25.1




[PATCH v8 39/78] target/riscv: rvv-1.0: whole register move instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vmv1r.v
* vmv2r.v
* vmv4r.v
* vmv8r.v

Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  |  4 
 target/riscv/insn_trans/trans_rvv.c.inc | 25 +
 2 files changed, 29 insertions(+)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ab5fdbf9be8..06a80763112 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -650,6 +650,10 @@ vrgatherei16_vv 001110 . . . 000 . 1010111 
@r_vm
 vrgather_vx 001100 . . . 100 . 1010111 @r_vm
 vrgather_vi 001100 . . . 011 . 1010111 @r_vm
 vcompress_vm010111 - . . 010 . 1010111 @r
+vmv1r_v 100111 1 . 0 011 . 1010111 @r2rd
+vmv2r_v 100111 1 . 1 011 . 1010111 @r2rd
+vmv4r_v 100111 1 . 00011 011 . 1010111 @r2rd
+vmv8r_v 100111 1 . 00111 011 . 1010111 @r2rd
 
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index aec0316fba4..5eaf978fe90 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3258,3 +3258,28 @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a)
 }
 return false;
 }
+
+/*
+ * Whole Vector Register Move Instructions ignore vtype and vl setting.
+ * Thus, we don't need to check vill bit. (Section 16.6)
+ */
+#define GEN_VMV_WHOLE_TRANS(NAME, LEN)  \
+static bool trans_##NAME(DisasContext *s, arg_##NAME * a)   \
+{   \
+if (require_rvv(s) &&   \
+QEMU_IS_ALIGNED(a->rd, LEN) &&  \
+QEMU_IS_ALIGNED(a->rs2, LEN)) { \
+/* EEW = 8 */   \
+tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd),  \
+ vreg_ofs(s, a->rs2),   \
+ s->vlen / 8 * LEN, s->vlen / 8 * LEN); \
+mark_vs_dirty(s);   \
+return true;\
+}   \
+return false;   \
+}
+
+GEN_VMV_WHOLE_TRANS(vmv1r_v, 1)
+GEN_VMV_WHOLE_TRANS(vmv2r_v, 2)
+GEN_VMV_WHOLE_TRANS(vmv4r_v, 4)
+GEN_VMV_WHOLE_TRANS(vmv8r_v, 8)
-- 
2.25.1




[PATCH v8 24/78] target/riscv: rvv-1.0: load/store whole register instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vlre.v
* vsr.v

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   | 21 
 target/riscv/insn32.decode  | 22 
 target/riscv/insn_trans/trans_rvv.c.inc | 68 +
 target/riscv/vector_helper.c| 65 +++
 4 files changed, 176 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 57560b8c04d..b8894d61510 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -173,6 +173,27 @@ DEF_HELPER_5(vle16ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle32ff_v, void, ptr, ptr, tl, env, i32)
 DEF_HELPER_5(vle64ff_v, void, ptr, ptr, tl, env, i32)
 
+DEF_HELPER_4(vl1re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl1re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl2re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl4re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re8_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re16_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re32_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vl8re64_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs1r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs2r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs4r_v, void, ptr, tl, env, i32)
+DEF_HELPER_4(vs8r_v, void, ptr, tl, env, i32)
+
 DEF_HELPER_6(vadd_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 180d97ecba3..7d8441d1f21 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -332,6 +332,28 @@ vle16ff_v ... 000 . 1 . 101 . 111 
@r2_nfvm
 vle32ff_v ... 000 . 1 . 110 . 111 @r2_nfvm
 vle64ff_v ... 000 . 1 . 111 . 111 @r2_nfvm
 
+# Vector whole register insns
+vl1re8_v  000 000 1 01000 . 000 . 111 @r2
+vl1re16_v 000 000 1 01000 . 101 . 111 @r2
+vl1re32_v 000 000 1 01000 . 110 . 111 @r2
+vl1re64_v 000 000 1 01000 . 111 . 111 @r2
+vl2re8_v  001 000 1 01000 . 000 . 111 @r2
+vl2re16_v 001 000 1 01000 . 101 . 111 @r2
+vl2re32_v 001 000 1 01000 . 110 . 111 @r2
+vl2re64_v 001 000 1 01000 . 111 . 111 @r2
+vl4re8_v  011 000 1 01000 . 000 . 111 @r2
+vl4re16_v 011 000 1 01000 . 101 . 111 @r2
+vl4re32_v 011 000 1 01000 . 110 . 111 @r2
+vl4re64_v 011 000 1 01000 . 111 . 111 @r2
+vl8re8_v  111 000 1 01000 . 000 . 111 @r2
+vl8re16_v 111 000 1 01000 . 101 . 111 @r2
+vl8re32_v 111 000 1 01000 . 110 . 111 @r2
+vl8re64_v 111 000 1 01000 . 111 . 111 @r2
+vs1r_v000 000 1 01000 . 000 . 0100111 @r2
+vs2r_v001 000 1 01000 . 000 . 0100111 @r2
+vs4r_v011 000 1 01000 . 000 . 0100111 @r2
+vs8r_v111 000 1 01000 . 000 . 0100111 @r2
+
 # *** new major opcode OP-V ***
 vadd_vv 00 . . . 000 . 1010111 @r_vm
 vadd_vx 00 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index d7c04fa2a62..edf3e34207c 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -960,6 +960,74 @@ GEN_VEXT_TRANS(vle16ff_v, MO_16, r2nfvm, ldff_op, 
ld_us_check)
 GEN_VEXT_TRANS(vle32ff_v, MO_32, r2nfvm, ldff_op, ld_us_check)
 GEN_VEXT_TRANS(vle64ff_v, MO_64, r2nfvm, ldff_op, ld_us_check)
 
+/*
+ * load and store whole register instructions
+ */
+typedef void gen_helper_ldst_whole(TCGv_ptr, TCGv, TCGv_env, TCGv_i32);
+
+static bool ldst_whole_trans(uint32_t vd, uint32_t rs1, uint32_t nf,
+ gen_helper_ldst_whole *fn, DisasContext *s,
+ bool is_store)
+{
+TCGv_ptr dest;
+TCGv base;
+TCGv_i32 desc;
+
+uint32_t data = FIELD_DP32(0, VDATA, NF, nf);
+dest = tcg_temp_new_ptr();
+desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+
+base = get_gpr(s, rs1, EXT_NONE);
+tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
+
+fn(dest, base, cpu_env, desc);
+
+tcg_temp_free_ptr(dest);
+
+if (!is_store) {
+mark_vs_dirty(s);
+}
+
+return true;
+}
+
+/*
+ * load and store whole register instructions ignore vtype and vl setting.
+ 

[PATCH v8 25/78] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 32 ++--
 target/riscv/vector_helper.c| 99 ++---
 2 files changed, 80 insertions(+), 51 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index edf3e34207c..118591ddda2 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -540,6 +540,12 @@ static bool trans_##NAME(DisasContext *s, arg_##ARGTYPE * 
a) \
 return false;\
 }
 
+static uint8_t vext_get_emul(DisasContext *s, uint8_t eew)
+{
+int8_t emul = eew - s->sew + s->lmul;
+return emul < 0 ? 0 : emul;
+}
+
 /*
  *** unit stride load and store
  */
@@ -604,8 +610,14 @@ static bool ld_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 return false;
 }
 
+/*
+ * Vector load/store instructions have the EEW encoded
+ * directly in the instructions. The maximum vector size is
+ * calculated with EMUL rather than LMUL.
+ */
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, false);
 }
@@ -640,8 +652,9 @@ static bool st_us_op(DisasContext *s, arg_r2nfvm *a, 
uint8_t eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_us_trans(a->rd, a->rs1, data, fn, s, true);
 }
@@ -711,8 +724,9 @@ static bool ld_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_stride_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
@@ -739,8 +753,9 @@ static bool st_stride_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 gen_helper_vsse32_v,  gen_helper_vsse64_v
 };
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 fn = fns[eew];
 if (fn == NULL) {
@@ -836,8 +851,9 @@ static bool ld_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 
 fn = fns[eew][s->sew];
 
+uint8_t emul = vext_get_emul(s, s->sew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, false);
 }
@@ -887,8 +903,9 @@ static bool st_index_op(DisasContext *s, arg_rnfvm *a, 
uint8_t eew)
 
 fn = fns[eew][s->sew];
 
+uint8_t emul = vext_get_emul(s, s->sew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldst_index_trans(a->rd, a->rs1, a->rs2, data, fn, s, true);
 }
@@ -949,8 +966,9 @@ static bool ldff_op(DisasContext *s, arg_r2nfvm *a, uint8_t 
eew)
 return false;
 }
 
+uint8_t emul = vext_get_emul(s, eew);
 data = FIELD_DP32(data, VDATA, VM, a->vm);
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+data = FIELD_DP32(data, VDATA, LMUL, emul);
 data = FIELD_DP32(data, VDATA, NF, a->nf);
 return ldff_trans(a->rd, a->rs1, data, fn, s);
 }
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 9a39a0e2d26..f9919273dca 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -17,6 +17,7 @@
  */
 
 #include "qemu/osdep.h"
+#include "qemu/host-utils.h"
 #include "cpu.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
@@ -116,14 +117,21 @@ static inline int32_t vext_lmul(uint32_t desc)
 }
 
 /*
- * Get vector group length in bytes. Its range is [64, 2048].
+ * Get the maximum number of elements can be operated.
  *
- * As simd_desc support at most 256, the max vlen is 512 bits.
- * So vlen in bytes is encoded as maxsz.
+ * esz: log2 of element size in bytes.
  */
-static inline uint32_t vext_maxsz(uint32_t desc)
+static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
 {
-return simd_maxsz(desc) << vext_lmul(desc);
+/*
+ * As simd_desc support at most 256 bytes, the max vlen is 256 bits.
+ * so vlen in bytes (vlenb)

[PATCH v8 37/78] target/riscv: rvv-1.0: floating-point move instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

NaN-boxed the scalar floating-point register based on RVV 1.0's rules.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 42a9f2764d5..1340ce56806 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2460,9 +2460,15 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 require_rvf(s) &&
 vext_check_isa_ill(s) &&
 require_align(a->rd, s->lmul)) {
+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), cpu_fpr[a->rs1]);
+ MAXSZ(s), MAXSZ(s), t1);
 mark_vs_dirty(s);
 } else {
 TCGv_ptr dest;
@@ -2476,15 +2482,21 @@ static bool trans_vfmv_v_f(DisasContext *s, 
arg_vfmv_v_f *a)
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
+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->vlen / 8, s->vlen / 8, data));
 tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
-fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
+
+fns[s->sew - 1](dest, t1, cpu_env, desc);
 
 tcg_temp_free_ptr(dest);
 mark_vs_dirty(s);
 gen_set_label(over);
 }
+tcg_temp_free_i64(t1);
 return true;
 }
 return false;
-- 
2.25.1




[PATCH v8 42/78] target/riscv: rvv-1.0: single-width bit shift instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Truncate vsll.vi, vsrl.vi, vsra.vi's immediate values to lg2(SEW) bits.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 0fc19b19c69..1fcde9f4df4 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1685,9 +1685,9 @@ GEN_OPIVX_GVEC_SHIFT_TRANS(vsll_vx,  shls)
 GEN_OPIVX_GVEC_SHIFT_TRANS(vsrl_vx,  shrs)
 GEN_OPIVX_GVEC_SHIFT_TRANS(vsra_vx,  sars)
 
-GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_ZX, vsll_vx, shli)
-GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_ZX, vsrl_vx, shri)
-GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_ZX, vsra_vx, sari)
+GEN_OPIVI_GVEC_TRANS(vsll_vi, IMM_TRUNC_SEW, vsll_vx, shli)
+GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, shri)
+GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari)
 
 /* Vector Narrowing Integer Right Shift Instructions */
 static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a)
-- 
2.25.1




[PATCH v8 29/78] target/riscv: rvv-1.0: count population in mask instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 2 +-
 target/riscv/insn32.decode  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 7 ---
 target/riscv/vector_helper.c| 6 +++---
 4 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index b8894d61510..3f30882aec4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1020,7 +1020,7 @@ DEF_HELPER_6(vmnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmornot_mm, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmxnor_mm, void, ptr, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_4(vmpopc_m, tl, ptr, ptr, env, i32)
+DEF_HELPER_4(vcpop_m, tl, ptr, ptr, env, i32)
 
 DEF_HELPER_4(vmfirst_m, tl, ptr, ptr, env, i32)
 
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f61eaf7c6ba..e748f7ca714 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -627,7 +627,7 @@ vmor_mm 011010 - . . 010 . 1010111 @r
 vmnor_mm00 - . . 010 . 1010111 @r
 vmornot_mm  011100 - . . 010 . 1010111 @r
 vmxnor_mm   01 - . . 010 . 1010111 @r
-vmpopc_m010100 . . - 010 . 1010111 @r2_vm
+vcpop_m 01 . . 1 010 . 1010111 @r2_vm
 vmfirst_m   010101 . . - 010 . 1010111 @r2_vm
 vmsbf_m 010110 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010110 . . 00011 010 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 3ba74cdc403..fc17e57d0f7 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2663,8 +2663,8 @@ GEN_MM_TRANS(vmnor_mm)
 GEN_MM_TRANS(vmornot_mm)
 GEN_MM_TRANS(vmxnor_mm)
 
-/* Vector mask population count vmpopc */
-static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
+/* Vector count population in mask vcpop */
+static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s)) {
@@ -2683,11 +2683,12 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
 tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
-gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
+gen_helper_vcpop_m(dst, mask, src2, cpu_env, desc);
 gen_set_gpr(s, a->rd, dst);
 
 tcg_temp_free_ptr(mask);
 tcg_temp_free_ptr(src2);
+
 return true;
 }
 return false;
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f9919273dca..9451112b3da 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4214,9 +4214,9 @@ GEN_VEXT_MASK_VV(vmnor_mm, DO_NOR)
 GEN_VEXT_MASK_VV(vmornot_mm, DO_ORNOT)
 GEN_VEXT_MASK_VV(vmxnor_mm, DO_XNOR)
 
-/* Vector mask population count vmpopc */
-target_ulong HELPER(vmpopc_m)(void *v0, void *vs2, CPURISCVState *env,
-  uint32_t desc)
+/* Vector count population in mask vcpop */
+target_ulong HELPER(vcpop_m)(void *v0, void *vs2, CPURISCVState *env,
+ uint32_t desc)
 {
 target_ulong cnt = 0;
 uint32_t vm = vext_vm(desc);
-- 
2.25.1




[PATCH v8 40/78] target/riscv: rvv-1.0: integer extension instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vzext.vf2
* vzext.vf4
* vzext.vf8
* vsext.vf2
* vsext.vf4
* vsext.vf8

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 14 +
 target/riscv/insn32.decode  |  8 +++
 target/riscv/insn_trans/trans_rvv.c.inc | 80 +
 target/riscv/vector_helper.c| 31 ++
 4 files changed, 133 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index bd0768d048f..878d82caf61 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1072,3 +1072,17 @@ DEF_HELPER_6(vcompress_vm_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf2_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf4_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf4_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vzext_vf8_d, void, ptr, ptr, ptr, env, i32)
+
+DEF_HELPER_5(vsext_vf2_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf2_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf2_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf4_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf4_d, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vsext_vf8_d, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 06a80763112..a6f9e5dcc66 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -655,6 +655,14 @@ vmv2r_v 100111 1 . 1 011 . 1010111 
@r2rd
 vmv4r_v 100111 1 . 00011 011 . 1010111 @r2rd
 vmv8r_v 100111 1 . 00111 011 . 1010111 @r2rd
 
+# Vector Integer Extension
+vzext_vf2   010010 . . 00110 010 . 1010111 @r2_vm
+vzext_vf4   010010 . . 00100 010 . 1010111 @r2_vm
+vzext_vf8   010010 . . 00010 010 . 1010111 @r2_vm
+vsext_vf2   010010 . . 00111 010 . 1010111 @r2_vm
+vsext_vf4   010010 . . 00101 010 . 1010111 @r2_vm
+vsext_vf8   010010 . . 00011 010 . 1010111 @r2_vm
+
 vsetvli 0 ... . 111 . 1010111  @r2_zimm
 vsetvl  100 . . 111 . 1010111  @r
 
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 5eaf978fe90..43cdc846d9f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3283,3 +3283,83 @@ GEN_VMV_WHOLE_TRANS(vmv1r_v, 1)
 GEN_VMV_WHOLE_TRANS(vmv2r_v, 2)
 GEN_VMV_WHOLE_TRANS(vmv4r_v, 4)
 GEN_VMV_WHOLE_TRANS(vmv8r_v, 8)
+
+static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div)
+{
+uint8_t from = (s->sew + 3) - div;
+bool ret = require_rvv(s) &&
+(from >= 3 && from <= 8) &&
+(a->rd != a->rs2) &&
+require_align(a->rd, s->lmul) &&
+require_align(a->rs2, s->lmul - div) &&
+require_vm(a->vm, a->rd) &&
+require_noover(a->rd, s->lmul, a->rs2, s->lmul - div);
+return ret;
+}
+
+static bool int_ext_op(DisasContext *s, arg_rmr *a, uint8_t seq)
+{
+uint32_t data = 0;
+gen_helper_gvec_3_ptr *fn;
+TCGLabel *over = gen_new_label();
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+
+static gen_helper_gvec_3_ptr * const fns[6][4] = {
+{
+NULL, gen_helper_vzext_vf2_h,
+gen_helper_vzext_vf2_w, gen_helper_vzext_vf2_d
+},
+{
+NULL, NULL,
+gen_helper_vzext_vf4_w, gen_helper_vzext_vf4_d,
+},
+{
+NULL, NULL,
+NULL, gen_helper_vzext_vf8_d
+},
+{
+NULL, gen_helper_vsext_vf2_h,
+gen_helper_vsext_vf2_w, gen_helper_vsext_vf2_d
+},
+{
+NULL, NULL,
+gen_helper_vsext_vf4_w, gen_helper_vsext_vf4_d,
+},
+{
+NULL, NULL,
+NULL, gen_helper_vsext_vf8_d
+}
+};
+
+fn = fns[seq][s->sew];
+if (fn == NULL) {
+return false;
+}
+
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs2), cpu_env,
+   s->vlen / 8, s->vlen / 8, data, fn);
+
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+
+/* Vector Integer Extension */
+#define GEN_INT_EXT_TRANS(NAME, DIV, SEQ) \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a) \
+{ \
+if (int_ext_check(s, a, DIV)) {   \
+return int_ext_op(s, a, SEQ); \
+}   

[PATCH v8 26/78] target/riscv: rvv-1.0: take fractional LMUL into vector max elements calculation

2021-10-15 Thread frank . chang
From: Frank Chang 

Update vext_get_vlmax() and MAXSZ() to take fractional LMUL into
calculation for RVV 1.0.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu.h  | 43 ++---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 ++-
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index f958e2f3c0d..9b2af4e4d0e 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -407,18 +407,27 @@ FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 bool riscv_cpu_is_32bit(CPURISCVState *env);
 
 /*
- * A simplification for VLMAX
- * = (1 << LMUL) * VLEN / (8 * (1 << SEW))
- * = (VLEN << LMUL) / (8 << SEW)
- * = (VLEN << LMUL) >> (SEW + 3)
- * = VLEN >> (SEW + 3 - LMUL)
+ * Encode LMUL to lmul as follows:
+ * LMULvlmullmul
+ *  1   000   0
+ *  2   001   1
+ *  4   010   2
+ *  8   011   3
+ *  -   100   -
+ * 1/8  101  -3
+ * 1/4  110  -2
+ * 1/2  111  -1
+ *
+ * then, we can calculate VLMAX = vlen >> (vsew + 3 - lmul)
+ * e.g. vlen = 256 bits, SEW = 16, LMUL = 1/8
+ *  => VLMAX = vlen >> (1 + 3 - (-3))
+ *   = 256 >> 7
+ *   = 2
  */
 static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
 {
-uint8_t sew, lmul;
-
-sew = FIELD_EX64(vtype, VTYPE, VSEW);
-lmul = FIELD_EX64(vtype, VTYPE, VLMUL);
+uint8_t sew = FIELD_EX64(vtype, VTYPE, VSEW);
+int8_t lmul = sextract32(FIELD_EX64(vtype, VTYPE, VLMUL), 0, 3);
 return cpu->cfg.vlen >> (sew + 3 - lmul);
 }
 
@@ -431,12 +440,22 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 *cs_base = 0;
 
 if (riscv_has_ext(env, RVV)) {
+/*
+ * If env->vl equals to VLMAX, we can use generic vector operation
+ * expanders (GVEC) to accerlate the vector operations.
+ * However, as LMUL could be a fractional number. The maximum
+ * vector size can be operated might be less than 8 bytes,
+ * which is not supported by GVEC. So we set vl_eq_vlmax flag to true
+ * only when maxsz >= 8 bytes.
+ */
 uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
-bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
+uint32_t sew = FIELD_EX64(env->vtype, VTYPE, VSEW);
+uint32_t maxsz = vlmax << sew;
+bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl)
+   && (maxsz >= 8);
 flags = FIELD_DP32(flags, TB_FLAGS, VILL,
 FIELD_EX64(env->vtype, VTYPE, VILL));
-flags = FIELD_DP32(flags, TB_FLAGS, SEW,
-FIELD_EX64(env->vtype, VTYPE, VSEW));
+flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
 flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
 FIELD_EX64(env->vtype, VTYPE, VLMUL));
 flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 118591ddda2..3ba74cdc403 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1049,7 +1049,17 @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true)
 /*
  *** Vector Integer Arithmetic Instructions
  */
-#define MAXSZ(s) (s->vlen >> (3 - s->lmul))
+
+/*
+ * MAXSZ returns the maximum vector size can be operated in bytes,
+ * which is used in GVEC IR when vl_eq_vlmax flag is set to true
+ * to accerlate vector operation.
+ */
+static inline uint32_t MAXSZ(DisasContext *s)
+{
+int scale = s->lmul - 3;
+return scale < 0 ? s->vlen >> -scale : s->vlen << scale;
+}
 
 static bool opivv_check(DisasContext *s, arg_rmrr *a)
 {
-- 
2.25.1




[PATCH v8 32/78] target/riscv: rvv-1.0: iota instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode  |  2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 10 --
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index d139c0aade7..3ac5162aeb7 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -632,7 +632,7 @@ vfirst_m01 . . 10001 010 . 1010111 
@r2_vm
 vmsbf_m 010100 . . 1 010 . 1010111 @r2_vm
 vmsif_m 010100 . . 00011 010 . 1010111 @r2_vm
 vmsof_m 010100 . . 00010 010 . 1010111 @r2_vm
-viota_m 010110 . . 1 010 . 1010111 @r2_vm
+viota_m 010100 . . 1 010 . 1010111 @r2_vm
 vid_v   010110 . 0 10001 010 . 1010111 @r1_vm
 vext_x_v001100 1 . . 010 . 1010111 @r
 vmv_s_x 001101 1 0 . 110 . 1010111 @r2
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 538a32a605a..3751496676f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2756,12 +2756,18 @@ GEN_M_TRANS(vmsbf_m)
 GEN_M_TRANS(vmsif_m)
 GEN_M_TRANS(vmsof_m)
 
-/* Vector Iota Instruction */
+/*
+ * Vector Iota Instruction
+ *
+ * 1. The destination register cannot overlap the source register.
+ * 2. If masked, cannot overlap the mask register ('v0').
+ * 3. An illegal instruction exception is raised if vstart is non-zero.
+ */
 static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s) &&
-require_noover(a->rd, s->lmul, a->rs2, 0) &&
+!is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
 require_vm(a->vm, a->rd) &&
 require_align(a->rd, s->lmul)) {
 uint32_t data = 0;
-- 
2.25.1




[PATCH v8 57/78] target/riscv: rvv-1.0: remove vmford.vv and vmford.vf

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 6 --
 target/riscv/insn32.decode  | 2 --
 target/riscv/insn_trans/trans_rvv.c.inc | 2 --
 target/riscv/vector_helper.c| 7 ---
 4 files changed, 17 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index af79570da8f..1727075dce4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -902,12 +902,6 @@ DEF_HELPER_6(vmfgt_vf_d, void, ptr, ptr, i64, ptr, env, 
i32)
 DEF_HELPER_6(vmfge_vf_h, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_w, void, ptr, ptr, i64, ptr, env, i32)
 DEF_HELPER_6(vmfge_vf_d, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_h, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_w, void, ptr, ptr, i64, ptr, env, i32)
-DEF_HELPER_6(vmford_vf_d, void, ptr, ptr, i64, ptr, env, i32)
 
 DEF_HELPER_5(vfclass_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfclass_v_w, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index aee3a6cd01f..82484fda751 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -582,8 +582,6 @@ vmfle_vv011001 . . . 001 . 1010111 @r_vm
 vmfle_vf011001 . . . 101 . 1010111 @r_vm
 vmfgt_vf011101 . . . 101 . 1010111 @r_vm
 vmfge_vf01 . . . 101 . 1010111 @r_vm
-vmford_vv   011010 . . . 001 . 1010111 @r_vm
-vmford_vf   011010 . . . 101 . 1010111 @r_vm
 vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 77cf3682b35..93f94552f5e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2424,7 +2424,6 @@ GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmfne_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmflt_vv, opfvv_cmp_check)
 GEN_OPFVV_TRANS(vmfle_vv, opfvv_cmp_check)
-GEN_OPFVV_TRANS(vmford_vv, opfvv_cmp_check)
 
 static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
 {
@@ -2440,7 +2439,6 @@ GEN_OPFVF_TRANS(vmflt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfle_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfgt_vf, opfvf_cmp_check)
 GEN_OPFVF_TRANS(vmfge_vf, opfvf_cmp_check)
-GEN_OPFVF_TRANS(vmford_vf, opfvf_cmp_check)
 
 /* Vector Floating-Point Classify Instruction */
 GEN_OPFV_TRANS(vfclass_v, opfv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 4840bd938af..dd15010c3da 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3630,13 +3630,6 @@ GEN_VEXT_CMP_VF(vmfge_vf_h, uint16_t, H2, vmfge16)
 GEN_VEXT_CMP_VF(vmfge_vf_w, uint32_t, H4, vmfge32)
 GEN_VEXT_CMP_VF(vmfge_vf_d, uint64_t, H8, vmfge64)
 
-GEN_VEXT_CMP_VV_ENV(vmford_vv_h, uint16_t, H2, !float16_unordered_quiet)
-GEN_VEXT_CMP_VV_ENV(vmford_vv_w, uint32_t, H4, !float32_unordered_quiet)
-GEN_VEXT_CMP_VV_ENV(vmford_vv_d, uint64_t, H8, !float64_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_h, uint16_t, H2, !float16_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_w, uint32_t, H4, !float32_unordered_quiet)
-GEN_VEXT_CMP_VF(vmford_vf_d, uint64_t, H8, !float64_unordered_quiet)
-
 /* Vector Floating-Point Classify Instruction */
 #define OPIVV1(NAME, TD, T2, TX2, HD, HS2, OP) \
 static void do_##NAME(void *vd, void *vs2, int i)  \
-- 
2.25.1




[PATCH v8 43/78] target/riscv: rvv-1.0: integer add-with-carry/subtract-with-borrow

2021-10-15 Thread frank . chang
From: Frank Chang 

* Only do carry-in or borrow-in if is masked (vm=0).
* Remove clear function from helper functions as the tail elements
  are unchanged in RVV 1.0.

Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  | 20 ++--
 target/riscv/insn_trans/trans_rvv.c.inc |  2 +-
 target/riscv/vector_helper.c| 21 ++---
 3 files changed, 17 insertions(+), 26 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f83c8daf24e..9c4089d7a7b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -378,16 +378,16 @@ vwsubu_wv   110110 . . . 010 . 1010111 
@r_vm
 vwsubu_wx   110110 . . . 110 . 1010111 @r_vm
 vwsub_wv110111 . . . 010 . 1010111 @r_vm
 vwsub_wx110111 . . . 110 . 1010111 @r_vm
-vadc_vvm01 1 . . 000 . 1010111 @r_vm_1
-vadc_vxm01 1 . . 100 . 1010111 @r_vm_1
-vadc_vim01 1 . . 011 . 1010111 @r_vm_1
-vmadc_vvm   010001 1 . . 000 . 1010111 @r_vm_1
-vmadc_vxm   010001 1 . . 100 . 1010111 @r_vm_1
-vmadc_vim   010001 1 . . 011 . 1010111 @r_vm_1
-vsbc_vvm010010 1 . . 000 . 1010111 @r_vm_1
-vsbc_vxm010010 1 . . 100 . 1010111 @r_vm_1
-vmsbc_vvm   010011 1 . . 000 . 1010111 @r_vm_1
-vmsbc_vxm   010011 1 . . 100 . 1010111 @r_vm_1
+vadc_vvm01 0 . . 000 . 1010111 @r_vm_1
+vadc_vxm01 0 . . 100 . 1010111 @r_vm_1
+vadc_vim01 0 . . 011 . 1010111 @r_vm_1
+vmadc_vvm   010001 . . . 000 . 1010111 @r_vm
+vmadc_vxm   010001 . . . 100 . 1010111 @r_vm
+vmadc_vim   010001 . . . 011 . 1010111 @r_vm
+vsbc_vvm010010 0 . . 000 . 1010111 @r_vm_1
+vsbc_vxm010010 0 . . 100 . 1010111 @r_vm_1
+vmsbc_vvm   010011 . . . 000 . 1010111 @r_vm
+vmsbc_vxm   010011 . . . 100 . 1010111 @r_vm
 vand_vv 001001 . . . 000 . 1010111 @r_vm
 vand_vx 001001 . . . 100 . 1010111 @r_vm
 vand_vi 001001 . . . 011 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 1fcde9f4df4..f3003d023e5 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1547,7 +1547,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 
 /*
  * For vadc and vsbc, an illegal instruction exception is raised if the
- * destination vector register is v0 and LMUL > 1. (Section 12.3)
+ * destination vector register is v0 and LMUL > 1. (Section 12.4)
  */
 static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a)
 {
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 6891f28116f..54405d898b9 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -944,7 +944,7 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, 
  \
 for (i = 0; i < vl; i++) {\
 ETYPE s1 = *((ETYPE *)vs1 + H(i));\
 ETYPE s2 = *((ETYPE *)vs2 + H(i));\
-uint8_t carry = vext_elem_mask(v0, i);\
+ETYPE carry = vext_elem_mask(v0, i);  \
   \
 *((ETYPE *)vd + H(i)) = DO_OP(s2, s1, carry); \
 } \
@@ -969,7 +969,7 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void 
*vs2,\
  \
 for (i = 0; i < vl; i++) {   \
 ETYPE s2 = *((ETYPE *)vs2 + H(i));   \
-uint8_t carry = vext_elem_mask(v0, i);   \
+ETYPE carry = vext_elem_mask(v0, i); \
  \
 *((ETYPE *)vd + H(i)) = DO_OP(s2, (ETYPE)(target_long)s1, carry);\
 }\
@@ -994,20 +994,15 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
   CPURISCVState *env, uint32_t desc)  \
 { \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
+uint32_t vm = vext_vm(desc);  \
 uint32_t i;   \
   

[PATCH v8 34/78] target/riscv: rvv-1.0: allow load element with sign-extended

2021-10-15 Thread frank . chang
From: Frank Chang 

For some vector instructions (e.g. vmv.s.x), the element is loaded with
sign-extended.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 32 +
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 3751496676f..31ea231b3be 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2824,17 +2824,29 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
 /* Integer Extract Instruction */
 
 static void load_element(TCGv_i64 dest, TCGv_ptr base,
- int ofs, int sew)
+ int ofs, int sew, bool sign)
 {
 switch (sew) {
 case MO_8:
-tcg_gen_ld8u_i64(dest, base, ofs);
+if (!sign) {
+tcg_gen_ld8u_i64(dest, base, ofs);
+} else {
+tcg_gen_ld8s_i64(dest, base, ofs);
+}
 break;
 case MO_16:
-tcg_gen_ld16u_i64(dest, base, ofs);
+if (!sign) {
+tcg_gen_ld16u_i64(dest, base, ofs);
+} else {
+tcg_gen_ld16s_i64(dest, base, ofs);
+}
 break;
 case MO_32:
-tcg_gen_ld32u_i64(dest, base, ofs);
+if (!sign) {
+tcg_gen_ld32u_i64(dest, base, ofs);
+} else {
+tcg_gen_ld32s_i64(dest, base, ofs);
+}
 break;
 case MO_64:
 tcg_gen_ld_i64(dest, base, ofs);
@@ -2889,7 +2901,7 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 
dest,
 
 /* Perform the load. */
 load_element(dest, base,
- vreg_ofs(s, vreg), s->sew);
+ vreg_ofs(s, vreg), s->sew, false);
 tcg_temp_free_ptr(base);
 tcg_temp_free_i32(ofs);
 
@@ -2905,9 +2917,9 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 
dest,
 }
 
 static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
-  int vreg, int idx)
+  int vreg, int idx, bool sign)
 {
-load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew);
+load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
 }
 
 static bool trans_vext_x_v(DisasContext *s, arg_r *a)
@@ -2917,7 +2929,7 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
 
 if (a->rs1 == 0) {
 /* Special case vmv.x.s rd, vs2. */
-vec_element_loadi(s, tmp, a->rs2, 0);
+vec_element_loadi(s, tmp, a->rs2, 0, false);
 } else {
 /* This instruction ignores LMUL and vector register groups */
 int vlmax = s->vlen >> (3 + s->sew);
@@ -2999,7 +3011,7 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s 
*a)
 (s->mstatus_fs != 0) && (s->sew != 0)) {
 unsigned int len = 8 << s->sew;
 
-vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0);
+vec_element_loadi(s, cpu_fpr[a->rd], a->rs2, 0, false);
 if (len < 64) {
 tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd],
 MAKE_64BIT_MASK(len, 64 - len));
@@ -3101,7 +3113,7 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
*a)
 TCGv_i64 dest = tcg_temp_new_i64();
 
 if (a->rs1 == 0) {
-vec_element_loadi(s, dest, a->rs2, 0);
+vec_element_loadi(s, dest, a->rs2, 0, false);
 } else {
 vec_element_loadx(s, dest, a->rs2, cpu_gpr[a->rs1], vlmax);
 }
-- 
2.25.1




[PATCH v8 41/78] target/riscv: rvv-1.0: single-width averaging add and subtract instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vaaddu.vv
* vaaddu.vx
* vasubu.vv
* vasubu.vx

Remove the following instructions:

* vadd.vi

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 16 ++
 target/riscv/insn32.decode  | 13 +++--
 target/riscv/insn_trans/trans_rvv.c.inc |  5 +-
 target/riscv/vector_helper.c| 74 +
 4 files changed, 102 insertions(+), 6 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 878d82caf61..f2e8d107d2f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -648,18 +648,34 @@ DEF_HELPER_6(vaadd_vv_b, void, ptr, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_6(vaadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vasub_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vasubu_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vaadd_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vaaddu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vasub_vx_d, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vasubu_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vsmul_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vsmul_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a6f9e5dcc66..f83c8daf24e 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -493,11 +493,14 @@ vssubu_vv   100010 . . . 000 . 1010111 
@r_vm
 vssubu_vx   100010 . . . 100 . 1010111 @r_vm
 vssub_vv100011 . . . 000 . 1010111 @r_vm
 vssub_vx100011 . . . 100 . 1010111 @r_vm
-vaadd_vv100100 . . . 000 . 1010111 @r_vm
-vaadd_vx100100 . . . 100 . 1010111 @r_vm
-vaadd_vi100100 . . . 011 . 1010111 @r_vm
-vasub_vv100110 . . . 000 . 1010111 @r_vm
-vasub_vx100110 . . . 100 . 1010111 @r_vm
+vaadd_vv001001 . . . 010 . 1010111 @r_vm
+vaadd_vx001001 . . . 110 . 1010111 @r_vm
+vaaddu_vv   001000 . . . 010 . 1010111 @r_vm
+vaaddu_vx   001000 . . . 110 . 1010111 @r_vm
+vasub_vv001011 . . . 010 . 1010111 @r_vm
+vasub_vx001011 . . . 110 . 1010111 @r_vm
+vasubu_vv   001010 . . . 010 . 1010111 @r_vm
+vasubu_vx   001010 . . . 110 . 1010111 @r_vm
 vsmul_vv100111 . . . 000 . 1010111 @r_vm
 vsmul_vx100111 . . . 100 . 1010111 @r_vm
 vwsmaccu_vv 00 . . . 000 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 43cdc846d9f..0fc19b19c69 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2003,10 +2003,13 @@ GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check)
 
 /* Vector Single-Width Averaging Add and Subtract */
 GEN_OPIVV_TRANS(vaadd_vv, opivv_check)
+GEN_OPIVV_TRANS(vaaddu_vv, opivv_check)
 GEN_OPIVV_TRANS(vasub_vv, opivv_check)
+GEN_OPIVV_TRANS(vasubu_vv, opivv_check)
 GEN_OPIVX_TRANS(vaadd_vx,  opivx_check)
+GEN_OPIVX_TRANS(vaaddu_vx,  opivx_check)
 GEN_OPIVX_TRANS(vasub_vx,  opivx_check)
-GEN_OPIVI_TRANS(vaadd_vi, 0, vaadd_vx, opivx_check)
+GEN_OPIVX_TRANS(vasubu_vx,  opivx_check)
 
 /* Vector Single-Width Fractional Multip

[PATCH v8 59/78] target/riscv: rvv-1.0: floating-point min/max instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index dd15010c3da..c19cd937e1a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3387,28 +3387,28 @@ GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4)
 GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8)
 
 /* Vector Floating-Point MIN/MAX Instructions */
-RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum)
-RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum)
-RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum)
+RVVCALL(OPFVV2, vfmin_vv_h, OP_UUU_H, H2, H2, H2, float16_minnum_noprop)
+RVVCALL(OPFVV2, vfmin_vv_w, OP_UUU_W, H4, H4, H4, float32_minnum_noprop)
+RVVCALL(OPFVV2, vfmin_vv_d, OP_UUU_D, H8, H8, H8, float64_minnum_noprop)
 GEN_VEXT_VV_ENV(vfmin_vv_h, 2, 2)
 GEN_VEXT_VV_ENV(vfmin_vv_w, 4, 4)
 GEN_VEXT_VV_ENV(vfmin_vv_d, 8, 8)
-RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum)
-RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum)
-RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum)
+RVVCALL(OPFVF2, vfmin_vf_h, OP_UUU_H, H2, H2, float16_minnum_noprop)
+RVVCALL(OPFVF2, vfmin_vf_w, OP_UUU_W, H4, H4, float32_minnum_noprop)
+RVVCALL(OPFVF2, vfmin_vf_d, OP_UUU_D, H8, H8, float64_minnum_noprop)
 GEN_VEXT_VF(vfmin_vf_h, 2, 2)
 GEN_VEXT_VF(vfmin_vf_w, 4, 4)
 GEN_VEXT_VF(vfmin_vf_d, 8, 8)
 
-RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum)
-RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum)
-RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum)
+RVVCALL(OPFVV2, vfmax_vv_h, OP_UUU_H, H2, H2, H2, float16_maxnum_noprop)
+RVVCALL(OPFVV2, vfmax_vv_w, OP_UUU_W, H4, H4, H4, float32_maxnum_noprop)
+RVVCALL(OPFVV2, vfmax_vv_d, OP_UUU_D, H8, H8, H8, float64_maxnum_noprop)
 GEN_VEXT_VV_ENV(vfmax_vv_h, 2, 2)
 GEN_VEXT_VV_ENV(vfmax_vv_w, 4, 4)
 GEN_VEXT_VV_ENV(vfmax_vv_d, 8, 8)
-RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum)
-RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum)
-RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum)
+RVVCALL(OPFVF2, vfmax_vf_h, OP_UUU_H, H2, H2, float16_maxnum_noprop)
+RVVCALL(OPFVF2, vfmax_vf_w, OP_UUU_W, H4, H4, float32_maxnum_noprop)
+RVVCALL(OPFVF2, vfmax_vf_d, OP_UUU_D, H8, H8, float64_maxnum_noprop)
 GEN_VEXT_VF(vfmax_vf_h, 2, 2)
 GEN_VEXT_VF(vfmax_vf_w, 4, 4)
 GEN_VEXT_VF(vfmax_vf_d, 8, 8)
-- 
2.25.1




[PATCH v8 46/78] target/riscv: rvv-1.0: single-width saturating add and subtract instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Sign-extend vsaddu.vi immediate value.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 65c58fc591f..575d42b68ab 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1998,7 +1998,7 @@ GEN_OPIVX_TRANS(vsaddu_vx,  opivx_check)
 GEN_OPIVX_TRANS(vsadd_vx,  opivx_check)
 GEN_OPIVX_TRANS(vssubu_vx,  opivx_check)
 GEN_OPIVX_TRANS(vssub_vx,  opivx_check)
-GEN_OPIVI_TRANS(vsaddu_vi, IMM_ZX, vsaddu_vx, opivx_check)
+GEN_OPIVI_TRANS(vsaddu_vi, IMM_SX, vsaddu_vx, opivx_check)
 GEN_OPIVI_TRANS(vsadd_vi, IMM_SX, vsadd_vx, opivx_check)
 
 /* Vector Single-Width Averaging Add and Subtract */
-- 
2.25.1




[PATCH v8 35/78] target/riscv: rvv-1.0: register gather instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

* Add vrgatherei16.vv instruction.

Signed-off-by: Frank Chang 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.h   |  4 
 target/riscv/insn32.decode  |  1 +
 target/riscv/insn_trans/trans_rvv.c.inc | 27 ++---
 target/riscv/vector_helper.c| 23 -
 4 files changed, 43 insertions(+), 12 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 7646567eb27..bd0768d048f 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1059,6 +1059,10 @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, 
env, i32)
 DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index ab274dcde12..4653a9679ef 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -645,6 +645,7 @@ vslidedown_vx   00 . . . 100 . 1010111 @r_vm
 vslidedown_vi   00 . . . 011 . 1010111 @r_vm
 vslide1down_vx  00 . . . 110 . 1010111 @r_vm
 vrgather_vv 001100 . . . 000 . 1010111 @r_vm
+vrgatherei16_vv 001110 . . . 000 . 1010111 @r_vm
 vrgather_vx 001100 . . . 100 . 1010111 @r_vm
 vrgather_vi 001100 . . . 011 . 1010111 @r_vm
 vcompress_vm010111 - . . 010 . 1010111 @r
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 31ea231b3be..43da36f4200 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3089,7 +3089,25 @@ static bool vrgather_vv_check(DisasContext *s, arg_rmrr 
*a)
require_vm(a->vm, a->rd);
 }
 
+static bool vrgatherei16_vv_check(DisasContext *s, arg_rmrr *a)
+{
+int8_t emul = MO_16 - s->sew + s->lmul;
+return require_rvv(s) &&
+   vext_check_isa_ill(s) &&
+   (emul >= -3 && emul <= 3) &&
+   require_align(a->rd, s->lmul) &&
+   require_align(a->rs1, emul) &&
+   require_align(a->rs2, s->lmul) &&
+   (a->rd != a->rs2 && a->rd != a->rs1) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
+  a->rs1, 1 << MAX(emul, 0)) &&
+   !is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
+  a->rs2, 1 << MAX(s->lmul, 0)) &&
+   require_vm(a->vm, a->rd);
+}
+
 GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check)
+GEN_OPIVV_TRANS(vrgatherei16_vv, vrgatherei16_vv_check)
 
 static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a)
 {
@@ -3109,7 +3127,8 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-int vlmax = s->vlen;
+int scale = s->lmul - (s->sew + 3);
+int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
 TCGv_i64 dest = tcg_temp_new_i64();
 
 if (a->rs1 == 0) {
@@ -3140,8 +3159,10 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr 
*a)
 }
 
 if (a->vm && s->vl_eq_vlmax) {
-if (a->rs1 >= s->vlen) {
-tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd),
+int scale = s->lmul - (s->sew + 3);
+int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
+if (a->rs1 >= vlmax) {
+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),
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index b0dc971a860..86d03d8e395 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4460,11 +4460,11 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4)
 GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8)
 
 /* Vector Register Gather Instruction */
-#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H)  \
+#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2)\
 void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2,   \
   CPURISCVState *env, uint32_t desc)  \
 { \
-uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));   \
+uint32_t vlmax = vext_max_elems(desc, ctzl(siz

[PATCH v8 44/78] target/riscv: rvv-1.0: narrowing integer right shift instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 24 +++---
 target/riscv/insn32.decode  | 12 +++
 target/riscv/insn_trans/trans_rvv.c.inc | 42 -
 target/riscv/vector_helper.c| 24 +++---
 4 files changed, 51 insertions(+), 51 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index f2e8d107d2f..304c12494d4 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -351,18 +351,18 @@ DEF_HELPER_6(vsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vsra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
-DEF_HELPER_6(vnsrl_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsra_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsrl_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnsra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsra_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsrl_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnsra_wx_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vmseq_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vmseq_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 9c4089d7a7b..a3f1101cd63 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -406,12 +406,12 @@ vsrl_vi 101000 . . . 011 . 1010111 
@r_vm
 vsra_vv 101001 . . . 000 . 1010111 @r_vm
 vsra_vx 101001 . . . 100 . 1010111 @r_vm
 vsra_vi 101001 . . . 011 . 1010111 @r_vm
-vnsrl_vv101100 . . . 000 . 1010111 @r_vm
-vnsrl_vx101100 . . . 100 . 1010111 @r_vm
-vnsrl_vi101100 . . . 011 . 1010111 @r_vm
-vnsra_vv101101 . . . 000 . 1010111 @r_vm
-vnsra_vx101101 . . . 100 . 1010111 @r_vm
-vnsra_vi101101 . . . 011 . 1010111 @r_vm
+vnsrl_wv101100 . . . 000 . 1010111 @r_vm
+vnsrl_wx101100 . . . 100 . 1010111 @r_vm
+vnsrl_wi101100 . . . 011 . 1010111 @r_vm
+vnsra_wv101101 . . . 000 . 1010111 @r_vm
+vnsra_wx101101 . . . 100 . 1010111 @r_vm
+vnsra_wi101101 . . . 011 . 1010111 @r_vm
 vmseq_vv011000 . . . 000 . 1010111 @r_vm
 vmseq_vx011000 . . . 100 . 1010111 @r_vm
 vmseq_vi011000 . . . 011 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index f3003d023e5..65c58fc591f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1690,7 +1690,7 @@ GEN_OPIVI_GVEC_TRANS(vsrl_vi, IMM_TRUNC_SEW, vsrl_vx, 
shri)
 GEN_OPIVI_GVEC_TRANS(vsra_vi, IMM_TRUNC_SEW, vsra_vx, sari)
 
 /* Vector Narrowing Integer Right Shift Instructions */
-static bool opivv_narrow_check(DisasContext *s, arg_rmrr *a)
+static bool opiwv_narrow_check(DisasContext *s, arg_rmrr *a)
 {
 return require_rvv(s) &&
vext_check_isa_ill(s) &&
@@ -1698,10 +1698,10 @@ static bool opivv_narrow_check(DisasContext *s, 
arg_rmrr *a)
 }
 
 /* OPIVV with NARROW */
-#define GEN_OPIVV_NARROW_TRANS(NAME)   \
+#define GEN_OPIWV_NARROW_TRANS(NAME)   \
 static bool trans_##NAME(DisasContext *s, arg_rmrr *a) \
 {  \
-if (opivv_narrow_check(s, a)) {\
+if (opiwv_narrow_check(s, a)) {\
 uint32_t data = 0; \
 static gen_helper_gvec_4_ptr * const fns[3] =

[PATCH v8 60/78] target/riscv: introduce floating-point rounding mode enum

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/fpu_helper.c   | 12 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 18 +-
 target/riscv/internals.h|  9 +
 3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index f90f7dca59c..43ce6148313 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -55,23 +55,23 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
rm)
 {
 int softrm;
 
-if (rm == 7) {
+if (rm == RISCV_FRM_DYN) {
 rm = env->frm;
 }
 switch (rm) {
-case 0:
+case RISCV_FRM_RNE:
 softrm = float_round_nearest_even;
 break;
-case 1:
+case RISCV_FRM_RTZ:
 softrm = float_round_to_zero;
 break;
-case 2:
+case RISCV_FRM_RDN:
 softrm = float_round_down;
 break;
-case 3:
+case RISCV_FRM_RUP:
 softrm = float_round_up;
 break;
-case 4:
+case RISCV_FRM_RMM:
 softrm = float_round_ties_away;
 break;
 default:
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index e113e002962..676336a5200 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2087,7 +2087,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_d, \
 }; \
 TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, 7);  \
+gen_set_rm(s, RISCV_FRM_DYN);  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -2166,7 +2166,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
\
 gen_helper_##NAME##_w,\
 gen_helper_##NAME##_d,\
 };\
-gen_set_rm(s, 7); \
+gen_set_rm(s, RISCV_FRM_DYN); \
 data = FIELD_DP32(data, VDATA, VM, a->vm);\
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);\
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,   \
@@ -2198,7 +2198,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
 TCGLabel *over = gen_new_label();\
-gen_set_rm(s, 7);\
+gen_set_rm(s, RISCV_FRM_DYN);\
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);\
  \
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
@@ -2235,7 +2235,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 static gen_helper_opfvf *const fns[2] = {\
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
-gen_set_rm(s, 7);\
+gen_set_rm(s, RISCV_FRM_DYN);\
 data = FIELD_DP32(data, VDATA, VM, a->vm);   \
 data = FIELD_DP32(data, VDATA, LMUL, s->lmul);   \
 return opfvf_trans(a->rd, a->rs1, a->rs2, data,  \
@@ -2265,7 +2265,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,  \
 }; \
 TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, 7);  \
+gen_set_rm(s, RISCV_FRM_DYN);  \
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
\
 data = FIELD_DP32(data, VDATA, VM, a->vm); \
@@ -2302,7 +2302,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
   \
 static gen_helper_opfvf *const fns[2] = {\
 gen_helper_##NAME##_h, gen_helper_##NAME##_w,\
 };   \
-gen_set_rm(s, 7);\
+gen_set_rm(s, R

[PATCH v8 48/78] target/riscv: rvv-1.0: floating-point compare instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 9 -
 1 file changed, 9 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 277a5e4120a..71d7b1e8796 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -3710,8 +3710,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
 uint32_t i;   \
   \
 for (i = 0; i < vl; i++) {\
@@ -3723,9 +3721,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 vext_set_elem_mask(vd, i, \
DO_OP(s2, s1, &env->fp_status));   \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 GEN_VEXT_CMP_VV_ENV(vmfeq_vv_h, uint16_t, H2, float16_eq_quiet)
@@ -3738,7 +3733,6 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
 uint32_t i; \
 \
 for (i = 0; i < vl; i++) {  \
@@ -3749,9 +3743,6 @@ void HELPER(NAME)(void *vd, void *v0, uint64_t s1, void 
*vs2,   \
 vext_set_elem_mask(vd, i,   \
DO_OP(s2, (ETYPE)s1, &env->fp_status));  \
 }   \
-for (; i < vlmax; i++) {\
-vext_set_elem_mask(vd, i, 0);   \
-}   \
 }
 
 GEN_VEXT_CMP_VF(vmfeq_vf_h, uint16_t, H2, float16_eq_quiet)
-- 
2.25.1




[PATCH v8 49/78] target/riscv: rvv-1.0: mask-register logical instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 3 ++-
 target/riscv/vector_helper.c| 4 
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 2fe8f4a3c2f..e59fc5a01d8 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2651,7 +2651,8 @@ GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
 #define GEN_MM_TRANS(NAME) \
 static bool trans_##NAME(DisasContext *s, arg_r *a)\
 {  \
-if (vext_check_isa_ill(s)) {   \
+if (require_rvv(s) &&  \
+vext_check_isa_ill(s)) {   \
 uint32_t data = 0; \
 gen_helper_gvec_4_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 71d7b1e8796..f883fdf4749 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4231,7 +4231,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
   void *vs2, CPURISCVState *env,  \
   uint32_t desc)  \
 { \
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;  \
 uint32_t vl = env->vl;\
 uint32_t i;   \
 int a, b; \
@@ -4241,9 +4240,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1,  
\
 b = vext_elem_mask(vs2, i);   \
 vext_set_elem_mask(vd, i, OP(b, a));  \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 #define DO_NAND(N, M)  (!(N & M))
-- 
2.25.1




[PATCH v8 45/78] target/riscv: rvv-1.0: widening integer multiply-add instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index a3f1101cd63..7548b71efdb 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -474,9 +474,9 @@ vwmaccu_vv  00 . . . 010 . 1010111 @r_vm
 vwmaccu_vx  00 . . . 110 . 1010111 @r_vm
 vwmacc_vv   01 . . . 010 . 1010111 @r_vm
 vwmacc_vx   01 . . . 110 . 1010111 @r_vm
-vwmaccsu_vv 10 . . . 010 . 1010111 @r_vm
-vwmaccsu_vx 10 . . . 110 . 1010111 @r_vm
-vwmaccus_vx 11 . . . 110 . 1010111 @r_vm
+vwmaccsu_vv 11 . . . 010 . 1010111 @r_vm
+vwmaccsu_vx 11 . . . 110 . 1010111 @r_vm
+vwmaccus_vx 10 . . . 110 . 1010111 @r_vm
 vmv_v_v 010111 1 0 . 000 . 1010111 @r2
 vmv_v_x 010111 1 0 . 100 . 1010111 @r2
 vmv_v_i 010111 1 0 . 011 . 1010111 @r2
-- 
2.25.1




[PATCH v8 63/78] target/riscv: add "set round to odd" rounding mode helper function

2021-10-15 Thread frank . chang
From: Frank Chang 

helper_set_rounding_mode() is responsible for SIGILL, and "round to odd"
should be an interface private to translation, so add a new independent
helper_set_rod_rounding_mode().

Signed-off-by: Frank Chang 
---
 target/riscv/fpu_helper.c | 5 +
 target/riscv/helper.h | 1 +
 target/riscv/internals.h  | 1 +
 target/riscv/translate.c  | 7 +++
 4 files changed, 14 insertions(+)

diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 43ce6148313..cf21097b5fb 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -81,6 +81,11 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t 
rm)
 set_float_rounding_mode(softrm, &env->fp_status);
 }
 
+void helper_set_rod_rounding_mode(CPURISCVState *env)
+{
+set_float_rounding_mode(float_round_to_odd, &env->fp_status);
+}
+
 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
uint64_t rs3, int flags)
 {
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 53cf88cd402..606bf72d5cb 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
 
 /* Floating Point - fused */
 DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index db105d4d640..065e8162a2f 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -43,6 +43,7 @@ enum {
 RISCV_FRM_RUP = 3,  /* Round Up */
 RISCV_FRM_RMM = 4,  /* Round to Nearest, ties to Max Magnitude */
 RISCV_FRM_DYN = 7,  /* Dynamic rounding mode */
+RISCV_FRM_ROD = 8,  /* Round to Odd */
 };
 
 static inline uint64_t nanbox_s(float32 f)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6a3f105d431..6fa7e016e22 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -30,6 +30,7 @@
 #include "exec/log.h"
 
 #include "instmap.h"
+#include "internals.h"
 
 /* global register indices */
 static TCGv cpu_gpr[32], cpu_pc, cpu_vl;
@@ -382,6 +383,12 @@ static void gen_set_rm(DisasContext *ctx, int rm)
 return;
 }
 ctx->frm = rm;
+
+if (rm == RISCV_FRM_ROD) {
+gen_helper_set_rod_rounding_mode(cpu_env);
+return;
+}
+
 gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
 }
 
-- 
2.25.1




[PATCH v8 50/78] target/riscv: rvv-1.0: slide instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

* Remove clear function from helper functions as the tail elements
  are unchanged in RVV 1.0.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/vector_helper.c | 19 ---
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index f883fdf4749..d79f59e443e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4430,17 +4430,22 @@ GEN_VEXT_VSLIDEUP_VX(vslideup_vx_d, uint64_t, H8)
 void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
   CPURISCVState *env, uint32_t desc)  \
 { \
-uint32_t vlmax = env_archcpu(env)->cfg.vlen;  \
+uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE)));   \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-target_ulong offset = s1, i;  \
+target_ulong i_max, i;\
   \
-for (i = 0; i < vl; ++i) {\
-target_ulong j = i + offset;  \
-if (!vm && !vext_elem_mask(v0, i)) {  \
-continue; \
+i_max = MIN(s1 < vlmax ? vlmax - s1 : 0, vl); \
+for (i = 0; i < i_max; ++i) { \
+if (vm || vext_elem_mask(v0, i)) {\
+*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i + s1));  \
+} \
+} \
+  \
+for (i = i_max; i < vl; ++i) {\
+if (vm || vext_elem_mask(v0, i)) {\
+*((ETYPE *)vd + H(i)) = 0;\
 } \
-*((ETYPE *)vd + H(i)) = j >= vlmax ? 0 : *((ETYPE *)vs2 + H(j));  \
 } \
 }
 
-- 
2.25.1




[PATCH v8 51/78] target/riscv: rvv-1.0: floating-point slide instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfslide1up.vf
* vfslide1down.vf

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |   7 ++
 target/riscv/insn32.decode  |   2 +
 target/riscv/insn_trans/trans_rvv.c.inc |  16 +++
 target/riscv/vector_helper.c| 141 
 4 files changed, 121 insertions(+), 45 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 304c12494d4..012d0343771 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -1071,6 +1071,13 @@ DEF_HELPER_6(vslide1down_vx_h, void, ptr, ptr, tl, ptr, 
env, i32)
 DEF_HELPER_6(vslide1down_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vslide1down_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
+DEF_HELPER_6(vfslide1up_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1up_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1up_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_h, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_w, void, ptr, ptr, i64, ptr, env, i32)
+DEF_HELPER_6(vfslide1down_vf_d, void, ptr, ptr, i64, ptr, env, i32)
+
 DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 7548b71efdb..c5cc14c45c4 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -577,6 +577,8 @@ vfsgnjn_vv  001001 . . . 001 . 1010111 @r_vm
 vfsgnjn_vf  001001 . . . 101 . 1010111 @r_vm
 vfsgnjx_vv  001010 . . . 001 . 1010111 @r_vm
 vfsgnjx_vf  001010 . . . 101 . 1010111 @r_vm
+vfslide1up_vf   001110 . . . 101 . 1010111 @r_vm
+vfslide1down_vf 00 . . . 101 . 1010111 @r_vm
 vmfeq_vv011000 . . . 001 . 1010111 @r_vm
 vmfeq_vf011000 . . . 101 . 1010111 @r_vm
 vmfne_vv011100 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index e59fc5a01d8..7ee1e122e8e 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -3120,6 +3120,22 @@ GEN_OPIVX_TRANS(vslidedown_vx, slidedown_check)
 GEN_OPIVX_TRANS(vslide1down_vx, slidedown_check)
 GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check)
 
+/* Vector Floating-Point Slide Instructions */
+static bool fslideup_check(DisasContext *s, arg_rmrr *a)
+{
+return slideup_check(s, a) &&
+   require_rvf(s);
+}
+
+static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
+{
+return slidedown_check(s, a) &&
+   require_rvf(s);
+}
+
+GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check)
+GEN_OPFVF_TRANS(vfslide1down_vf, fslidedown_check)
+
 /* Vector Register Gather Instruction */
 static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
 {
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index d79f59e443e..7fa5189af4e 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4455,57 +4455,108 @@ GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_h, uint16_t, H2)
 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_w, uint32_t, H4)
 GEN_VEXT_VSLIDEDOWN_VX(vslidedown_vx_d, uint64_t, H8)
 
-#define GEN_VEXT_VSLIDE1UP_VX(NAME, ETYPE, H) \
-void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \
-  CPURISCVState *env, uint32_t desc)  \
-{ \
-uint32_t vm = vext_vm(desc);  \
-uint32_t vl = env->vl;\
-uint32_t i;   \
-  \
-for (i = 0; i < vl; i++) {\
-if (!vm && !vext_elem_mask(v0, i)) {  \
-continue; \
-} \
-if (i == 0) { \
-*((ETYPE *)vd + H(i)) = s1;   \
-} else {  \
-*((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(i - 1));   \
-} \
-} \
+#define GEN_VEXT_VSLIE1UP(ESZ, H)   \
+static void vslide1up_##ESZ(void *vd, void *v0, target_ulong s1, void *vs2, \
+ 

[PATCH v8 47/78] target/riscv: rvv-1.0: integer comparison instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

* Sign-extend vmselu.vi and vmsgtu.vi immediate values.
* Remove "set tail elements to zeros" as tail elements can be unchanged
  for either VTA to have undisturbed or agnostic setting.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 9 -
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 575d42b68ab..2fe8f4a3c2f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1809,9 +1809,9 @@ GEN_OPIVX_TRANS(vmsgt_vx, opivx_cmp_check)
 
 GEN_OPIVI_TRANS(vmseq_vi, IMM_SX, vmseq_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsne_vi, IMM_SX, vmsne_vx, opivx_cmp_check)
-GEN_OPIVI_TRANS(vmsleu_vi, IMM_ZX, vmsleu_vx, opivx_cmp_check)
+GEN_OPIVI_TRANS(vmsleu_vi, IMM_SX, vmsleu_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsle_vi, IMM_SX, vmsle_vx, opivx_cmp_check)
-GEN_OPIVI_TRANS(vmsgtu_vi, IMM_ZX, vmsgtu_vx, opivx_cmp_check)
+GEN_OPIVI_TRANS(vmsgtu_vi, IMM_SX, vmsgtu_vx, opivx_cmp_check)
 GEN_OPIVI_TRANS(vmsgt_vi, IMM_SX, vmsgt_vx, opivx_cmp_check)
 
 /* Vector Integer Min/Max Instructions */
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index e885d4d3539..277a5e4120a 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -1190,8 +1190,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 { \
 uint32_t vm = vext_vm(desc);  \
 uint32_t vl = env->vl;\
-uint32_t vlmax = vext_max_elems(desc, \
-ctzl(sizeof(ETYPE))); \
 uint32_t i;   \
   \
 for (i = 0; i < vl; i++) {\
@@ -1202,9 +1200,6 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void 
*vs2,   \
 } \
 vext_set_elem_mask(vd, i, DO_OP(s2, s1)); \
 } \
-for (; i < vlmax; i++) {  \
-vext_set_elem_mask(vd, i, 0); \
-} \
 }
 
 GEN_VEXT_CMP_VV(vmseq_vv_b, uint8_t,  H1, DO_MSEQ)
@@ -1243,7 +1238,6 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 {   \
 uint32_t vm = vext_vm(desc);\
 uint32_t vl = env->vl;  \
-uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \
 uint32_t i; \
 \
 for (i = 0; i < vl; i++) {  \
@@ -1254,9 +1248,6 @@ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, 
void *vs2,   \
 vext_set_elem_mask(vd, i,   \
 DO_OP(s2, (ETYPE)(target_long)s1)); \
 }   \
-for (; i < vlmax; i++) {\
-vext_set_elem_mask(vd, i, 0);   \
-}   \
 }
 
 GEN_VEXT_CMP_VX(vmseq_vx_b, uint8_t,  H1, DO_MSEQ)
-- 
2.25.1




[PATCH v8 64/78] target/riscv: rvv-1.0: narrowing floating-point/integer type-convert

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   | 22 -
 target/riscv/insn32.decode  | 15 ---
 target/riscv/insn_trans/trans_rvv.c.inc | 59 +
 target/riscv/vector_helper.c| 45 ++-
 4 files changed, 97 insertions(+), 44 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 606bf72d5cb..1a0d817f0f5 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -938,16 +938,18 @@ DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
 
-DEF_HELPER_5(vfncvt_xu_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
-DEF_HELPER_5(vfncvt_f_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_xu_f_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_b, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_x_f_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_xu_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_x_w_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_w_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfncvt_f_f_w_w, void, ptr, ptr, ptr, env, i32)
 
 DEF_HELPER_6(vredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 664d0fb3716..c4fdc76a269 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -600,11 +600,16 @@ vfwcvt_f_x_v   010010 . . 01011 001 . 1010111 
@r2_vm
 vfwcvt_f_f_v   010010 . . 01100 001 . 1010111 @r2_vm
 vfwcvt_rtz_xu_f_v  010010 . . 01110 001 . 1010111 @r2_vm
 vfwcvt_rtz_x_f_v   010010 . . 0 001 . 1010111 @r2_vm
-vfncvt_xu_f_v   100010 . . 1 001 . 1010111 @r2_vm
-vfncvt_x_f_v100010 . . 10001 001 . 1010111 @r2_vm
-vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
-vfncvt_f_x_v100010 . . 10011 001 . 1010111 @r2_vm
-vfncvt_f_f_v100010 . . 10100 001 . 1010111 @r2_vm
+
+vfncvt_xu_f_w  010010 . . 1 001 . 1010111 @r2_vm
+vfncvt_x_f_w   010010 . . 10001 001 . 1010111 @r2_vm
+vfncvt_f_xu_w  010010 . . 10010 001 . 1010111 @r2_vm
+vfncvt_f_x_w   010010 . . 10011 001 . 1010111 @r2_vm
+vfncvt_f_f_w   010010 . . 10100 001 . 1010111 @r2_vm
+vfncvt_rod_f_f_w   010010 . . 10101 001 . 1010111 @r2_vm
+vfncvt_rtz_xu_f_w  010010 . . 10110 001 . 1010111 @r2_vm
+vfncvt_rtz_x_f_w   010010 . . 10111 001 . 1010111 @r2_vm
+
 vredsum_vs  00 . . . 010 . 1010111 @r_vm
 vredand_vs  01 . . . 010 . 1010111 @r_vm
 vredor_vs   10 . . . 010 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 63d33b22068..92a23b52e49 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2622,17 +2622,17 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr 
*a)
vext_check_sd(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_NARROW_TRANS(NAME)\
+#define GEN_OPFV_NARROW_TRANS(NAME, HELPER, FRM)   \
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_narrow_check(s, a)) { \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
-gen_helper_##NAME##_h, \
-gen_helper_##NAME##_w, \
+gen_helper_##HELPER##_h,   \
+gen_helper_##HELPER##_w,   \
 }; \
 TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, RISCV_FRM_DYN

[PATCH v8 58/78] target/riscv: rvv-1.0: remove integer extract instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn32.decode  |  1 -
 target/riscv/insn_trans/trans_rvv.c.inc | 23 ---
 2 files changed, 24 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 82484fda751..20b3095f56c 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -632,7 +632,6 @@ viota_m 010100 . . 1 010 . 1010111 
@r2_vm
 vid_v   010100 . 0 10001 010 . 1010111 @r1_vm
 vmv_x_s 01 1 . 0 010 . 1010111 @r2rd
 vmv_s_x 01 1 0 . 110 . 1010111 @r2
-vext_x_v001100 1 . . 010 . 1010111 @r
 vfmv_f_s01 1 . 0 001 . 1010111 @r2rd
 vfmv_s_f01 1 0 . 101 . 1010111 @r2
 vslideup_vx 001110 . . . 100 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 93f94552f5e..e113e002962 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2839,8 +2839,6 @@ static bool trans_vid_v(DisasContext *s, arg_vid_v *a)
  *** Vector Permutation Instructions
  */
 
-/* Integer Extract Instruction */
-
 static void load_element(TCGv_i64 dest, TCGv_ptr base,
  int ofs, int sew, bool sign)
 {
@@ -2940,27 +2938,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 
dest,
 load_element(dest, cpu_env, endian_ofs(s, vreg, idx), s->sew, sign);
 }
 
-static bool trans_vext_x_v(DisasContext *s, arg_r *a)
-{
-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. */
-vec_element_loadi(s, tmp, a->rs2, 0, false);
-} else {
-/* This instruction ignores LMUL and vector register groups */
-int vlmax = s->vlen >> (3 + s->sew);
-vec_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_temp_free_i64(tmp);
-return true;
-}
-
 /* Integer Scalar Move Instruction */
 
 static void store_element(TCGv_i64 val, TCGv_ptr base,
-- 
2.25.1




[PATCH v8 67/78] target/riscv: rvv-1.0: trigger illegal instruction exception if frm is not valid

2021-10-15 Thread frank . chang
From: Frank Chang 

If the frm field contains an invalid rounding mode (101-111),
attempting to execute any vector floating-point instruction, even
those that do not depend on the rounding mode, will raise an illegal
instruction exception.

Call gen_set_rm() with DYN rounding mode to check and trigger illegal
instruction exception if frm field contains invalid value at run-time
for vector floating-point instructions.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ebdea84fef9..09ae8fad90a 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2373,6 +2373,10 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
 int rm)
 {
 if (checkfn(s, a)) {
+if (rm != RISCV_FRM_DYN) {
+gen_set_rm(s, RISCV_FRM_DYN);
+}
+
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 gen_set_rm(s, rm);
@@ -2458,6 +2462,8 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f 
*a)
 require_rvf(s) &&
 vext_check_isa_ill(s) &&
 require_align(a->rd, s->lmul)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 TCGv_i64 t1;
 
 if (s->vl_eq_vlmax) {
@@ -2539,6 +2545,10 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_widen_check(s, a)) {  \
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
 gen_helper_##HELPER##_h,   \
@@ -2626,6 +2636,10 @@ static bool opfv_narrow_check(DisasContext *s, arg_rmr 
*a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_narrow_check(s, a)) { \
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
 gen_helper_##HELPER##_h,   \
@@ -2667,6 +2681,10 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr 
*a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opxfv_narrow_check(s, a)) {\
+if (FRM != RISCV_FRM_DYN) {\
+gen_set_rm(s, RISCV_FRM_DYN);  \
+}  \
+   \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[3] = {\
 gen_helper_##HELPER##_b,   \
@@ -3137,6 +3155,8 @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s 
*a)
 if (require_rvv(s) &&
 require_rvf(s) &&
 vext_check_isa_ill(s)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 unsigned int ofs = (8 << s->sew);
 unsigned int len = 64 - ofs;
 TCGv_i64 t_nan;
@@ -3161,6 +3181,8 @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f 
*a)
 if (require_rvv(s) &&
 require_rvf(s) &&
 vext_check_isa_ill(s)) {
+gen_set_rm(s, RISCV_FRM_DYN);
+
 /* The instructions ignore LMUL and vector register group. */
 TCGv_i64 t1;
 TCGLabel *over = gen_new_label();
-- 
2.25.1




[PATCH v8 52/78] target/riscv: rvv-1.0: narrowing fixed-point clip instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/helper.h   | 24 ++--
 target/riscv/insn32.decode  | 12 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 +++---
 target/riscv/vector_helper.c| 52 -
 4 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 012d0343771..3ea21b4a578 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -725,18 +725,18 @@ DEF_HELPER_6(vssra_vx_h, void, ptr, ptr, tl, ptr, env, 
i32)
 DEF_HELPER_6(vssra_vx_w, void, ptr, ptr, tl, ptr, env, i32)
 DEF_HELPER_6(vssra_vx_d, void, ptr, ptr, tl, ptr, env, i32)
 
-DEF_HELPER_6(vnclip_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclip_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclip_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_b, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclipu_vx_w, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_b, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_h, void, ptr, ptr, tl, ptr, env, i32)
-DEF_HELPER_6(vnclip_vx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclip_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_b, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_h, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wv_w, void, ptr, ptr, ptr, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclipu_wx_w, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_b, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_h, void, ptr, ptr, tl, ptr, env, i32)
+DEF_HELPER_6(vnclip_wx_w, void, ptr, ptr, tl, ptr, env, i32)
 
 DEF_HELPER_6(vfadd_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfadd_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c5cc14c45c4..eeab6b00a1b 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -516,12 +516,12 @@ vssrl_vi101010 . . . 011 . 1010111 
@r_vm
 vssra_vv101011 . . . 000 . 1010111 @r_vm
 vssra_vx101011 . . . 100 . 1010111 @r_vm
 vssra_vi101011 . . . 011 . 1010111 @r_vm
-vnclipu_vv  101110 . . . 000 . 1010111 @r_vm
-vnclipu_vx  101110 . . . 100 . 1010111 @r_vm
-vnclipu_vi  101110 . . . 011 . 1010111 @r_vm
-vnclip_vv   10 . . . 000 . 1010111 @r_vm
-vnclip_vx   10 . . . 100 . 1010111 @r_vm
-vnclip_vi   10 . . . 011 . 1010111 @r_vm
+vnclipu_wv  101110 . . . 000 . 1010111 @r_vm
+vnclipu_wx  101110 . . . 100 . 1010111 @r_vm
+vnclipu_wi  101110 . . . 011 . 1010111 @r_vm
+vnclip_wv   10 . . . 000 . 1010111 @r_vm
+vnclip_wx   10 . . . 100 . 1010111 @r_vm
+vnclip_wi   10 . . . 011 . 1010111 @r_vm
 vfadd_vv00 . . . 001 . 1010111 @r_vm
 vfadd_vf00 . . . 101 . 1010111 @r_vm
 vfsub_vv10 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 7ee1e122e8e..ef54f8e04fa 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2033,12 +2033,12 @@ GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check)
 GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check)
 
 /* Vector Narrowing Fixed-Point Clip Instructions */
-GEN_OPIWV_NARROW_TRANS(vnclipu_vv)
-GEN_OPIWV_NARROW_TRANS(vnclip_vv)
-GEN_OPIWX_NARROW_TRANS(vnclipu_vx)
-GEN_OPIWX_NARROW_TRANS(vnclip_vx)
-GEN_OPIWI_NARROW_TRANS(vnclipu_vi, IMM_ZX, vnclipu_vx)
-GEN_OPIWI_NARROW_TRANS(vnclip_vi, IMM_ZX, vnclip_vx)
+GEN_OPIWV_NARROW_TRANS(vnclipu_wv)
+GEN_OPIWV_NARROW_TRANS(vnclip_wv)
+GEN_OPIWX_NARROW_TRANS(vnclipu_wx)
+GEN_OPIWX_NARROW_TRANS(vnclip_wx)
+GEN_OPIWI_NARROW_TRANS(vnclipu_wi, IMM_ZX, vnclipu_wx)
+GEN_OPIWI_NARROW_TRANS(vnclip_wi, IMM_ZX, vnclip_wx)
 
 /*
  *** Vector Float Point Arithmetic Instructions
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 7fa5189af4e..c95c8bd9db3 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -2875,19 +2875,19 @@ vnclip32(CPURISCVState *env, int vxrm, int64_t a, 
int32_t b)
 }

[PATCH v8 65/78] target/riscv: rvv-1.0: relax RV_VLEN_MAX to 1024-bits

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 

--
---
 target/riscv/cpu.h  | 2 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 target/riscv/vector_helper.c| 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9b2af4e4d0e..49eece111e2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -101,7 +101,7 @@ typedef struct CPURISCVState CPURISCVState;
 #include "pmp.h"
 #endif
 
-#define RV_VLEN_MAX 256
+#define RV_VLEN_MAX 1024
 
 FIELD(VTYPE, VLMUL, 0, 3)
 FIELD(VTYPE, VSEW, 3, 3)
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 92a23b52e49..dcb96c954ec 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -567,8 +567,8 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, 
uint32_t data,
 base = get_gpr(s, rs1, EXT_NONE);
 
 /*
- * As simd_desc supports at most 256 bytes, and in this implementation,
- * the max vector group length is 2048 bytes. So split it into two parts.
+ * As simd_desc supports at most 2048 bytes, and in this implementation,
+ * the max vector group length is 4096 bytes. So split it into two parts.
  *
  * The first part is vlen in bytes, encoded in maxsz of simd_desc.
  * The second part is lmul, encoded in data of simd_desc.
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index 37b2451bd05..70ddc55e16b 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -124,7 +124,7 @@ static inline int32_t vext_lmul(uint32_t desc)
 static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
 {
 /*
- * As simd_desc support at most 256 bytes, the max vlen is 256 bits.
+ * As simd_desc support at most 2048 bytes, the max vlen is 1024 bits.
  * so vlen in bytes (vlenb) is encoded as maxsz.
  */
 uint32_t vlenb = simd_maxsz(desc);
-- 
2.25.1




[PATCH v8 72/78] target/riscv: set mstatus.SD bit when writing fp CSRs

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
---
 target/riscv/csr.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9f51626a3d8..3929abb112a 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -224,7 +224,8 @@ static RISCVException write_fflags(CPURISCVState *env, int 
csrno,
target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+target_ulong sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
+env->mstatus |= MSTATUS_FS | sd;
 #endif
 riscv_cpu_set_fflags(env, val & (FSR_AEXC >> FSR_AEXC_SHIFT));
 return RISCV_EXCP_NONE;
@@ -241,7 +242,8 @@ static RISCVException write_frm(CPURISCVState *env, int 
csrno,
 target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+target_ulong sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
+env->mstatus |= MSTATUS_FS | sd;
 #endif
 env->frm = val & (FSR_RD >> FSR_RD_SHIFT);
 return RISCV_EXCP_NONE;
@@ -259,7 +261,8 @@ static RISCVException write_fcsr(CPURISCVState *env, int 
csrno,
  target_ulong val)
 {
 #if !defined(CONFIG_USER_ONLY)
-env->mstatus |= MSTATUS_FS;
+target_ulong sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
+env->mstatus |= MSTATUS_FS | sd;
 #endif
 env->frm = (val & FSR_RD) >> FSR_RD_SHIFT;
 riscv_cpu_set_fflags(env, (val & FSR_AEXC) >> FSR_AEXC_SHIFT);
-- 
2.25.1




[PATCH v8 61/78] target/riscv: rvv-1.0: floating-point/integer type-convert instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfcvt.rtz.xu.f.v
* vfcvt.rtz.x.f.v

Also adjust GEN_OPFV_TRANS() to accept multiple floating-point rounding
modes.

Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode  | 11 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 84 +++--
 2 files changed, 59 insertions(+), 36 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 20b3095f56c..02064f8ec98 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -585,10 +585,13 @@ vmfge_vf01 . . . 101 . 1010111 
@r_vm
 vfclass_v   010011 . . 1 001 . 1010111 @r2_vm
 vfmerge_vfm 010111 0 . . 101 . 1010111 @r_vm_0
 vfmv_v_f010111 1 0 . 101 . 1010111 @r2
-vfcvt_xu_f_v100010 . . 0 001 . 1010111 @r2_vm
-vfcvt_x_f_v 100010 . . 1 001 . 1010111 @r2_vm
-vfcvt_f_xu_v100010 . . 00010 001 . 1010111 @r2_vm
-vfcvt_f_x_v 100010 . . 00011 001 . 1010111 @r2_vm
+
+vfcvt_xu_f_v   010010 . . 0 001 . 1010111 @r2_vm
+vfcvt_x_f_v010010 . . 1 001 . 1010111 @r2_vm
+vfcvt_f_xu_v   010010 . . 00010 001 . 1010111 @r2_vm
+vfcvt_f_x_v010010 . . 00011 001 . 1010111 @r2_vm
+vfcvt_rtz_xu_f_v   010010 . . 00110 001 . 1010111 @r2_vm
+vfcvt_rtz_x_f_v010010 . . 00111 001 . 1010111 @r2_vm
 vfwcvt_xu_f_v   100010 . . 01000 001 . 1010111 @r2_vm
 vfwcvt_x_f_v100010 . . 01001 001 . 1010111 @r2_vm
 vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 676336a5200..b1ea15517c0 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1,5 +1,4 @@
 /*
- * RISC-V translation routines for the RVV Standard Extension.
  *
  * Copyright (c) 2020 T-Head Semiconductor Co., Ltd. All rights reserved.
  *
@@ -2368,34 +2367,41 @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
vext_check_ss(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_TRANS(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, \
-}; \
-TCGLabel *over = gen_new_label();  \
-gen_set_rm(s, RISCV_FRM_DYN);  \
-tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
-   \
-data = FIELD_DP32(data, VDATA, VM, a->vm); \
-data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
-tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
-   vreg_ofs(s, a->rs2), cpu_env,   \
-   s->vlen / 8, s->vlen / 8, data, \
-   fns[s->sew - 1]);   \
-mark_vs_dirty(s);  \
-gen_set_label(over);   \
-return true;   \
-}  \
-return false;  \
+static bool do_opfv(DisasContext *s, arg_rmr *a,
+gen_helper_gvec_3_ptr *fn,
+bool (*checkfn)(DisasContext *, arg_rmr *),
+int rm)
+{
+if (checkfn(s, a)) {
+uint32_t data = 0;
+TCGLabel *over = gen_new_label();
+gen_set_rm(s, rm);
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
+
+data = FIELD_DP32(data, VDATA, VM, a->vm);
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0),
+   vreg_ofs(s, a->rs2), cpu_env,
+   s->vlen / 8, s->vlen / 8, data, fn);
+mark_vs_dirty(s);
+gen_set_label(over);
+return true;
+}
+return false;
+}
+
+#define GEN_OPFV_TRANS(NAME, CHECK, FRM)   \
+static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
+{  \
+static gen_helper_gvec_3_ptr * const fns[3] = {\
+gen_helper_##NAME##_h,

[PATCH v8 53/78] target/riscv: rvv-1.0: single-width floating-point reduction

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 12 +---
 target/riscv/vector_helper.c| 12 ++--
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ef54f8e04fa..0c171a25930 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2636,9 +2636,15 @@ GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check)
 GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check)
 
 /* Vector Single-Width Floating-Point Reduction Instructions */
-GEN_OPFVV_TRANS(vfredsum_vs, reduction_check)
-GEN_OPFVV_TRANS(vfredmax_vs, reduction_check)
-GEN_OPFVV_TRANS(vfredmin_vs, reduction_check)
+static bool freduction_check(DisasContext *s, arg_rmrr *a)
+{
+return reduction_check(s, a) &&
+   require_rvf(s);
+}
+
+GEN_OPFVV_TRANS(vfredsum_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
+GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
 GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index c95c8bd9db3..17633ac2792 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -4173,14 +4173,14 @@ GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, 
H4, float32_add)
 GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
 
 /* Maximum value */
-GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum)
-GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum)
-GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum)
+GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maxnum_noprop)
+GEN_VEXT_FRED(vfredmax_vs_w, uint32_t, uint32_t, H4, H4, float32_maxnum_noprop)
+GEN_VEXT_FRED(vfredmax_vs_d, uint64_t, uint64_t, H8, H8, float64_maxnum_noprop)
 
 /* Minimum value */
-GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum)
-GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum)
-GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum)
+GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minnum_noprop)
+GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minnum_noprop)
+GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minnum_noprop)
 
 /* Vector Widening Floating-Point Reduction Instructions */
 /* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
-- 
2.25.1




[PATCH v8 62/78] target/riscv: rvv-1.0: widening floating-point/integer type-convert

2021-10-15 Thread frank . chang
From: Frank Chang 

Add the following instructions:

* vfwcvt.rtz.xu.f.v
* vfwcvt.rtz.x.f.v

Also adjust GEN_OPFV_WIDEN_TRANS() to accept multiple floating-point
rounding modes.

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |  2 +
 target/riscv/insn32.decode  | 13 +++---
 target/riscv/insn_trans/trans_rvv.c.inc | 55 +
 target/riscv/vector_helper.c|  7 +++-
 4 files changed, 63 insertions(+), 14 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1727075dce4..53cf88cd402 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -928,8 +928,10 @@ DEF_HELPER_5(vfwcvt_xu_f_v_h, void, ptr, ptr, ptr, env, 
i32)
 DEF_HELPER_5(vfwcvt_xu_f_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_x_f_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_xu_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_xu_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfwcvt_f_x_v_b, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_x_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfwcvt_f_f_v_h, void, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 02064f8ec98..664d0fb3716 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -592,11 +592,14 @@ vfcvt_f_xu_v   010010 . . 00010 001 . 1010111 
@r2_vm
 vfcvt_f_x_v010010 . . 00011 001 . 1010111 @r2_vm
 vfcvt_rtz_xu_f_v   010010 . . 00110 001 . 1010111 @r2_vm
 vfcvt_rtz_x_f_v010010 . . 00111 001 . 1010111 @r2_vm
-vfwcvt_xu_f_v   100010 . . 01000 001 . 1010111 @r2_vm
-vfwcvt_x_f_v100010 . . 01001 001 . 1010111 @r2_vm
-vfwcvt_f_xu_v   100010 . . 01010 001 . 1010111 @r2_vm
-vfwcvt_f_x_v100010 . . 01011 001 . 1010111 @r2_vm
-vfwcvt_f_f_v100010 . . 01100 001 . 1010111 @r2_vm
+
+vfwcvt_xu_f_v  010010 . . 01000 001 . 1010111 @r2_vm
+vfwcvt_x_f_v   010010 . . 01001 001 . 1010111 @r2_vm
+vfwcvt_f_xu_v  010010 . . 01010 001 . 1010111 @r2_vm
+vfwcvt_f_x_v   010010 . . 01011 001 . 1010111 @r2_vm
+vfwcvt_f_f_v   010010 . . 01100 001 . 1010111 @r2_vm
+vfwcvt_rtz_xu_f_v  010010 . . 01110 001 . 1010111 @r2_vm
+vfwcvt_rtz_x_f_v   010010 . . 0 001 . 1010111 @r2_vm
 vfncvt_xu_f_v   100010 . . 1 001 . 1010111 @r2_vm
 vfncvt_x_f_v100010 . . 10001 001 . 1010111 @r2_vm
 vfncvt_f_xu_v   100010 . . 10010 001 . 1010111 @r2_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b1ea15517c0..63d33b22068 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2535,12 +2535,55 @@ static bool opfv_widen_check(DisasContext *s, arg_rmr 
*a)
vext_check_ds(s, a->rd, a->rs2, a->vm);
 }
 
-#define GEN_OPFV_WIDEN_TRANS(NAME) \
+#define GEN_OPFV_WIDEN_TRANS(NAME, HELPER, FRM)\
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 {  \
 if (opfv_widen_check(s, a)) {  \
 uint32_t data = 0; \
 static gen_helper_gvec_3_ptr * const fns[2] = {\
+gen_helper_##HELPER##_h,   \
+gen_helper_##HELPER##_w,   \
+}; \
+TCGLabel *over = gen_new_label();  \
+gen_set_rm(s, FRM);\
+tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);  \
+   \
+data = FIELD_DP32(data, VDATA, VM, a->vm); \
+data = FIELD_DP32(data, VDATA, LMUL, s->lmul); \
+tcg_gen_gvec_3_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, 0), \
+   vreg_ofs(s, a->rs2), cpu_env,   \
+   s->vlen / 8, s->vlen / 8, data, \
+   fns[s->sew - 1]);   \
+mark_vs_dirty(s);  \
+gen_set_label(over);   \
+return true;   \
+}  \
+return false;  \
+}
+
+GEN_OPFV_WIDEN_TRANS(vfwcvt_xu_f_v, vfwcvt_xu_f_v, RISCV_FRM_DYN)
+GEN_OPFV_WIDEN_TRANS(vfwcvt_x_f_v, vfwcvt_x_f

[PATCH v8 69/78] target/riscv: gdb: support vector registers for rv64 & rv32

2021-10-15 Thread frank . chang
From: Hsiangkai Wang 

Signed-off-by: Hsiangkai Wang 
Signed-off-by: Greentime Hu 
Signed-off-by: Frank Chang 
---
 target/riscv/cpu.c |   2 +
 target/riscv/cpu.h |   1 +
 target/riscv/gdbstub.c | 184 +
 3 files changed, 187 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 36448e61572..4d2ae445361 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -634,6 +634,8 @@ static const char *riscv_gdb_get_dynamic_xml(CPUState *cs, 
const char *xmlname)
 
 if (strcmp(xmlname, "riscv-csr.xml") == 0) {
 return cpu->dyn_csr_xml;
+} else if (strcmp(xmlname, "riscv-vector.xml") == 0) {
+return cpu->dyn_vreg_xml;
 }
 
 return NULL;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 49eece111e2..7a18f539037 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -277,6 +277,7 @@ struct RISCVCPU {
 CPURISCVState env;
 
 char *dyn_csr_xml;
+char *dyn_vreg_xml;
 
 /* Configuration Settings */
 struct {
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
index a7a9c0b1fec..de764c1970e 100644
--- a/target/riscv/gdbstub.c
+++ b/target/riscv/gdbstub.c
@@ -20,6 +20,32 @@
 #include "exec/gdbstub.h"
 #include "cpu.h"
 
+struct TypeSize {
+const char *gdb_type;
+const char *id;
+int size;
+const char suffix;
+};
+
+static const struct TypeSize vec_lanes[] = {
+/* quads */
+{ "uint128", "quads", 128, 'q' },
+/* 64 bit */
+{ "uint64", "longs", 64, 'l' },
+/* 32 bit */
+{ "uint32", "words", 32, 'w' },
+/* 16 bit */
+{ "uint16", "shorts", 16, 's' },
+/*
+ * TODO: currently there is no reliable way of telling
+ * if the remote gdb actually understands ieee_half so
+ * we don't expose it in the target description for now.
+ * { "ieee_half", 16, 'h', 'f' },
+ */
+/* bytes */
+{ "uint8", "bytes", 8, 'b' },
+};
+
 int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
 {
 RISCVCPU *cpu = RISCV_CPU(cs);
@@ -101,6 +127,96 @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t 
*mem_buf, int n)
 return 0;
 }
 
+/*
+ * Convert register index number passed by GDB to the correspond
+ * vector CSR number. Vector CSRs are defined after vector registers
+ * in dynamic generated riscv-vector.xml, thus the starting register index
+ * of vector CSRs is 32.
+ * Return 0 if register index number is out of range.
+ */
+static int riscv_gdb_vector_csrno(int num_regs)
+{
+/*
+ * The order of vector CSRs in the switch case
+ * should match with the order defined in csr_ops[].
+ */
+switch (num_regs) {
+case 32:
+return CSR_VSTART;
+case 33:
+return CSR_VXSAT;
+case 34:
+return CSR_VXRM;
+case 35:
+return CSR_VCSR;
+case 36:
+return CSR_VL;
+case 37:
+return CSR_VTYPE;
+case 38:
+return CSR_VLENB;
+default:
+/* Unknown register. */
+return 0;
+}
+}
+
+static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
+{
+uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+if (n < 32) {
+int i;
+int cnt = 0;
+for (i = 0; i < vlenb; i += 8) {
+cnt += gdb_get_reg64(buf,
+ env->vreg[(n * vlenb + i) / 8]);
+}
+return cnt;
+}
+
+int csrno = riscv_gdb_vector_csrno(n);
+
+if (!csrno) {
+return 0;
+}
+
+target_ulong val = 0;
+int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
+
+if (result == 0) {
+return gdb_get_regl(buf, val);
+}
+
+return 0;
+}
+
+static int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
+{
+uint16_t vlenb = env_archcpu(env)->cfg.vlen >> 3;
+if (n < 32) {
+int i;
+for (i = 0; i < vlenb; i += 8) {
+env->vreg[(n * vlenb + i) / 8] = ldq_p(mem_buf + i);
+}
+return vlenb;
+}
+
+int csrno = riscv_gdb_vector_csrno(n);
+
+if (!csrno) {
+return 0;
+}
+
+target_ulong val = ldtul_p(mem_buf);
+int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
+
+if (result == 0) {
+return sizeof(target_ulong);
+}
+
+return 0;
+}
+
 static int riscv_gdb_get_csr(CPURISCVState *env, GByteArray *buf, int n)
 {
 if (n < CSR_TABLE_SIZE) {
@@ -187,6 +303,68 @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int 
base_reg)
 return CSR_TABLE_SIZE;
 }
 
+static int ricsv_gen_dynamic_vector_xml(CPUState *cs, int base_reg)
+{
+RISCVCPU *cpu = RISCV_CPU(cs);
+GString *s = g_string_new(NULL);
+g_autoptr(GString) ts = g_string_new("");
+int reg_width = cpu->cfg.vlen;
+int num_regs = 0;
+int i;
+
+g_string_printf(s, "");
+g_string_append_printf(s, "");
+g_string_append_printf(s, "");
+
+/* First define types and totals in a whole VL */
+for (i = 0; i < ARRAY_SIZE(vec_la

[PATCH v8 54/78] target/riscv: rvv-1.0: widening floating-point reduction instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 0c171a25930..a30da823d25 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2647,7 +2647,14 @@ GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
 GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
 
 /* Vector Widening Floating-Point Reduction Instructions */
-GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, reduction_check)
+static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
+{
+return reduction_widen_check(s, a) &&
+   require_scale_rvf(s) &&
+   (s->sew != MO_8);
+}
+
+GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, freduction_widen_check)
 
 /*
  *** Vector Mask Operations
-- 
2.25.1




[PATCH v8 78/78] target/riscv: rvv-1.0: update opivv_vadc_check() comment

2021-10-15 Thread frank . chang
From: Frank Chang 

Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions is
moved to Section 11.4 in RVV v1.0 spec. Update the comment, no
functional changes.

Signed-off-by: Frank Chang 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index b78c13f0be7..de2e2e506fe 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -1613,7 +1613,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmrr *a)
 \
 
 /*
  * For vadc and vsbc, an illegal instruction exception is raised if the
- * destination vector register is v0 and LMUL > 1. (Section 12.4)
+ * destination vector register is v0 and LMUL > 1. (Section 11.4)
  */
 static bool opivv_vadc_check(DisasContext *s, arg_rmrr *a)
 {
-- 
2.25.1




[PATCH v8 73/78] target/riscv: rvv-1.0: rename r2_zimm to r2_zimm11

2021-10-15 Thread frank . chang
From: Frank Chang 

Rename r2_zimm to r2_zimm11 for the upcoming vsetivli instruction.
vsetivli has 10-bits of zimm but vsetvli has 11-bits of zimm.

Signed-off-by: Frank Chang 
---
 target/riscv/insn32.decode | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index 952768f8ded..d7c6bc9af26 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -78,7 +78,7 @@
 @r_vm.. vm:1 . . ... . ... &rmrr %rs2 %rs1 %rd
 @r_vm_1  .. . . . ... . ...&rmrr vm=1 %rs2 %rs1 %rd
 @r_vm_0  .. . . . ... . ...&rmrr vm=0 %rs2 %rs1 %rd
-@r2_zimm . zimm:11  . ... . ... %rs1 %rd
+@r2_zimm11 . zimm:11  . ... . ... %rs1 %rd
 @r2_s...   . . ... . ... %rs2 %rs1
 
 @hfence_gvma ... . .   ... . ... %rs2 %rs1
@@ -671,7 +671,7 @@ vsext_vf2   010010 . . 00111 010 . 1010111 
@r2_vm
 vsext_vf4   010010 . . 00101 010 . 1010111 @r2_vm
 vsext_vf8   010010 . . 00011 010 . 1010111 @r2_vm
 
-vsetvli 0 ... . 111 . 1010111  @r2_zimm
+vsetvli 0 ... . 111 . 1010111  @r2_zimm11
 vsetvl  100 . . 111 . 1010111  @r
 
 # *** RV32 Zba Standard Extension ***
-- 
2.25.1




[PATCH v8 70/78] target/riscv: rvv-1.0: floating-point reciprocal square-root estimate instruction

2021-10-15 Thread frank . chang
From: Frank Chang 

Implement the floating-point reciprocal square-root estimate to 7 bits
instruction.

Signed-off-by: Frank Chang 
---
 target/riscv/helper.h   |   4 +
 target/riscv/insn32.decode  |   1 +
 target/riscv/insn_trans/trans_rvv.c.inc |   1 +
 target/riscv/vector_helper.c| 183 
 4 files changed, 189 insertions(+)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index a717a87a0e0..bdf06dfb24d 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -841,6 +841,10 @@ DEF_HELPER_5(vfsqrt_v_h, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_w, void, ptr, ptr, ptr, env, i32)
 DEF_HELPER_5(vfsqrt_v_d, void, ptr, ptr, ptr, env, i32)
 
+DEF_HELPER_5(vfrsqrt7_v_h, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrsqrt7_v_w, void, ptr, ptr, ptr, env, i32)
+DEF_HELPER_5(vfrsqrt7_v_d, void, ptr, ptr, ptr, env, i32)
+
 DEF_HELPER_6(vfmin_vv_h, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_w, void, ptr, ptr, ptr, ptr, env, i32)
 DEF_HELPER_6(vfmin_vv_d, void, ptr, ptr, ptr, ptr, env, i32)
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index c4fdc76a269..6e5f288943a 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -560,6 +560,7 @@ vfwmsac_vf  10 . . . 101 . 1010111 @r_vm
 vfwnmsac_vv 11 . . . 001 . 1010111 @r_vm
 vfwnmsac_vf 11 . . . 101 . 1010111 @r_vm
 vfsqrt_v010011 . . 0 001 . 1010111 @r2_vm
+vfrsqrt7_v  010011 . . 00100 001 . 1010111 @r2_vm
 vfmin_vv000100 . . . 001 . 1010111 @r_vm
 vfmin_vf000100 . . . 101 . 1010111 @r_vm
 vfmax_vv000110 . . . 001 . 1010111 @r_vm
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index 09ae8fad90a..a573b56b2ff 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2406,6 +2406,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)  \
 }
 
 GEN_OPFV_TRANS(vfsqrt_v, opfv_check, RISCV_FRM_DYN)
+GEN_OPFV_TRANS(vfrsqrt7_v, opfv_check, RISCV_FRM_DYN)
 
 /* Vector Floating-Point MIN/MAX Instructions */
 GEN_OPFVV_TRANS(vfmin_vv, opfvv_check)
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
index cb0699f4ba2..f61e5ec4612 100644
--- a/target/riscv/vector_helper.c
+++ b/target/riscv/vector_helper.c
@@ -18,6 +18,7 @@
 
 #include "qemu/osdep.h"
 #include "qemu/host-utils.h"
+#include "qemu/bitops.h"
 #include "cpu.h"
 #include "exec/memop.h"
 #include "exec/exec-all.h"
@@ -3404,6 +3405,188 @@ GEN_VEXT_V_ENV(vfsqrt_v_h, 2, 2)
 GEN_VEXT_V_ENV(vfsqrt_v_w, 4, 4)
 GEN_VEXT_V_ENV(vfsqrt_v_d, 8, 8)
 
+/*
+ * Vector Floating-Point Reciprocal Square-Root Estimate Instruction
+ *
+ * Adapted from riscv-v-spec recip.c:
+ * https://github.com/riscv/riscv-v-spec/blob/master/recip.c
+ */
+static uint64_t frsqrt7(uint64_t f, int exp_size, int frac_size)
+{
+uint64_t sign = extract64(f, frac_size + exp_size, 1);
+uint64_t exp = extract64(f, frac_size, exp_size);
+uint64_t frac = extract64(f, 0, frac_size);
+
+const uint8_t lookup_table[] = {
+52, 51, 50, 48, 47, 46, 44, 43,
+42, 41, 40, 39, 38, 36, 35, 34,
+33, 32, 31, 30, 30, 29, 28, 27,
+26, 25, 24, 23, 23, 22, 21, 20,
+19, 19, 18, 17, 16, 16, 15, 14,
+14, 13, 12, 12, 11, 10, 10, 9,
+9, 8, 7, 7, 6, 6, 5, 4,
+4, 3, 3, 2, 2, 1, 1, 0,
+127, 125, 123, 121, 119, 118, 116, 114,
+113, 111, 109, 108, 106, 105, 103, 102,
+100, 99, 97, 96, 95, 93, 92, 91,
+90, 88, 87, 86, 85, 84, 83, 82,
+80, 79, 78, 77, 76, 75, 74, 73,
+72, 71, 70, 70, 69, 68, 67, 66,
+65, 64, 63, 63, 62, 61, 60, 59,
+59, 58, 57, 56, 56, 55, 54, 53
+};
+const int precision = 7;
+
+if (exp == 0 && frac != 0) { /* subnormal */
+/* Normalize the subnormal. */
+while (extract64(frac, frac_size - 1, 1) == 0) {
+exp--;
+frac <<= 1;
+}
+
+frac = (frac << 1) & MAKE_64BIT_MASK(0, frac_size);
+}
+
+int idx = ((exp & 1) << (precision - 1)) |
+(frac >> (frac_size - precision + 1));
+uint64_t out_frac = (uint64_t)(lookup_table[idx]) <<
+(frac_size - precision);
+uint64_t out_exp = (3 * MAKE_64BIT_MASK(0, exp_size - 1) + ~exp) / 2;
+
+uint64_t val = 0;
+val = deposit64(val, 0, frac_size, out_frac);
+val = deposit64(val, frac_size, exp_size, out_exp);
+val = deposit64(val, frac_size + exp_size, 1, sign);
+return val;
+}
+
+static float16 frsqrt7_h(float16 f, float_status *s)
+{
+int exp_size = 5, frac_size = 10;
+bool sign = float16_is_neg(f);
+
+/*
+ * frsqrt7(sNaN) = canonical NaN
+ * frsqrt7(-inf) = canonical NaN
+ * frsqrt7(-normal) = canonical NaN
+ * frsqrt7(-subnorm

[PATCH v8 55/78] target/riscv: rvv-1.0: single-width scaling shift instructions

2021-10-15 Thread frank . chang
From: Frank Chang 

log(SEW) truncate vssra.vi immediate value.

Signed-off-by: Frank Chang 
Reviewed-by: Richard Henderson 
---
 target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index a30da823d25..40061fc304f 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2029,8 +2029,8 @@ GEN_OPIVV_TRANS(vssrl_vv, opivv_check)
 GEN_OPIVV_TRANS(vssra_vv, opivv_check)
 GEN_OPIVX_TRANS(vssrl_vx,  opivx_check)
 GEN_OPIVX_TRANS(vssra_vx,  opivx_check)
-GEN_OPIVI_TRANS(vssrl_vi, IMM_ZX, vssrl_vx, opivx_check)
-GEN_OPIVI_TRANS(vssra_vi, IMM_SX, vssra_vx, opivx_check)
+GEN_OPIVI_TRANS(vssrl_vi, IMM_TRUNC_SEW, vssrl_vx, opivx_check)
+GEN_OPIVI_TRANS(vssra_vi, IMM_TRUNC_SEW, vssra_vx, opivx_check)
 
 /* Vector Narrowing Fixed-Point Clip Instructions */
 GEN_OPIWV_NARROW_TRANS(vnclipu_wv)
-- 
2.25.1




Re: Is the ppc440 "bamboo" board in QEMU still of any use?

2021-10-15 Thread Thomas Huth

On 14/10/2021 13.44, Mark Cave-Ayland wrote:

On 14/10/2021 11:47, Christophe Leroy wrote:


Le 14/10/2021 à 12:34, Christophe Leroy a écrit :



Le 14/10/2021 à 11:31, Thomas Huth a écrit :


  Hi,

I tried to build a current Linux kernel for the "bamboo" board and use 
it in QEMU, but QEMU then quickly aborts with:


  pci.c:262: pci_bus_change_irq_level: Assertion `irq_num >= 0' failed.

(or with a "DCR write error" if I try to use the cuImage instead).

I googled a little bit and found this discussion:

https://qemu-devel.nongnu.narkive.com/vYHona3u/emulating-powerpc-440ep-with-qemu-system-ppcemb#post2 



Seems like this board was used for KVM on the PPC440 only, and has never 
been enabled with the TCG emulation?


Well, KVM support on the 440 has been removed years ago already:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b2677b8dd8de0dc1496ede4da09b9dfd59f15cea 



So is this "bamboo" board dead code in QEMU now? Or does anybody still 
have a kernel binary which could be used for testing it? Note: This 
board does not support "-bios", so u-boot or other firmwares are 
certainly also not an option here...

Should we mark "bamboo" as deprecated nowadays?



I have the following change in QEMU to be able to run the bamboo, found 
it some time ago via google (can't remember where):


diff --git a/hw/ppc/ppc4xx_pci.c b/hw/ppc/ppc4xx_pci.c
index 8147ba6f94..600e89e791 100644
--- a/hw/ppc/ppc4xx_pci.c
+++ b/hw/ppc/ppc4xx_pci.c
@@ -246,7 +246,7 @@ static int ppc4xx_pci_map_irq(PCIDevice *pci_dev, int 
irq_num)


  trace_ppc4xx_pci_map_irq(pci_dev->devfn, irq_num, slot);

-    return slot - 1;
+    return slot ? slot - 1 : slot;
  }

  static void ppc4xx_pci_set_irq(void *opaque, int irq_num, int level)
---

It's probably no the final change, but at least it allows booting bamboo 
on qemu again.




Found the source : 
https://www.mail-archive.com/qemu-devel@nongnu.org/msg769121.html


Ah yes, that thread rings a bell. I think the important part was in my 
initial reply at 
https://www.mail-archive.com/qemu-devel@nongnu.org/msg769115.html: in other 
words ppc4xx_pci_map_irq() function expects the IRQ number to range from 1 
to 4.


When I looked at this the issue was caused by the guest writing to PCI 
configuration space to disable PCI interrupts: this ends up calling 
pci_update_irq_disabled() as below:


/* Called after interrupt disabled field update in config space,
  * assert/deassert interrupts if necessary.
  * Gets original interrupt disable bit value (before update). */
static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
{
     int i, disabled = pci_irq_disabled(d);
     if (disabled == was_irq_disabled)
     return;
     for (i = 0; i < PCI_NUM_PINS; ++i) {
     int state = pci_irq_state(d, i);
     pci_change_irq_level(d, i, disabled ? -state : state);
     }
}

Since the IRQ is disabled pci_change_irq_level() ends up being called with 
-1 which triggers the assert().


I think you likely mixed up the paramters here. The -1 is the "change" 
parameter, but the critical value that is tested in the assert() statement 
later is the irq_num variable which comes from the map_irq() function.


Now looking at ppc4xx_pci_map_irq(), I think the code is basically correct 
for the PCI slots 1 to 4. You can verify that with the image from



http://landley.net/aboriginal/downloads/binaries/system-image-powerpc-440fp.tar.gz

and by starting QEMU e.g. with:

qemu-system-ppc64  -kernel linux -initrd rootfs.cpio.gz \
  -M bamboo -device e1000  -device e1000 -device e1000 \
  -netdev user,id=u1 -device rtl8139,netdev=u1

You can see the 8139 card with "lspci" in the last slot, and a "ping 
10.0.2.2" only works if the map_irq function returns "slot - 1" in this case 
(otherwise it even crashes after a while).


Now back to the original problem: This seems to occur indeed since recent 
self-compiled Linux kernels also try to mess with the pci host bridge device 
in slot 0. So the question is only, which interrupt number should the 
map_irq() function return in case it has been called with the PCI host 
bridge device in slot 0?


Both hacks with "return slot ? slot - 1 : 0;" and "return (slot - 1) & 3" 
seem to work, as far as I can tell, and I think the IRQ for the host bridge 
is then ignored anyway, so maybe we should simply add one of the two and 
call it a day?


 Thomas




  1   2   3   4   >