[PATCH] docs: vhost-user: VHOST_USER_GET_STATUS require reply

2023-05-04 Thread Yajun Wu
Add VHOST_USER_GET_STATUS to the list of requests that require a reply.

Cc: Maxime Coquelin 
Cc: Michael S. Tsirkin 
Signed-off-by: Yajun Wu 
---
 docs/interop/vhost-user.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/interop/vhost-user.rst b/docs/interop/vhost-user.rst
index 8a5924ea75..2d13108284 100644
--- a/docs/interop/vhost-user.rst
+++ b/docs/interop/vhost-user.rst
@@ -299,6 +299,7 @@ replies. Here is a list of the ones that do:
 * ``VHOST_USER_GET_VRING_BASE``
 * ``VHOST_USER_SET_LOG_BASE`` (if ``VHOST_USER_PROTOCOL_F_LOG_SHMFD``)
 * ``VHOST_USER_GET_INFLIGHT_FD`` (if ``VHOST_USER_PROTOCOL_F_INFLIGHT_SHMFD``)
+* ``VHOST_USER_GET_STATUS`` (if ``VHOST_USER_PROTOCOL_F_STATUS``)
 
 .. seealso::
 
-- 
2.27.0




Re: [PATCH v3 0/5] virtio-gpu cleanups and obvious definitions

2023-05-04 Thread Akihiko Odaki

On 2023/05/05 4:12, Gurchetan Singh wrote:

From: Gurchetan Singh 

v3 of "virtio-gpu cleanups and obvious definitions"

https://lists.gnu.org/archive/html/qemu-devel/2023-04/msg05392.html

All patches have been reviewed, though there was a question from
Bernhard Beschow about patch (3) and how it fits with the QOM:

https://lists.gnu.org/archive/html/qemu-devel/2023-05/msg00057.html

I go into detail in patch 3 commit message, but I think we meet
the requirements (which are tricky/fuzzy anyways).  Also, I think
this is the cleanest way to add another 3D virtgpu backend.  But
if anyone has other ideas, please do reply/review.

Antonio Caggiano (1):
   virtio-gpu: CONTEXT_INIT feature

Dr. David Alan Gilbert (1):
   virtio: Add shared memory capability

Gurchetan Singh (3):
   hw/display/virtio-gpu-virgl: virtio_gpu_gl -> virtio_gpu_virgl
   hw/display/virtio-gpu-virgl: make GL device more library agnostic
   hw/display/virtio-gpu-virgl: define callbacks in realize function

  hw/display/virtio-gpu-base.c   |   3 +
  hw/display/virtio-gpu-gl.c | 114 +--
  hw/display/virtio-gpu-virgl.c  | 137 +++--
  hw/virtio/virtio-pci.c |  18 +
  include/hw/virtio/virtio-gpu.h |  11 +--
  include/hw/virtio/virtio-pci.h |   4 +
  6 files changed, 160 insertions(+), 127 deletions(-)



For all patches:

Reviewed-by: Akihiko Odaki 



Re: [RFC 0/7] vhost-vdpa: add support for iommufd

2023-05-04 Thread Jason Wang
Hi Cindy

On Wed, May 3, 2023 at 5:13 PM Cindy Lu  wrote:
>
> Hi All
> There is the RFC to support the IOMMUFD in vdpa device
> any comments are welcome
> Thanks
> Cindy

Please post the kernel patch as well as a reference.

Thanks

>
> Cindy Lu (7):
>   vhost: introduce new UAPI to support IOMMUFD
>   qapi: support iommufd in vdpa
>   virtio : add a ptr for vdpa_iommufd in VirtIODevice
>   net/vhost-vdpa: Add the check for iommufd
>   vhost-vdpa: Add the iommufd support in the map/unmap function
>   vhost-vdpa: init iommufd function in vhost_vdpa start
>   vhost-vdpa-iommufd: Add iommufd support for vdpa
>
>  hw/virtio/meson.build  |   2 +-
>  hw/virtio/vhost-vdpa-iommufd.c | 240 +
>  hw/virtio/vhost-vdpa.c |  74 +-
>  include/hw/virtio/vhost-vdpa.h |  47 +++
>  include/hw/virtio/virtio.h |   5 +
>  linux-headers/linux/vhost.h|  72 ++
>  net/vhost-vdpa.c   |  31 +++--
>  qapi/net.json  |   1 +
>  8 files changed, 451 insertions(+), 21 deletions(-)
>  create mode 100644 hw/virtio/vhost-vdpa-iommufd.c
>
> --
> 2.34.3
>




[PULL 23/45] target/loongarch: Implement vsllwil vextl

2023-05-04 Thread Song Gao
This patch includes:
- VSLLWIL.{H.B/W.H/D.W};
- VSLLWIL.{HU.BU/WU.HU/DU.WU};
- VEXTL.Q.D, VEXTL.QU.DU.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-24-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  9 +
 target/loongarch/helper.h   |  9 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 21 +++
 target/loongarch/insns.decode   |  9 +
 target/loongarch/lsx_helper.c   | 41 +
 5 files changed, 89 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index f7d0fb4441..087cac10ad 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1139,3 +1139,12 @@ INSN_LSX(vrotri_b, vv_i)
 INSN_LSX(vrotri_h, vv_i)
 INSN_LSX(vrotri_w, vv_i)
 INSN_LSX(vrotri_d, vv_i)
+
+INSN_LSX(vsllwil_h_b,  vv_i)
+INSN_LSX(vsllwil_w_h,  vv_i)
+INSN_LSX(vsllwil_d_w,  vv_i)
+INSN_LSX(vextl_q_d,vv)
+INSN_LSX(vsllwil_hu_bu,vv_i)
+INSN_LSX(vsllwil_wu_hu,vv_i)
+INSN_LSX(vsllwil_du_wu,vv_i)
+INSN_LSX(vextl_qu_du,  vv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 617c579592..e98f7c3e6f 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -352,3 +352,12 @@ DEF_HELPER_3(vmskgez_b, void, env, i32, i32)
 DEF_HELPER_3(vmsknz_b, void, env, i32,i32)
 
 DEF_HELPER_FLAGS_4(vnori_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_4(vsllwil_h_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vsllwil_w_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsllwil_d_w, void, env, i32, i32, i32)
+DEF_HELPER_3(vextl_q_d, void, env, i32, i32)
+DEF_HELPER_4(vsllwil_hu_bu, void, env, i32, i32, i32)
+DEF_HELPER_4(vsllwil_wu_hu, void, env, i32, i32, i32)
+DEF_HELPER_4(vsllwil_du_wu, void, env, i32, i32, i32)
+DEF_HELPER_3(vextl_qu_du, void, env, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index ad8f32ed18..037c742aa4 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -39,6 +39,18 @@ static bool gen_vv(DisasContext *ctx, arg_vv *a,
 return true;
 }
 
+static bool gen_vv_i(DisasContext *ctx, arg_vv_i *a,
+ void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32))
+{
+TCGv_i32 vd = tcg_constant_i32(a->vd);
+TCGv_i32 vj = tcg_constant_i32(a->vj);
+TCGv_i32 imm = tcg_constant_i32(a->imm);
+
+CHECK_SXE;
+func(cpu_env, vd, vj, imm);
+return true;
+}
+
 static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
  void (*func)(unsigned, uint32_t, uint32_t,
   uint32_t, uint32_t, uint32_t))
@@ -2966,3 +2978,12 @@ TRANS(vrotri_b, gvec_vv_i, MO_8, tcg_gen_gvec_rotri)
 TRANS(vrotri_h, gvec_vv_i, MO_16, tcg_gen_gvec_rotri)
 TRANS(vrotri_w, gvec_vv_i, MO_32, tcg_gen_gvec_rotri)
 TRANS(vrotri_d, gvec_vv_i, MO_64, tcg_gen_gvec_rotri)
+
+TRANS(vsllwil_h_b, gen_vv_i, gen_helper_vsllwil_h_b)
+TRANS(vsllwil_w_h, gen_vv_i, gen_helper_vsllwil_w_h)
+TRANS(vsllwil_d_w, gen_vv_i, gen_helper_vsllwil_d_w)
+TRANS(vextl_q_d, gen_vv, gen_helper_vextl_q_d)
+TRANS(vsllwil_hu_bu, gen_vv_i, gen_helper_vsllwil_hu_bu)
+TRANS(vsllwil_wu_hu, gen_vv_i, gen_helper_vsllwil_wu_hu)
+TRANS(vsllwil_du_wu, gen_vv_i, gen_helper_vsllwil_du_wu)
+TRANS(vextl_qu_du, gen_vv, gen_helper_vextl_qu_du)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 7c0b0c4ac8..23dd338026 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -839,3 +839,12 @@ vrotri_b 0111 00101010 0 01 ... . .   
@vv_ui3
 vrotri_h 0111 00101010 0 1  . .   @vv_ui4
 vrotri_w 0111 00101010 1 . . .@vv_ui5
 vrotri_d 0111 00101010 0001 .. . .@vv_ui6
+
+vsllwil_h_b  0111 0011 1 01 ... . .   @vv_ui3
+vsllwil_w_h  0111 0011 1 1  . .   @vv_ui4
+vsllwil_d_w  0111 0011 10001 . . .@vv_ui5
+vextl_q_d0111 0011 10010 0 . .@vv
+vsllwil_hu_bu0111 0011 11000 01 ... . .   @vv_ui3
+vsllwil_wu_hu0111 0011 11000 1  . .   @vv_ui4
+vsllwil_du_wu0111 0011 11001 . . .@vv_ui5
+vextl_qu_du  0111 0011 11010 0 . .@vv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index ff00d60ab8..de86f41cce 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -793,3 +793,44 @@ void HELPER(vnori_b)(void *vd, void *vj, uint64_t imm, 
uint32_t v)
 Vd->B(i) = ~(Vj->B(i) | (uint8_t)imm);
 }
 }
+
+#define VSLLWIL(NAME, BIT, E1, E2)\
+void HELPER(NAME)(CPULoongArchState *env, \
+  uint32_t vd, uint32_t vj, uint32_t imm) \
+{ 

[PULL 19/45] target/loongarch: Implement vsigncov

2023-05-04 Thread Song Gao
This patch includes:
- VSIGNCOV.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-20-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  5 ++
 target/loongarch/helper.h   |  5 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 53 +
 target/loongarch/insns.decode   |  5 ++
 target/loongarch/lsx_helper.c   |  7 +++
 5 files changed, 75 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 412c1cedcb..46e808c321 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1079,3 +1079,8 @@ INSN_LSX(vexth_hu_bu,  vv)
 INSN_LSX(vexth_wu_hu,  vv)
 INSN_LSX(vexth_du_wu,  vv)
 INSN_LSX(vexth_qu_du,  vv)
+
+INSN_LSX(vsigncov_b,   vvv)
+INSN_LSX(vsigncov_h,   vvv)
+INSN_LSX(vsigncov_w,   vvv)
+INSN_LSX(vsigncov_d,   vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 005988be25..e1e5d58697 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -338,3 +338,8 @@ DEF_HELPER_3(vexth_hu_bu, void, env, i32, i32)
 DEF_HELPER_3(vexth_wu_hu, void, env, i32, i32)
 DEF_HELPER_3(vexth_du_wu, void, env, i32, i32)
 DEF_HELPER_3(vexth_qu_du, void, env, i32, i32)
+
+DEF_HELPER_FLAGS_4(vsigncov_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsigncov_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsigncov_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsigncov_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 93ae76bc4c..644917a695 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2814,3 +2814,56 @@ TRANS(vexth_hu_bu, gen_vv, gen_helper_vexth_hu_bu)
 TRANS(vexth_wu_hu, gen_vv, gen_helper_vexth_wu_hu)
 TRANS(vexth_du_wu, gen_vv, gen_helper_vexth_du_wu)
 TRANS(vexth_qu_du, gen_vv, gen_helper_vexth_qu_du)
+
+static void gen_vsigncov(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec t1, zero;
+
+t1 = tcg_temp_new_vec_matching(t);
+zero = tcg_constant_vec_matching(t, vece, 0);
+
+tcg_gen_neg_vec(vece, t1, b);
+tcg_gen_cmpsel_vec(TCG_COND_LT, vece, t, a, zero, t1, b);
+tcg_gen_cmpsel_vec(TCG_COND_EQ, vece, t, a, zero, zero, t);
+}
+
+static void do_vsigncov(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_neg_vec, INDEX_op_cmpsel_vec, 0
+};
+static const GVecGen3 op[4] = {
+{
+.fniv = gen_vsigncov,
+.fno = gen_helper_vsigncov_b,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vsigncov,
+.fno = gen_helper_vsigncov_h,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vsigncov,
+.fno = gen_helper_vsigncov_w,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vsigncov,
+.fno = gen_helper_vsigncov_d,
+.opt_opc = vecop_list,
+.vece = MO_64
+},
+};
+
+tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, [vece]);
+}
+
+TRANS(vsigncov_b, gvec_vvv, MO_8, do_vsigncov)
+TRANS(vsigncov_h, gvec_vvv, MO_16, do_vsigncov)
+TRANS(vsigncov_w, gvec_vvv, MO_32, do_vsigncov)
+TRANS(vsigncov_d, gvec_vvv, MO_64, do_vsigncov)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 39c582d098..4233dd7404 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -778,3 +778,8 @@ vexth_hu_bu  0111 00101001 11101 11100 . .
@vv
 vexth_wu_hu  0111 00101001 11101 11101 . .@vv
 vexth_du_wu  0111 00101001 11101 0 . .@vv
 vexth_qu_du  0111 00101001 11101 1 . .@vv
+
+vsigncov_b   0111 00010010 11100 . . .@vvv
+vsigncov_h   0111 00010010 11101 . . .@vvv
+vsigncov_w   0111 00010010 0 . . .@vvv
+vsigncov_d   0111 00010010 1 . . .@vvv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index b4582a49d9..408815ea45 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -662,3 +662,10 @@ VEXTH(vexth_d_w, 64, D, W)
 VEXTH(vexth_hu_bu, 16, UH, UB)
 VEXTH(vexth_wu_hu, 32, UW, UH)
 VEXTH(vexth_du_wu, 64, UD, UW)
+
+#define DO_SIGNCOV(a, b)  (a == 0 ? 0 : a < 0 ? -b : b)
+
+DO_3OP(vsigncov_b, 8, B, DO_SIGNCOV)
+DO_3OP(vsigncov_h, 16, H, DO_SIGNCOV)
+DO_3OP(vsigncov_w, 32, W, DO_SIGNCOV)
+DO_3OP(vsigncov_d, 64, D, DO_SIGNCOV)
-- 
2.31.1




[PULL 18/45] target/loongarch: Implement vexth

2023-05-04 Thread Song Gao
This patch includes:
- VEXTH.{H.B/W.H/D.W/Q.D};
- VEXTH.{HU.BU/WU.HU/DU.WU/QU.DU}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-19-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  9 ++
 target/loongarch/helper.h   |  9 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 20 
 target/loongarch/insns.decode   |  9 ++
 target/loongarch/lsx_helper.c   | 35 +
 5 files changed, 82 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index b04aefe3ed..412c1cedcb 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1070,3 +1070,12 @@ INSN_LSX(vsat_bu,  vv_i)
 INSN_LSX(vsat_hu,  vv_i)
 INSN_LSX(vsat_wu,  vv_i)
 INSN_LSX(vsat_du,  vv_i)
+
+INSN_LSX(vexth_h_b,vv)
+INSN_LSX(vexth_w_h,vv)
+INSN_LSX(vexth_d_w,vv)
+INSN_LSX(vexth_q_d,vv)
+INSN_LSX(vexth_hu_bu,  vv)
+INSN_LSX(vexth_wu_hu,  vv)
+INSN_LSX(vexth_du_wu,  vv)
+INSN_LSX(vexth_qu_du,  vv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index d2b1c9f2a4..005988be25 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -329,3 +329,12 @@ DEF_HELPER_FLAGS_4(vsat_bu, TCG_CALL_NO_RWG, void, ptr, 
ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vsat_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vsat_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vsat_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_3(vexth_h_b, void, env, i32, i32)
+DEF_HELPER_3(vexth_w_h, void, env, i32, i32)
+DEF_HELPER_3(vexth_d_w, void, env, i32, i32)
+DEF_HELPER_3(vexth_q_d, void, env, i32, i32)
+DEF_HELPER_3(vexth_hu_bu, void, env, i32, i32)
+DEF_HELPER_3(vexth_wu_hu, void, env, i32, i32)
+DEF_HELPER_3(vexth_du_wu, void, env, i32, i32)
+DEF_HELPER_3(vexth_qu_du, void, env, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index b8f05c66a5..93ae76bc4c 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -28,6 +28,17 @@ static bool gen_vvv(DisasContext *ctx, arg_vvv *a,
 return true;
 }
 
+static bool gen_vv(DisasContext *ctx, arg_vv *a,
+   void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32))
+{
+TCGv_i32 vd = tcg_constant_i32(a->vd);
+TCGv_i32 vj = tcg_constant_i32(a->vj);
+
+CHECK_SXE;
+func(cpu_env, vd, vj);
+return true;
+}
+
 static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
  void (*func)(unsigned, uint32_t, uint32_t,
   uint32_t, uint32_t, uint32_t))
@@ -2794,3 +2805,12 @@ TRANS(vsat_bu, gvec_vv_i, MO_8, do_vsat_u)
 TRANS(vsat_hu, gvec_vv_i, MO_16, do_vsat_u)
 TRANS(vsat_wu, gvec_vv_i, MO_32, do_vsat_u)
 TRANS(vsat_du, gvec_vv_i, MO_64, do_vsat_u)
+
+TRANS(vexth_h_b, gen_vv, gen_helper_vexth_h_b)
+TRANS(vexth_w_h, gen_vv, gen_helper_vexth_w_h)
+TRANS(vexth_d_w, gen_vv, gen_helper_vexth_d_w)
+TRANS(vexth_q_d, gen_vv, gen_helper_vexth_q_d)
+TRANS(vexth_hu_bu, gen_vv, gen_helper_vexth_hu_bu)
+TRANS(vexth_wu_hu, gen_vv, gen_helper_vexth_wu_hu)
+TRANS(vexth_du_wu, gen_vv, gen_helper_vexth_du_wu)
+TRANS(vexth_qu_du, gen_vv, gen_helper_vexth_qu_du)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 3ed61b3d68..39c582d098 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -769,3 +769,12 @@ vsat_bu  0111 00110010 1 01 ... . .   
@vv_ui3
 vsat_hu  0111 00110010 1 1  . .   @vv_ui4
 vsat_wu  0111 00110010 10001 . . .@vv_ui5
 vsat_du  0111 00110010 1001 .. . .@vv_ui6
+
+vexth_h_b0111 00101001 11101 11000 . .@vv
+vexth_w_h0111 00101001 11101 11001 . .@vv
+vexth_d_w0111 00101001 11101 11010 . .@vv
+vexth_q_d0111 00101001 11101 11011 . .@vv
+vexth_hu_bu  0111 00101001 11101 11100 . .@vv
+vexth_wu_hu  0111 00101001 11101 11101 . .@vv
+vexth_du_wu  0111 00101001 11101 0 . .@vv
+vexth_qu_du  0111 00101001 11101 1 . .@vv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index 9ba16ac631..b4582a49d9 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -627,3 +627,38 @@ VSAT_U(vsat_bu, 8, UB)
 VSAT_U(vsat_hu, 16, UH)
 VSAT_U(vsat_wu, 32, UW)
 VSAT_U(vsat_du, 64, UD)
+
+#define VEXTH(NAME, BIT, E1, E2)\
+void HELPER(NAME)(CPULoongArchState *env, uint32_t vd, uint32_t vj) \
+{   \
+int i;  \
+VReg *Vd = &(env->fpr[vd].vreg);   

[PULL 45/45] hw/intc: don't use target_ulong for LoongArch ipi

2023-05-04 Thread Song Gao
From: Alex Bennée 

The calling function is already working with hwaddr and uint64_t so
lets avoid bringing target_ulong in if we don't need to.

Signed-off-by: Alex Bennée 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Song Gao 
Message-Id: <20230404132711.2563638-1-alex.ben...@linaro.org>
Signed-off-by: Song Gao 
---
 hw/intc/loongarch_ipi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
index aa4bf9eb74..bdba0f8107 100644
--- a/hw/intc/loongarch_ipi.c
+++ b/hw/intc/loongarch_ipi.c
@@ -50,7 +50,7 @@ static uint64_t loongarch_ipi_readl(void *opaque, hwaddr 
addr, unsigned size)
 return ret;
 }
 
-static void send_ipi_data(CPULoongArchState *env, target_ulong val, 
target_ulong addr)
+static void send_ipi_data(CPULoongArchState *env, uint64_t val, hwaddr addr)
 {
 int i, mask = 0, data = 0;
 
-- 
2.31.1




[PULL 37/45] target/loongarch: Implement vbitsel vset

2023-05-04 Thread Song Gao
This patch includes:
- VBITSEL.V;
- VBITSELI.B;
- VSET{EQZ/NEZ}.V;
- VSETANYEQZ.{B/H/W/D};
- VSETALLNEZ.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-38-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 20 ++
 target/loongarch/helper.h   | 11 +++
 target/loongarch/insn_trans/trans_lsx.c.inc | 74 +
 target/loongarch/insns.decode   | 17 +
 target/loongarch/lsx_helper.c   | 52 +++
 5 files changed, 174 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 64db01d2f9..ecf0c7b577 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -792,6 +792,12 @@ static bool trans_##insn(DisasContext *ctx, arg_##type * 
a) \
 return true;\
 }
 
+static void output_cv(DisasContext *ctx, arg_cv *a,
+const char *mnemonic)
+{
+output(ctx, mnemonic, "fcc%d, v%d", a->cd, a->vj);
+}
+
 static void output_vvv(DisasContext *ctx, arg_vvv *a, const char *mnemonic)
 {
 output(ctx, mnemonic, "v%d, v%d, v%d", a->vd, a->vj, a->vk);
@@ -1541,3 +1547,17 @@ static bool trans_vfcmp_cond_##suffix(DisasContext *ctx, 
\
 
 LSX_FCMP_INSN(s)
 LSX_FCMP_INSN(d)
+
+INSN_LSX(vbitsel_v,)
+INSN_LSX(vbitseli_b,   vv_i)
+
+INSN_LSX(vseteqz_v,cv)
+INSN_LSX(vsetnez_v,cv)
+INSN_LSX(vsetanyeqz_b, cv)
+INSN_LSX(vsetanyeqz_h, cv)
+INSN_LSX(vsetanyeqz_w, cv)
+INSN_LSX(vsetanyeqz_d, cv)
+INSN_LSX(vsetallnez_b, cv)
+INSN_LSX(vsetallnez_h, cv)
+INSN_LSX(vsetallnez_w, cv)
+INSN_LSX(vsetallnez_d, cv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 867756fdb5..8eb2738cd0 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -642,3 +642,14 @@ DEF_HELPER_5(vfcmp_c_s, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(vfcmp_s_s, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(vfcmp_c_d, void, env, i32, i32, i32, i32)
 DEF_HELPER_5(vfcmp_s_d, void, env, i32, i32, i32, i32)
+
+DEF_HELPER_FLAGS_4(vbitseli_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_3(vsetanyeqz_b, void, env, i32, i32)
+DEF_HELPER_3(vsetanyeqz_h, void, env, i32, i32)
+DEF_HELPER_3(vsetanyeqz_w, void, env, i32, i32)
+DEF_HELPER_3(vsetanyeqz_d, void, env, i32, i32)
+DEF_HELPER_3(vsetallnez_b, void, env, i32, i32)
+DEF_HELPER_3(vsetallnez_h, void, env, i32, i32)
+DEF_HELPER_3(vsetallnez_w, void, env, i32, i32)
+DEF_HELPER_3(vsetallnez_d, void, env, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index abb6efc09d..964c3c47bf 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -65,6 +65,17 @@ static bool gen_vv_i(DisasContext *ctx, arg_vv_i *a,
 return true;
 }
 
+static bool gen_cv(DisasContext *ctx, arg_cv *a,
+void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32))
+{
+TCGv_i32 vj = tcg_constant_i32(a->vj);
+TCGv_i32 cd = tcg_constant_i32(a->cd);
+
+CHECK_SXE;
+func(cpu_env, cd, vj);
+return true;
+}
+
 static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
  void (*func)(unsigned, uint32_t, uint32_t,
   uint32_t, uint32_t, uint32_t))
@@ -3749,3 +3760,66 @@ static bool trans_vfcmp_cond_d(DisasContext *ctx, 
arg_vvv_fcond *a)
 
 return true;
 }
+
+static bool trans_vbitsel_v(DisasContext *ctx, arg_ *a)
+{
+CHECK_SXE;
+
+tcg_gen_gvec_bitsel(MO_64, vec_full_offset(a->vd), vec_full_offset(a->va),
+vec_full_offset(a->vk), vec_full_offset(a->vj),
+16, ctx->vl/8);
+return true;
+}
+
+static void gen_vbitseli(unsigned vece, TCGv_vec a, TCGv_vec b, int64_t imm)
+{
+tcg_gen_bitsel_vec(vece, a, a, tcg_constant_vec_matching(a, vece, imm), b);
+}
+
+static bool trans_vbitseli_b(DisasContext *ctx, arg_vv_i *a)
+{
+static const GVecGen2i op = {
+   .fniv = gen_vbitseli,
+   .fnoi = gen_helper_vbitseli_b,
+   .vece = MO_8,
+   .load_dest = true
+};
+
+CHECK_SXE;
+
+tcg_gen_gvec_2i(vec_full_offset(a->vd), vec_full_offset(a->vj),
+16, ctx->vl/8, a->imm, );
+return true;
+}
+
+#define VSET(NAME, COND)   
\
+static bool trans_## NAME (DisasContext *ctx, arg_cv *a)   
\
+{  
\
+TCGv_i64 t1, al, ah;   
\
+   
\
+al = tcg_temp_new_i64();   
\
+ah = tcg_temp_new_i64();   
\
+t1 = tcg_temp_new_i64();  

[PULL 44/45] target/loongarch: CPUCFG support LSX

2023-05-04 Thread Song Gao
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-45-gaos...@loongson.cn>
---
 target/loongarch/cpu.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 55d7f9255e..c0afc21b2f 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -388,6 +388,7 @@ static void loongarch_la464_initfn(Object *obj)
 data = FIELD_DP32(data, CPUCFG2, FP_SP, 1);
 data = FIELD_DP32(data, CPUCFG2, FP_DP, 1);
 data = FIELD_DP32(data, CPUCFG2, FP_VER, 1);
+data = FIELD_DP32(data, CPUCFG2, LSX, 1),
 data = FIELD_DP32(data, CPUCFG2, LLFTP, 1);
 data = FIELD_DP32(data, CPUCFG2, LLFTP_VER, 1);
 data = FIELD_DP32(data, CPUCFG2, LAM, 1);
-- 
2.31.1




[PULL 41/45] target/loongarch: Implement vld vst

2023-05-04 Thread Song Gao
This patch includes:
- VLD[X], VST[X];
- VLDREPL.{B/H/W/D};
- VSTELM.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-42-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  34 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 159 
 target/loongarch/insns.decode   |  36 +
 target/loongarch/translate.c|  10 ++
 4 files changed, 239 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 0b62bbb8be..8627908fc9 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -21,11 +21,21 @@ static inline int plus_1(DisasContext *ctx, int x)
 return x + 1;
 }
 
+static inline int shl_1(DisasContext *ctx, int x)
+{
+return x << 1;
+}
+
 static inline int shl_2(DisasContext *ctx, int x)
 {
 return x << 2;
 }
 
+static inline int shl_3(DisasContext *ctx, int x)
+{
+return x << 3;
+}
+
 #define CSR_NAME(REG) \
 [LOONGARCH_CSR_##REG] = (#REG)
 
@@ -823,6 +833,11 @@ static void output_vr_i(DisasContext *ctx, arg_vr_i *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, r%d, 0x%x", a->vd, a->rj, a->imm);
 }
 
+static void output_vr_ii(DisasContext *ctx, arg_vr_ii *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, r%d, 0x%x, 0x%x", a->vd, a->rj, a->imm, 
a->imm2);
+}
+
 static void output_rv_i(DisasContext *ctx, arg_rv_i *a, const char *mnemonic)
 {
 output(ctx, mnemonic, "r%d, v%d, 0x%x", a->rd, a->vj,  a->imm);
@@ -838,6 +853,11 @@ static void output_vvr(DisasContext *ctx, arg_vvr *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, v%d, r%d", a->vd, a->vj, a->rk);
 }
 
+static void output_vrr(DisasContext *ctx, arg_vrr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, r%d, r%d", a->vd, a->rj, a->rk);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -1654,3 +1674,17 @@ INSN_LSX(vextrins_d,   vv_i)
 INSN_LSX(vextrins_w,   vv_i)
 INSN_LSX(vextrins_h,   vv_i)
 INSN_LSX(vextrins_b,   vv_i)
+
+INSN_LSX(vld,  vr_i)
+INSN_LSX(vst,  vr_i)
+INSN_LSX(vldx, vrr)
+INSN_LSX(vstx, vrr)
+
+INSN_LSX(vldrepl_d,vr_i)
+INSN_LSX(vldrepl_w,vr_i)
+INSN_LSX(vldrepl_h,vr_i)
+INSN_LSX(vldrepl_b,vr_i)
+INSN_LSX(vstelm_d, vr_ii)
+INSN_LSX(vstelm_w, vr_ii)
+INSN_LSX(vstelm_h, vr_ii)
+INSN_LSX(vstelm_b, vr_ii)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index e1eee6bc4c..86dfd2b399 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4102,3 +4102,162 @@ TRANS(vextrins_b, gen_vv_i, gen_helper_vextrins_b)
 TRANS(vextrins_h, gen_vv_i, gen_helper_vextrins_h)
 TRANS(vextrins_w, gen_vv_i, gen_helper_vextrins_w)
 TRANS(vextrins_d, gen_vv_i, gen_helper_vextrins_d)
+
+static bool trans_vld(DisasContext *ctx, arg_vr_i *a)
+{
+TCGv addr, temp;
+TCGv_i64 rl, rh;
+TCGv_i128 val;
+
+CHECK_SXE;
+
+addr = gpr_src(ctx, a->rj, EXT_NONE);
+val = tcg_temp_new_i128();
+rl = tcg_temp_new_i64();
+rh = tcg_temp_new_i64();
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
+tcg_gen_extr_i128_i64(rl, rh, val);
+set_vreg64(rh, a->vd, 1);
+set_vreg64(rl, a->vd, 0);
+
+return true;
+}
+
+static bool trans_vst(DisasContext *ctx, arg_vr_i *a)
+{
+TCGv addr, temp;
+TCGv_i128 val;
+TCGv_i64 ah, al;
+
+CHECK_SXE;
+
+addr = gpr_src(ctx, a->rj, EXT_NONE);
+val = tcg_temp_new_i128();
+ah = tcg_temp_new_i64();
+al = tcg_temp_new_i64();
+
+if (a->imm) {
+temp = tcg_temp_new();
+tcg_gen_addi_tl(temp, addr, a->imm);
+addr = temp;
+}
+
+get_vreg64(ah, a->vd, 1);
+get_vreg64(al, a->vd, 0);
+tcg_gen_concat_i64_i128(val, al, ah);
+tcg_gen_qemu_st_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
+
+return true;
+}
+
+static bool trans_vldx(DisasContext *ctx, arg_vrr *a)
+{
+TCGv addr, src1, src2;
+TCGv_i64 rl, rh;
+TCGv_i128 val;
+
+CHECK_SXE;
+
+addr = tcg_temp_new();
+src1 = gpr_src(ctx, a->rj, EXT_NONE);
+src2 = gpr_src(ctx, a->rk, EXT_NONE);
+val = tcg_temp_new_i128();
+rl = tcg_temp_new_i64();
+rh = tcg_temp_new_i64();
+
+tcg_gen_add_tl(addr, src1, src2);
+tcg_gen_qemu_ld_i128(val, addr, ctx->mem_idx, MO_128 | MO_TE);
+tcg_gen_extr_i128_i64(rl, rh, val);
+set_vreg64(rh, a->vd, 1);
+set_vreg64(rl, a->vd, 0);
+
+return true;
+}
+
+static bool trans_vstx(DisasContext *ctx, arg_vrr *a)
+{
+TCGv addr, src1, src2;
+TCGv_i64 ah, al;
+TCGv_i128 val;
+
+CHECK_SXE;
+
+addr = tcg_temp_new();
+src1 = gpr_src(ctx, 

[PULL 43/45] target/loongarch: Use {set/get}_gpr replace to cpu_fpr

2023-05-04 Thread Song Gao
Introduce set_fpr() and get_fpr() and remove cpu_fpr.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-44-gaos...@loongson.cn>
---
 .../loongarch/insn_trans/trans_farith.c.inc   | 72 +++
 target/loongarch/insn_trans/trans_fcmp.c.inc  | 12 ++--
 .../loongarch/insn_trans/trans_fmemory.c.inc  | 37 ++
 target/loongarch/insn_trans/trans_fmov.c.inc  | 31 +---
 target/loongarch/translate.c  | 20 --
 5 files changed, 129 insertions(+), 43 deletions(-)

diff --git a/target/loongarch/insn_trans/trans_farith.c.inc 
b/target/loongarch/insn_trans/trans_farith.c.inc
index 7081fbb89b..21ea47308b 100644
--- a/target/loongarch/insn_trans/trans_farith.c.inc
+++ b/target/loongarch/insn_trans/trans_farith.c.inc
@@ -17,18 +17,29 @@
 static bool gen_fff(DisasContext *ctx, arg_fff *a,
 void (*func)(TCGv, TCGv_env, TCGv, TCGv))
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src1 = get_fpr(ctx, a->fj);
+TCGv src2 = get_fpr(ctx, a->fk);
+
 CHECK_FPE;
 
-func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj], cpu_fpr[a->fk]);
+func(dest, cpu_env, src1, src2);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool gen_ff(DisasContext *ctx, arg_ff *a,
void (*func)(TCGv, TCGv_env, TCGv))
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj]);
+func(dest, cpu_env, src);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
@@ -37,61 +48,98 @@ static bool gen_muladd(DisasContext *ctx, arg_ *a,
int flag)
 {
 TCGv_i32 tflag = tcg_constant_i32(flag);
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src1 = get_fpr(ctx, a->fj);
+TCGv src2 = get_fpr(ctx, a->fk);
+TCGv src3 = get_fpr(ctx, a->fa);
 
 CHECK_FPE;
 
-func(cpu_fpr[a->fd], cpu_env, cpu_fpr[a->fj],
- cpu_fpr[a->fk], cpu_fpr[a->fa], tflag);
+func(dest, cpu_env, src1, src2, src3, tflag);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fcopysign_s(DisasContext *ctx, arg_fcopysign_s *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src1 = get_fpr(ctx, a->fk);
+TCGv src2 = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 31);
+tcg_gen_deposit_i64(dest, src1, src2, 0, 31);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fcopysign_d(DisasContext *ctx, arg_fcopysign_d *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src1 = get_fpr(ctx, a->fk);
+TCGv src2 = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_deposit_i64(cpu_fpr[a->fd], cpu_fpr[a->fk], cpu_fpr[a->fj], 0, 63);
+tcg_gen_deposit_i64(dest, src1, src2, 0, 63);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fabs_s(DisasContext *ctx, arg_fabs_s *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 31));
-gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 31));
+gen_nanbox_s(dest, dest);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fabs_d(DisasContext *ctx, arg_fabs_d *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_andi_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], MAKE_64BIT_MASK(0, 63));
+tcg_gen_andi_i64(dest, src, MAKE_64BIT_MASK(0, 63));
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fneg_s(DisasContext *ctx, arg_fneg_s *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000);
-gen_nanbox_s(cpu_fpr[a->fd], cpu_fpr[a->fd]);
+tcg_gen_xori_i64(dest, src, 0x8000);
+gen_nanbox_s(dest, dest);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
 static bool trans_fneg_d(DisasContext *ctx, arg_fneg_d *a)
 {
+TCGv dest = get_fpr(ctx, a->fd);
+TCGv src = get_fpr(ctx, a->fj);
+
 CHECK_FPE;
 
-tcg_gen_xori_i64(cpu_fpr[a->fd], cpu_fpr[a->fj], 0x8000LL);
+tcg_gen_xori_i64(dest, src, 0x8000LL);
+set_fpr(a->fd, dest);
+
 return true;
 }
 
diff --git a/target/loongarch/insn_trans/trans_fcmp.c.inc 
b/target/loongarch/insn_trans/trans_fcmp.c.inc
index 3b0da2b9f4..a78868dbc4 100644
--- a/target/loongarch/insn_trans/trans_fcmp.c.inc
+++ b/target/loongarch/insn_trans/trans_fcmp.c.inc
@@ -25,17 +25,19 @@ static uint32_t get_fcmp_flags(int cond)
 
 static bool trans_fcmp_cond_s(DisasContext *ctx, arg_fcmp_cond_s *a)
 {
-TCGv var;
+TCGv var, src1, src2;
 uint32_t flags;
 void (*fn)(TCGv, TCGv_env, TCGv, TCGv, TCGv_i32);
 
 CHECK_FPE;
 
 var = tcg_temp_new();
+src1 = get_fpr(ctx, a->fj);
+src2 = 

[PULL 00/45] loongarch-to-apply queue

2023-05-04 Thread Song Gao
The following changes since commit f6b761bdbd8ba63cee7428d52fb6b46e4224ddab:

  Merge tag 'qga-pull-2023-05-04' of https://github.com/kostyanf14/qemu into 
staging (2023-05-04 12:08:00 +0100)

are available in the Git repository at:

  https://gitlab.com/gaosong/qemu.git tags/pull-loongarch-20230505

for you to fetch changes up to 9dd207d409cc2eb08fe52965b9d1fd4a12a82bd5:

  hw/intc: don't use target_ulong for LoongArch ipi (2023-05-05 10:00:47 +0800)


Add LoongArch LSX instructions.


Alex Bennée (1):
  hw/intc: don't use target_ulong for LoongArch ipi

Song Gao (44):
  target/loongarch: Add LSX data type VReg
  target/loongarch: meson.build support build LSX
  target/loongarch: Add CHECK_SXE maccro for check LSX enable
  target/loongarch: Implement vadd/vsub
  target/loongarch: Implement vaddi/vsubi
  target/loongarch: Implement vneg
  target/loongarch: Implement vsadd/vssub
  target/loongarch: Implement vhaddw/vhsubw
  target/loongarch: Implement vaddw/vsubw
  target/loongarch: Implement vavg/vavgr
  target/loongarch: Implement vabsd
  target/loongarch: Implement vadda
  target/loongarch: Implement vmax/vmin
  target/loongarch: Implement vmul/vmuh/vmulw{ev/od}
  target/loongarch: Implement vmadd/vmsub/vmaddw{ev/od}
  target/loongarch: Implement vdiv/vmod
  target/loongarch: Implement vsat
  target/loongarch: Implement vexth
  target/loongarch: Implement vsigncov
  target/loongarch: Implement vmskltz/vmskgez/vmsknz
  target/loongarch: Implement LSX logic instructions
  target/loongarch: Implement vsll vsrl vsra vrotr
  target/loongarch: Implement vsllwil vextl
  target/loongarch: Implement vsrlr vsrar
  target/loongarch: Implement vsrln vsran
  target/loongarch: Implement vsrlrn vsrarn
  target/loongarch: Implement vssrln vssran
  target/loongarch: Implement vssrlrn vssrarn
  target/loongarch: Implement vclo vclz
  target/loongarch: Implement vpcnt
  target/loongarch: Implement vbitclr vbitset vbitrev
  target/loongarch: Implement vfrstp
  target/loongarch: Implement LSX fpu arith instructions
  target/loongarch: Implement LSX fpu fcvt instructions
  target/loongarch: Implement vseq vsle vslt
  target/loongarch: Implement vfcmp
  target/loongarch: Implement vbitsel vset
  target/loongarch: Implement vinsgr2vr vpickve2gr vreplgr2vr
  target/loongarch: Implement vreplve vpack vpick
  target/loongarch: Implement vilvl vilvh vextrins vshuf
  target/loongarch: Implement vld vst
  target/loongarch: Implement vldi
  target/loongarch: Use {set/get}_gpr replace to cpu_fpr
  target/loongarch: CPUCFG support LSX

 hw/intc/loongarch_ipi.c |2 +-
 linux-user/loongarch64/signal.c |4 +-
 target/loongarch/cpu.c  |5 +-
 target/loongarch/cpu.h  |   27 +-
 target/loongarch/disas.c|  911 +
 target/loongarch/fpu_helper.c   |2 +-
 target/loongarch/gdbstub.c  |4 +-
 target/loongarch/helper.h   |  566 +++
 target/loongarch/insn_trans/trans_farith.c.inc  |   72 +-
 target/loongarch/insn_trans/trans_fcmp.c.inc|   12 +-
 target/loongarch/insn_trans/trans_fmemory.c.inc |   37 +-
 target/loongarch/insn_trans/trans_fmov.c.inc|   31 +-
 target/loongarch/insn_trans/trans_lsx.c.inc | 4400 +++
 target/loongarch/insns.decode   |  811 +
 target/loongarch/internals.h|   23 +
 target/loongarch/lsx_helper.c   | 3004 
 target/loongarch/machine.c  |   79 +-
 target/loongarch/meson.build|1 +
 target/loongarch/translate.c|   55 +-
 target/loongarch/translate.h|1 +
 20 files changed, 9989 insertions(+), 58 deletions(-)
 create mode 100644 target/loongarch/insn_trans/trans_lsx.c.inc
 create mode 100644 target/loongarch/lsx_helper.c




[PULL 15/45] target/loongarch: Implement vmadd/vmsub/vmaddw{ev/od}

2023-05-04 Thread Song Gao
This patch includes:
- VMADD.{B/H/W/D};
- VMSUB.{B/H/W/D};
- VMADDW{EV/OD}.{H.B/W.H/D.W/Q.D}[U];
- VMADDW{EV/OD}.{H.BU.B/W.HU.H/D.WU.W/Q.DU.D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-16-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  34 ++
 target/loongarch/helper.h   |  30 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 612 
 target/loongarch/insns.decode   |  34 ++
 target/loongarch/lsx_helper.c   | 107 
 5 files changed, 817 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 48e6ef5309..980e6e6375 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1010,3 +1010,37 @@ INSN_LSX(vmulwod_h_bu_b,   vvv)
 INSN_LSX(vmulwod_w_hu_h,   vvv)
 INSN_LSX(vmulwod_d_wu_w,   vvv)
 INSN_LSX(vmulwod_q_du_d,   vvv)
+
+INSN_LSX(vmadd_b,  vvv)
+INSN_LSX(vmadd_h,  vvv)
+INSN_LSX(vmadd_w,  vvv)
+INSN_LSX(vmadd_d,  vvv)
+INSN_LSX(vmsub_b,  vvv)
+INSN_LSX(vmsub_h,  vvv)
+INSN_LSX(vmsub_w,  vvv)
+INSN_LSX(vmsub_d,  vvv)
+
+INSN_LSX(vmaddwev_h_b, vvv)
+INSN_LSX(vmaddwev_w_h, vvv)
+INSN_LSX(vmaddwev_d_w, vvv)
+INSN_LSX(vmaddwev_q_d, vvv)
+INSN_LSX(vmaddwod_h_b, vvv)
+INSN_LSX(vmaddwod_w_h, vvv)
+INSN_LSX(vmaddwod_d_w, vvv)
+INSN_LSX(vmaddwod_q_d, vvv)
+INSN_LSX(vmaddwev_h_bu,vvv)
+INSN_LSX(vmaddwev_w_hu,vvv)
+INSN_LSX(vmaddwev_d_wu,vvv)
+INSN_LSX(vmaddwev_q_du,vvv)
+INSN_LSX(vmaddwod_h_bu,vvv)
+INSN_LSX(vmaddwod_w_hu,vvv)
+INSN_LSX(vmaddwod_d_wu,vvv)
+INSN_LSX(vmaddwod_q_du,vvv)
+INSN_LSX(vmaddwev_h_bu_b,  vvv)
+INSN_LSX(vmaddwev_w_hu_h,  vvv)
+INSN_LSX(vmaddwev_d_wu_w,  vvv)
+INSN_LSX(vmaddwev_q_du_d,  vvv)
+INSN_LSX(vmaddwod_h_bu_b,  vvv)
+INSN_LSX(vmaddwod_w_hu_h,  vvv)
+INSN_LSX(vmaddwod_d_wu_w,  vvv)
+INSN_LSX(vmaddwod_q_du_d,  vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 830d8cbe62..8cf9620702 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -273,3 +273,33 @@ DEF_HELPER_FLAGS_4(vmulwev_d_wu_w, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmulwod_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmulwod_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmulwod_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmadd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmadd_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmsub_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmsub_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmsub_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmsub_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmaddwev_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmaddwev_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmaddwev_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwev_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmaddwod_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 9a36f942e2..400c3a0339 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2064,3 +2064,615 @@ static void do_vmulwod_u_s(unsigned vece, uint32_t 
vd_ofs, uint32_t vj_ofs,
 TRANS(vmulwod_h_bu_b, gvec_vvv, MO_8, do_vmulwod_u_s)
 TRANS(vmulwod_w_hu_h, gvec_vvv, MO_16, do_vmulwod_u_s)
 TRANS(vmulwod_d_wu_w, gvec_vvv, MO_32, do_vmulwod_u_s)
+
+static void 

[PULL 27/45] target/loongarch: Implement vssrln vssran

2023-05-04 Thread Song Gao
This patch includes:
- VSSRLN.{B.H/H.W/W.D};
- VSSRAN.{B.H/H.W/W.D};
- VSSRLN.{BU.H/HU.W/WU.D};
- VSSRAN.{BU.H/HU.W/WU.D};
- VSSRLNI.{B.H/H.W/W.D/D.Q};
- VSSRANI.{B.H/H.W/W.D/D.Q};
- VSSRLNI.{BU.H/HU.W/WU.D/DU.Q};
- VSSRANI.{BU.H/HU.W/WU.D/DU.Q}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-28-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  30 ++
 target/loongarch/helper.h   |  30 ++
 target/loongarch/insn_trans/trans_lsx.c.inc |  30 ++
 target/loongarch/insns.decode   |  30 ++
 target/loongarch/lsx_helper.c   | 379 
 5 files changed, 499 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 185cd36381..426d30dc01 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1198,3 +1198,33 @@ INSN_LSX(vsrarni_b_h,  vv_i)
 INSN_LSX(vsrarni_h_w,  vv_i)
 INSN_LSX(vsrarni_w_d,  vv_i)
 INSN_LSX(vsrarni_d_q,  vv_i)
+
+INSN_LSX(vssrln_b_h,   vvv)
+INSN_LSX(vssrln_h_w,   vvv)
+INSN_LSX(vssrln_w_d,   vvv)
+INSN_LSX(vssran_b_h,   vvv)
+INSN_LSX(vssran_h_w,   vvv)
+INSN_LSX(vssran_w_d,   vvv)
+INSN_LSX(vssrln_bu_h,  vvv)
+INSN_LSX(vssrln_hu_w,  vvv)
+INSN_LSX(vssrln_wu_d,  vvv)
+INSN_LSX(vssran_bu_h,  vvv)
+INSN_LSX(vssran_hu_w,  vvv)
+INSN_LSX(vssran_wu_d,  vvv)
+
+INSN_LSX(vssrlni_b_h,  vv_i)
+INSN_LSX(vssrlni_h_w,  vv_i)
+INSN_LSX(vssrlni_w_d,  vv_i)
+INSN_LSX(vssrlni_d_q,  vv_i)
+INSN_LSX(vssrani_b_h,  vv_i)
+INSN_LSX(vssrani_h_w,  vv_i)
+INSN_LSX(vssrani_w_d,  vv_i)
+INSN_LSX(vssrani_d_q,  vv_i)
+INSN_LSX(vssrlni_bu_h, vv_i)
+INSN_LSX(vssrlni_hu_w, vv_i)
+INSN_LSX(vssrlni_wu_d, vv_i)
+INSN_LSX(vssrlni_du_q, vv_i)
+INSN_LSX(vssrani_bu_h, vv_i)
+INSN_LSX(vssrani_hu_w, vv_i)
+INSN_LSX(vssrani_wu_d, vv_i)
+INSN_LSX(vssrani_du_q, vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 0a8cfe3625..28f159768c 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -411,3 +411,33 @@ DEF_HELPER_4(vsrarni_b_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrarni_h_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrarni_w_d, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrarni_d_q, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vssrln_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrln_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrln_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrln_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrln_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrln_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssran_wu_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vssrlni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlni_du_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrani_du_q, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 6034a74bfb..5d7e45a793 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3037,3 +3037,33 @@ TRANS(vsrarni_b_h, gen_vv_i, gen_helper_vsrarni_b_h)
 TRANS(vsrarni_h_w, gen_vv_i, gen_helper_vsrarni_h_w)
 TRANS(vsrarni_w_d, gen_vv_i, gen_helper_vsrarni_w_d)
 TRANS(vsrarni_d_q, gen_vv_i, gen_helper_vsrarni_d_q)
+
+TRANS(vssrln_b_h, gen_vvv, gen_helper_vssrln_b_h)
+TRANS(vssrln_h_w, gen_vvv, gen_helper_vssrln_h_w)
+TRANS(vssrln_w_d, gen_vvv, gen_helper_vssrln_w_d)
+TRANS(vssran_b_h, gen_vvv, gen_helper_vssran_b_h)
+TRANS(vssran_h_w, gen_vvv, gen_helper_vssran_h_w)
+TRANS(vssran_w_d, gen_vvv, gen_helper_vssran_w_d)
+TRANS(vssrln_bu_h, gen_vvv, gen_helper_vssrln_bu_h)
+TRANS(vssrln_hu_w, gen_vvv, gen_helper_vssrln_hu_w)
+TRANS(vssrln_wu_d, gen_vvv, gen_helper_vssrln_wu_d)
+TRANS(vssran_bu_h, gen_vvv, gen_helper_vssran_bu_h)
+TRANS(vssran_hu_w, gen_vvv, gen_helper_vssran_hu_w)
+TRANS(vssran_wu_d, gen_vvv, gen_helper_vssran_wu_d)
+
+TRANS(vssrlni_b_h, gen_vv_i, 

[PULL 17/45] target/loongarch: Implement vsat

2023-05-04 Thread Song Gao
This patch includes:
- VSAT.{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-18-gaos...@loongson.cn>
---
 target/loongarch/disas.c|   9 ++
 target/loongarch/helper.h   |   9 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 101 
 target/loongarch/insns.decode   |  12 +++
 target/loongarch/lsx_helper.c   |  37 +++
 5 files changed, 168 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 6e4f676a42..b04aefe3ed 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1061,3 +1061,12 @@ INSN_LSX(vmod_bu,  vvv)
 INSN_LSX(vmod_hu,  vvv)
 INSN_LSX(vmod_wu,  vvv)
 INSN_LSX(vmod_du,  vvv)
+
+INSN_LSX(vsat_b,   vv_i)
+INSN_LSX(vsat_h,   vv_i)
+INSN_LSX(vsat_w,   vv_i)
+INSN_LSX(vsat_d,   vv_i)
+INSN_LSX(vsat_bu,  vv_i)
+INSN_LSX(vsat_hu,  vv_i)
+INSN_LSX(vsat_wu,  vv_i)
+INSN_LSX(vsat_du,  vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 7b7c685ede..d2b1c9f2a4 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -320,3 +320,12 @@ DEF_HELPER_4(vmod_bu, void, env, i32, i32, i32)
 DEF_HELPER_4(vmod_hu, void, env, i32, i32, i32)
 DEF_HELPER_4(vmod_wu, void, env, i32, i32, i32)
 DEF_HELPER_4(vmod_du, void, env, i32, i32, i32)
+
+DEF_HELPER_FLAGS_4(vsat_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vsat_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index b295a9c4df..b8f05c66a5 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2693,3 +2693,104 @@ TRANS(vmod_bu, gen_vvv, gen_helper_vmod_bu)
 TRANS(vmod_hu, gen_vvv, gen_helper_vmod_hu)
 TRANS(vmod_wu, gen_vvv, gen_helper_vmod_wu)
 TRANS(vmod_du, gen_vvv, gen_helper_vmod_du)
+
+static void gen_vsat_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
+{
+TCGv_vec min;
+
+min = tcg_temp_new_vec_matching(t);
+tcg_gen_not_vec(vece, min, max);
+tcg_gen_smax_vec(vece, t, a, min);
+tcg_gen_smin_vec(vece, t, t, max);
+}
+
+static void do_vsat_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+  int64_t imm, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_smax_vec, INDEX_op_smin_vec, 0
+};
+static const GVecGen2s op[4] = {
+{
+.fniv = gen_vsat_s,
+.fno = gen_helper_vsat_b,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vsat_s,
+.fno = gen_helper_vsat_h,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vsat_s,
+.fno = gen_helper_vsat_w,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vsat_s,
+.fno = gen_helper_vsat_d,
+.opt_opc = vecop_list,
+.vece = MO_64
+},
+};
+
+tcg_gen_gvec_2s(vd_ofs, vj_ofs, oprsz, maxsz,
+tcg_constant_i64((1ll<< imm) -1), [vece]);
+}
+
+TRANS(vsat_b, gvec_vv_i, MO_8, do_vsat_s)
+TRANS(vsat_h, gvec_vv_i, MO_16, do_vsat_s)
+TRANS(vsat_w, gvec_vv_i, MO_32, do_vsat_s)
+TRANS(vsat_d, gvec_vv_i, MO_64, do_vsat_s)
+
+static void gen_vsat_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec max)
+{
+tcg_gen_umin_vec(vece, t, a, max);
+}
+
+static void do_vsat_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+   int64_t imm, uint32_t oprsz, uint32_t maxsz)
+{
+uint64_t max;
+static const TCGOpcode vecop_list[] = {
+INDEX_op_umin_vec, 0
+};
+static const GVecGen2s op[4] = {
+{
+.fniv = gen_vsat_u,
+.fno = gen_helper_vsat_bu,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vsat_u,
+.fno = gen_helper_vsat_hu,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vsat_u,
+.fno = gen_helper_vsat_wu,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vsat_u,
+.fno = gen_helper_vsat_du,
+.opt_opc = vecop_list,
+   

[PULL 36/45] target/loongarch: Implement vfcmp

2023-05-04 Thread Song Gao
This patch includes:
- VFCMP.cond.{S/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-37-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 94 +
 target/loongarch/helper.h   |  5 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 32 +++
 target/loongarch/insns.decode   |  5 ++
 target/loongarch/lsx_helper.c   | 54 
 5 files changed, 190 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index e589b23f4c..64db01d2f9 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1447,3 +1447,97 @@ INSN_LSX(vslti_bu, vv_i)
 INSN_LSX(vslti_hu, vv_i)
 INSN_LSX(vslti_wu, vv_i)
 INSN_LSX(vslti_du, vv_i)
+
+#define output_vfcmp(C, PREFIX, SUFFIX) \
+{   \
+(C)->info->fprintf_func((C)->info->stream, "%08x   %s%s\t%d, f%d, f%d", \
+(C)->insn, PREFIX, SUFFIX, a->vd,   \
+a->vj, a->vk);  \
+}
+
+static bool output_vvv_fcond(DisasContext *ctx, arg_vvv_fcond * a,
+ const char *suffix)
+{
+bool ret = true;
+switch (a->fcond) {
+case 0x0:
+output_vfcmp(ctx, "vfcmp_caf_", suffix);
+break;
+case 0x1:
+output_vfcmp(ctx, "vfcmp_saf_", suffix);
+break;
+case 0x2:
+output_vfcmp(ctx, "vfcmp_clt_", suffix);
+break;
+case 0x3:
+output_vfcmp(ctx, "vfcmp_slt_", suffix);
+break;
+case 0x4:
+output_vfcmp(ctx, "vfcmp_ceq_", suffix);
+break;
+case 0x5:
+output_vfcmp(ctx, "vfcmp_seq_", suffix);
+break;
+case 0x6:
+output_vfcmp(ctx, "vfcmp_cle_", suffix);
+break;
+case 0x7:
+output_vfcmp(ctx, "vfcmp_sle_", suffix);
+break;
+case 0x8:
+output_vfcmp(ctx, "vfcmp_cun_", suffix);
+break;
+case 0x9:
+output_vfcmp(ctx, "vfcmp_sun_", suffix);
+break;
+case 0xA:
+output_vfcmp(ctx, "vfcmp_cult_", suffix);
+break;
+case 0xB:
+output_vfcmp(ctx, "vfcmp_sult_", suffix);
+break;
+case 0xC:
+output_vfcmp(ctx, "vfcmp_cueq_", suffix);
+break;
+case 0xD:
+output_vfcmp(ctx, "vfcmp_sueq_", suffix);
+break;
+case 0xE:
+output_vfcmp(ctx, "vfcmp_cule_", suffix);
+break;
+case 0xF:
+output_vfcmp(ctx, "vfcmp_sule_", suffix);
+break;
+case 0x10:
+output_vfcmp(ctx, "vfcmp_cne_", suffix);
+break;
+case 0x11:
+output_vfcmp(ctx, "vfcmp_sne_", suffix);
+break;
+case 0x14:
+output_vfcmp(ctx, "vfcmp_cor_", suffix);
+break;
+case 0x15:
+output_vfcmp(ctx, "vfcmp_sor_", suffix);
+break;
+case 0x18:
+output_vfcmp(ctx, "vfcmp_cune_", suffix);
+break;
+case 0x19:
+output_vfcmp(ctx, "vfcmp_sune_", suffix);
+break;
+default:
+ret = false;
+}
+return ret;
+}
+
+#define LSX_FCMP_INSN(suffix)\
+static bool trans_vfcmp_cond_##suffix(DisasContext *ctx, \
+ arg_vvv_fcond * a)  \
+{\
+return output_vvv_fcond(ctx, a, #suffix);\
+}
+
+LSX_FCMP_INSN(s)
+LSX_FCMP_INSN(d)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index e9e9fa7f87..867756fdb5 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -637,3 +637,8 @@ DEF_HELPER_FLAGS_4(vslti_bu, TCG_CALL_NO_RWG, void, ptr, 
ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vslti_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vslti_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vslti_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_5(vfcmp_c_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfcmp_s_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfcmp_c_d, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfcmp_s_d, void, env, i32, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 4d9f88bf4f..abb6efc09d 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3717,3 +3717,35 @@ TRANS(vslti_bu, do_vslti_u, MO_8)
 TRANS(vslti_hu, do_vslti_u, MO_16)
 TRANS(vslti_wu, do_vslti_u, MO_32)
 TRANS(vslti_du, do_vslti_u, MO_64)
+
+static bool trans_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a)
+{
+uint32_t flags;
+void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
+TCGv_i32 vd = tcg_constant_i32(a->vd);
+TCGv_i32 vj = tcg_constant_i32(a->vj);
+TCGv_i32 vk = tcg_constant_i32(a->vk);
+

[PULL 29/45] target/loongarch: Implement vclo vclz

2023-05-04 Thread Song Gao
This patch includes:
- VCLO.{B/H/W/D};
- VCLZ.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-30-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  9 ++
 target/loongarch/helper.h   |  9 ++
 target/loongarch/insn_trans/trans_lsx.c.inc |  9 ++
 target/loongarch/insns.decode   |  9 ++
 target/loongarch/lsx_helper.c   | 31 +
 5 files changed, 67 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 405e8885cd..0c82a1d9d1 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1258,3 +1258,12 @@ INSN_LSX(vssrarni_bu_h,vv_i)
 INSN_LSX(vssrarni_hu_w,vv_i)
 INSN_LSX(vssrarni_wu_d,vv_i)
 INSN_LSX(vssrarni_du_q,vv_i)
+
+INSN_LSX(vclo_b,   vv)
+INSN_LSX(vclo_h,   vv)
+INSN_LSX(vclo_w,   vv)
+INSN_LSX(vclo_d,   vv)
+INSN_LSX(vclz_b,   vv)
+INSN_LSX(vclz_h,   vv)
+INSN_LSX(vclz_w,   vv)
+INSN_LSX(vclz_d,   vv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 724112da81..e21e9b9704 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -471,3 +471,12 @@ DEF_HELPER_4(vssrarni_bu_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrarni_hu_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrarni_wu_d, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrarni_du_q, void, env, i32, i32, i32)
+
+DEF_HELPER_3(vclo_b, void, env, i32, i32)
+DEF_HELPER_3(vclo_h, void, env, i32, i32)
+DEF_HELPER_3(vclo_w, void, env, i32, i32)
+DEF_HELPER_3(vclo_d, void, env, i32, i32)
+DEF_HELPER_3(vclz_b, void, env, i32, i32)
+DEF_HELPER_3(vclz_h, void, env, i32, i32)
+DEF_HELPER_3(vclz_w, void, env, i32, i32)
+DEF_HELPER_3(vclz_d, void, env, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 9c24cbc297..c7649fb777 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3097,3 +3097,12 @@ TRANS(vssrarni_bu_h, gen_vv_i, gen_helper_vssrarni_bu_h)
 TRANS(vssrarni_hu_w, gen_vv_i, gen_helper_vssrarni_hu_w)
 TRANS(vssrarni_wu_d, gen_vv_i, gen_helper_vssrarni_wu_d)
 TRANS(vssrarni_du_q, gen_vv_i, gen_helper_vssrarni_du_q)
+
+TRANS(vclo_b, gen_vv, gen_helper_vclo_b)
+TRANS(vclo_h, gen_vv, gen_helper_vclo_h)
+TRANS(vclo_w, gen_vv, gen_helper_vclo_w)
+TRANS(vclo_d, gen_vv, gen_helper_vclo_d)
+TRANS(vclz_b, gen_vv, gen_helper_vclz_b)
+TRANS(vclz_h, gen_vv, gen_helper_vclz_h)
+TRANS(vclz_w, gen_vv, gen_helper_vclz_w)
+TRANS(vclz_d, gen_vv, gen_helper_vclz_d)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index bb4b2a8632..7591ec1bab 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -959,3 +959,12 @@ vssrarni_bu_h0111 00110110 11000 1  . .   
@vv_ui4
 vssrarni_hu_w0111 00110110 11001 . . .@vv_ui5
 vssrarni_wu_d0111 00110110 1101 .. . .@vv_ui6
 vssrarni_du_q0111 00110110 111 ... . .@vv_ui7
+
+vclo_b   0111 00101001 11000 0 . .@vv
+vclo_h   0111 00101001 11000 1 . .@vv
+vclo_w   0111 00101001 11000 00010 . .@vv
+vclo_d   0111 00101001 11000 00011 . .@vv
+vclz_b   0111 00101001 11000 00100 . .@vv
+vclz_h   0111 00101001 11000 00101 . .@vv
+vclz_w   0111 00101001 11000 00110 . .@vv
+vclz_d   0111 00101001 11000 00111 . .@vv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index fb6f29c94d..044032f180 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -1915,3 +1915,34 @@ void HELPER(vssrarni_du_q)(CPULoongArchState *env,
 VSSRARNUI(vssrarni_bu_h, 16, B, H)
 VSSRARNUI(vssrarni_hu_w, 32, H, W)
 VSSRARNUI(vssrarni_wu_d, 64, W, D)
+
+#define DO_2OP(NAME, BIT, E, DO_OP) \
+void HELPER(NAME)(CPULoongArchState *env, uint32_t vd, uint32_t vj) \
+{   \
+int i;  \
+VReg *Vd = &(env->fpr[vd].vreg);\
+VReg *Vj = &(env->fpr[vj].vreg);\
+\
+for (i = 0; i < LSX_LEN/BIT; i++)   \
+{   \
+Vd->E(i) = DO_OP(Vj->E(i)); \
+}   \
+}
+
+#define DO_CLO_B(N)  (clz32(~N & 0xff) - 24)
+#define DO_CLO_H(N)  (clz32(~N & 0x) - 16)
+#define DO_CLO_W(N)  (clz32(~N))
+#define DO_CLO_D(N)  (clz64(~N))
+#define DO_CLZ_B(N)  

[PULL 22/45] target/loongarch: Implement vsll vsrl vsra vrotr

2023-05-04 Thread Song Gao
This patch includes:
- VSLL[I].{B/H/W/D};
- VSRL[I].{B/H/W/D};
- VSRA[I].{B/H/W/D};
- VROTR[I].{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-23-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 36 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 36 +
 target/loongarch/insns.decode   | 36 +
 3 files changed, 108 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index eca0a4bb7b..f7d0fb4441 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1103,3 +1103,39 @@ INSN_LSX(vandi_b,  vv_i)
 INSN_LSX(vori_b,   vv_i)
 INSN_LSX(vxori_b,  vv_i)
 INSN_LSX(vnori_b,  vv_i)
+
+INSN_LSX(vsll_b,   vvv)
+INSN_LSX(vsll_h,   vvv)
+INSN_LSX(vsll_w,   vvv)
+INSN_LSX(vsll_d,   vvv)
+INSN_LSX(vslli_b,  vv_i)
+INSN_LSX(vslli_h,  vv_i)
+INSN_LSX(vslli_w,  vv_i)
+INSN_LSX(vslli_d,  vv_i)
+
+INSN_LSX(vsrl_b,   vvv)
+INSN_LSX(vsrl_h,   vvv)
+INSN_LSX(vsrl_w,   vvv)
+INSN_LSX(vsrl_d,   vvv)
+INSN_LSX(vsrli_b,  vv_i)
+INSN_LSX(vsrli_h,  vv_i)
+INSN_LSX(vsrli_w,  vv_i)
+INSN_LSX(vsrli_d,  vv_i)
+
+INSN_LSX(vsra_b,   vvv)
+INSN_LSX(vsra_h,   vvv)
+INSN_LSX(vsra_w,   vvv)
+INSN_LSX(vsra_d,   vvv)
+INSN_LSX(vsrai_b,  vv_i)
+INSN_LSX(vsrai_h,  vv_i)
+INSN_LSX(vsrai_w,  vv_i)
+INSN_LSX(vsrai_d,  vv_i)
+
+INSN_LSX(vrotr_b,  vvv)
+INSN_LSX(vrotr_h,  vvv)
+INSN_LSX(vrotr_w,  vvv)
+INSN_LSX(vrotr_d,  vvv)
+INSN_LSX(vrotri_b, vv_i)
+INSN_LSX(vrotri_h, vv_i)
+INSN_LSX(vrotri_w, vv_i)
+INSN_LSX(vrotri_d, vv_i)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index e5e194106b..ad8f32ed18 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2930,3 +2930,39 @@ static void do_vnori_b(unsigned vece, uint32_t vd_ofs, 
uint32_t vj_ofs,
 }
 
 TRANS(vnori_b, gvec_vv_i, MO_8, do_vnori_b)
+
+TRANS(vsll_b, gvec_vvv, MO_8, tcg_gen_gvec_shlv)
+TRANS(vsll_h, gvec_vvv, MO_16, tcg_gen_gvec_shlv)
+TRANS(vsll_w, gvec_vvv, MO_32, tcg_gen_gvec_shlv)
+TRANS(vsll_d, gvec_vvv, MO_64, tcg_gen_gvec_shlv)
+TRANS(vslli_b, gvec_vv_i, MO_8, tcg_gen_gvec_shli)
+TRANS(vslli_h, gvec_vv_i, MO_16, tcg_gen_gvec_shli)
+TRANS(vslli_w, gvec_vv_i, MO_32, tcg_gen_gvec_shli)
+TRANS(vslli_d, gvec_vv_i, MO_64, tcg_gen_gvec_shli)
+
+TRANS(vsrl_b, gvec_vvv, MO_8, tcg_gen_gvec_shrv)
+TRANS(vsrl_h, gvec_vvv, MO_16, tcg_gen_gvec_shrv)
+TRANS(vsrl_w, gvec_vvv, MO_32, tcg_gen_gvec_shrv)
+TRANS(vsrl_d, gvec_vvv, MO_64, tcg_gen_gvec_shrv)
+TRANS(vsrli_b, gvec_vv_i, MO_8, tcg_gen_gvec_shri)
+TRANS(vsrli_h, gvec_vv_i, MO_16, tcg_gen_gvec_shri)
+TRANS(vsrli_w, gvec_vv_i, MO_32, tcg_gen_gvec_shri)
+TRANS(vsrli_d, gvec_vv_i, MO_64, tcg_gen_gvec_shri)
+
+TRANS(vsra_b, gvec_vvv, MO_8, tcg_gen_gvec_sarv)
+TRANS(vsra_h, gvec_vvv, MO_16, tcg_gen_gvec_sarv)
+TRANS(vsra_w, gvec_vvv, MO_32, tcg_gen_gvec_sarv)
+TRANS(vsra_d, gvec_vvv, MO_64, tcg_gen_gvec_sarv)
+TRANS(vsrai_b, gvec_vv_i, MO_8, tcg_gen_gvec_sari)
+TRANS(vsrai_h, gvec_vv_i, MO_16, tcg_gen_gvec_sari)
+TRANS(vsrai_w, gvec_vv_i, MO_32, tcg_gen_gvec_sari)
+TRANS(vsrai_d, gvec_vv_i, MO_64, tcg_gen_gvec_sari)
+
+TRANS(vrotr_b, gvec_vvv, MO_8, tcg_gen_gvec_rotrv)
+TRANS(vrotr_h, gvec_vvv, MO_16, tcg_gen_gvec_rotrv)
+TRANS(vrotr_w, gvec_vvv, MO_32, tcg_gen_gvec_rotrv)
+TRANS(vrotr_d, gvec_vvv, MO_64, tcg_gen_gvec_rotrv)
+TRANS(vrotri_b, gvec_vv_i, MO_8, tcg_gen_gvec_rotri)
+TRANS(vrotri_h, gvec_vv_i, MO_16, tcg_gen_gvec_rotri)
+TRANS(vrotri_w, gvec_vv_i, MO_32, tcg_gen_gvec_rotri)
+TRANS(vrotri_d, gvec_vv_i, MO_64, tcg_gen_gvec_rotri)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 6309683be9..7c0b0c4ac8 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -803,3 +803,39 @@ vandi_b  0111 0001 00  . .
@vv_ui8
 vori_b   0111 0001 01  . .@vv_ui8
 vxori_b  0111 0001 10  . .@vv_ui8
 vnori_b  0111 0001 11  . .@vv_ui8
+
+vsll_b   0111 1110 1 . . .@vvv
+vsll_h   0111 1110 10001 . . .@vvv
+vsll_w   0111 1110 10010 . . .@vvv
+vsll_d   0111 1110 10011 . . .@vvv
+vslli_b  0111 00110010 11000 01 ... . .   @vv_ui3
+vslli_h  0111 00110010 11000 1  . .   @vv_ui4
+vslli_w  0111 00110010 11001 . . .@vv_ui5
+vslli_d  0111 00110010 1101 .. . .@vv_ui6
+
+vsrl_b   0111 1110 10100 . . 

[PULL 33/45] target/loongarch: Implement LSX fpu arith instructions

2023-05-04 Thread Song Gao
This patch includes:
- VF{ADD/SUB/MUL/DIV}.{S/D};
- VF{MADD/MSUB/NMADD/NMSUB}.{S/D};
- VF{MAX/MIN}.{S/D};
- VF{MAXA/MINA}.{S/D};
- VFLOGB.{S/D};
- VFCLASS.{S/D};
- VF{SQRT/RECIP/RSQRT}.{S/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-34-gaos...@loongson.cn>
---
 target/loongarch/cpu.h  |   4 +
 target/loongarch/disas.c|  46 +
 target/loongarch/fpu_helper.c   |   2 +-
 target/loongarch/helper.h   |  41 +
 target/loongarch/insn_trans/trans_lsx.c.inc |  55 ++
 target/loongarch/insns.decode   |  43 +
 target/loongarch/internals.h|   1 +
 target/loongarch/lsx_helper.c   | 186 
 8 files changed, 377 insertions(+), 1 deletion(-)

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 6755b1f0c7..1f37e36b7c 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -55,6 +55,10 @@ FIELD(FCSR0, CAUSE, 24, 5)
 do { \
 (REG) = FIELD_DP32(REG, FCSR0, CAUSE, V); \
 } while (0)
+#define UPDATE_FP_CAUSE(REG, V) \
+do { \
+(REG) |= FIELD_DP32(0, FCSR0, CAUSE, V); \
+} while (0)
 
 #define GET_FP_ENABLES(REG)FIELD_EX32(REG, FCSR0, ENABLES)
 #define SET_FP_ENABLES(REG, V) \
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index be2bb9cc42..b57b284e49 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -807,6 +807,11 @@ static void output_vv(DisasContext *ctx, arg_vv *a, const 
char *mnemonic)
 output(ctx, mnemonic, "v%d, v%d", a->vd, a->vj);
 }
 
+static void output_(DisasContext *ctx, arg_ *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, v%d, v%d, v%d", a->vd, a->vj, a->vk, a->va);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -1302,3 +1307,44 @@ INSN_LSX(vfrstp_b, vvv)
 INSN_LSX(vfrstp_h, vvv)
 INSN_LSX(vfrstpi_b,vv_i)
 INSN_LSX(vfrstpi_h,vv_i)
+
+INSN_LSX(vfadd_s,  vvv)
+INSN_LSX(vfadd_d,  vvv)
+INSN_LSX(vfsub_s,  vvv)
+INSN_LSX(vfsub_d,  vvv)
+INSN_LSX(vfmul_s,  vvv)
+INSN_LSX(vfmul_d,  vvv)
+INSN_LSX(vfdiv_s,  vvv)
+INSN_LSX(vfdiv_d,  vvv)
+
+INSN_LSX(vfmadd_s, )
+INSN_LSX(vfmadd_d, )
+INSN_LSX(vfmsub_s, )
+INSN_LSX(vfmsub_d, )
+INSN_LSX(vfnmadd_s,)
+INSN_LSX(vfnmadd_d,)
+INSN_LSX(vfnmsub_s,)
+INSN_LSX(vfnmsub_d,)
+
+INSN_LSX(vfmax_s,  vvv)
+INSN_LSX(vfmax_d,  vvv)
+INSN_LSX(vfmin_s,  vvv)
+INSN_LSX(vfmin_d,  vvv)
+
+INSN_LSX(vfmaxa_s, vvv)
+INSN_LSX(vfmaxa_d, vvv)
+INSN_LSX(vfmina_s, vvv)
+INSN_LSX(vfmina_d, vvv)
+
+INSN_LSX(vflogb_s, vv)
+INSN_LSX(vflogb_d, vv)
+
+INSN_LSX(vfclass_s,vv)
+INSN_LSX(vfclass_d,vv)
+
+INSN_LSX(vfsqrt_s, vv)
+INSN_LSX(vfsqrt_d, vv)
+INSN_LSX(vfrecip_s,vv)
+INSN_LSX(vfrecip_d,vv)
+INSN_LSX(vfrsqrt_s,vv)
+INSN_LSX(vfrsqrt_d,vv)
diff --git a/target/loongarch/fpu_helper.c b/target/loongarch/fpu_helper.c
index 4b9637210a..f6753c5875 100644
--- a/target/loongarch/fpu_helper.c
+++ b/target/loongarch/fpu_helper.c
@@ -33,7 +33,7 @@ void restore_fp_status(CPULoongArchState *env)
 set_flush_to_zero(0, >fp_status);
 }
 
-static int ieee_ex_to_loongarch(int xcpt)
+int ieee_ex_to_loongarch(int xcpt)
 {
 int ret = 0;
 if (xcpt & float_flag_invalid) {
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 2cc235d019..a0c9de271d 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -517,3 +517,44 @@ DEF_HELPER_4(vfrstp_b, void, env, i32, i32, i32)
 DEF_HELPER_4(vfrstp_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vfrstpi_b, void, env, i32, i32, i32)
 DEF_HELPER_4(vfrstpi_h, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vfadd_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfadd_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vfsub_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfsub_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vfmul_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfmul_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vfdiv_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfdiv_d, void, env, i32, i32, i32)
+
+DEF_HELPER_5(vfmadd_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfmadd_d, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfmsub_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfmsub_d, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfnmadd_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfnmadd_d, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfnmsub_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(vfnmsub_d, void, env, i32, i32, i32, i32)
+
+DEF_HELPER_4(vfmax_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfmax_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vfmin_s, void, env, i32, 

[PULL 39/45] target/loongarch: Implement vreplve vpack vpick

2023-05-04 Thread Song Gao
This patch includes:
- VREPLVE[I].{B/H/W/D};
- VBSLL.V, VBSRL.V;
- VPACK{EV/OD}.{B/H/W/D};
- VPICK{EV/OD}.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-40-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  35 +
 target/loongarch/helper.h   |  18 +++
 target/loongarch/insn_trans/trans_lsx.c.inc | 144 
 target/loongarch/insns.decode   |  34 +
 target/loongarch/lsx_helper.c   |  88 
 5 files changed, 319 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 7255a2aa4f..c6cf782725 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -833,6 +833,11 @@ static void output_vr(DisasContext *ctx, arg_vr *a, const 
char *mnemonic)
 output(ctx, mnemonic, "v%d, r%d", a->vd, a->rj);
 }
 
+static void output_vvr(DisasContext *ctx, arg_vvr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, v%d, r%d", a->vd, a->vj, a->rk);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -1594,3 +1599,33 @@ INSN_LSX(vreplgr2vr_b, vr)
 INSN_LSX(vreplgr2vr_h, vr)
 INSN_LSX(vreplgr2vr_w, vr)
 INSN_LSX(vreplgr2vr_d, vr)
+
+INSN_LSX(vreplve_b,vvr)
+INSN_LSX(vreplve_h,vvr)
+INSN_LSX(vreplve_w,vvr)
+INSN_LSX(vreplve_d,vvr)
+INSN_LSX(vreplvei_b,   vv_i)
+INSN_LSX(vreplvei_h,   vv_i)
+INSN_LSX(vreplvei_w,   vv_i)
+INSN_LSX(vreplvei_d,   vv_i)
+
+INSN_LSX(vbsll_v,  vv_i)
+INSN_LSX(vbsrl_v,  vv_i)
+
+INSN_LSX(vpackev_b,vvv)
+INSN_LSX(vpackev_h,vvv)
+INSN_LSX(vpackev_w,vvv)
+INSN_LSX(vpackev_d,vvv)
+INSN_LSX(vpackod_b,vvv)
+INSN_LSX(vpackod_h,vvv)
+INSN_LSX(vpackod_w,vvv)
+INSN_LSX(vpackod_d,vvv)
+
+INSN_LSX(vpickev_b,vvv)
+INSN_LSX(vpickev_h,vvv)
+INSN_LSX(vpickev_w,vvv)
+INSN_LSX(vpickev_d,vvv)
+INSN_LSX(vpickod_b,vvv)
+INSN_LSX(vpickod_h,vvv)
+INSN_LSX(vpickod_w,vvv)
+INSN_LSX(vpickod_d,vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 8eb2738cd0..51ad694be2 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -653,3 +653,21 @@ DEF_HELPER_3(vsetallnez_b, void, env, i32, i32)
 DEF_HELPER_3(vsetallnez_h, void, env, i32, i32)
 DEF_HELPER_3(vsetallnez_w, void, env, i32, i32)
 DEF_HELPER_3(vsetallnez_d, void, env, i32, i32)
+
+DEF_HELPER_4(vpackev_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackev_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackev_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackev_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackod_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackod_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackod_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vpackod_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vpickev_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickev_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickev_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickev_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickod_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickod_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickod_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vpickod_d, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index e722b79bea..1146ace1b7 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3933,3 +3933,147 @@ TRANS(vreplgr2vr_b, gvec_dup, MO_8)
 TRANS(vreplgr2vr_h, gvec_dup, MO_16)
 TRANS(vreplgr2vr_w, gvec_dup, MO_32)
 TRANS(vreplgr2vr_d, gvec_dup, MO_64)
+
+static bool trans_vreplvei_b(DisasContext *ctx, arg_vv_i *a)
+{
+CHECK_SXE;
+tcg_gen_gvec_dup_mem(MO_8,vec_full_offset(a->vd),
+ offsetof(CPULoongArchState,
+  fpr[a->vj].vreg.B((a->imm))),
+ 16, ctx->vl/8);
+return true;
+}
+
+static bool trans_vreplvei_h(DisasContext *ctx, arg_vv_i *a)
+{
+CHECK_SXE;
+tcg_gen_gvec_dup_mem(MO_16, vec_full_offset(a->vd),
+ offsetof(CPULoongArchState,
+  fpr[a->vj].vreg.H((a->imm))),
+ 16, ctx->vl/8);
+return true;
+}
+static bool trans_vreplvei_w(DisasContext *ctx, arg_vv_i *a)
+{
+CHECK_SXE;
+tcg_gen_gvec_dup_mem(MO_32, vec_full_offset(a->vd),
+ offsetof(CPULoongArchState,
+  fpr[a->vj].vreg.W((a->imm))),
+16, ctx->vl/8);
+return true;
+}
+static bool trans_vreplvei_d(DisasContext *ctx, arg_vv_i *a)
+{
+CHECK_SXE;
+tcg_gen_gvec_dup_mem(MO_64, vec_full_offset(a->vd),
+ offsetof(CPULoongArchState,
+  

[PULL 16/45] target/loongarch: Implement vdiv/vmod

2023-05-04 Thread Song Gao
This patch includes:
- VDIV.{B/H/W/D}[U];
- VMOD.{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-17-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 17 ++
 target/loongarch/helper.h   | 17 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 17 ++
 target/loongarch/insns.decode   | 17 ++
 target/loongarch/lsx_helper.c   | 37 +
 5 files changed, 105 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 980e6e6375..6e4f676a42 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1044,3 +1044,20 @@ INSN_LSX(vmaddwod_h_bu_b,  vvv)
 INSN_LSX(vmaddwod_w_hu_h,  vvv)
 INSN_LSX(vmaddwod_d_wu_w,  vvv)
 INSN_LSX(vmaddwod_q_du_d,  vvv)
+
+INSN_LSX(vdiv_b,   vvv)
+INSN_LSX(vdiv_h,   vvv)
+INSN_LSX(vdiv_w,   vvv)
+INSN_LSX(vdiv_d,   vvv)
+INSN_LSX(vdiv_bu,  vvv)
+INSN_LSX(vdiv_hu,  vvv)
+INSN_LSX(vdiv_wu,  vvv)
+INSN_LSX(vdiv_du,  vvv)
+INSN_LSX(vmod_b,   vvv)
+INSN_LSX(vmod_h,   vvv)
+INSN_LSX(vmod_w,   vvv)
+INSN_LSX(vmod_d,   vvv)
+INSN_LSX(vmod_bu,  vvv)
+INSN_LSX(vmod_hu,  vvv)
+INSN_LSX(vmod_wu,  vvv)
+INSN_LSX(vmod_du,  vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 8cf9620702..7b7c685ede 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -303,3 +303,20 @@ DEF_HELPER_FLAGS_4(vmaddwev_d_wu_w, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmaddwod_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmaddwod_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vmaddwod_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_4(vdiv_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_bu, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_hu, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_wu, void, env, i32, i32, i32)
+DEF_HELPER_4(vdiv_du, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_bu, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_hu, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_wu, void, env, i32, i32, i32)
+DEF_HELPER_4(vmod_du, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 400c3a0339..b295a9c4df 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2676,3 +2676,20 @@ static void do_vmaddwod_u_s(unsigned vece, uint32_t 
vd_ofs, uint32_t vj_ofs,
 TRANS(vmaddwod_h_bu_b, gvec_vvv, MO_8, do_vmaddwod_u_s)
 TRANS(vmaddwod_w_hu_h, gvec_vvv, MO_16, do_vmaddwod_u_s)
 TRANS(vmaddwod_d_wu_w, gvec_vvv, MO_32, do_vmaddwod_u_s)
+
+TRANS(vdiv_b, gen_vvv, gen_helper_vdiv_b)
+TRANS(vdiv_h, gen_vvv, gen_helper_vdiv_h)
+TRANS(vdiv_w, gen_vvv, gen_helper_vdiv_w)
+TRANS(vdiv_d, gen_vvv, gen_helper_vdiv_d)
+TRANS(vdiv_bu, gen_vvv, gen_helper_vdiv_bu)
+TRANS(vdiv_hu, gen_vvv, gen_helper_vdiv_hu)
+TRANS(vdiv_wu, gen_vvv, gen_helper_vdiv_wu)
+TRANS(vdiv_du, gen_vvv, gen_helper_vdiv_du)
+TRANS(vmod_b, gen_vvv, gen_helper_vmod_b)
+TRANS(vmod_h, gen_vvv, gen_helper_vmod_h)
+TRANS(vmod_w, gen_vvv, gen_helper_vmod_w)
+TRANS(vmod_d, gen_vvv, gen_helper_vmod_d)
+TRANS(vmod_bu, gen_vvv, gen_helper_vmod_bu)
+TRANS(vmod_hu, gen_vvv, gen_helper_vmod_hu)
+TRANS(vmod_wu, gen_vvv, gen_helper_vmod_wu)
+TRANS(vmod_du, gen_vvv, gen_helper_vmod_du)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index df23d4ee1e..67d016edb7 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -740,3 +740,20 @@ vmaddwod_h_bu_b  0111 1011 11100 . . .
@vvv
 vmaddwod_w_hu_h  0111 1011 11101 . . .@vvv
 vmaddwod_d_wu_w  0111 1011 0 . . .@vvv
 vmaddwod_q_du_d  0111 1011 1 . . .@vvv
+
+vdiv_b   0111 1110 0 . . .@vvv
+vdiv_h   0111 1110 1 . . .@vvv
+vdiv_w   0111 1110 00010 . . .@vvv
+vdiv_d   0111 1110 00011 . . .@vvv
+vdiv_bu  0111 1110 01000 . . .@vvv
+vdiv_hu  0111 1110 01001 . . .@vvv
+vdiv_wu  0111 1110 01010 . . .@vvv
+vdiv_du  0111 1110 01011 . . .@vvv
+vmod_b   0111 1110 00100 . . .@vvv
+vmod_h   0111 1110 00101 . . .@vvv

[PULL 35/45] target/loongarch: Implement vseq vsle vslt

2023-05-04 Thread Song Gao
This patch includes:
- VSEQ[I].{B/H/W/D};
- VSLE[I].{B/H/W/D}[U];
- VSLT[I].{B/H/W/D/}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-36-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  43 +
 target/loongarch/helper.h   |  23 +++
 target/loongarch/insn_trans/trans_lsx.c.inc | 185 
 target/loongarch/insns.decode   |  43 +
 target/loongarch/lsx_helper.c   |  38 
 5 files changed, 332 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c04271081f..e589b23f4c 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1404,3 +1404,46 @@ INSN_LSX(vffint_d_lu,  vv)
 INSN_LSX(vffintl_d_w,  vv)
 INSN_LSX(vffinth_d_w,  vv)
 INSN_LSX(vffint_s_l,   vvv)
+
+INSN_LSX(vseq_b,   vvv)
+INSN_LSX(vseq_h,   vvv)
+INSN_LSX(vseq_w,   vvv)
+INSN_LSX(vseq_d,   vvv)
+INSN_LSX(vseqi_b,  vv_i)
+INSN_LSX(vseqi_h,  vv_i)
+INSN_LSX(vseqi_w,  vv_i)
+INSN_LSX(vseqi_d,  vv_i)
+
+INSN_LSX(vsle_b,   vvv)
+INSN_LSX(vsle_h,   vvv)
+INSN_LSX(vsle_w,   vvv)
+INSN_LSX(vsle_d,   vvv)
+INSN_LSX(vslei_b,  vv_i)
+INSN_LSX(vslei_h,  vv_i)
+INSN_LSX(vslei_w,  vv_i)
+INSN_LSX(vslei_d,  vv_i)
+INSN_LSX(vsle_bu,  vvv)
+INSN_LSX(vsle_hu,  vvv)
+INSN_LSX(vsle_wu,  vvv)
+INSN_LSX(vsle_du,  vvv)
+INSN_LSX(vslei_bu, vv_i)
+INSN_LSX(vslei_hu, vv_i)
+INSN_LSX(vslei_wu, vv_i)
+INSN_LSX(vslei_du, vv_i)
+
+INSN_LSX(vslt_b,   vvv)
+INSN_LSX(vslt_h,   vvv)
+INSN_LSX(vslt_w,   vvv)
+INSN_LSX(vslt_d,   vvv)
+INSN_LSX(vslti_b,  vv_i)
+INSN_LSX(vslti_h,  vv_i)
+INSN_LSX(vslti_w,  vv_i)
+INSN_LSX(vslti_d,  vv_i)
+INSN_LSX(vslt_bu,  vvv)
+INSN_LSX(vslt_hu,  vvv)
+INSN_LSX(vslt_wu,  vvv)
+INSN_LSX(vslt_du,  vvv)
+INSN_LSX(vslti_bu, vv_i)
+INSN_LSX(vslti_hu, vv_i)
+INSN_LSX(vslti_wu, vv_i)
+INSN_LSX(vslti_du, vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index f32235aa97..e9e9fa7f87 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -614,3 +614,26 @@ DEF_HELPER_3(vffint_d_lu, void, env, i32, i32)
 DEF_HELPER_3(vffintl_d_w, void, env, i32, i32)
 DEF_HELPER_3(vffinth_d_w, void, env, i32, i32)
 DEF_HELPER_4(vffint_s_l, void, env, i32, i32, i32)
+
+DEF_HELPER_FLAGS_4(vseqi_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vseqi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vseqi_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vseqi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vslei_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslei_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vslti_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vslti_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index e0c72c6bff..4d9f88bf4f 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3532,3 +3532,188 @@ TRANS(vffint_d_lu, gen_vv, gen_helper_vffint_d_lu)
 TRANS(vffintl_d_w, gen_vv, gen_helper_vffintl_d_w)
 TRANS(vffinth_d_w, gen_vv, gen_helper_vffinth_d_w)
 TRANS(vffint_s_l, gen_vvv, gen_helper_vffint_s_l)
+
+static bool do_cmp(DisasContext *ctx, arg_vvv *a, MemOp mop, TCGCond cond)
+{
+uint32_t vd_ofs, vj_ofs, vk_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+vk_ofs = vec_full_offset(a->vk);
+
+tcg_gen_gvec_cmp(cond, mop, vd_ofs, vj_ofs, vk_ofs, 16, ctx->vl/8);
+return true;
+}
+
+static void do_cmpi_vec(TCGCond cond,
+unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
+{
+

[PULL 24/45] target/loongarch: Implement vsrlr vsrar

2023-05-04 Thread Song Gao
This patch includes:
- VSRLR[I].{B/H/W/D};
- VSRAR[I].{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-25-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  18 
 target/loongarch/helper.h   |  18 
 target/loongarch/insn_trans/trans_lsx.c.inc |  18 
 target/loongarch/insns.decode   |  18 
 target/loongarch/lsx_helper.c   | 104 
 5 files changed, 176 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 087cac10ad..c62b6720ec 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1148,3 +1148,21 @@ INSN_LSX(vsllwil_hu_bu,vv_i)
 INSN_LSX(vsllwil_wu_hu,vv_i)
 INSN_LSX(vsllwil_du_wu,vv_i)
 INSN_LSX(vextl_qu_du,  vv)
+
+INSN_LSX(vsrlr_b,  vvv)
+INSN_LSX(vsrlr_h,  vvv)
+INSN_LSX(vsrlr_w,  vvv)
+INSN_LSX(vsrlr_d,  vvv)
+INSN_LSX(vsrlri_b, vv_i)
+INSN_LSX(vsrlri_h, vv_i)
+INSN_LSX(vsrlri_w, vv_i)
+INSN_LSX(vsrlri_d, vv_i)
+
+INSN_LSX(vsrar_b,  vvv)
+INSN_LSX(vsrar_h,  vvv)
+INSN_LSX(vsrar_w,  vvv)
+INSN_LSX(vsrar_d,  vvv)
+INSN_LSX(vsrari_b, vv_i)
+INSN_LSX(vsrari_h, vv_i)
+INSN_LSX(vsrari_w, vv_i)
+INSN_LSX(vsrari_d, vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index e98f7c3e6f..20a5e7c8e6 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -361,3 +361,21 @@ DEF_HELPER_4(vsllwil_hu_bu, void, env, i32, i32, i32)
 DEF_HELPER_4(vsllwil_wu_hu, void, env, i32, i32, i32)
 DEF_HELPER_4(vsllwil_du_wu, void, env, i32, i32, i32)
 DEF_HELPER_3(vextl_qu_du, void, env, i32, i32)
+
+DEF_HELPER_4(vsrlr_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlr_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlr_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlr_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlri_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlri_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlri_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlri_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vsrar_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrar_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrar_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrar_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrari_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrari_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrari_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrari_d, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 037c742aa4..fb43e1b3ce 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2987,3 +2987,21 @@ TRANS(vsllwil_hu_bu, gen_vv_i, gen_helper_vsllwil_hu_bu)
 TRANS(vsllwil_wu_hu, gen_vv_i, gen_helper_vsllwil_wu_hu)
 TRANS(vsllwil_du_wu, gen_vv_i, gen_helper_vsllwil_du_wu)
 TRANS(vextl_qu_du, gen_vv, gen_helper_vextl_qu_du)
+
+TRANS(vsrlr_b, gen_vvv, gen_helper_vsrlr_b)
+TRANS(vsrlr_h, gen_vvv, gen_helper_vsrlr_h)
+TRANS(vsrlr_w, gen_vvv, gen_helper_vsrlr_w)
+TRANS(vsrlr_d, gen_vvv, gen_helper_vsrlr_d)
+TRANS(vsrlri_b, gen_vv_i, gen_helper_vsrlri_b)
+TRANS(vsrlri_h, gen_vv_i, gen_helper_vsrlri_h)
+TRANS(vsrlri_w, gen_vv_i, gen_helper_vsrlri_w)
+TRANS(vsrlri_d, gen_vv_i, gen_helper_vsrlri_d)
+
+TRANS(vsrar_b, gen_vvv, gen_helper_vsrar_b)
+TRANS(vsrar_h, gen_vvv, gen_helper_vsrar_h)
+TRANS(vsrar_w, gen_vvv, gen_helper_vsrar_w)
+TRANS(vsrar_d, gen_vvv, gen_helper_vsrar_d)
+TRANS(vsrari_b, gen_vv_i, gen_helper_vsrari_b)
+TRANS(vsrari_h, gen_vv_i, gen_helper_vsrari_h)
+TRANS(vsrari_w, gen_vv_i, gen_helper_vsrari_w)
+TRANS(vsrari_d, gen_vv_i, gen_helper_vsrari_d)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 23dd338026..a21743 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -848,3 +848,21 @@ vsllwil_hu_bu0111 0011 11000 01 ... . .   
@vv_ui3
 vsllwil_wu_hu0111 0011 11000 1  . .   @vv_ui4
 vsllwil_du_wu0111 0011 11001 . . .@vv_ui5
 vextl_qu_du  0111 0011 11010 0 . .@vv
+
+vsrlr_b  0111  0 . . .@vvv
+vsrlr_h  0111  1 . . .@vvv
+vsrlr_w  0111  00010 . . .@vvv
+vsrlr_d  0111  00011 . . .@vvv
+vsrlri_b 0111 00101010 01000 01 ... . .   @vv_ui3
+vsrlri_h 0111 00101010 01000 1  . .   @vv_ui4
+vsrlri_w 0111 00101010 01001 . . .@vv_ui5
+vsrlri_d 0111 00101010 0101 .. . .@vv_ui6
+
+vsrar_b  0111  00100 . . .@vvv
+vsrar_h  0111  00101 . . .@vvv
+vsrar_w  0111  00110 . . .@vvv

[PULL 01/45] target/loongarch: Add LSX data type VReg

2023-05-04 Thread Song Gao
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-2-gaos...@loongson.cn>
---
 linux-user/loongarch64/signal.c |  4 +-
 target/loongarch/cpu.c  |  2 +-
 target/loongarch/cpu.h  | 21 -
 target/loongarch/gdbstub.c  |  4 +-
 target/loongarch/internals.h| 22 +
 target/loongarch/machine.c  | 79 ++---
 6 files changed, 119 insertions(+), 13 deletions(-)

diff --git a/linux-user/loongarch64/signal.c b/linux-user/loongarch64/signal.c
index 7c7afb652e..bb8efb1172 100644
--- a/linux-user/loongarch64/signal.c
+++ b/linux-user/loongarch64/signal.c
@@ -128,7 +128,7 @@ static void setup_sigframe(CPULoongArchState *env,
 
 fpu_ctx = (struct target_fpu_context *)(info + 1);
 for (i = 0; i < 32; ++i) {
-__put_user(env->fpr[i], _ctx->regs[i]);
+__put_user(env->fpr[i].vreg.D(0), _ctx->regs[i]);
 }
 __put_user(read_fcc(env), _ctx->fcc);
 __put_user(env->fcsr0, _ctx->fcsr);
@@ -193,7 +193,7 @@ static void restore_sigframe(CPULoongArchState *env,
 uint64_t fcc;
 
 for (i = 0; i < 32; ++i) {
-__get_user(env->fpr[i], _ctx->regs[i]);
+__get_user(env->fpr[i].vreg.D(0), _ctx->regs[i]);
 }
 __get_user(fcc, _ctx->fcc);
 write_fcc(env, fcc);
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 97e6579f6a..18b41221a6 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -656,7 +656,7 @@ void loongarch_cpu_dump_state(CPUState *cs, FILE *f, int 
flags)
 /* fpr */
 if (flags & CPU_DUMP_FPU) {
 for (i = 0; i < 32; i++) {
-qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], env->fpr[i]);
+qemu_fprintf(f, " %s %016" PRIx64, fregnames[i], 
env->fpr[i].vreg.D(0));
 if ((i & 3) == 3) {
 qemu_fprintf(f, "\n");
 }
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index e11c875188..fd0f61936d 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -8,6 +8,7 @@
 #ifndef LOONGARCH_CPU_H
 #define LOONGARCH_CPU_H
 
+#include "qemu/int128.h"
 #include "exec/cpu-defs.h"
 #include "fpu/softfloat-types.h"
 #include "hw/registerfields.h"
@@ -241,6 +242,24 @@ FIELD(TLB_MISC, ASID, 1, 10)
 FIELD(TLB_MISC, VPPN, 13, 35)
 FIELD(TLB_MISC, PS, 48, 6)
 
+#define LSX_LEN   (128)
+typedef union VReg {
+int8_t   B[LSX_LEN / 8];
+int16_t  H[LSX_LEN / 16];
+int32_t  W[LSX_LEN / 32];
+int64_t  D[LSX_LEN / 64];
+uint8_t  UB[LSX_LEN / 8];
+uint16_t UH[LSX_LEN / 16];
+uint32_t UW[LSX_LEN / 32];
+uint64_t UD[LSX_LEN / 64];
+Int128   Q[LSX_LEN / 128];
+}VReg;
+
+typedef union fpr_t fpr_t;
+union fpr_t {
+VReg  vreg;
+};
+
 struct LoongArchTLB {
 uint64_t tlb_misc;
 /* Fields corresponding to CSR_TLBELO0/1 */
@@ -253,7 +272,7 @@ typedef struct CPUArchState {
 uint64_t gpr[32];
 uint64_t pc;
 
-uint64_t fpr[32];
+fpr_t fpr[32];
 float_status fp_status;
 bool cf[8];
 
diff --git a/target/loongarch/gdbstub.c b/target/loongarch/gdbstub.c
index fa3e034d15..0752fff924 100644
--- a/target/loongarch/gdbstub.c
+++ b/target/loongarch/gdbstub.c
@@ -69,7 +69,7 @@ static int loongarch_gdb_get_fpu(CPULoongArchState *env,
  GByteArray *mem_buf, int n)
 {
 if (0 <= n && n < 32) {
-return gdb_get_reg64(mem_buf, env->fpr[n]);
+return gdb_get_reg64(mem_buf, env->fpr[n].vreg.D(0));
 } else if (n == 32) {
 uint64_t val = read_fcc(env);
 return gdb_get_reg64(mem_buf, val);
@@ -85,7 +85,7 @@ static int loongarch_gdb_set_fpu(CPULoongArchState *env,
 int length = 0;
 
 if (0 <= n && n < 32) {
-env->fpr[n] = ldq_p(mem_buf);
+env->fpr[n].vreg.D(0) = ldq_p(mem_buf);
 length = 8;
 } else if (n == 32) {
 uint64_t val = ldq_p(mem_buf);
diff --git a/target/loongarch/internals.h b/target/loongarch/internals.h
index f01635aed6..4c5752fc01 100644
--- a/target/loongarch/internals.h
+++ b/target/loongarch/internals.h
@@ -21,6 +21,28 @@
 /* Global bit for huge page */
 #define LOONGARCH_HGLOBAL_SHIFT 12
 
+#if  HOST_BIG_ENDIAN
+#define B(x)  B[15 - (x)]
+#define H(x)  H[7 - (x)]
+#define W(x)  W[3 - (x)]
+#define D(x)  D[1 - (x)]
+#define UB(x) UB[15 - (x)]
+#define UH(x) UH[7 - (x)]
+#define UW(x) UW[3 - (x)]
+#define UD(x) UD[1 -(x)]
+#define Q(x)  Q[x]
+#else
+#define B(x)  B[x]
+#define H(x)  H[x]
+#define W(x)  W[x]
+#define D(x)  D[x]
+#define UB(x) UB[x]
+#define UH(x) UH[x]
+#define UW(x) UW[x]
+#define UD(x) UD[x]
+#define Q(x)  Q[x]
+#endif
+
 void loongarch_translate_init(void);
 
 void loongarch_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
index b1e523ea72..7adc1bdff9 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -10,6 +10,72 @@
 #include "migration/cpu.h"
 #include 

[PULL 12/45] target/loongarch: Implement vadda

2023-05-04 Thread Song Gao
This patch includes:
- VADDA.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-13-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  5 ++
 target/loongarch/helper.h   |  5 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 53 +
 target/loongarch/insns.decode   |  5 ++
 target/loongarch/lsx_helper.c   | 19 
 5 files changed, 87 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index e98ea37793..1f61e67d1f 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -934,3 +934,8 @@ INSN_LSX(vabsd_bu, vvv)
 INSN_LSX(vabsd_hu, vvv)
 INSN_LSX(vabsd_wu, vvv)
 INSN_LSX(vabsd_du, vvv)
+
+INSN_LSX(vadda_b,  vvv)
+INSN_LSX(vadda_h,  vvv)
+INSN_LSX(vadda_w,  vvv)
+INSN_LSX(vadda_d,  vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index c3a5d2566e..85fb8f60d2 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -220,3 +220,8 @@ DEF_HELPER_FLAGS_4(vabsd_bu, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vabsd_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vabsd_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vabsd_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vadda_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vadda_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vadda_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vadda_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 0e9301bf93..8ad81c8517 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -1261,3 +1261,56 @@ TRANS(vabsd_bu, gvec_vvv, MO_8, do_vabsd_u)
 TRANS(vabsd_hu, gvec_vvv, MO_16, do_vabsd_u)
 TRANS(vabsd_wu, gvec_vvv, MO_32, do_vabsd_u)
 TRANS(vabsd_du, gvec_vvv, MO_64, do_vabsd_u)
+
+static void gen_vadda(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+TCGv_vec t1, t2;
+
+t1 = tcg_temp_new_vec_matching(a);
+t2 = tcg_temp_new_vec_matching(b);
+
+tcg_gen_abs_vec(vece, t1, a);
+tcg_gen_abs_vec(vece, t2, b);
+tcg_gen_add_vec(vece, t, t1, t2);
+}
+
+static void do_vadda(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+ uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_abs_vec, INDEX_op_add_vec, 0
+};
+static const GVecGen3 op[4] = {
+{
+.fniv = gen_vadda,
+.fno = gen_helper_vadda_b,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vadda,
+.fno = gen_helper_vadda_h,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vadda,
+.fno = gen_helper_vadda_w,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vadda,
+.fno = gen_helper_vadda_d,
+.opt_opc = vecop_list,
+.vece = MO_64
+},
+};
+
+tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, [vece]);
+}
+
+TRANS(vadda_b, gvec_vvv, MO_8, do_vadda)
+TRANS(vadda_h, gvec_vvv, MO_16, do_vadda)
+TRANS(vadda_w, gvec_vvv, MO_32, do_vadda)
+TRANS(vadda_d, gvec_vvv, MO_64, do_vadda)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 825ddedf4d..6cb22f9297 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -628,3 +628,8 @@ vabsd_bu 0111 0110 00100 . . .
@vvv
 vabsd_hu 0111 0110 00101 . . .@vvv
 vabsd_wu 0111 0110 00110 . . .@vvv
 vabsd_du 0111 0110 00111 . . .@vvv
+
+vadda_b  0111 0101 11000 . . .@vvv
+vadda_h  0111 0101 11001 . . .@vvv
+vadda_w  0111 0101 11010 . . .@vvv
+vadda_d  0111 0101 11011 . . .@vvv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index f0baffa9e3..8230fe2ed5 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -318,3 +318,22 @@ DO_3OP(vabsd_bu, 8, UB, DO_VABSD)
 DO_3OP(vabsd_hu, 16, UH, DO_VABSD)
 DO_3OP(vabsd_wu, 32, UW, DO_VABSD)
 DO_3OP(vabsd_du, 64, UD, DO_VABSD)
+
+#define DO_VABS(a)  ((a < 0) ? (-a) : (a))
+
+#define DO_VADDA(NAME, BIT, E, DO_OP)   \
+void HELPER(NAME)(void *vd, void *vj, void *vk, uint32_t v) \
+{   \
+int i;  \
+VReg *Vd = 

[PULL 21/45] target/loongarch: Implement LSX logic instructions

2023-05-04 Thread Song Gao
This patch includes:
- V{AND/OR/XOR/NOR/ANDN/ORN}.V;
- V{AND/OR/XOR/NOR}I.B.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-22-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 12 +
 target/loongarch/helper.h   |  2 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 56 +
 target/loongarch/insns.decode   | 13 +
 target/loongarch/lsx_helper.c   | 11 
 5 files changed, 94 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 2725b827ee..eca0a4bb7b 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1091,3 +1091,15 @@ INSN_LSX(vmskltz_w,vv)
 INSN_LSX(vmskltz_d,vv)
 INSN_LSX(vmskgez_b,vv)
 INSN_LSX(vmsknz_b, vv)
+
+INSN_LSX(vand_v,   vvv)
+INSN_LSX(vor_v,vvv)
+INSN_LSX(vxor_v,   vvv)
+INSN_LSX(vnor_v,   vvv)
+INSN_LSX(vandn_v,  vvv)
+INSN_LSX(vorn_v,   vvv)
+
+INSN_LSX(vandi_b,  vv_i)
+INSN_LSX(vori_b,   vv_i)
+INSN_LSX(vxori_b,  vv_i)
+INSN_LSX(vnori_b,  vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 34b7b2f576..617c579592 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -350,3 +350,5 @@ DEF_HELPER_3(vmskltz_w, void, env, i32, i32)
 DEF_HELPER_3(vmskltz_d, void, env, i32, i32)
 DEF_HELPER_3(vmskgez_b, void, env, i32, i32)
 DEF_HELPER_3(vmsknz_b, void, env, i32,i32)
+
+DEF_HELPER_FLAGS_4(vnori_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 64387f2666..e5e194106b 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2874,3 +2874,59 @@ TRANS(vmskltz_w, gen_vv, gen_helper_vmskltz_w)
 TRANS(vmskltz_d, gen_vv, gen_helper_vmskltz_d)
 TRANS(vmskgez_b, gen_vv, gen_helper_vmskgez_b)
 TRANS(vmsknz_b, gen_vv, gen_helper_vmsknz_b)
+
+TRANS(vand_v, gvec_vvv, MO_64, tcg_gen_gvec_and)
+TRANS(vor_v, gvec_vvv, MO_64, tcg_gen_gvec_or)
+TRANS(vxor_v, gvec_vvv, MO_64, tcg_gen_gvec_xor)
+TRANS(vnor_v, gvec_vvv, MO_64, tcg_gen_gvec_nor)
+
+static bool trans_vandn_v(DisasContext *ctx, arg_vvv *a)
+{
+uint32_t vd_ofs, vj_ofs, vk_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+vk_ofs = vec_full_offset(a->vk);
+
+tcg_gen_gvec_andc(MO_64, vd_ofs, vk_ofs, vj_ofs, 16, ctx->vl/8);
+return true;
+}
+TRANS(vorn_v, gvec_vvv, MO_64, tcg_gen_gvec_orc)
+TRANS(vandi_b, gvec_vv_i, MO_8, tcg_gen_gvec_andi)
+TRANS(vori_b, gvec_vv_i, MO_8, tcg_gen_gvec_ori)
+TRANS(vxori_b, gvec_vv_i, MO_8, tcg_gen_gvec_xori)
+
+static void gen_vnori(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
+{
+TCGv_vec t1;
+
+t1 = tcg_constant_vec_matching(t, vece, imm);
+tcg_gen_nor_vec(vece, t, a, t1);
+}
+
+static void gen_vnori_b(TCGv_i64 t, TCGv_i64 a, int64_t imm)
+{
+tcg_gen_movi_i64(t, dup_const(MO_8, imm));
+tcg_gen_nor_i64(t, a, t);
+}
+
+static void do_vnori_b(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+   int64_t imm, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_nor_vec, 0
+};
+static const GVecGen2i op = {
+   .fni8 = gen_vnori_b,
+   .fniv = gen_vnori,
+   .fnoi = gen_helper_vnori_b,
+   .opt_opc = vecop_list,
+   .vece = MO_8
+};
+
+tcg_gen_gvec_2i(vd_ofs, vj_ofs, oprsz, maxsz, imm, );
+}
+
+TRANS(vnori_b, gvec_vv_i, MO_8, do_vnori_b)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 47c1ef78a7..6309683be9 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -503,6 +503,7 @@ dbcl  0010 10101 ...  
@i15
 @vv_ui4   . . imm:4 vj:5 vd:5_i
 @vv_ui5     . imm:5 vj:5 vd:5_i
 @vv_ui6   imm:6 vj:5 vd:5_i
+@vv_ui8    .. imm:8 vj:5 vd:5_i
 @vv_i5     . imm:s5 vj:5 vd:5_i
 
 vadd_b   0111  10100 . . .@vvv
@@ -790,3 +791,15 @@ vmskltz_w0111 00101001 11000 10010 . .
@vv
 vmskltz_d0111 00101001 11000 10011 . .@vv
 vmskgez_b0111 00101001 11000 10100 . .@vv
 vmsknz_b 0111 00101001 11000 11000 . .@vv
+
+vand_v   0111 00010010 01100 . . .@vvv
+vor_v0111 00010010 01101 . . .@vvv
+vxor_v   0111 00010010 01110 . . .@vvv
+vnor_v   0111 00010010 0 . . .@vvv
+vandn_v  0111 00010010 1 . . .@vvv
+vorn_v   0111 00010010 10001 . . .@vvv
+
+vandi_b  0111 

[PULL 25/45] target/loongarch: Implement vsrln vsran

2023-05-04 Thread Song Gao
This patch includes:
- VSRLN.{B.H/H.W/W.D};
- VSRAN.{B.H/H.W/W.D};
- VSRLNI.{B.H/H.W/W.D/D.Q};
- VSRANI.{B.H/H.W/W.D/D.Q}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-26-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  16 +++
 target/loongarch/helper.h   |  16 +++
 target/loongarch/insn_trans/trans_lsx.c.inc |  16 +++
 target/loongarch/insns.decode   |  17 +++
 target/loongarch/lsx_helper.c   | 114 
 5 files changed, 179 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c62b6720ec..f0fc2ff84b 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1166,3 +1166,19 @@ INSN_LSX(vsrari_b, vv_i)
 INSN_LSX(vsrari_h, vv_i)
 INSN_LSX(vsrari_w, vv_i)
 INSN_LSX(vsrari_d, vv_i)
+
+INSN_LSX(vsrln_b_h,   vvv)
+INSN_LSX(vsrln_h_w,   vvv)
+INSN_LSX(vsrln_w_d,   vvv)
+INSN_LSX(vsran_b_h,   vvv)
+INSN_LSX(vsran_h_w,   vvv)
+INSN_LSX(vsran_w_d,   vvv)
+
+INSN_LSX(vsrlni_b_h,   vv_i)
+INSN_LSX(vsrlni_h_w,   vv_i)
+INSN_LSX(vsrlni_w_d,   vv_i)
+INSN_LSX(vsrlni_d_q,   vv_i)
+INSN_LSX(vsrani_b_h,   vv_i)
+INSN_LSX(vsrani_h_w,   vv_i)
+INSN_LSX(vsrani_w_d,   vv_i)
+INSN_LSX(vsrani_d_q,   vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 20a5e7c8e6..afe7e3d2d0 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -379,3 +379,19 @@ DEF_HELPER_4(vsrari_b, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrari_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrari_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrari_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vsrln_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrln_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrln_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsran_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsran_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsran_w_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vsrlni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlni_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrani_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrani_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrani_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrani_d_q, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index fb43e1b3ce..ad34378ada 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3005,3 +3005,19 @@ TRANS(vsrari_b, gen_vv_i, gen_helper_vsrari_b)
 TRANS(vsrari_h, gen_vv_i, gen_helper_vsrari_h)
 TRANS(vsrari_w, gen_vv_i, gen_helper_vsrari_w)
 TRANS(vsrari_d, gen_vv_i, gen_helper_vsrari_d)
+
+TRANS(vsrln_b_h, gen_vvv, gen_helper_vsrln_b_h)
+TRANS(vsrln_h_w, gen_vvv, gen_helper_vsrln_h_w)
+TRANS(vsrln_w_d, gen_vvv, gen_helper_vsrln_w_d)
+TRANS(vsran_b_h, gen_vvv, gen_helper_vsran_b_h)
+TRANS(vsran_h_w, gen_vvv, gen_helper_vsran_h_w)
+TRANS(vsran_w_d, gen_vvv, gen_helper_vsran_w_d)
+
+TRANS(vsrlni_b_h, gen_vv_i, gen_helper_vsrlni_b_h)
+TRANS(vsrlni_h_w, gen_vv_i, gen_helper_vsrlni_h_w)
+TRANS(vsrlni_w_d, gen_vv_i, gen_helper_vsrlni_w_d)
+TRANS(vsrlni_d_q, gen_vv_i, gen_helper_vsrlni_d_q)
+TRANS(vsrani_b_h, gen_vv_i, gen_helper_vsrani_b_h)
+TRANS(vsrani_h_w, gen_vv_i, gen_helper_vsrani_h_w)
+TRANS(vsrani_w_d, gen_vv_i, gen_helper_vsrani_w_d)
+TRANS(vsrani_d_q, gen_vv_i, gen_helper_vsrani_d_q)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index a21743..ee54b632a7 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -503,6 +503,7 @@ dbcl  0010 10101 ...  
@i15
 @vv_ui4   . . imm:4 vj:5 vd:5_i
 @vv_ui5     . imm:5 vj:5 vd:5_i
 @vv_ui6   imm:6 vj:5 vd:5_i
+@vv_ui7   ... imm:7 vj:5 vd:5_i
 @vv_ui8    .. imm:8 vj:5 vd:5_i
 @vv_i5     . imm:s5 vj:5 vd:5_i
 
@@ -866,3 +867,19 @@ vsrari_b 0111 00101010 1 01 ... . .   
@vv_ui3
 vsrari_h 0111 00101010 1 1  . .   @vv_ui4
 vsrari_w 0111 00101010 10001 . . .@vv_ui5
 vsrari_d 0111 00101010 1001 .. . .@vv_ui6
+
+vsrln_b_h0111  01001 . . .@vvv
+vsrln_h_w0111  01010 . . .@vvv
+vsrln_w_d0111  01011 . . .@vvv
+vsran_b_h0111  01101 . . .@vvv
+vsran_h_w0111  01110 . . .@vvv
+vsran_w_d0111  0 . . .@vvv
+
+vsrlni_b_h   0111 00110100 0 1 

[PULL 32/45] target/loongarch: Implement vfrstp

2023-05-04 Thread Song Gao
This patch includes:
- VFRSTP[I].{B/H}.

Acked-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-33-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  5 +++
 target/loongarch/helper.h   |  5 +++
 target/loongarch/insn_trans/trans_lsx.c.inc |  5 +++
 target/loongarch/insns.decode   |  5 +++
 target/loongarch/lsx_helper.c   | 41 +
 5 files changed, 61 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 48c7ea47a4..be2bb9cc42 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1297,3 +1297,8 @@ INSN_LSX(vbitrevi_b,   vv_i)
 INSN_LSX(vbitrevi_h,   vv_i)
 INSN_LSX(vbitrevi_w,   vv_i)
 INSN_LSX(vbitrevi_d,   vv_i)
+
+INSN_LSX(vfrstp_b, vvv)
+INSN_LSX(vfrstp_h, vvv)
+INSN_LSX(vfrstpi_b,vv_i)
+INSN_LSX(vfrstpi_h,vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 75120ca55e..2cc235d019 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -512,3 +512,8 @@ DEF_HELPER_FLAGS_4(vbitrevi_b, TCG_CALL_NO_RWG, void, ptr, 
ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vbitrevi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vbitrevi_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vbitrevi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_4(vfrstp_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vfrstp_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vfrstpi_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vfrstpi_h, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 86243b54ba..ee84a5a4ee 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3416,3 +3416,8 @@ TRANS(vbitrevi_b, gvec_vv_i, MO_8, do_vbitrevi)
 TRANS(vbitrevi_h, gvec_vv_i, MO_16, do_vbitrevi)
 TRANS(vbitrevi_w, gvec_vv_i, MO_32, do_vbitrevi)
 TRANS(vbitrevi_d, gvec_vv_i, MO_64, do_vbitrevi)
+
+TRANS(vfrstp_b, gen_vvv, gen_helper_vfrstp_b)
+TRANS(vfrstp_h, gen_vvv, gen_helper_vfrstp_h)
+TRANS(vfrstpi_b, gen_vv_i, gen_helper_vfrstpi_b)
+TRANS(vfrstpi_h, gen_vv_i, gen_helper_vfrstpi_h)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 801c97714e..4cb286ffe5 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -998,3 +998,8 @@ vbitrevi_b   0111 00110001 1 01 ... . .   
@vv_ui3
 vbitrevi_h   0111 00110001 1 1  . .   @vv_ui4
 vbitrevi_w   0111 00110001 10001 . . .@vv_ui5
 vbitrevi_d   0111 00110001 1001 .. . .@vv_ui6
+
+vfrstp_b 0111 00010010 10110 . . .@vvv
+vfrstp_h 0111 00010010 10111 . . .@vvv
+vfrstpi_b0111 00101001 10100 . . .@vv_ui5
+vfrstpi_h0111 00101001 10101 . . .@vv_ui5
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index f160abfd8e..ad0d2dbe87 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -2019,3 +2019,44 @@ DO_BITI(vbitrevi_b, 8, UB, DO_BITREV)
 DO_BITI(vbitrevi_h, 16, UH, DO_BITREV)
 DO_BITI(vbitrevi_w, 32, UW, DO_BITREV)
 DO_BITI(vbitrevi_d, 64, UD, DO_BITREV)
+
+#define VFRSTP(NAME, BIT, MASK, E)   \
+void HELPER(NAME)(CPULoongArchState *env,\
+  uint32_t vd, uint32_t vj, uint32_t vk) \
+{\
+int i, m;\
+VReg *Vd = &(env->fpr[vd].vreg); \
+VReg *Vj = &(env->fpr[vj].vreg); \
+VReg *Vk = &(env->fpr[vk].vreg); \
+ \
+for (i = 0; i < LSX_LEN/BIT; i++) {  \
+if (Vj->E(i) < 0) {  \
+break;   \
+}\
+}\
+m = Vk->E(0) & MASK; \
+Vd->E(m) = i;\
+}
+
+VFRSTP(vfrstp_b, 8, 0xf, B)
+VFRSTP(vfrstp_h, 16, 0x7, H)
+
+#define VFRSTPI(NAME, BIT, E) \
+void HELPER(NAME)(CPULoongArchState *env, \
+  uint32_t vd, uint32_t vj, uint32_t imm) \
+{ \
+int i, m; \
+VReg *Vd = &(env->fpr[vd].vreg);  \
+VReg *Vj = &(env->fpr[vj].vreg);  \
+  \
+for (i = 0; i < LSX_LEN/BIT; i++) {   \
+if (Vj->E(i) < 0) { 

[PULL 04/45] target/loongarch: Implement vadd/vsub

2023-05-04 Thread Song Gao
This patch includes:
- VADD.{B/H/W/D/Q};
- VSUB.{B/H/W/D/Q}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-5-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 23 +++
 target/loongarch/insn_trans/trans_lsx.c.inc | 69 +
 target/loongarch/insns.decode   | 22 +++
 target/loongarch/translate.c| 24 +++
 target/loongarch/translate.h|  1 +
 5 files changed, 139 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 2e93e77e0d..a5948d7847 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -784,3 +784,26 @@ PCADD_INSN(pcaddi)
 PCADD_INSN(pcalau12i)
 PCADD_INSN(pcaddu12i)
 PCADD_INSN(pcaddu18i)
+
+#define INSN_LSX(insn, type)\
+static bool trans_##insn(DisasContext *ctx, arg_##type * a) \
+{   \
+output_##type(ctx, a, #insn);   \
+return true;\
+}
+
+static void output_vvv(DisasContext *ctx, arg_vvv *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, v%d, v%d", a->vd, a->vj, a->vk);
+}
+
+INSN_LSX(vadd_b,   vvv)
+INSN_LSX(vadd_h,   vvv)
+INSN_LSX(vadd_w,   vvv)
+INSN_LSX(vadd_d,   vvv)
+INSN_LSX(vadd_q,   vvv)
+INSN_LSX(vsub_b,   vvv)
+INSN_LSX(vsub_h,   vvv)
+INSN_LSX(vsub_w,   vvv)
+INSN_LSX(vsub_d,   vvv)
+INSN_LSX(vsub_q,   vvv)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 5dedb044d7..ddeb9fde28 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -14,3 +14,72 @@
 #else
 #define CHECK_SXE
 #endif
+
+static bool gen_vvv(DisasContext *ctx, arg_vvv *a,
+void (*func)(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32))
+{
+TCGv_i32 vd = tcg_constant_i32(a->vd);
+TCGv_i32 vj = tcg_constant_i32(a->vj);
+TCGv_i32 vk = tcg_constant_i32(a->vk);
+
+CHECK_SXE;
+
+func(cpu_env, vd, vj, vk);
+return true;
+}
+
+static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp mop,
+ void (*func)(unsigned, uint32_t, uint32_t,
+  uint32_t, uint32_t, uint32_t))
+{
+uint32_t vd_ofs, vj_ofs, vk_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+vk_ofs = vec_full_offset(a->vk);
+
+func(mop, vd_ofs, vj_ofs, vk_ofs, 16, ctx->vl/8);
+return true;
+}
+
+TRANS(vadd_b, gvec_vvv, MO_8, tcg_gen_gvec_add)
+TRANS(vadd_h, gvec_vvv, MO_16, tcg_gen_gvec_add)
+TRANS(vadd_w, gvec_vvv, MO_32, tcg_gen_gvec_add)
+TRANS(vadd_d, gvec_vvv, MO_64, tcg_gen_gvec_add)
+
+#define VADDSUB_Q(NAME)\
+static bool trans_v## NAME ##_q(DisasContext *ctx, arg_vvv *a) \
+{  \
+TCGv_i64 rh, rl, ah, al, bh, bl;   \
+   \
+CHECK_SXE; \
+   \
+rh = tcg_temp_new_i64();   \
+rl = tcg_temp_new_i64();   \
+ah = tcg_temp_new_i64();   \
+al = tcg_temp_new_i64();   \
+bh = tcg_temp_new_i64();   \
+bl = tcg_temp_new_i64();   \
+   \
+get_vreg64(ah, a->vj, 1);  \
+get_vreg64(al, a->vj, 0);  \
+get_vreg64(bh, a->vk, 1);  \
+get_vreg64(bl, a->vk, 0);  \
+   \
+tcg_gen_## NAME ##2_i64(rl, rh, al, ah, bl, bh);   \
+   \
+set_vreg64(rh, a->vd, 1);  \
+set_vreg64(rl, a->vd, 0);  \
+   \
+return true;   \
+}
+
+VADDSUB_Q(add)
+VADDSUB_Q(sub)
+
+TRANS(vsub_b, gvec_vvv, MO_8, tcg_gen_gvec_sub)
+TRANS(vsub_h, gvec_vvv, MO_16, tcg_gen_gvec_sub)
+TRANS(vsub_w, gvec_vvv, MO_32, tcg_gen_gvec_sub)
+TRANS(vsub_d, gvec_vvv, MO_64, tcg_gen_gvec_sub)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index de7b8f0f3c..d18db68d51 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -485,3 +485,25 @@ ldpte 01100100 

[PULL 30/45] target/loongarch: Implement vpcnt

2023-05-04 Thread Song Gao
This patch includes:
- VPCNT.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-31-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  5 +
 target/loongarch/helper.h   |  5 +
 target/loongarch/insn_trans/trans_lsx.c.inc |  5 +
 target/loongarch/insns.decode   |  5 +
 target/loongarch/lsx_helper.c   | 18 ++
 5 files changed, 38 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 0c82a1d9d1..0ca51de9d8 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1267,3 +1267,8 @@ INSN_LSX(vclz_b,   vv)
 INSN_LSX(vclz_h,   vv)
 INSN_LSX(vclz_w,   vv)
 INSN_LSX(vclz_d,   vv)
+
+INSN_LSX(vpcnt_b,  vv)
+INSN_LSX(vpcnt_h,  vv)
+INSN_LSX(vpcnt_w,  vv)
+INSN_LSX(vpcnt_d,  vv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index e21e9b9704..96b9b16923 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -480,3 +480,8 @@ DEF_HELPER_3(vclz_b, void, env, i32, i32)
 DEF_HELPER_3(vclz_h, void, env, i32, i32)
 DEF_HELPER_3(vclz_w, void, env, i32, i32)
 DEF_HELPER_3(vclz_d, void, env, i32, i32)
+
+DEF_HELPER_3(vpcnt_b, void, env, i32, i32)
+DEF_HELPER_3(vpcnt_h, void, env, i32, i32)
+DEF_HELPER_3(vpcnt_w, void, env, i32, i32)
+DEF_HELPER_3(vpcnt_d, void, env, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index c7649fb777..f4ebdca63c 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3106,3 +3106,8 @@ TRANS(vclz_b, gen_vv, gen_helper_vclz_b)
 TRANS(vclz_h, gen_vv, gen_helper_vclz_h)
 TRANS(vclz_w, gen_vv, gen_helper_vclz_w)
 TRANS(vclz_d, gen_vv, gen_helper_vclz_d)
+
+TRANS(vpcnt_b, gen_vv, gen_helper_vpcnt_b)
+TRANS(vpcnt_h, gen_vv, gen_helper_vpcnt_h)
+TRANS(vpcnt_w, gen_vv, gen_helper_vpcnt_w)
+TRANS(vpcnt_d, gen_vv, gen_helper_vpcnt_d)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 7591ec1bab..f865e83da5 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -968,3 +968,8 @@ vclz_b   0111 00101001 11000 00100 . .
@vv
 vclz_h   0111 00101001 11000 00101 . .@vv
 vclz_w   0111 00101001 11000 00110 . .@vv
 vclz_d   0111 00101001 11000 00111 . .@vv
+
+vpcnt_b  0111 00101001 11000 01000 . .@vv
+vpcnt_h  0111 00101001 11000 01001 . .@vv
+vpcnt_w  0111 00101001 11000 01010 . .@vv
+vpcnt_d  0111 00101001 11000 01011 . .@vv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index 044032f180..f18c4a2978 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -1946,3 +1946,21 @@ DO_2OP(vclz_b, 8, UB, DO_CLZ_B)
 DO_2OP(vclz_h, 16, UH, DO_CLZ_H)
 DO_2OP(vclz_w, 32, UW, DO_CLZ_W)
 DO_2OP(vclz_d, 64, UD, DO_CLZ_D)
+
+#define VPCNT(NAME, BIT, E, FN) \
+void HELPER(NAME)(CPULoongArchState *env, uint32_t vd, uint32_t vj) \
+{   \
+int i;  \
+VReg *Vd = &(env->fpr[vd].vreg);\
+VReg *Vj = &(env->fpr[vj].vreg);\
+\
+for (i = 0; i < LSX_LEN/BIT; i++)   \
+{   \
+Vd->E(i) = FN(Vj->E(i));\
+}   \
+}
+
+VPCNT(vpcnt_b, 8, UB, ctpop8)
+VPCNT(vpcnt_h, 16, UH, ctpop16)
+VPCNT(vpcnt_w, 32, UW, ctpop32)
+VPCNT(vpcnt_d, 64, UD, ctpop64)
-- 
2.31.1




[PULL 42/45] target/loongarch: Implement vldi

2023-05-04 Thread Song Gao
This patch includes:
- VLDI.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-43-gaos...@loongson.cn>
---
 target/loongarch/disas.c|   7 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 137 
 target/loongarch/insns.decode   |   4 +
 3 files changed, 148 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 8627908fc9..5c402d944d 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -858,6 +858,11 @@ static void output_vrr(DisasContext *ctx, arg_vrr *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, r%d, r%d", a->vd, a->rj, a->rk);
 }
 
+static void output_v_i(DisasContext *ctx, arg_v_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, 0x%x", a->vd, a->imm);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -1143,6 +1148,8 @@ INSN_LSX(vmskltz_d,vv)
 INSN_LSX(vmskgez_b,vv)
 INSN_LSX(vmsknz_b, vv)
 
+INSN_LSX(vldi, v_i)
+
 INSN_LSX(vand_v,   vvv)
 INSN_LSX(vor_v,vvv)
 INSN_LSX(vxor_v,   vvv)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 86dfd2b399..0be2b5a3a8 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2912,6 +2912,143 @@ TRANS(vmskltz_d, gen_vv, gen_helper_vmskltz_d)
 TRANS(vmskgez_b, gen_vv, gen_helper_vmskgez_b)
 TRANS(vmsknz_b, gen_vv, gen_helper_vmsknz_b)
 
+#define EXPAND_BYTE(bit)  ((uint64_t)(bit ? 0xff : 0))
+
+static uint64_t vldi_get_value(DisasContext *ctx, uint32_t imm)
+{
+int mode;
+uint64_t data, t;
+
+/*
+ * imm bit [11:8] is mode, mode value is 0-12.
+ * other values are invalid.
+ */
+mode = (imm >> 8) & 0xf;
+t =  imm & 0xff;
+switch (mode) {
+case 0:
+/* data: {2{24'0, imm[7:0]}} */
+data =  (t << 32) | t ;
+break;
+case 1:
+/* data: {2{16'0, imm[7:0], 8'0}} */
+data = (t << 24) | (t << 8);
+break;
+case 2:
+/* data: {2{8'0, imm[7:0], 16'0}} */
+data = (t << 48) | (t << 16);
+break;
+case 3:
+/* data: {2{imm[7:0], 24'0}} */
+data = (t << 56) | (t << 24);
+break;
+case 4:
+/* data: {4{8'0, imm[7:0]}} */
+data = (t << 48) | (t << 32) | (t << 16) | t;
+break;
+case 5:
+/* data: {4{imm[7:0], 8'0}} */
+data = (t << 56) |(t << 40) | (t << 24) | (t << 8);
+break;
+case 6:
+/* data: {2{16'0, imm[7:0], 8'1}} */
+data = (t << 40) | ((uint64_t)0xff << 32) | (t << 8) | 0xff;
+break;
+case 7:
+/* data: {2{8'0, imm[7:0], 16'1}} */
+data = (t << 48) | ((uint64_t)0x << 32) | (t << 16) | 0x;
+break;
+case 8:
+/* data: {8{imm[7:0]}} */
+data =(t << 56) | (t << 48) | (t << 40) | (t << 32) |
+  (t << 24) | (t << 16) | (t << 8) | t;
+break;
+case 9:
+/* data: {{8{imm[7]}, ..., 8{imm[0]}}} */
+{
+uint64_t b0,b1,b2,b3,b4,b5,b6,b7;
+b0 = t& 0x1;
+b1 = (t & 0x2) >> 1;
+b2 = (t & 0x4) >> 2;
+b3 = (t & 0x8) >> 3;
+b4 = (t & 0x10) >> 4;
+b5 = (t & 0x20) >> 5;
+b6 = (t & 0x40) >> 6;
+b7 = (t & 0x80) >> 7;
+data = (EXPAND_BYTE(b7) << 56) |
+   (EXPAND_BYTE(b6) << 48) |
+   (EXPAND_BYTE(b5) << 40) |
+   (EXPAND_BYTE(b4) << 32) |
+   (EXPAND_BYTE(b3) << 24) |
+   (EXPAND_BYTE(b2) << 16) |
+   (EXPAND_BYTE(b1) <<  8) |
+   EXPAND_BYTE(b0);
+}
+break;
+case 10:
+/* data: {2{imm[7], ~imm[6], {5{imm[6]}}, imm[5:0], 19'0}} */
+{
+uint64_t b6, b7;
+uint64_t t0, t1;
+b6 = (imm & 0x40) >> 6;
+b7 = (imm & 0x80) >> 7;
+t0 = (imm & 0x3f);
+t1 = (b7 << 6) | ((1-b6) << 5) | (uint64_t)(b6 ? 0x1f : 0);
+data  = (t1 << 57) | (t0 << 51) | (t1 << 25) | (t0 << 19);
+}
+break;
+case 11:
+/* data: {32'0, imm[7], ~{imm[6]}, 5{imm[6]}, imm[5:0], 19'0} */
+{
+uint64_t b6,b7;
+uint64_t t0, t1;
+b6 = (imm & 0x40) >> 6;
+b7 = (imm & 0x80) >> 7;
+t0 = (imm & 0x3f);
+t1 = (b7 << 6) | ((1-b6) << 5) | (b6 ? 0x1f : 0);
+data = (t1 << 25) | (t0 << 19);
+}
+break;
+case 12:
+/* data: {imm[7], ~imm[6], 8{imm[6]}, imm[5:0], 48'0} */
+{
+uint64_t b6,b7;
+uint64_t t0, t1;
+b6 = (imm & 0x40) >> 6;
+b7 = (imm & 0x80) >> 7;
+t0 = (imm & 0x3f);
+t1 = (b7 << 

[PULL 34/45] target/loongarch: Implement LSX fpu fcvt instructions

2023-05-04 Thread Song Gao
This patch includes:
- VFCVT{L/H}.{S.H/D.S};
- VFCVT.{H.S/S.D};
- VFRINT[{RNE/RZ/RP/RM}].{S/D};
- VFTINT[{RNE/RZ/RP/RM}].{W.S/L.D};
- VFTINT[RZ].{WU.S/LU.D};
- VFTINT[{RNE/RZ/RP/RM}].W.D;
- VFTINT[{RNE/RZ/RP/RM}]{L/H}.L.S;
- VFFINT.{S.W/D.L}[U];
- VFFINT.S.L, VFFINT{L/H}.D.W.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-35-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  56 +++
 target/loongarch/helper.h   |  56 +++
 target/loongarch/insn_trans/trans_lsx.c.inc |  56 +++
 target/loongarch/insns.decode   |  56 +++
 target/loongarch/lsx_helper.c   | 376 
 5 files changed, 600 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index b57b284e49..c04271081f 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1348,3 +1348,59 @@ INSN_LSX(vfrecip_s,vv)
 INSN_LSX(vfrecip_d,vv)
 INSN_LSX(vfrsqrt_s,vv)
 INSN_LSX(vfrsqrt_d,vv)
+
+INSN_LSX(vfcvtl_s_h,   vv)
+INSN_LSX(vfcvth_s_h,   vv)
+INSN_LSX(vfcvtl_d_s,   vv)
+INSN_LSX(vfcvth_d_s,   vv)
+INSN_LSX(vfcvt_h_s,vvv)
+INSN_LSX(vfcvt_s_d,vvv)
+
+INSN_LSX(vfrint_s, vv)
+INSN_LSX(vfrint_d, vv)
+INSN_LSX(vfrintrm_s,   vv)
+INSN_LSX(vfrintrm_d,   vv)
+INSN_LSX(vfrintrp_s,   vv)
+INSN_LSX(vfrintrp_d,   vv)
+INSN_LSX(vfrintrz_s,   vv)
+INSN_LSX(vfrintrz_d,   vv)
+INSN_LSX(vfrintrne_s,  vv)
+INSN_LSX(vfrintrne_d,  vv)
+
+INSN_LSX(vftint_w_s,   vv)
+INSN_LSX(vftint_l_d,   vv)
+INSN_LSX(vftintrm_w_s, vv)
+INSN_LSX(vftintrm_l_d, vv)
+INSN_LSX(vftintrp_w_s, vv)
+INSN_LSX(vftintrp_l_d, vv)
+INSN_LSX(vftintrz_w_s, vv)
+INSN_LSX(vftintrz_l_d, vv)
+INSN_LSX(vftintrne_w_s,vv)
+INSN_LSX(vftintrne_l_d,vv)
+INSN_LSX(vftint_wu_s,  vv)
+INSN_LSX(vftint_lu_d,  vv)
+INSN_LSX(vftintrz_wu_s,vv)
+INSN_LSX(vftintrz_lu_d,vv)
+INSN_LSX(vftint_w_d,   vvv)
+INSN_LSX(vftintrm_w_d, vvv)
+INSN_LSX(vftintrp_w_d, vvv)
+INSN_LSX(vftintrz_w_d, vvv)
+INSN_LSX(vftintrne_w_d,vvv)
+INSN_LSX(vftintl_l_s,  vv)
+INSN_LSX(vftinth_l_s,  vv)
+INSN_LSX(vftintrml_l_s,vv)
+INSN_LSX(vftintrmh_l_s,vv)
+INSN_LSX(vftintrpl_l_s,vv)
+INSN_LSX(vftintrph_l_s,vv)
+INSN_LSX(vftintrzl_l_s,vv)
+INSN_LSX(vftintrzh_l_s,vv)
+INSN_LSX(vftintrnel_l_s,   vv)
+INSN_LSX(vftintrneh_l_s,   vv)
+
+INSN_LSX(vffint_s_w,   vv)
+INSN_LSX(vffint_s_wu,  vv)
+INSN_LSX(vffint_d_l,   vv)
+INSN_LSX(vffint_d_lu,  vv)
+INSN_LSX(vffintl_d_w,  vv)
+INSN_LSX(vffinth_d_w,  vv)
+INSN_LSX(vffint_s_l,   vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index a0c9de271d..f32235aa97 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -558,3 +558,59 @@ DEF_HELPER_3(vfrecip_s, void, env, i32, i32)
 DEF_HELPER_3(vfrecip_d, void, env, i32, i32)
 DEF_HELPER_3(vfrsqrt_s, void, env, i32, i32)
 DEF_HELPER_3(vfrsqrt_d, void, env, i32, i32)
+
+DEF_HELPER_3(vfcvtl_s_h, void, env, i32, i32)
+DEF_HELPER_3(vfcvth_s_h, void, env, i32, i32)
+DEF_HELPER_3(vfcvtl_d_s, void, env, i32, i32)
+DEF_HELPER_3(vfcvth_d_s, void, env, i32, i32)
+DEF_HELPER_4(vfcvt_h_s, void, env, i32, i32, i32)
+DEF_HELPER_4(vfcvt_s_d, void, env, i32, i32, i32)
+
+DEF_HELPER_3(vfrintrne_s, void, env, i32, i32)
+DEF_HELPER_3(vfrintrne_d, void, env, i32, i32)
+DEF_HELPER_3(vfrintrz_s, void, env, i32, i32)
+DEF_HELPER_3(vfrintrz_d, void, env, i32, i32)
+DEF_HELPER_3(vfrintrp_s, void, env, i32, i32)
+DEF_HELPER_3(vfrintrp_d, void, env, i32, i32)
+DEF_HELPER_3(vfrintrm_s, void, env, i32, i32)
+DEF_HELPER_3(vfrintrm_d, void, env, i32, i32)
+DEF_HELPER_3(vfrint_s, void, env, i32, i32)
+DEF_HELPER_3(vfrint_d, void, env, i32, i32)
+
+DEF_HELPER_3(vftintrne_w_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrne_l_d, void, env, i32, i32)
+DEF_HELPER_3(vftintrz_w_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrz_l_d, void, env, i32, i32)
+DEF_HELPER_3(vftintrp_w_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrp_l_d, void, env, i32, i32)
+DEF_HELPER_3(vftintrm_w_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrm_l_d, void, env, i32, i32)
+DEF_HELPER_3(vftint_w_s, void, env, i32, i32)
+DEF_HELPER_3(vftint_l_d, void, env, i32, i32)
+DEF_HELPER_3(vftintrz_wu_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrz_lu_d, void, env, i32, i32)
+DEF_HELPER_3(vftint_wu_s, void, env, i32, i32)
+DEF_HELPER_3(vftint_lu_d, void, env, i32, i32)
+DEF_HELPER_4(vftintrne_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vftintrz_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vftintrp_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vftintrm_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vftint_w_d, void, env, i32, i32, i32)
+DEF_HELPER_3(vftintrnel_l_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrneh_l_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrzl_l_s, void, env, i32, i32)
+DEF_HELPER_3(vftintrzh_l_s, void, 

[PULL 20/45] target/loongarch: Implement vmskltz/vmskgez/vmsknz

2023-05-04 Thread Song Gao
This patch includes:
- VMSKLTZ.{B/H/W/D};
- VMSKGEZ.B;
- VMSKNZ.B.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-21-gaos...@loongson.cn>
---
 target/loongarch/disas.c|   7 ++
 target/loongarch/helper.h   |   7 ++
 target/loongarch/insn_trans/trans_lsx.c.inc |   7 ++
 target/loongarch/insns.decode   |   7 ++
 target/loongarch/lsx_helper.c   | 113 
 5 files changed, 141 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 46e808c321..2725b827ee 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1084,3 +1084,10 @@ INSN_LSX(vsigncov_b,   vvv)
 INSN_LSX(vsigncov_h,   vvv)
 INSN_LSX(vsigncov_w,   vvv)
 INSN_LSX(vsigncov_d,   vvv)
+
+INSN_LSX(vmskltz_b,vv)
+INSN_LSX(vmskltz_h,vv)
+INSN_LSX(vmskltz_w,vv)
+INSN_LSX(vmskltz_d,vv)
+INSN_LSX(vmskgez_b,vv)
+INSN_LSX(vmsknz_b, vv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index e1e5d58697..34b7b2f576 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -343,3 +343,10 @@ DEF_HELPER_FLAGS_4(vsigncov_b, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vsigncov_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vsigncov_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vsigncov_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_3(vmskltz_b, void, env, i32, i32)
+DEF_HELPER_3(vmskltz_h, void, env, i32, i32)
+DEF_HELPER_3(vmskltz_w, void, env, i32, i32)
+DEF_HELPER_3(vmskltz_d, void, env, i32, i32)
+DEF_HELPER_3(vmskgez_b, void, env, i32, i32)
+DEF_HELPER_3(vmsknz_b, void, env, i32,i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 644917a695..64387f2666 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -2867,3 +2867,10 @@ TRANS(vsigncov_b, gvec_vvv, MO_8, do_vsigncov)
 TRANS(vsigncov_h, gvec_vvv, MO_16, do_vsigncov)
 TRANS(vsigncov_w, gvec_vvv, MO_32, do_vsigncov)
 TRANS(vsigncov_d, gvec_vvv, MO_64, do_vsigncov)
+
+TRANS(vmskltz_b, gen_vv, gen_helper_vmskltz_b)
+TRANS(vmskltz_h, gen_vv, gen_helper_vmskltz_h)
+TRANS(vmskltz_w, gen_vv, gen_helper_vmskltz_w)
+TRANS(vmskltz_d, gen_vv, gen_helper_vmskltz_d)
+TRANS(vmskgez_b, gen_vv, gen_helper_vmskgez_b)
+TRANS(vmsknz_b, gen_vv, gen_helper_vmsknz_b)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 4233dd7404..47c1ef78a7 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -783,3 +783,10 @@ vsigncov_b   0111 00010010 11100 . . .
@vvv
 vsigncov_h   0111 00010010 11101 . . .@vvv
 vsigncov_w   0111 00010010 0 . . .@vvv
 vsigncov_d   0111 00010010 1 . . .@vvv
+
+vmskltz_b0111 00101001 11000 1 . .@vv
+vmskltz_h0111 00101001 11000 10001 . .@vv
+vmskltz_w0111 00101001 11000 10010 . .@vv
+vmskltz_d0111 00101001 11000 10011 . .@vv
+vmskgez_b0111 00101001 11000 10100 . .@vv
+vmsknz_b 0111 00101001 11000 11000 . .@vv
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index 408815ea45..2359c63fdf 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -669,3 +669,116 @@ DO_3OP(vsigncov_b, 8, B, DO_SIGNCOV)
 DO_3OP(vsigncov_h, 16, H, DO_SIGNCOV)
 DO_3OP(vsigncov_w, 32, W, DO_SIGNCOV)
 DO_3OP(vsigncov_d, 64, D, DO_SIGNCOV)
+
+static uint64_t do_vmskltz_b(int64_t val)
+{
+uint64_t m = 0x8080808080808080ULL;
+uint64_t c =  val & m;
+c |= c << 7;
+c |= c << 14;
+c |= c << 28;
+return c >> 56;
+}
+
+void HELPER(vmskltz_b)(CPULoongArchState *env, uint32_t vd, uint32_t vj)
+{
+uint16_t temp = 0;
+VReg *Vd = &(env->fpr[vd].vreg);
+VReg *Vj = &(env->fpr[vj].vreg);
+
+temp = do_vmskltz_b(Vj->D(0));
+temp |= (do_vmskltz_b(Vj->D(1)) << 8);
+Vd->D(0) = temp;
+Vd->D(1) = 0;
+}
+
+static uint64_t do_vmskltz_h(int64_t val)
+{
+uint64_t m = 0x8000800080008000ULL;
+uint64_t c =  val & m;
+c |= c << 15;
+c |= c << 30;
+return c >> 60;
+}
+
+void HELPER(vmskltz_h)(CPULoongArchState *env, uint32_t vd, uint32_t vj)
+{
+uint16_t temp = 0;
+VReg *Vd = &(env->fpr[vd].vreg);
+VReg *Vj = &(env->fpr[vj].vreg);
+
+temp = do_vmskltz_h(Vj->D(0));
+temp |= (do_vmskltz_h(Vj->D(1)) << 4);
+Vd->D(0) = temp;
+Vd->D(1) = 0;
+}
+
+static uint64_t do_vmskltz_w(int64_t val)
+{
+uint64_t m = 0x80008000ULL;
+uint64_t c =  val & m;
+c |= c << 31;
+return c >> 62;
+}
+
+void HELPER(vmskltz_w)(CPULoongArchState *env, uint32_t vd, uint32_t vj)
+{
+uint16_t temp = 0;
+VReg *Vd = 

[PULL 14/45] target/loongarch: Implement vmul/vmuh/vmulw{ev/od}

2023-05-04 Thread Song Gao
This patch includes:
- VMUL.{B/H/W/D};
- VMUH.{B/H/W/D}[U];
- VMULW{EV/OD}.{H.B/W.H/D.W/Q.D}[U];
- VMULW{EV/OD}.{H.BU.B/W.HU.H/D.WU.W/Q.DU.D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-15-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  38 ++
 target/loongarch/helper.h   |  30 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 550 
 target/loongarch/insns.decode   |  38 ++
 target/loongarch/lsx_helper.c   |  76 +++
 5 files changed, 732 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 6b0e518bfa..48e6ef5309 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -972,3 +972,41 @@ INSN_LSX(vmini_bu, vv_i)
 INSN_LSX(vmini_hu, vv_i)
 INSN_LSX(vmini_wu, vv_i)
 INSN_LSX(vmini_du, vv_i)
+
+INSN_LSX(vmul_b,   vvv)
+INSN_LSX(vmul_h,   vvv)
+INSN_LSX(vmul_w,   vvv)
+INSN_LSX(vmul_d,   vvv)
+INSN_LSX(vmuh_b,   vvv)
+INSN_LSX(vmuh_h,   vvv)
+INSN_LSX(vmuh_w,   vvv)
+INSN_LSX(vmuh_d,   vvv)
+INSN_LSX(vmuh_bu,  vvv)
+INSN_LSX(vmuh_hu,  vvv)
+INSN_LSX(vmuh_wu,  vvv)
+INSN_LSX(vmuh_du,  vvv)
+
+INSN_LSX(vmulwev_h_b,  vvv)
+INSN_LSX(vmulwev_w_h,  vvv)
+INSN_LSX(vmulwev_d_w,  vvv)
+INSN_LSX(vmulwev_q_d,  vvv)
+INSN_LSX(vmulwod_h_b,  vvv)
+INSN_LSX(vmulwod_w_h,  vvv)
+INSN_LSX(vmulwod_d_w,  vvv)
+INSN_LSX(vmulwod_q_d,  vvv)
+INSN_LSX(vmulwev_h_bu, vvv)
+INSN_LSX(vmulwev_w_hu, vvv)
+INSN_LSX(vmulwev_d_wu, vvv)
+INSN_LSX(vmulwev_q_du, vvv)
+INSN_LSX(vmulwod_h_bu, vvv)
+INSN_LSX(vmulwod_w_hu, vvv)
+INSN_LSX(vmulwod_d_wu, vvv)
+INSN_LSX(vmulwod_q_du, vvv)
+INSN_LSX(vmulwev_h_bu_b,   vvv)
+INSN_LSX(vmulwev_w_hu_h,   vvv)
+INSN_LSX(vmulwev_d_wu_w,   vvv)
+INSN_LSX(vmulwev_q_du_d,   vvv)
+INSN_LSX(vmulwod_h_bu_b,   vvv)
+INSN_LSX(vmulwod_w_hu_h,   vvv)
+INSN_LSX(vmulwod_d_wu_w,   vvv)
+INSN_LSX(vmulwod_q_du_d,   vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 379f961d1e..830d8cbe62 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -243,3 +243,33 @@ DEF_HELPER_FLAGS_4(vmaxi_bu, TCG_CALL_NO_RWG, void, ptr, 
ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vmaxi_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vmaxi_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
 DEF_HELPER_FLAGS_4(vmaxi_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vmuh_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmuh_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmulwev_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmulwev_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmulwev_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwev_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_h_bu_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vmulwod_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 15bb7888d3..9a36f942e2 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -1514,3 +1514,553 @@ TRANS(vmaxi_bu, gvec_vv_i, MO_8, do_vmaxi_u)
 TRANS(vmaxi_hu, gvec_vv_i, MO_16, do_vmaxi_u)
 TRANS(vmaxi_wu, gvec_vv_i, MO_32, do_vmaxi_u)
 TRANS(vmaxi_du, gvec_vv_i, MO_64, 

[PULL 38/45] target/loongarch: Implement vinsgr2vr vpickve2gr vreplgr2vr

2023-05-04 Thread Song Gao
This patch includes:
- VINSGR2VR.{B/H/W/D};
- VPICKVE2GR.{B/H/W/D}[U];
- VREPLGR2VR.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-39-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  33 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 110 
 target/loongarch/insns.decode   |  30 ++
 3 files changed, 173 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index ecf0c7b577..7255a2aa4f 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -818,6 +818,21 @@ static void output_(DisasContext *ctx, arg_ *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, v%d, v%d, v%d", a->vd, a->vj, a->vk, a->va);
 }
 
+static void output_vr_i(DisasContext *ctx, arg_vr_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, r%d, 0x%x", a->vd, a->rj, a->imm);
+}
+
+static void output_rv_i(DisasContext *ctx, arg_rv_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "r%d, v%d, 0x%x", a->rd, a->vj,  a->imm);
+}
+
+static void output_vr(DisasContext *ctx, arg_vr *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, r%d", a->vd, a->rj);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -1561,3 +1576,21 @@ INSN_LSX(vsetallnez_b, cv)
 INSN_LSX(vsetallnez_h, cv)
 INSN_LSX(vsetallnez_w, cv)
 INSN_LSX(vsetallnez_d, cv)
+
+INSN_LSX(vinsgr2vr_b,  vr_i)
+INSN_LSX(vinsgr2vr_h,  vr_i)
+INSN_LSX(vinsgr2vr_w,  vr_i)
+INSN_LSX(vinsgr2vr_d,  vr_i)
+INSN_LSX(vpickve2gr_b, rv_i)
+INSN_LSX(vpickve2gr_h, rv_i)
+INSN_LSX(vpickve2gr_w, rv_i)
+INSN_LSX(vpickve2gr_d, rv_i)
+INSN_LSX(vpickve2gr_bu,rv_i)
+INSN_LSX(vpickve2gr_hu,rv_i)
+INSN_LSX(vpickve2gr_wu,rv_i)
+INSN_LSX(vpickve2gr_du,rv_i)
+
+INSN_LSX(vreplgr2vr_b, vr)
+INSN_LSX(vreplgr2vr_h, vr)
+INSN_LSX(vreplgr2vr_w, vr)
+INSN_LSX(vreplgr2vr_d, vr)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 964c3c47bf..e722b79bea 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3823,3 +3823,113 @@ TRANS(vsetallnez_b, gen_cv, gen_helper_vsetallnez_b)
 TRANS(vsetallnez_h, gen_cv, gen_helper_vsetallnez_h)
 TRANS(vsetallnez_w, gen_cv, gen_helper_vsetallnez_w)
 TRANS(vsetallnez_d, gen_cv, gen_helper_vsetallnez_d)
+
+static bool trans_vinsgr2vr_b(DisasContext *ctx, arg_vr_i *a)
+{
+CHECK_SXE;
+tcg_gen_st8_i64(cpu_gpr[a->rj], cpu_env,
+offsetof(CPULoongArchState, fpr[a->vd].vreg.B(a->imm)));
+return true;
+}
+
+static bool trans_vinsgr2vr_h(DisasContext *ctx, arg_vr_i *a)
+{
+CHECK_SXE;
+tcg_gen_st16_i64(cpu_gpr[a->rj], cpu_env,
+offsetof(CPULoongArchState, fpr[a->vd].vreg.H(a->imm)));
+return true;
+}
+
+static bool trans_vinsgr2vr_w(DisasContext *ctx, arg_vr_i *a)
+{
+CHECK_SXE;
+tcg_gen_st32_i64(cpu_gpr[a->rj], cpu_env,
+ offsetof(CPULoongArchState, fpr[a->vd].vreg.W(a->imm)));
+return true;
+}
+
+static bool trans_vinsgr2vr_d(DisasContext *ctx, arg_vr_i *a)
+{
+CHECK_SXE;
+tcg_gen_st_i64(cpu_gpr[a->rj], cpu_env,
+   offsetof(CPULoongArchState, fpr[a->vd].vreg.D(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_b(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld8s_i64(cpu_gpr[a->rd], cpu_env,
+ offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_h(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld16s_i64(cpu_gpr[a->rd], cpu_env,
+  offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_w(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld32s_i64(cpu_gpr[a->rd], cpu_env,
+  offsetof(CPULoongArchState, fpr[a->vj].vreg.W(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_d(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld_i64(cpu_gpr[a->rd], cpu_env,
+   offsetof(CPULoongArchState, fpr[a->vj].vreg.D(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_bu(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld8u_i64(cpu_gpr[a->rd], cpu_env,
+ offsetof(CPULoongArchState, fpr[a->vj].vreg.B(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_hu(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld16u_i64(cpu_gpr[a->rd], cpu_env,
+  offsetof(CPULoongArchState, fpr[a->vj].vreg.H(a->imm)));
+return true;
+}
+
+static bool trans_vpickve2gr_wu(DisasContext *ctx, arg_rv_i *a)
+{
+CHECK_SXE;
+tcg_gen_ld32u_i64(cpu_gpr[a->rd], cpu_env,
+  

[PULL 11/45] target/loongarch: Implement vabsd

2023-05-04 Thread Song Gao
This patch includes:
- VABSD.{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-12-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  9 ++
 target/loongarch/helper.h   |  9 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 95 +
 target/loongarch/insns.decode   |  9 ++
 target/loongarch/lsx_helper.c   | 11 +++
 5 files changed, 133 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index e7592e7a34..e98ea37793 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -925,3 +925,12 @@ INSN_LSX(vavgr_bu, vvv)
 INSN_LSX(vavgr_hu, vvv)
 INSN_LSX(vavgr_wu, vvv)
 INSN_LSX(vavgr_du, vvv)
+
+INSN_LSX(vabsd_b,  vvv)
+INSN_LSX(vabsd_h,  vvv)
+INSN_LSX(vabsd_w,  vvv)
+INSN_LSX(vabsd_d,  vvv)
+INSN_LSX(vabsd_bu, vvv)
+INSN_LSX(vabsd_hu, vvv)
+INSN_LSX(vabsd_wu, vvv)
+INSN_LSX(vabsd_du, vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index af0f9f9b0d..c3a5d2566e 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -211,3 +211,12 @@ DEF_HELPER_FLAGS_4(vavgr_bu, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vavgr_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vavgr_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vavgr_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vabsd_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vabsd_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 5fa4792305..0e9301bf93 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -1166,3 +1166,98 @@ TRANS(vavgr_bu, gvec_vvv, MO_8, do_vavgr_u)
 TRANS(vavgr_hu, gvec_vvv, MO_16, do_vavgr_u)
 TRANS(vavgr_wu, gvec_vvv, MO_32, do_vavgr_u)
 TRANS(vavgr_du, gvec_vvv, MO_64, do_vavgr_u)
+
+static void gen_vabsd_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+tcg_gen_smax_vec(vece, t, a, b);
+tcg_gen_smin_vec(vece, a, a, b);
+tcg_gen_sub_vec(vece, t, t, a);
+}
+
+static void do_vabsd_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+   uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_smax_vec, INDEX_op_smin_vec, INDEX_op_sub_vec, 0
+};
+static const GVecGen3 op[4] = {
+{
+.fniv = gen_vabsd_s,
+.fno = gen_helper_vabsd_b,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vabsd_s,
+.fno = gen_helper_vabsd_h,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vabsd_s,
+.fno = gen_helper_vabsd_w,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vabsd_s,
+.fno = gen_helper_vabsd_d,
+.opt_opc = vecop_list,
+.vece = MO_64
+},
+};
+
+tcg_gen_gvec_3(vd_ofs, vj_ofs, vk_ofs, oprsz, maxsz, [vece]);
+}
+
+static void gen_vabsd_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+tcg_gen_umax_vec(vece, t, a, b);
+tcg_gen_umin_vec(vece, a, a, b);
+tcg_gen_sub_vec(vece, t, t, a);
+}
+
+static void do_vabsd_u(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+   uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_umax_vec, INDEX_op_umin_vec, INDEX_op_sub_vec, 0
+};
+static const GVecGen3 op[4] = {
+{
+.fniv = gen_vabsd_u,
+.fno = gen_helper_vabsd_bu,
+.opt_opc = vecop_list,
+.vece = MO_8
+},
+{
+.fniv = gen_vabsd_u,
+.fno = gen_helper_vabsd_hu,
+.opt_opc = vecop_list,
+.vece = MO_16
+},
+{
+.fniv = gen_vabsd_u,
+.fno = gen_helper_vabsd_wu,
+.opt_opc = vecop_list,
+.vece = MO_32
+},
+{
+.fniv = gen_vabsd_u,
+.fno = gen_helper_vabsd_du,
+.opt_opc = vecop_list,
+.vece = MO_64
+},
+};
+
+tcg_gen_gvec_3(vd_ofs, 

[PULL 31/45] target/loongarch: Implement vbitclr vbitset vbitrev

2023-05-04 Thread Song Gao
This patch includes:
- VBITCLR[I].{B/H/W/D};
- VBITSET[I].{B/H/W/D};
- VBITREV[I].{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-32-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  25 ++
 target/loongarch/helper.h   |  27 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 305 
 target/loongarch/insns.decode   |  25 ++
 target/loongarch/lsx_helper.c   |  55 
 5 files changed, 437 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 0ca51de9d8..48c7ea47a4 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1272,3 +1272,28 @@ INSN_LSX(vpcnt_b,  vv)
 INSN_LSX(vpcnt_h,  vv)
 INSN_LSX(vpcnt_w,  vv)
 INSN_LSX(vpcnt_d,  vv)
+
+INSN_LSX(vbitclr_b,vvv)
+INSN_LSX(vbitclr_h,vvv)
+INSN_LSX(vbitclr_w,vvv)
+INSN_LSX(vbitclr_d,vvv)
+INSN_LSX(vbitclri_b,   vv_i)
+INSN_LSX(vbitclri_h,   vv_i)
+INSN_LSX(vbitclri_w,   vv_i)
+INSN_LSX(vbitclri_d,   vv_i)
+INSN_LSX(vbitset_b,vvv)
+INSN_LSX(vbitset_h,vvv)
+INSN_LSX(vbitset_w,vvv)
+INSN_LSX(vbitset_d,vvv)
+INSN_LSX(vbitseti_b,   vv_i)
+INSN_LSX(vbitseti_h,   vv_i)
+INSN_LSX(vbitseti_w,   vv_i)
+INSN_LSX(vbitseti_d,   vv_i)
+INSN_LSX(vbitrev_b,vvv)
+INSN_LSX(vbitrev_h,vvv)
+INSN_LSX(vbitrev_w,vvv)
+INSN_LSX(vbitrev_d,vvv)
+INSN_LSX(vbitrevi_b,   vv_i)
+INSN_LSX(vbitrevi_h,   vv_i)
+INSN_LSX(vbitrevi_w,   vv_i)
+INSN_LSX(vbitrevi_d,   vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 96b9b16923..75120ca55e 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -485,3 +485,30 @@ DEF_HELPER_3(vpcnt_b, void, env, i32, i32)
 DEF_HELPER_3(vpcnt_h, void, env, i32, i32)
 DEF_HELPER_3(vpcnt_w, void, env, i32, i32)
 DEF_HELPER_3(vpcnt_d, void, env, i32, i32)
+
+DEF_HELPER_FLAGS_4(vbitclr_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitclr_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitclr_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitclr_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitclri_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitclri_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitclri_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitclri_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vbitset_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitset_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitset_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitset_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitseti_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitseti_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitseti_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitseti_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vbitrev_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitrev_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitrev_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitrev_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vbitrevi_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitrevi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitrevi_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vbitrevi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index f4ebdca63c..86243b54ba 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3111,3 +3111,308 @@ TRANS(vpcnt_b, gen_vv, gen_helper_vpcnt_b)
 TRANS(vpcnt_h, gen_vv, gen_helper_vpcnt_h)
 TRANS(vpcnt_w, gen_vv, gen_helper_vpcnt_w)
 TRANS(vpcnt_d, gen_vv, gen_helper_vpcnt_d)
+
+static void do_vbit(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
+void (*func)(unsigned, TCGv_vec, TCGv_vec, TCGv_vec))
+{
+TCGv_vec mask, lsh, t1, one;
+
+lsh = tcg_temp_new_vec_matching(t);
+t1 = tcg_temp_new_vec_matching(t);
+mask = tcg_constant_vec_matching(t, vece, (8 << vece) - 1);
+one = tcg_constant_vec_matching(t, vece, 1);
+
+tcg_gen_and_vec(vece, lsh, b, mask);
+tcg_gen_shlv_vec(vece, t1, one, lsh);
+func(vece, t, a, t1);
+}
+
+static void gen_vbitclr(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vbit(vece, t, a, b, tcg_gen_andc_vec);
+}
+
+static void gen_vbitset(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vbit(vece, t, a, b, 

[PULL 40/45] target/loongarch: Implement vilvl vilvh vextrins vshuf

2023-05-04 Thread Song Gao
This patch includes:
- VILV{L/H}.{B/H/W/D};
- VSHUF.{B/H/W/D};
- VSHUF4I.{B/H/W/D};
- VPERMI.W;
- VEXTRINS.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-41-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  25 
 target/loongarch/helper.h   |  25 
 target/loongarch/insn_trans/trans_lsx.c.inc |  25 
 target/loongarch/insns.decode   |  25 
 target/loongarch/lsx_helper.c   | 148 
 5 files changed, 248 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c6cf782725..0b62bbb8be 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1629,3 +1629,28 @@ INSN_LSX(vpickod_b,vvv)
 INSN_LSX(vpickod_h,vvv)
 INSN_LSX(vpickod_w,vvv)
 INSN_LSX(vpickod_d,vvv)
+
+INSN_LSX(vilvl_b,  vvv)
+INSN_LSX(vilvl_h,  vvv)
+INSN_LSX(vilvl_w,  vvv)
+INSN_LSX(vilvl_d,  vvv)
+INSN_LSX(vilvh_b,  vvv)
+INSN_LSX(vilvh_h,  vvv)
+INSN_LSX(vilvh_w,  vvv)
+INSN_LSX(vilvh_d,  vvv)
+
+INSN_LSX(vshuf_b,  )
+INSN_LSX(vshuf_h,  vvv)
+INSN_LSX(vshuf_w,  vvv)
+INSN_LSX(vshuf_d,  vvv)
+INSN_LSX(vshuf4i_b,vv_i)
+INSN_LSX(vshuf4i_h,vv_i)
+INSN_LSX(vshuf4i_w,vv_i)
+INSN_LSX(vshuf4i_d,vv_i)
+
+INSN_LSX(vpermi_w, vv_i)
+
+INSN_LSX(vextrins_d,   vv_i)
+INSN_LSX(vextrins_w,   vv_i)
+INSN_LSX(vextrins_h,   vv_i)
+INSN_LSX(vextrins_b,   vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 51ad694be2..b9de77d926 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -671,3 +671,28 @@ DEF_HELPER_4(vpickod_b, void, env, i32, i32, i32)
 DEF_HELPER_4(vpickod_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vpickod_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vpickod_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vilvl_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvl_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvl_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvl_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvh_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvh_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvh_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vilvh_d, void, env, i32, i32, i32)
+
+DEF_HELPER_5(vshuf_b, void, env, i32, i32, i32, i32)
+DEF_HELPER_4(vshuf_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf4i_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf4i_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf4i_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vshuf4i_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vpermi_w, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vextrins_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vextrins_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vextrins_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vextrins_d, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 1146ace1b7..e1eee6bc4c 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -4077,3 +4077,28 @@ TRANS(vpickod_b, gen_vvv, gen_helper_vpickod_b)
 TRANS(vpickod_h, gen_vvv, gen_helper_vpickod_h)
 TRANS(vpickod_w, gen_vvv, gen_helper_vpickod_w)
 TRANS(vpickod_d, gen_vvv, gen_helper_vpickod_d)
+
+TRANS(vilvl_b, gen_vvv, gen_helper_vilvl_b)
+TRANS(vilvl_h, gen_vvv, gen_helper_vilvl_h)
+TRANS(vilvl_w, gen_vvv, gen_helper_vilvl_w)
+TRANS(vilvl_d, gen_vvv, gen_helper_vilvl_d)
+TRANS(vilvh_b, gen_vvv, gen_helper_vilvh_b)
+TRANS(vilvh_h, gen_vvv, gen_helper_vilvh_h)
+TRANS(vilvh_w, gen_vvv, gen_helper_vilvh_w)
+TRANS(vilvh_d, gen_vvv, gen_helper_vilvh_d)
+
+TRANS(vshuf_b, gen_, gen_helper_vshuf_b)
+TRANS(vshuf_h, gen_vvv, gen_helper_vshuf_h)
+TRANS(vshuf_w, gen_vvv, gen_helper_vshuf_w)
+TRANS(vshuf_d, gen_vvv, gen_helper_vshuf_d)
+TRANS(vshuf4i_b, gen_vv_i, gen_helper_vshuf4i_b)
+TRANS(vshuf4i_h, gen_vv_i, gen_helper_vshuf4i_h)
+TRANS(vshuf4i_w, gen_vv_i, gen_helper_vshuf4i_w)
+TRANS(vshuf4i_d, gen_vv_i, gen_helper_vshuf4i_d)
+
+TRANS(vpermi_w, gen_vv_i, gen_helper_vpermi_w)
+
+TRANS(vextrins_b, gen_vv_i, gen_helper_vextrins_b)
+TRANS(vextrins_h, gen_vv_i, gen_helper_vextrins_h)
+TRANS(vextrins_w, gen_vv_i, gen_helper_vextrins_w)
+TRANS(vextrins_d, gen_vv_i, gen_helper_vextrins_d)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index ab9e9e422f..0263bce28e 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -1231,3 +1231,28 @@ vpickod_b0111 00010010 0 . . .   
 @vvv
 vpickod_h0111 00010010 1 . . .@vvv
 vpickod_w0111 00010010 00010 . . .@vvv
 vpickod_d0111 00010010 00011 . . .@vvv
+
+vilvl_b 

[PULL 26/45] target/loongarch: Implement vsrlrn vsrarn

2023-05-04 Thread Song Gao
This patch includes:
- VSRLRN.{B.H/H.W/W.D};
- VSRARN.{B.H/H.W/W.D};
- VSRLRNI.{B.H/H.W/W.D/D.Q};
- VSRARNI.{B.H/H.W/W.D/D.Q}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-27-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  16 +++
 target/loongarch/helper.h   |  16 +++
 target/loongarch/insn_trans/trans_lsx.c.inc |  16 +++
 target/loongarch/insns.decode   |  16 +++
 target/loongarch/lsx_helper.c   | 126 
 5 files changed, 190 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index f0fc2ff84b..185cd36381 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1182,3 +1182,19 @@ INSN_LSX(vsrani_b_h,   vv_i)
 INSN_LSX(vsrani_h_w,   vv_i)
 INSN_LSX(vsrani_w_d,   vv_i)
 INSN_LSX(vsrani_d_q,   vv_i)
+
+INSN_LSX(vsrlrn_b_h,   vvv)
+INSN_LSX(vsrlrn_h_w,   vvv)
+INSN_LSX(vsrlrn_w_d,   vvv)
+INSN_LSX(vsrarn_b_h,   vvv)
+INSN_LSX(vsrarn_h_w,   vvv)
+INSN_LSX(vsrarn_w_d,   vvv)
+
+INSN_LSX(vsrlrni_b_h,  vv_i)
+INSN_LSX(vsrlrni_h_w,  vv_i)
+INSN_LSX(vsrlrni_w_d,  vv_i)
+INSN_LSX(vsrlrni_d_q,  vv_i)
+INSN_LSX(vsrarni_b_h,  vv_i)
+INSN_LSX(vsrarni_h_w,  vv_i)
+INSN_LSX(vsrarni_w_d,  vv_i)
+INSN_LSX(vsrarni_d_q,  vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index afe7e3d2d0..0a8cfe3625 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -395,3 +395,19 @@ DEF_HELPER_4(vsrani_b_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrani_h_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrani_w_d, void, env, i32, i32, i32)
 DEF_HELPER_4(vsrani_d_q, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vsrlrn_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlrn_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlrn_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarn_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarn_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarn_w_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vsrlrni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlrni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlrni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrlrni_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vsrarni_d_q, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index ad34378ada..6034a74bfb 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3021,3 +3021,19 @@ TRANS(vsrani_b_h, gen_vv_i, gen_helper_vsrani_b_h)
 TRANS(vsrani_h_w, gen_vv_i, gen_helper_vsrani_h_w)
 TRANS(vsrani_w_d, gen_vv_i, gen_helper_vsrani_w_d)
 TRANS(vsrani_d_q, gen_vv_i, gen_helper_vsrani_d_q)
+
+TRANS(vsrlrn_b_h, gen_vvv, gen_helper_vsrlrn_b_h)
+TRANS(vsrlrn_h_w, gen_vvv, gen_helper_vsrlrn_h_w)
+TRANS(vsrlrn_w_d, gen_vvv, gen_helper_vsrlrn_w_d)
+TRANS(vsrarn_b_h, gen_vvv, gen_helper_vsrarn_b_h)
+TRANS(vsrarn_h_w, gen_vvv, gen_helper_vsrarn_h_w)
+TRANS(vsrarn_w_d, gen_vvv, gen_helper_vsrarn_w_d)
+
+TRANS(vsrlrni_b_h, gen_vv_i, gen_helper_vsrlrni_b_h)
+TRANS(vsrlrni_h_w, gen_vv_i, gen_helper_vsrlrni_h_w)
+TRANS(vsrlrni_w_d, gen_vv_i, gen_helper_vsrlrni_w_d)
+TRANS(vsrlrni_d_q, gen_vv_i, gen_helper_vsrlrni_d_q)
+TRANS(vsrarni_b_h, gen_vv_i, gen_helper_vsrarni_b_h)
+TRANS(vsrarni_h_w, gen_vv_i, gen_helper_vsrarni_h_w)
+TRANS(vsrarni_w_d, gen_vv_i, gen_helper_vsrarni_w_d)
+TRANS(vsrarni_d_q, gen_vv_i, gen_helper_vsrarni_d_q)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index ee54b632a7..29bf4a8a6a 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -883,3 +883,19 @@ vsrani_b_h   0111 00110101 1 1  . .   
@vv_ui4
 vsrani_h_w   0111 00110101 10001 . . .@vv_ui5
 vsrani_w_d   0111 00110101 1001 .. . .@vv_ui6
 vsrani_d_q   0111 00110101 101 ... . .@vv_ui7
+
+vsrlrn_b_h   0111  10001 . . .@vvv
+vsrlrn_h_w   0111  10010 . . .@vvv
+vsrlrn_w_d   0111  10011 . . .@vvv
+vsrarn_b_h   0111  10101 . . .@vvv
+vsrarn_h_w   0111  10110 . . .@vvv
+vsrarn_w_d   0111  10111 . . .@vvv
+
+vsrlrni_b_h  0111 00110100 01000 1  . .   @vv_ui4
+vsrlrni_h_w  0111 00110100 01001 . . .@vv_ui5
+vsrlrni_w_d  0111 00110100 0101 .. . .@vv_ui6
+vsrlrni_d_q  0111 00110100 011 ... . .@vv_ui7
+vsrarni_b_h  0111 00110101 11000 1  . .   @vv_ui4
+vsrarni_h_w  0111 00110101 11001 . . .@vv_ui5
+vsrarni_w_d 

[PULL 13/45] target/loongarch: Implement vmax/vmin

2023-05-04 Thread Song Gao
This patch includes:
- VMAX[I].{B/H/W/D}[U];
- VMIN[I].{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-14-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  33 
 target/loongarch/helper.h   |  18 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 200 
 target/loongarch/insns.decode   |  35 
 target/loongarch/lsx_helper.c   |  33 
 5 files changed, 319 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 1f61e67d1f..6b0e518bfa 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -939,3 +939,36 @@ INSN_LSX(vadda_b,  vvv)
 INSN_LSX(vadda_h,  vvv)
 INSN_LSX(vadda_w,  vvv)
 INSN_LSX(vadda_d,  vvv)
+
+INSN_LSX(vmax_b,   vvv)
+INSN_LSX(vmax_h,   vvv)
+INSN_LSX(vmax_w,   vvv)
+INSN_LSX(vmax_d,   vvv)
+INSN_LSX(vmin_b,   vvv)
+INSN_LSX(vmin_h,   vvv)
+INSN_LSX(vmin_w,   vvv)
+INSN_LSX(vmin_d,   vvv)
+INSN_LSX(vmax_bu,  vvv)
+INSN_LSX(vmax_hu,  vvv)
+INSN_LSX(vmax_wu,  vvv)
+INSN_LSX(vmax_du,  vvv)
+INSN_LSX(vmin_bu,  vvv)
+INSN_LSX(vmin_hu,  vvv)
+INSN_LSX(vmin_wu,  vvv)
+INSN_LSX(vmin_du,  vvv)
+INSN_LSX(vmaxi_b,  vv_i)
+INSN_LSX(vmaxi_h,  vv_i)
+INSN_LSX(vmaxi_w,  vv_i)
+INSN_LSX(vmaxi_d,  vv_i)
+INSN_LSX(vmini_b,  vv_i)
+INSN_LSX(vmini_h,  vv_i)
+INSN_LSX(vmini_w,  vv_i)
+INSN_LSX(vmini_d,  vv_i)
+INSN_LSX(vmaxi_bu, vv_i)
+INSN_LSX(vmaxi_hu, vv_i)
+INSN_LSX(vmaxi_wu, vv_i)
+INSN_LSX(vmaxi_du, vv_i)
+INSN_LSX(vmini_bu, vv_i)
+INSN_LSX(vmini_hu, vv_i)
+INSN_LSX(vmini_wu, vv_i)
+INSN_LSX(vmini_du, vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 85fb8f60d2..379f961d1e 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -225,3 +225,21 @@ DEF_HELPER_FLAGS_4(vadda_b, TCG_CALL_NO_RWG, void, ptr, 
ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vadda_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vadda_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vadda_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vmini_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmini_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_FLAGS_4(vmaxi_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_h, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_w, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_d, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+DEF_HELPER_FLAGS_4(vmaxi_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 8ad81c8517..15bb7888d3 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -1314,3 +1314,203 @@ TRANS(vadda_b, gvec_vvv, MO_8, do_vadda)
 TRANS(vadda_h, gvec_vvv, MO_16, do_vadda)
 TRANS(vadda_w, gvec_vvv, MO_32, do_vadda)
 TRANS(vadda_d, gvec_vvv, MO_64, do_vadda)
+
+TRANS(vmax_b, gvec_vvv, MO_8, tcg_gen_gvec_smax)
+TRANS(vmax_h, gvec_vvv, MO_16, tcg_gen_gvec_smax)
+TRANS(vmax_w, gvec_vvv, MO_32, tcg_gen_gvec_smax)
+TRANS(vmax_d, gvec_vvv, MO_64, tcg_gen_gvec_smax)
+TRANS(vmax_bu, gvec_vvv, MO_8, tcg_gen_gvec_umax)
+TRANS(vmax_hu, gvec_vvv, MO_16, tcg_gen_gvec_umax)
+TRANS(vmax_wu, gvec_vvv, MO_32, tcg_gen_gvec_umax)
+TRANS(vmax_du, gvec_vvv, MO_64, tcg_gen_gvec_umax)
+
+TRANS(vmin_b, gvec_vvv, MO_8, tcg_gen_gvec_smin)
+TRANS(vmin_h, gvec_vvv, MO_16, tcg_gen_gvec_smin)
+TRANS(vmin_w, gvec_vvv, MO_32, tcg_gen_gvec_smin)
+TRANS(vmin_d, gvec_vvv, MO_64, tcg_gen_gvec_smin)
+TRANS(vmin_bu, gvec_vvv, MO_8, tcg_gen_gvec_umin)
+TRANS(vmin_hu, gvec_vvv, MO_16, tcg_gen_gvec_umin)
+TRANS(vmin_wu, gvec_vvv, MO_32, tcg_gen_gvec_umin)
+TRANS(vmin_du, gvec_vvv, MO_64, tcg_gen_gvec_umin)
+
+static void gen_vmini_s(unsigned vece, TCGv_vec t, TCGv_vec a, int64_t imm)
+{
+tcg_gen_smin_vec(vece, t, a, tcg_constant_vec_matching(t, vece, imm));
+}
+
+static void 

[PULL 10/45] target/loongarch: Implement vavg/vavgr

2023-05-04 Thread Song Gao
This patch includes:
- VAVG.{B/H/W/D}[U];
- VAVGR.{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-11-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  17 ++
 target/loongarch/helper.h   |  18 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 197 
 target/loongarch/insns.decode   |  17 ++
 target/loongarch/lsx_helper.c   |  32 
 5 files changed, 281 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 8ee14916f3..e7592e7a34 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -908,3 +908,20 @@ INSN_LSX(vaddwod_h_bu_b,   vvv)
 INSN_LSX(vaddwod_w_hu_h,   vvv)
 INSN_LSX(vaddwod_d_wu_w,   vvv)
 INSN_LSX(vaddwod_q_du_d,   vvv)
+
+INSN_LSX(vavg_b,   vvv)
+INSN_LSX(vavg_h,   vvv)
+INSN_LSX(vavg_w,   vvv)
+INSN_LSX(vavg_d,   vvv)
+INSN_LSX(vavg_bu,  vvv)
+INSN_LSX(vavg_hu,  vvv)
+INSN_LSX(vavg_wu,  vvv)
+INSN_LSX(vavg_du,  vvv)
+INSN_LSX(vavgr_b,  vvv)
+INSN_LSX(vavgr_h,  vvv)
+INSN_LSX(vavgr_w,  vvv)
+INSN_LSX(vavgr_d,  vvv)
+INSN_LSX(vavgr_bu, vvv)
+INSN_LSX(vavgr_hu, vvv)
+INSN_LSX(vavgr_wu, vvv)
+INSN_LSX(vavgr_du, vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 505c336ff3..af0f9f9b0d 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -193,3 +193,21 @@ DEF_HELPER_FLAGS_4(vaddwod_h_bu_b, TCG_CALL_NO_RWG, void, 
ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vaddwod_w_hu_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vaddwod_d_wu_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_4(vaddwod_q_du_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vavg_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavg_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vavgr_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vavgr_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 8edff83157..5fa4792305 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -969,3 +969,200 @@ TRANS(vaddwod_h_bu_b, gvec_vvv, MO_8, do_vaddwod_u_s)
 TRANS(vaddwod_w_hu_h, gvec_vvv, MO_16, do_vaddwod_u_s)
 TRANS(vaddwod_d_wu_w, gvec_vvv, MO_32, do_vaddwod_u_s)
 TRANS(vaddwod_q_du_d, gvec_vvv, MO_64, do_vaddwod_u_s)
+
+static void do_vavg(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b,
+void (*gen_shr_vec)(unsigned, TCGv_vec,
+TCGv_vec, int64_t),
+void (*gen_round_vec)(unsigned, TCGv_vec,
+  TCGv_vec, TCGv_vec))
+{
+TCGv_vec tmp = tcg_temp_new_vec_matching(t);
+gen_round_vec(vece, tmp, a, b);
+tcg_gen_and_vec(vece, tmp, tmp, tcg_constant_vec_matching(t, vece, 1));
+gen_shr_vec(vece, a, a, 1);
+gen_shr_vec(vece, b, b, 1);
+tcg_gen_add_vec(vece, t, a, b);
+tcg_gen_add_vec(vece, t, t, tmp);
+}
+
+static void gen_vavg_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_and_vec);
+}
+
+static void gen_vavg_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_and_vec);
+}
+
+static void gen_vavgr_s(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vavg(vece, t, a, b, tcg_gen_sari_vec, tcg_gen_or_vec);
+}
+
+static void gen_vavgr_u(unsigned vece, TCGv_vec t, TCGv_vec a, TCGv_vec b)
+{
+do_vavg(vece, t, a, b, tcg_gen_shri_vec, tcg_gen_or_vec);
+}
+
+static void do_vavg_s(unsigned vece, uint32_t vd_ofs, uint32_t vj_ofs,
+  uint32_t vk_ofs, uint32_t oprsz, uint32_t maxsz)
+{
+static const TCGOpcode vecop_list[] = {
+INDEX_op_sari_vec, INDEX_op_add_vec, 0
+};
+static const 

[PULL 08/45] target/loongarch: Implement vhaddw/vhsubw

2023-05-04 Thread Song Gao
This patch includes:
- VHADDW.{H.B/W.H/D.W/Q.D/HU.BU/WU.HU/DU.WU/QU.DU};
- VHSUBW.{H.B/W.H/D.W/Q.D/HU.BU/WU.HU/DU.WU/QU.DU}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-9-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 17 +
 target/loongarch/helper.h   | 18 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 17 +
 target/loongarch/insns.decode   | 17 +
 target/loongarch/lsx_helper.c   | 81 +
 5 files changed, 150 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index b7f9320ba0..adfd693938 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -848,3 +848,20 @@ INSN_LSX(vssub_bu, vvv)
 INSN_LSX(vssub_hu, vvv)
 INSN_LSX(vssub_wu, vvv)
 INSN_LSX(vssub_du, vvv)
+
+INSN_LSX(vhaddw_h_b,   vvv)
+INSN_LSX(vhaddw_w_h,   vvv)
+INSN_LSX(vhaddw_d_w,   vvv)
+INSN_LSX(vhaddw_q_d,   vvv)
+INSN_LSX(vhaddw_hu_bu, vvv)
+INSN_LSX(vhaddw_wu_hu, vvv)
+INSN_LSX(vhaddw_du_wu, vvv)
+INSN_LSX(vhaddw_qu_du, vvv)
+INSN_LSX(vhsubw_h_b,   vvv)
+INSN_LSX(vhsubw_w_h,   vvv)
+INSN_LSX(vhsubw_d_w,   vvv)
+INSN_LSX(vhsubw_q_d,   vvv)
+INSN_LSX(vhsubw_hu_bu, vvv)
+INSN_LSX(vhsubw_wu_hu, vvv)
+INSN_LSX(vhsubw_du_wu, vvv)
+INSN_LSX(vhsubw_qu_du, vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 9c01823a26..6d58dabaed 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -130,3 +130,21 @@ DEF_HELPER_4(ldpte, void, env, tl, tl, i32)
 DEF_HELPER_1(ertn, void, env)
 DEF_HELPER_1(idle, void, env)
 #endif
+
+/* LoongArch LSX  */
+DEF_HELPER_4(vhaddw_h_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_w_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_d_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_q_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_hu_bu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_wu_hu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_du_wu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhaddw_qu_du, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_h_b, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_w_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_d_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_q_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_hu_bu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_wu_hu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_du_wu, void, env, i32, i32, i32)
+DEF_HELPER_4(vhsubw_qu_du, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 082bd738ce..562096c0d7 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -157,3 +157,20 @@ TRANS(vssub_bu, gvec_vvv, MO_8, tcg_gen_gvec_ussub)
 TRANS(vssub_hu, gvec_vvv, MO_16, tcg_gen_gvec_ussub)
 TRANS(vssub_wu, gvec_vvv, MO_32, tcg_gen_gvec_ussub)
 TRANS(vssub_du, gvec_vvv, MO_64, tcg_gen_gvec_ussub)
+
+TRANS(vhaddw_h_b, gen_vvv, gen_helper_vhaddw_h_b)
+TRANS(vhaddw_w_h, gen_vvv, gen_helper_vhaddw_w_h)
+TRANS(vhaddw_d_w, gen_vvv, gen_helper_vhaddw_d_w)
+TRANS(vhaddw_q_d, gen_vvv, gen_helper_vhaddw_q_d)
+TRANS(vhaddw_hu_bu, gen_vvv, gen_helper_vhaddw_hu_bu)
+TRANS(vhaddw_wu_hu, gen_vvv, gen_helper_vhaddw_wu_hu)
+TRANS(vhaddw_du_wu, gen_vvv, gen_helper_vhaddw_du_wu)
+TRANS(vhaddw_qu_du, gen_vvv, gen_helper_vhaddw_qu_du)
+TRANS(vhsubw_h_b, gen_vvv, gen_helper_vhsubw_h_b)
+TRANS(vhsubw_w_h, gen_vvv, gen_helper_vhsubw_w_h)
+TRANS(vhsubw_d_w, gen_vvv, gen_helper_vhsubw_d_w)
+TRANS(vhsubw_q_d, gen_vvv, gen_helper_vhsubw_q_d)
+TRANS(vhsubw_hu_bu, gen_vvv, gen_helper_vhsubw_hu_bu)
+TRANS(vhsubw_wu_hu, gen_vvv, gen_helper_vhsubw_wu_hu)
+TRANS(vhsubw_du_wu, gen_vvv, gen_helper_vhsubw_du_wu)
+TRANS(vhsubw_qu_du, gen_vvv, gen_helper_vhsubw_qu_du)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 3a29f0a9ab..10a20858e5 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -542,3 +542,20 @@ vssub_bu 0111 0100 11000 . . .
@vvv
 vssub_hu 0111 0100 11001 . . .@vvv
 vssub_wu 0111 0100 11010 . . .@vvv
 vssub_du 0111 0100 11011 . . .@vvv
+
+vhaddw_h_b   0111 0101 01000 . . .@vvv
+vhaddw_w_h   0111 0101 01001 . . .@vvv
+vhaddw_d_w   0111 0101 01010 . . .@vvv
+vhaddw_q_d   0111 0101 01011 . . .@vvv
+vhaddw_hu_bu 0111 0101 1 . . .@vvv
+vhaddw_wu_hu 0111 0101 10001 . . .@vvv
+vhaddw_du_wu 0111 0101 10010 . . .@vvv
+vhaddw_qu_du 0111 0101 10011 . . .@vvv
+vhsubw_h_b   0111 0101 01100 . . .@vvv
+vhsubw_w_h   0111 0101 01101 

[PULL 03/45] target/loongarch: Add CHECK_SXE maccro for check LSX enable

2023-05-04 Thread Song Gao
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-4-gaos...@loongson.cn>
---
 target/loongarch/cpu.c  |  2 ++
 target/loongarch/cpu.h  |  2 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 11 +++
 3 files changed, 15 insertions(+)

diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 18b41221a6..55d7f9255e 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -52,6 +52,7 @@ static const char * const excp_names[] = {
 [EXCCODE_FPE] = "Floating Point Exception",
 [EXCCODE_DBP] = "Debug breakpoint",
 [EXCCODE_BCE] = "Bound Check Exception",
+[EXCCODE_SXD] = "128 bit vector instructions Disable exception",
 };
 
 const char *loongarch_exception_name(int32_t exception)
@@ -187,6 +188,7 @@ static void loongarch_cpu_do_interrupt(CPUState *cs)
 case EXCCODE_FPD:
 case EXCCODE_FPE:
 case EXCCODE_BCE:
+case EXCCODE_SXD:
 env->CSR_BADV = env->pc;
 QEMU_FALLTHROUGH;
 case EXCCODE_ADEM:
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index fd0f61936d..6755b1f0c7 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -419,6 +419,7 @@ static inline int cpu_mmu_index(CPULoongArchState *env, 
bool ifetch)
 #define HW_FLAGS_PLV_MASK   R_CSR_CRMD_PLV_MASK  /* 0x03 */
 #define HW_FLAGS_CRMD_PGR_CSR_CRMD_PG_MASK   /* 0x10 */
 #define HW_FLAGS_EUEN_FPE   0x04
+#define HW_FLAGS_EUEN_SXE   0x08
 
 static inline void cpu_get_tb_cpu_state(CPULoongArchState *env,
 target_ulong *pc,
@@ -429,6 +430,7 @@ static inline void cpu_get_tb_cpu_state(CPULoongArchState 
*env,
 *cs_base = 0;
 *flags = env->CSR_CRMD & (R_CSR_CRMD_PLV_MASK | R_CSR_CRMD_PG_MASK);
 *flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, FPE) * HW_FLAGS_EUEN_FPE;
+*flags |= FIELD_EX64(env->CSR_EUEN, CSR_EUEN, SXE) * HW_FLAGS_EUEN_SXE;
 }
 
 void loongarch_cpu_list(void);
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 1cf3ab34a9..5dedb044d7 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3,3 +3,14 @@
  * LSX translate functions
  * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
  */
+
+#ifndef CONFIG_USER_ONLY
+#define CHECK_SXE do { \
+if ((ctx->base.tb->flags & HW_FLAGS_EUEN_SXE) == 0) { \
+generate_exception(ctx, EXCCODE_SXD); \
+return true; \
+} \
+} while (0)
+#else
+#define CHECK_SXE
+#endif
-- 
2.31.1




[PULL 06/45] target/loongarch: Implement vneg

2023-05-04 Thread Song Gao
This patch includes;
- VNEG.{B/H/W/D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-7-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 10 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 20 
 target/loongarch/insns.decode   |  7 +++
 3 files changed, 37 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c1960610c2..5eabb8c47a 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -802,6 +802,11 @@ static void output_vv_i(DisasContext *ctx, arg_vv_i *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, v%d, 0x%x", a->vd, a->vj, a->imm);
 }
 
+static void output_vv(DisasContext *ctx, arg_vv *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, v%d", a->vd, a->vj);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -821,3 +826,8 @@ INSN_LSX(vsubi_bu, vv_i)
 INSN_LSX(vsubi_hu, vv_i)
 INSN_LSX(vsubi_wu, vv_i)
 INSN_LSX(vsubi_du, vv_i)
+
+INSN_LSX(vneg_b,   vv)
+INSN_LSX(vneg_h,   vv)
+INSN_LSX(vneg_w,   vv)
+INSN_LSX(vneg_d,   vv)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index e6c1d0d2cc..d02db6285f 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -44,6 +44,21 @@ static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp 
mop,
 return true;
 }
 
+static bool gvec_vv(DisasContext *ctx, arg_vv *a, MemOp mop,
+void (*func)(unsigned, uint32_t, uint32_t,
+ uint32_t, uint32_t))
+{
+uint32_t vd_ofs, vj_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+
+func(mop, vd_ofs, vj_ofs, 16, ctx->vl/8);
+return true;
+}
+
 static bool gvec_vv_i(DisasContext *ctx, arg_vv_i *a, MemOp mop,
   void (*func)(unsigned, uint32_t, uint32_t,
int64_t, uint32_t, uint32_t))
@@ -120,3 +135,8 @@ TRANS(vsubi_bu, gvec_subi, MO_8)
 TRANS(vsubi_hu, gvec_subi, MO_16)
 TRANS(vsubi_wu, gvec_subi, MO_32)
 TRANS(vsubi_du, gvec_subi, MO_64)
+
+TRANS(vneg_b, gvec_vv, MO_8, tcg_gen_gvec_neg)
+TRANS(vneg_h, gvec_vv, MO_16, tcg_gen_gvec_neg)
+TRANS(vneg_w, gvec_vv, MO_32, tcg_gen_gvec_neg)
+TRANS(vneg_d, gvec_vv, MO_64, tcg_gen_gvec_neg)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 2a98c14518..d90798be11 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -490,12 +490,14 @@ dbcl  0010 10101 ...  
@i15
 # LSX Argument sets
 #
 
+   vd vj
   vd vj vk
 _i vd vj imm
 
 #
 # LSX Formats
 #
+@vv     . . vj:5 vd:5
 @vvv     . vk:5 vj:5 vd:5
 @vv_ui5     . imm:5 vj:5 vd:5_i
 
@@ -518,3 +520,8 @@ vsubi_bu 0111 00101000 11000 . . .
@vv_ui5
 vsubi_hu 0111 00101000 11001 . . .@vv_ui5
 vsubi_wu 0111 00101000 11010 . . .@vv_ui5
 vsubi_du 0111 00101000 11011 . . .@vv_ui5
+
+vneg_b   0111 00101001 11000 01100 . .@vv
+vneg_h   0111 00101001 11000 01101 . .@vv
+vneg_w   0111 00101001 11000 01110 . .@vv
+vneg_d   0111 00101001 11000 0 . .@vv
-- 
2.31.1




[PULL 09/45] target/loongarch: Implement vaddw/vsubw

2023-05-04 Thread Song Gao
This patch includes:
- VADDW{EV/OD}.{H.B/W.H/D.W/Q.D}[U];
- VSUBW{EV/OD}.{H.B/W.H/D.W/Q.D}[U];
- VADDW{EV/OD}.{H.BU.B/W.HU.H/D.WU.W/Q.DU.D}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-10-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  43 ++
 target/loongarch/helper.h   |  45 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 795 
 target/loongarch/insns.decode   |  43 ++
 target/loongarch/lsx_helper.c   | 190 +
 5 files changed, 1116 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index adfd693938..8ee14916f3 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -865,3 +865,46 @@ INSN_LSX(vhsubw_hu_bu, vvv)
 INSN_LSX(vhsubw_wu_hu, vvv)
 INSN_LSX(vhsubw_du_wu, vvv)
 INSN_LSX(vhsubw_qu_du, vvv)
+
+INSN_LSX(vaddwev_h_b,  vvv)
+INSN_LSX(vaddwev_w_h,  vvv)
+INSN_LSX(vaddwev_d_w,  vvv)
+INSN_LSX(vaddwev_q_d,  vvv)
+INSN_LSX(vaddwod_h_b,  vvv)
+INSN_LSX(vaddwod_w_h,  vvv)
+INSN_LSX(vaddwod_d_w,  vvv)
+INSN_LSX(vaddwod_q_d,  vvv)
+INSN_LSX(vsubwev_h_b,  vvv)
+INSN_LSX(vsubwev_w_h,  vvv)
+INSN_LSX(vsubwev_d_w,  vvv)
+INSN_LSX(vsubwev_q_d,  vvv)
+INSN_LSX(vsubwod_h_b,  vvv)
+INSN_LSX(vsubwod_w_h,  vvv)
+INSN_LSX(vsubwod_d_w,  vvv)
+INSN_LSX(vsubwod_q_d,  vvv)
+
+INSN_LSX(vaddwev_h_bu, vvv)
+INSN_LSX(vaddwev_w_hu, vvv)
+INSN_LSX(vaddwev_d_wu, vvv)
+INSN_LSX(vaddwev_q_du, vvv)
+INSN_LSX(vaddwod_h_bu, vvv)
+INSN_LSX(vaddwod_w_hu, vvv)
+INSN_LSX(vaddwod_d_wu, vvv)
+INSN_LSX(vaddwod_q_du, vvv)
+INSN_LSX(vsubwev_h_bu, vvv)
+INSN_LSX(vsubwev_w_hu, vvv)
+INSN_LSX(vsubwev_d_wu, vvv)
+INSN_LSX(vsubwev_q_du, vvv)
+INSN_LSX(vsubwod_h_bu, vvv)
+INSN_LSX(vsubwod_w_hu, vvv)
+INSN_LSX(vsubwod_d_wu, vvv)
+INSN_LSX(vsubwod_q_du, vvv)
+
+INSN_LSX(vaddwev_h_bu_b,   vvv)
+INSN_LSX(vaddwev_w_hu_h,   vvv)
+INSN_LSX(vaddwev_d_wu_w,   vvv)
+INSN_LSX(vaddwev_q_du_d,   vvv)
+INSN_LSX(vaddwod_h_bu_b,   vvv)
+INSN_LSX(vaddwod_w_hu_h,   vvv)
+INSN_LSX(vaddwod_d_wu_w,   vvv)
+INSN_LSX(vaddwod_q_du_d,   vvv)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 6d58dabaed..505c336ff3 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -148,3 +148,48 @@ DEF_HELPER_4(vhsubw_hu_bu, void, env, i32, i32, i32)
 DEF_HELPER_4(vhsubw_wu_hu, void, env, i32, i32, i32)
 DEF_HELPER_4(vhsubw_du_wu, void, env, i32, i32, i32)
 DEF_HELPER_4(vhsubw_qu_du, void, env, i32, i32, i32)
+
+DEF_HELPER_FLAGS_4(vaddwev_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_q_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_q_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vsubwev_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_q_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_h_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_w_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_d_w, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_q_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vaddwev_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwev_q_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vaddwod_q_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(vsubwev_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_d_wu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwev_q_du, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_h_bu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_w_hu, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_4(vsubwod_d_wu, TCG_CALL_NO_RWG, void, 

[PULL 28/45] target/loongarch: Implement vssrlrn vssrarn

2023-05-04 Thread Song Gao
This patch includes:
- VSSRLRN.{B.H/H.W/W.D};
- VSSRARN.{B.H/H.W/W.D};
- VSSRLRN.{BU.H/HU.W/WU.D};
- VSSRARN.{BU.H/HU.W/WU.D};
- VSSRLRNI.{B.H/H.W/W.D/D.Q};
- VSSRARNI.{B.H/H.W/W.D/D.Q};
- VSSRLRNI.{BU.H/HU.W/WU.D/DU.Q};
- VSSRARNI.{BU.H/HU.W/WU.D/DU.Q}.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-29-gaos...@loongson.cn>
---
 target/loongarch/disas.c|  30 ++
 target/loongarch/helper.h   |  30 ++
 target/loongarch/insn_trans/trans_lsx.c.inc |  30 ++
 target/loongarch/insns.decode   |  30 ++
 target/loongarch/lsx_helper.c   | 358 
 5 files changed, 478 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 426d30dc01..405e8885cd 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1228,3 +1228,33 @@ INSN_LSX(vssrani_bu_h, vv_i)
 INSN_LSX(vssrani_hu_w, vv_i)
 INSN_LSX(vssrani_wu_d, vv_i)
 INSN_LSX(vssrani_du_q, vv_i)
+
+INSN_LSX(vssrlrn_b_h,  vvv)
+INSN_LSX(vssrlrn_h_w,  vvv)
+INSN_LSX(vssrlrn_w_d,  vvv)
+INSN_LSX(vssrarn_b_h,  vvv)
+INSN_LSX(vssrarn_h_w,  vvv)
+INSN_LSX(vssrarn_w_d,  vvv)
+INSN_LSX(vssrlrn_bu_h, vvv)
+INSN_LSX(vssrlrn_hu_w, vvv)
+INSN_LSX(vssrlrn_wu_d, vvv)
+INSN_LSX(vssrarn_bu_h, vvv)
+INSN_LSX(vssrarn_hu_w, vvv)
+INSN_LSX(vssrarn_wu_d, vvv)
+
+INSN_LSX(vssrlrni_b_h, vv_i)
+INSN_LSX(vssrlrni_h_w, vv_i)
+INSN_LSX(vssrlrni_w_d, vv_i)
+INSN_LSX(vssrlrni_d_q, vv_i)
+INSN_LSX(vssrlrni_bu_h,vv_i)
+INSN_LSX(vssrlrni_hu_w,vv_i)
+INSN_LSX(vssrlrni_wu_d,vv_i)
+INSN_LSX(vssrlrni_du_q,vv_i)
+INSN_LSX(vssrarni_b_h, vv_i)
+INSN_LSX(vssrarni_h_w, vv_i)
+INSN_LSX(vssrarni_w_d, vv_i)
+INSN_LSX(vssrarni_d_q, vv_i)
+INSN_LSX(vssrarni_bu_h,vv_i)
+INSN_LSX(vssrarni_hu_w,vv_i)
+INSN_LSX(vssrarni_wu_d,vv_i)
+INSN_LSX(vssrarni_du_q,vv_i)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h
index 28f159768c..724112da81 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -441,3 +441,33 @@ DEF_HELPER_4(vssrani_bu_h, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrani_hu_w, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrani_wu_d, void, env, i32, i32, i32)
 DEF_HELPER_4(vssrani_du_q, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vssrlrn_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrn_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrn_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrn_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrn_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrn_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarn_wu_d, void, env, i32, i32, i32)
+
+DEF_HELPER_4(vssrlrni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_b_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_h_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_w_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_d_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrlrni_du_q, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_bu_h, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_hu_w, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_wu_d, void, env, i32, i32, i32)
+DEF_HELPER_4(vssrarni_du_q, void, env, i32, i32, i32)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index 5d7e45a793..9c24cbc297 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3067,3 +3067,33 @@ TRANS(vssrani_bu_h, gen_vv_i, gen_helper_vssrani_bu_h)
 TRANS(vssrani_hu_w, gen_vv_i, gen_helper_vssrani_hu_w)
 TRANS(vssrani_wu_d, gen_vv_i, gen_helper_vssrani_wu_d)
 TRANS(vssrani_du_q, gen_vv_i, gen_helper_vssrani_du_q)
+
+TRANS(vssrlrn_b_h, gen_vvv, gen_helper_vssrlrn_b_h)
+TRANS(vssrlrn_h_w, gen_vvv, gen_helper_vssrlrn_h_w)
+TRANS(vssrlrn_w_d, gen_vvv, gen_helper_vssrlrn_w_d)
+TRANS(vssrarn_b_h, gen_vvv, gen_helper_vssrarn_b_h)
+TRANS(vssrarn_h_w, gen_vvv, gen_helper_vssrarn_h_w)
+TRANS(vssrarn_w_d, gen_vvv, gen_helper_vssrarn_w_d)
+TRANS(vssrlrn_bu_h, gen_vvv, gen_helper_vssrlrn_bu_h)
+TRANS(vssrlrn_hu_w, gen_vvv, gen_helper_vssrlrn_hu_w)
+TRANS(vssrlrn_wu_d, gen_vvv, gen_helper_vssrlrn_wu_d)
+TRANS(vssrarn_bu_h, gen_vvv, gen_helper_vssrarn_bu_h)
+TRANS(vssrarn_hu_w, gen_vvv, gen_helper_vssrarn_hu_w)
+TRANS(vssrarn_wu_d, gen_vvv, 

[PULL 05/45] target/loongarch: Implement vaddi/vsubi

2023-05-04 Thread Song Gao
This patch includes:
- VADDI.{B/H/W/D}U;
- VSUBI.{B/H/W/D}U.

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-6-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 14 
 target/loongarch/insn_trans/trans_lsx.c.inc | 37 +
 target/loongarch/insns.decode   | 11 ++
 3 files changed, 62 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index a5948d7847..c1960610c2 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -797,6 +797,11 @@ static void output_vvv(DisasContext *ctx, arg_vvv *a, 
const char *mnemonic)
 output(ctx, mnemonic, "v%d, v%d, v%d", a->vd, a->vj, a->vk);
 }
 
+static void output_vv_i(DisasContext *ctx, arg_vv_i *a, const char *mnemonic)
+{
+output(ctx, mnemonic, "v%d, v%d, 0x%x", a->vd, a->vj, a->imm);
+}
+
 INSN_LSX(vadd_b,   vvv)
 INSN_LSX(vadd_h,   vvv)
 INSN_LSX(vadd_w,   vvv)
@@ -807,3 +812,12 @@ INSN_LSX(vsub_h,   vvv)
 INSN_LSX(vsub_w,   vvv)
 INSN_LSX(vsub_d,   vvv)
 INSN_LSX(vsub_q,   vvv)
+
+INSN_LSX(vaddi_bu, vv_i)
+INSN_LSX(vaddi_hu, vv_i)
+INSN_LSX(vaddi_wu, vv_i)
+INSN_LSX(vaddi_du, vv_i)
+INSN_LSX(vsubi_bu, vv_i)
+INSN_LSX(vsubi_hu, vv_i)
+INSN_LSX(vsubi_wu, vv_i)
+INSN_LSX(vsubi_du, vv_i)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index ddeb9fde28..e6c1d0d2cc 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -44,6 +44,34 @@ static bool gvec_vvv(DisasContext *ctx, arg_vvv *a, MemOp 
mop,
 return true;
 }
 
+static bool gvec_vv_i(DisasContext *ctx, arg_vv_i *a, MemOp mop,
+  void (*func)(unsigned, uint32_t, uint32_t,
+   int64_t, uint32_t, uint32_t))
+{
+uint32_t vd_ofs, vj_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+
+func(mop, vd_ofs, vj_ofs, a->imm , 16, ctx->vl/8);
+return true;
+}
+
+static bool gvec_subi(DisasContext *ctx, arg_vv_i *a, MemOp mop)
+{
+uint32_t vd_ofs, vj_ofs;
+
+CHECK_SXE;
+
+vd_ofs = vec_full_offset(a->vd);
+vj_ofs = vec_full_offset(a->vj);
+
+tcg_gen_gvec_addi(mop, vd_ofs, vj_ofs, -a->imm, 16, ctx->vl/8);
+return true;
+}
+
 TRANS(vadd_b, gvec_vvv, MO_8, tcg_gen_gvec_add)
 TRANS(vadd_h, gvec_vvv, MO_16, tcg_gen_gvec_add)
 TRANS(vadd_w, gvec_vvv, MO_32, tcg_gen_gvec_add)
@@ -83,3 +111,12 @@ TRANS(vsub_b, gvec_vvv, MO_8, tcg_gen_gvec_sub)
 TRANS(vsub_h, gvec_vvv, MO_16, tcg_gen_gvec_sub)
 TRANS(vsub_w, gvec_vvv, MO_32, tcg_gen_gvec_sub)
 TRANS(vsub_d, gvec_vvv, MO_64, tcg_gen_gvec_sub)
+
+TRANS(vaddi_bu, gvec_vv_i, MO_8, tcg_gen_gvec_addi)
+TRANS(vaddi_hu, gvec_vv_i, MO_16, tcg_gen_gvec_addi)
+TRANS(vaddi_wu, gvec_vv_i, MO_32, tcg_gen_gvec_addi)
+TRANS(vaddi_du, gvec_vv_i, MO_64, tcg_gen_gvec_addi)
+TRANS(vsubi_bu, gvec_subi, MO_8)
+TRANS(vsubi_hu, gvec_subi, MO_16)
+TRANS(vsubi_wu, gvec_subi, MO_32)
+TRANS(vsubi_du, gvec_subi, MO_64)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index d18db68d51..2a98c14518 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -491,11 +491,13 @@ dbcl  0010 10101 ...  
@i15
 #
 
   vd vj vk
+_i vd vj imm
 
 #
 # LSX Formats
 #
 @vvv     . vk:5 vj:5 vd:5
+@vv_ui5     . imm:5 vj:5 vd:5_i
 
 vadd_b   0111  10100 . . .@vvv
 vadd_h   0111  10101 . . .@vvv
@@ -507,3 +509,12 @@ vsub_h   0111  11001 . . .
@vvv
 vsub_w   0111  11010 . . .@vvv
 vsub_d   0111  11011 . . .@vvv
 vsub_q   0111 00010010 11011 . . .@vvv
+
+vaddi_bu 0111 00101000 10100 . . .@vv_ui5
+vaddi_hu 0111 00101000 10101 . . .@vv_ui5
+vaddi_wu 0111 00101000 10110 . . .@vv_ui5
+vaddi_du 0111 00101000 10111 . . .@vv_ui5
+vsubi_bu 0111 00101000 11000 . . .@vv_ui5
+vsubi_hu 0111 00101000 11001 . . .@vv_ui5
+vsubi_wu 0111 00101000 11010 . . .@vv_ui5
+vsubi_du 0111 00101000 11011 . . .@vv_ui5
-- 
2.31.1




[PULL 07/45] target/loongarch: Implement vsadd/vssub

2023-05-04 Thread Song Gao
This patch includes:
- VSADD.{B/H/W/D}[U];
- VSSUB.{B/H/W/D}[U].

Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-8-gaos...@loongson.cn>
---
 target/loongarch/disas.c| 17 +
 target/loongarch/insn_trans/trans_lsx.c.inc | 17 +
 target/loongarch/insns.decode   | 17 +
 3 files changed, 51 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index 5eabb8c47a..b7f9320ba0 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -831,3 +831,20 @@ INSN_LSX(vneg_b,   vv)
 INSN_LSX(vneg_h,   vv)
 INSN_LSX(vneg_w,   vv)
 INSN_LSX(vneg_d,   vv)
+
+INSN_LSX(vsadd_b,  vvv)
+INSN_LSX(vsadd_h,  vvv)
+INSN_LSX(vsadd_w,  vvv)
+INSN_LSX(vsadd_d,  vvv)
+INSN_LSX(vsadd_bu, vvv)
+INSN_LSX(vsadd_hu, vvv)
+INSN_LSX(vsadd_wu, vvv)
+INSN_LSX(vsadd_du, vvv)
+INSN_LSX(vssub_b,  vvv)
+INSN_LSX(vssub_h,  vvv)
+INSN_LSX(vssub_w,  vvv)
+INSN_LSX(vssub_d,  vvv)
+INSN_LSX(vssub_bu, vvv)
+INSN_LSX(vssub_hu, vvv)
+INSN_LSX(vssub_wu, vvv)
+INSN_LSX(vssub_du, vvv)
diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
index d02db6285f..082bd738ce 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -140,3 +140,20 @@ TRANS(vneg_b, gvec_vv, MO_8, tcg_gen_gvec_neg)
 TRANS(vneg_h, gvec_vv, MO_16, tcg_gen_gvec_neg)
 TRANS(vneg_w, gvec_vv, MO_32, tcg_gen_gvec_neg)
 TRANS(vneg_d, gvec_vv, MO_64, tcg_gen_gvec_neg)
+
+TRANS(vsadd_b, gvec_vvv, MO_8, tcg_gen_gvec_ssadd)
+TRANS(vsadd_h, gvec_vvv, MO_16, tcg_gen_gvec_ssadd)
+TRANS(vsadd_w, gvec_vvv, MO_32, tcg_gen_gvec_ssadd)
+TRANS(vsadd_d, gvec_vvv, MO_64, tcg_gen_gvec_ssadd)
+TRANS(vsadd_bu, gvec_vvv, MO_8, tcg_gen_gvec_usadd)
+TRANS(vsadd_hu, gvec_vvv, MO_16, tcg_gen_gvec_usadd)
+TRANS(vsadd_wu, gvec_vvv, MO_32, tcg_gen_gvec_usadd)
+TRANS(vsadd_du, gvec_vvv, MO_64, tcg_gen_gvec_usadd)
+TRANS(vssub_b, gvec_vvv, MO_8, tcg_gen_gvec_sssub)
+TRANS(vssub_h, gvec_vvv, MO_16, tcg_gen_gvec_sssub)
+TRANS(vssub_w, gvec_vvv, MO_32, tcg_gen_gvec_sssub)
+TRANS(vssub_d, gvec_vvv, MO_64, tcg_gen_gvec_sssub)
+TRANS(vssub_bu, gvec_vvv, MO_8, tcg_gen_gvec_ussub)
+TRANS(vssub_hu, gvec_vvv, MO_16, tcg_gen_gvec_ussub)
+TRANS(vssub_wu, gvec_vvv, MO_32, tcg_gen_gvec_ussub)
+TRANS(vssub_du, gvec_vvv, MO_64, tcg_gen_gvec_ussub)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index d90798be11..3a29f0a9ab 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -525,3 +525,20 @@ vneg_b   0111 00101001 11000 01100 . .
@vv
 vneg_h   0111 00101001 11000 01101 . .@vv
 vneg_w   0111 00101001 11000 01110 . .@vv
 vneg_d   0111 00101001 11000 0 . .@vv
+
+vsadd_b  0111 0100 01100 . . .@vvv
+vsadd_h  0111 0100 01101 . . .@vvv
+vsadd_w  0111 0100 01110 . . .@vvv
+vsadd_d  0111 0100 0 . . .@vvv
+vsadd_bu 0111 0100 10100 . . .@vvv
+vsadd_hu 0111 0100 10101 . . .@vvv
+vsadd_wu 0111 0100 10110 . . .@vvv
+vsadd_du 0111 0100 10111 . . .@vvv
+vssub_b  0111 0100 1 . . .@vvv
+vssub_h  0111 0100 10001 . . .@vvv
+vssub_w  0111 0100 10010 . . .@vvv
+vssub_d  0111 0100 10011 . . .@vvv
+vssub_bu 0111 0100 11000 . . .@vvv
+vssub_hu 0111 0100 11001 . . .@vvv
+vssub_wu 0111 0100 11010 . . .@vvv
+vssub_du 0111 0100 11011 . . .@vvv
-- 
2.31.1




[PULL 02/45] target/loongarch: meson.build support build LSX

2023-05-04 Thread Song Gao
Reviewed-by: Richard Henderson 
Signed-off-by: Song Gao 
Message-Id: <20230504122810.4094787-3-gaos...@loongson.cn>
---
 target/loongarch/insn_trans/trans_lsx.c.inc | 5 +
 target/loongarch/lsx_helper.c   | 6 ++
 target/loongarch/meson.build| 1 +
 target/loongarch/translate.c| 1 +
 4 files changed, 13 insertions(+)
 create mode 100644 target/loongarch/insn_trans/trans_lsx.c.inc
 create mode 100644 target/loongarch/lsx_helper.c

diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc 
b/target/loongarch/insn_trans/trans_lsx.c.inc
new file mode 100644
index 00..1cf3ab34a9
--- /dev/null
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LSX translate functions
+ * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
+ */
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
new file mode 100644
index 00..9332163aff
--- /dev/null
+++ b/target/loongarch/lsx_helper.c
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch LSX helper functions.
+ *
+ * Copyright (c) 2022-2023 Loongson Technology Corporation Limited
+ */
diff --git a/target/loongarch/meson.build b/target/loongarch/meson.build
index 9293a8ab78..1117a51c52 100644
--- a/target/loongarch/meson.build
+++ b/target/loongarch/meson.build
@@ -11,6 +11,7 @@ loongarch_tcg_ss.add(files(
   'op_helper.c',
   'translate.c',
   'gdbstub.c',
+  'lsx_helper.c',
 ))
 loongarch_tcg_ss.add(zlib)
 
diff --git a/target/loongarch/translate.c b/target/loongarch/translate.c
index 21d86077f4..97e019aeb4 100644
--- a/target/loongarch/translate.c
+++ b/target/loongarch/translate.c
@@ -171,6 +171,7 @@ static void gen_set_gpr(int reg_num, TCGv t, DisasExtend 
dst_ext)
 #include "insn_trans/trans_fmemory.c.inc"
 #include "insn_trans/trans_branch.c.inc"
 #include "insn_trans/trans_privileged.c.inc"
+#include "insn_trans/trans_lsx.c.inc"
 
 static void loongarch_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
 {
-- 
2.31.1




Re: [PATCH v3 0/3] target/riscv: implement query-cpu-definitions

2023-05-04 Thread Alistair Francis
On Wed, May 3, 2023 at 7:51 PM Daniel Henrique Barboza
 wrote:
>
> Alistair,
>
> Patch 2 has a typo right in the commit title:
>
> "target/riscv: add query-cpy-definitions support"
>
> it should be 'query-cpu-definitions'. Can you amend it in the tree? Or should
> I re-send?

I have fixed it in my tree, so no need to resend.

I did already send the PR though. I don't think it's worth re-sending
a v2 PR for the typo

Alistair

>
>
>
> Thanks,
>
>
> Daniel
>
>
>
> On 4/16/23 23:58, Alistair Francis wrote:
> > On Wed, Apr 12, 2023 at 4:36 AM Daniel Henrique Barboza
> >  wrote:
> >>
> >> Hi,
> >>
> >> In this v3 I removed patches 3 and 4 of v2.
> >>
> >> Patch 3 now implements a new type that the generic CPUs (any, rv32,
> >> rv64, x-rv128) were converted to. This type will be used by
> >> query-cpu-definitions to determine if a given cpu is static or not based
> >> on its type. This approach was suggested by Richard Henderson in the v2
> >> review.
> >>
> >> Patches are based on top of Alistair's riscv-to-apply.next.
> >>
> >> Changes from v2:
> >> - old patches 3 and 4: removed
> >> - patch 3:
> >>- add TYPE_RISCV_DYNAMIC_CPU
> >>- use this type to set 'q_static' in riscv_cpu_add_definition()
> >> - v2 link: 
> >> https://lists.gnu.org/archive/html/qemu-devel/2023-04/msg01310.html
> >>
> >> Daniel Henrique Barboza (3):
> >>target/riscv: add CPU QOM header
> >>target/riscv: add query-cpy-definitions support
> >>target/riscv: add TYPE_RISCV_DYNAMIC_CPU
> >
> > Thanks!
> >
> > Applied to riscv-to-apply.next
> >
> > Alistair
> >
> >>
> >>   qapi/machine-target.json  |  6 ++-
> >>   target/riscv/cpu-qom.h| 70 +++
> >>   target/riscv/cpu.c| 20 --
> >>   target/riscv/cpu.h| 46 +--
> >>   target/riscv/meson.build  |  3 +-
> >>   target/riscv/riscv-qmp-cmds.c | 57 
> >>   6 files changed, 150 insertions(+), 52 deletions(-)
> >>   create mode 100644 target/riscv/cpu-qom.h
> >>   create mode 100644 target/riscv/riscv-qmp-cmds.c
> >>
> >> --
> >> 2.39.2
> >>
> >>



[PULL 73/89] target/riscv: Check SUM in the correct register

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Table 9.5 "Effect of MPRV..." specifies that MPV=1 uses VS-level
vsstatus.SUM instead of HS-level sstatus.SUM.

For HLV/HSV instructions, the HS-level register does not apply, but
the VS-level register presumably does, though this is not mentioned
explicitly in the manual.  However, it matches the behavior for MPV.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-18-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-18-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 12 
 target/riscv/op_helper.c  |  6 +-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index baa4b3a1d2..38bd83f66d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -42,11 +42,16 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 
 /* All priv -> mmu_idx mapping are here */
 if (!ifetch) {
-if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+uint64_t status = env->mstatus;
+
+if (mode == PRV_M && get_field(status, MSTATUS_MPRV)) {
 mode = get_field(env->mstatus, MSTATUS_MPP);
 virt = get_field(env->mstatus, MSTATUS_MPV);
+if (virt) {
+status = env->vsstatus;
+}
 }
-if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+if (mode == PRV_S && get_field(status, MSTATUS_SUM)) {
 mode = MMUIdx_S_SUM;
 }
 }
@@ -826,8 +831,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 widened = 2;
 }
-/* status.SUM will be ignored if execute on background */
-sum = mmuidx_sum(mmu_idx) || use_background || is_debug;
+sum = mmuidx_sum(mmu_idx) || is_debug;
 switch (vm) {
 case VM_1_10_SV32:
   levels = 2; ptidxbits = 10; ptesize = 4; break;
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index f83f7b5347..f563dc3981 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,11 @@ static int check_access_hlsv(CPURISCVState *env, bool x, 
uintptr_t ra)
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
 }
 
-return get_field(env->hstatus, HSTATUS_SPVP) | MMU_2STAGE_BIT;
+int mode = get_field(env->hstatus, HSTATUS_SPVP);
+if (!x && mode == PRV_S && get_field(env->vsstatus, MSTATUS_SUM)) {
+mode = MMUIdx_S_SUM;
+}
+return mode | MMU_2STAGE_BIT;
 }
 
 target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
-- 
2.40.0




[PULL 16/89] target/riscv: expose properties for Zc* extension

2023-05-04 Thread Alistair Francis
From: Weiwei Li 

Expose zca,zcb,zcf,zcd,zcmp,zcmt properties.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230307081403.61950-9-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 97b0a77d8e..ed8dc61d10 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -87,6 +87,12 @@ static const struct isa_ext_data isa_edata_arr[] = {
 ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_11_0, ext_zfhmin),
 ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
 ISA_EXT_DATA_ENTRY(zdinx, true, PRIV_VERSION_1_12_0, ext_zdinx),
+ISA_EXT_DATA_ENTRY(zca, true, PRIV_VERSION_1_12_0, ext_zca),
+ISA_EXT_DATA_ENTRY(zcb, true, PRIV_VERSION_1_12_0, ext_zcb),
+ISA_EXT_DATA_ENTRY(zcf, true, PRIV_VERSION_1_12_0, ext_zcf),
+ISA_EXT_DATA_ENTRY(zcd, true, PRIV_VERSION_1_12_0, ext_zcd),
+ISA_EXT_DATA_ENTRY(zcmp, true, PRIV_VERSION_1_12_0, ext_zcmp),
+ISA_EXT_DATA_ENTRY(zcmt, true, PRIV_VERSION_1_12_0, ext_zcmt),
 ISA_EXT_DATA_ENTRY(zba, true, PRIV_VERSION_1_12_0, ext_zba),
 ISA_EXT_DATA_ENTRY(zbb, true, PRIV_VERSION_1_12_0, ext_zbb),
 ISA_EXT_DATA_ENTRY(zbc, true, PRIV_VERSION_1_12_0, ext_zbc),
@@ -1491,6 +1497,14 @@ static Property riscv_cpu_extensions[] = {
 /* These are experimental so mark with 'x-' */
 DEFINE_PROP_BOOL("x-zicond", RISCVCPU, cfg.ext_zicond, false),
 DEFINE_PROP_BOOL("x-j", RISCVCPU, cfg.ext_j, false),
+
+DEFINE_PROP_BOOL("x-zca", RISCVCPU, cfg.ext_zca, false),
+DEFINE_PROP_BOOL("x-zcb", RISCVCPU, cfg.ext_zcb, false),
+DEFINE_PROP_BOOL("x-zcd", RISCVCPU, cfg.ext_zcd, false),
+DEFINE_PROP_BOOL("x-zcf", RISCVCPU, cfg.ext_zcf, false),
+DEFINE_PROP_BOOL("x-zcmp", RISCVCPU, cfg.ext_zcmp, false),
+DEFINE_PROP_BOOL("x-zcmt", RISCVCPU, cfg.ext_zcmt, false),
+
 /* ePMP 0.9.3 */
 DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
 DEFINE_PROP_BOOL("x-smaia", RISCVCPU, cfg.ext_smaia, false),
-- 
2.40.0




[PULL 56/89] target/riscv: Use check for relationship between Zdinx/Zhinx{min} and Zfinx

2023-05-04 Thread Alistair Francis
From: Weiwei Li 

Zdinx/Zhinx{min} require Zfinx. And require relationship is usually done
by check currently.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Acked-by: Alistair Francis 
Message-Id: <20230408135908.25269-1-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d1769fd218..fab38859ec 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -916,8 +916,9 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zhinxmin = true;
 }
 
-if (cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) {
-cpu->cfg.ext_zfinx = true;
+if ((cpu->cfg.ext_zdinx || cpu->cfg.ext_zhinxmin) && !cpu->cfg.ext_zfinx) {
+error_setg(errp, "Zdinx/Zhinx/Zhinxmin extensions require Zfinx");
+return;
 }
 
 if (cpu->cfg.ext_zfinx) {
-- 
2.40.0




[PULL 69/89] target/riscv: Introduce mmuidx_priv

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Use the priv level encoded into the mmu_idx, rather than
starting from env->priv.  We have already checked MPRV+MPP
in riscv_cpu_mmu_index -- no need to repeat that.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-14-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-14-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/internals.h  | 9 +
 target/riscv/cpu_helper.c | 6 +-
 2 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 0b61f337dd..4aa1cb409f 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -37,6 +37,15 @@
 #define MMUIdx_M3
 #define MMU_2STAGE_BIT  (1 << 2)
 
+static inline int mmuidx_priv(int mmu_idx)
+{
+int ret = mmu_idx & 3;
+if (ret == MMUIdx_S_SUM) {
+ret = PRV_S;
+}
+return ret;
+}
+
 static inline bool mmuidx_sum(int mmu_idx)
 {
 return (mmu_idx & 3) == MMUIdx_S_SUM;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 29ee9b1b42..57bb19c76e 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -758,7 +758,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
  */
 MemTxResult res;
 MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
-int mode = env->priv;
+int mode = mmuidx_priv(mmu_idx);
 bool use_background = false;
 hwaddr ppn;
 int napot_bits = 0;
@@ -781,10 +781,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
  */
 if (riscv_cpu_two_stage_lookup(mmu_idx)) {
 mode = get_field(env->hstatus, HSTATUS_SPVP);
-} else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
-if (get_field(env->mstatus, MSTATUS_MPRV)) {
-mode = get_field(env->mstatus, MSTATUS_MPP);
-}
 }
 
 if (first_stage == false) {
-- 
2.40.0




[PULL 24/89] target/riscv: Convert env->virt to a bool env->virt_enabled

2023-05-04 Thread Alistair Francis
From: LIU Zhiwei 

Currently we only use the env->virt to encode the virtual mode enabled
status. Let's make it a bool type.

Signed-off-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Message-ID: <20230325145348.1208-1-zhiwei_...@linux.alibaba.com>
Reviewed-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Message-Id: <20230327080858.39703-6-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h| 2 +-
 target/riscv/cpu_bits.h   | 3 ---
 target/riscv/cpu_helper.c | 6 +++---
 target/riscv/machine.c| 6 +++---
 target/riscv/translate.c  | 4 ++--
 5 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5f38b0adc0..ff6b3c6720 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -185,7 +185,7 @@ struct CPUArchState {
 #ifndef CONFIG_USER_ONLY
 target_ulong priv;
 /* This contains QEMU specific information about the virt state. */
-target_ulong virt;
+bool virt_enabled;
 target_ulong geilen;
 uint64_t resetvec;
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index a92313a06f..190e517862 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -611,9 +611,6 @@ typedef enum {
 #define PRV_H 2 /* Reserved */
 #define PRV_M 3
 
-/* Virtulisation Register Fields */
-#define VIRT_ONOFF  1
-
 /* RV32 satp CSR field masks */
 #define SATP32_MODE 0x8000
 #define SATP32_ASID 0x7fc0
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b286118a6b..c7bc3fc553 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -560,18 +560,18 @@ void riscv_cpu_set_geilen(CPURISCVState *env, 
target_ulong geilen)
 
 bool riscv_cpu_virt_enabled(CPURISCVState *env)
 {
-return get_field(env->virt, VIRT_ONOFF);
+return env->virt_enabled;
 }
 
 /* This function can only be called to set virt when RVH is enabled */
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable)
 {
 /* Flush the TLB on all virt mode changes. */
-if (get_field(env->virt, VIRT_ONOFF) != enable) {
+if (env->virt_enabled != enable) {
 tlb_flush(env_cpu(env));
 }
 
-env->virt = set_field(env->virt, VIRT_ONOFF, enable);
+env->virt_enabled = enable;
 
 if (enable) {
 /*
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
index 27f430ad74..8869346089 100644
--- a/target/riscv/machine.c
+++ b/target/riscv/machine.c
@@ -349,8 +349,8 @@ static const VMStateDescription vmstate_jvt = {
 
 const VMStateDescription vmstate_riscv_cpu = {
 .name = "cpu",
-.version_id = 7,
-.minimum_version_id = 7,
+.version_id = 8,
+.minimum_version_id = 8,
 .post_load = riscv_cpu_post_load,
 .fields = (VMStateField[]) {
 VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
@@ -370,7 +370,7 @@ const VMStateDescription vmstate_riscv_cpu = {
 VMSTATE_UINT32(env.misa_mxl_max, RISCVCPU),
 VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
 VMSTATE_UINTTL(env.priv, RISCVCPU),
-VMSTATE_UINTTL(env.virt, RISCVCPU),
+VMSTATE_BOOL(env.virt_enabled, RISCVCPU),
 VMSTATE_UINT64(env.resetvec, RISCVCPU),
 VMSTATE_UINTTL(env.mhartid, RISCVCPU),
 VMSTATE_UINT64(env.mstatus, RISCVCPU),
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6872d17fb9..5dddac44bc 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1266,8 +1266,8 @@ static void riscv_tr_disas_log(const DisasContextBase 
*dcbase,
 
 fprintf(logfile, "IN: %s\n", lookup_symbol(dcbase->pc_first));
 #ifndef CONFIG_USER_ONLY
-fprintf(logfile, "Priv: "TARGET_FMT_ld"; Virt: "TARGET_FMT_ld"\n",
-env->priv, env->virt);
+fprintf(logfile, "Priv: "TARGET_FMT_ld"; Virt: %d\n",
+env->priv, env->virt_enabled);
 #endif
 target_disas(logfile, cpu, dcbase->pc_first, dcbase->tb->size);
 }
-- 
2.40.0




[PULL 53/89] target/riscv: Fix the mstatus.MPP value after executing MRET

2023-05-04 Thread Alistair Francis
From: Weiwei Li 

The MPP will be set to the least-privileged supported mode (U if
U-mode is implemented, else M).

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Alistair Francis 
Message-Id: <20230407014743.18779-2-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index ec9a384772..b8a03afebb 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -338,7 +338,8 @@ target_ulong helper_mret(CPURISCVState *env)
 mstatus = set_field(mstatus, MSTATUS_MIE,
 get_field(mstatus, MSTATUS_MPIE));
 mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
-mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
+mstatus = set_field(mstatus, MSTATUS_MPP,
+riscv_has_ext(env, RVU) ? PRV_U : PRV_M);
 mstatus = set_field(mstatus, MSTATUS_MPV, 0);
 if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
 mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
-- 
2.40.0




[PULL 61/89] target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Merge with mstatus_{fs,vs}.  We might perform a redundant
assignment to one or the other field, but it's a trivial
and saves 4 bits from TB_FLAGS.

Signed-off-by: Richard Henderson 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-5-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-5-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h| 16 +++-
 target/riscv/cpu_helper.c | 33 -
 target/riscv/translate.c  | 32 ++--
 3 files changed, 33 insertions(+), 48 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 51d39687fe..ab64d5f92d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -644,19 +644,17 @@ FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
 FIELD(TB_FLAGS, VILL, 14, 1)
 /* Is a Hypervisor instruction load/store allowed? */
 FIELD(TB_FLAGS, HLSX, 15, 1)
-FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
-FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
-FIELD(TB_FLAGS, XL, 20, 2)
+FIELD(TB_FLAGS, XL, 16, 2)
 /* If PointerMasking should be applied */
-FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
-FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
-FIELD(TB_FLAGS, VTA, 24, 1)
-FIELD(TB_FLAGS, VMA, 25, 1)
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
+FIELD(TB_FLAGS, VTA, 20, 1)
+FIELD(TB_FLAGS, VMA, 21, 1)
 /* Native debug itrigger */
-FIELD(TB_FLAGS, ITRIGGER, 26, 1)
+FIELD(TB_FLAGS, ITRIGGER, 22, 1)
 /* Virtual mode enabled */
-FIELD(TB_FLAGS, VIRT_ENABLED, 27, 1)
+FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 8412ef26ee..e3e620137b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -45,7 +45,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 {
 CPUState *cs = env_cpu(env);
 RISCVCPU *cpu = RISCV_CPU(cs);
-
+RISCVExtStatus fs, vs;
 uint32_t flags = 0;
 
 *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
@@ -79,18 +79,12 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 }
 
 #ifdef CONFIG_USER_ONLY
-flags = FIELD_DP32(flags, TB_FLAGS, FS, EXT_STATUS_DIRTY);
-flags = FIELD_DP32(flags, TB_FLAGS, VS, EXT_STATUS_DIRTY);
+fs = EXT_STATUS_DIRTY;
+vs = EXT_STATUS_DIRTY;
 #else
 flags |= cpu_mmu_index(env, 0);
-if (riscv_cpu_fp_enabled(env)) {
-flags = FIELD_DP32(flags, TB_FLAGS, FS,
-   get_field(env->mstatus, MSTATUS_FS));
-}
-if (riscv_cpu_vector_enabled(env)) {
-flags = FIELD_DP32(flags, TB_FLAGS, VS,
-   get_field(env->mstatus, MSTATUS_VS));
-}
+fs = get_field(env->mstatus, MSTATUS_FS);
+vs = get_field(env->mstatus, MSTATUS_VS);
 
 if (riscv_has_ext(env, RVH)) {
 if (env->priv == PRV_M ||
@@ -100,18 +94,23 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
 }
 
-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));
-flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, env->virt_enabled);
+if (env->virt_enabled) {
+flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
+/*
+ * Merge DISABLED and !DIRTY states using MIN.
+ * We will set both fields when dirtying.
+ */
+fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
+vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
+}
 }
 if (cpu->cfg.debug && !icount_enabled()) {
 flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
 }
 #endif
 
+flags = FIELD_DP32(flags, TB_FLAGS, FS, fs);
+flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
 flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
 if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
 flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 411e771e6f..3092c942ab 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -66,8 +66,6 @@ typedef struct DisasContext {
 uint32_t opcode;
 RISCVExtStatus mstatus_fs;
 RISCVExtStatus mstatus_vs;
-RISCVExtStatus mstatus_hs_fs;
-RISCVExtStatus mstatus_hs_vs;
 uint32_t mem_idx;
 /*
  * Remember the rounding mode encoded in the previous fp instruction,
@@ -620,16 +618,12 @@ static void 

[PULL 58/89] target/riscv: Extract virt enabled state from tb flags

2023-05-04 Thread Alistair Francis
From: LIU Zhiwei 

Virt enabled state is not a constant, so we should put it into tb flags.
Thus we can use it like a constant condition at translation phase.

Reported-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Message-Id: <20230324143031.1093-2-zhiwei_...@linux.alibaba.com>
Reviewed-by: Alistair Francis 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-2-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-2-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c |  1 +
 target/riscv/translate.c  | 10 +-
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 86e08d10da..aa53d0e256 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -648,6 +648,8 @@ FIELD(TB_FLAGS, VTA, 24, 1)
 FIELD(TB_FLAGS, VMA, 25, 1)
 /* Native debug itrigger */
 FIELD(TB_FLAGS, ITRIGGER, 26, 1)
+/* Virtual mode enabled */
+FIELD(TB_FLAGS, VIRT_ENABLED, 27, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 433ea529b0..1d90977d46 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -104,6 +104,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 
 flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
get_field(env->mstatus_hs, MSTATUS_VS));
+flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, env->virt_enabled);
 }
 if (cpu->cfg.debug && !icount_enabled()) {
 flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index d0094922b6..ebd00529ff 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1171,15 +1171,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
 ctx->mstatus_vs = tb_flags & TB_FLAGS_MSTATUS_VS;
 ctx->priv_ver = env->priv_ver;
-#if !defined(CONFIG_USER_ONLY)
-if (riscv_has_ext(env, RVH)) {
-ctx->virt_enabled = env->virt_enabled;
-} else {
-ctx->virt_enabled = false;
-}
-#else
-ctx->virt_enabled = false;
-#endif
+ctx->virt_enabled = FIELD_EX32(tb_flags, TB_FLAGS, VIRT_ENABLED);
 ctx->misa_ext = env->misa_ext;
 ctx->frm = -1;  /* unknown rounding mode */
 ctx->cfg_ptr = &(cpu->cfg);
-- 
2.40.0




[PULL 66/89] target/riscv: Handle HLV, HSV via helpers

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Implement these instructions via helpers, in expectation
of determining the mmu_idx to use at runtime.  This allows
the permission check to also be moved out of line, which
allows HLSX to be removed from TB_FLAGS.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-11-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-11-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |   6 +-
 target/riscv/helper.h   |  12 ++-
 target/riscv/cpu_helper.c   |  26 ++---
 target/riscv/op_helper.c|  99 --
 target/riscv/translate.c|   2 -
 target/riscv/insn_trans/trans_rvh.c.inc | 129 ++--
 6 files changed, 165 insertions(+), 109 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 6239c99f4c..35cf2e2691 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -639,8 +639,7 @@ FIELD(TB_FLAGS, LMUL, 7, 3)
 FIELD(TB_FLAGS, SEW, 10, 3)
 FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
 FIELD(TB_FLAGS, VILL, 14, 1)
-/* Is a Hypervisor instruction load/store allowed? */
-FIELD(TB_FLAGS, HLSX, 15, 1)
+FIELD(TB_FLAGS, VSTART_EQ_ZERO, 15, 1)
 /* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
 FIELD(TB_FLAGS, XL, 16, 2)
 /* If PointerMasking should be applied */
@@ -652,8 +651,7 @@ FIELD(TB_FLAGS, VMA, 21, 1)
 FIELD(TB_FLAGS, ITRIGGER, 22, 1)
 /* Virtual mode enabled */
 FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
-FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
-FIELD(TB_FLAGS, PRIV, 25, 2)
+FIELD(TB_FLAGS, PRIV, 24, 2)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 1880e95c50..98e97810fd 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -123,8 +123,16 @@ DEF_HELPER_1(itrigger_match, void, env)
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_1(hyp_tlb_flush, void, env)
 DEF_HELPER_1(hyp_gvma_tlb_flush, void, env)
-DEF_HELPER_2(hyp_hlvx_hu, tl, env, tl)
-DEF_HELPER_2(hyp_hlvx_wu, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_bu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_hu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_wu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlv_d, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlvx_hu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_2(hyp_hlvx_wu, TCG_CALL_NO_WG, tl, env, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_b, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_h, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_w, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(hyp_hsv_d, TCG_CALL_NO_WG, void, env, tl, tl)
 #endif
 
 /* Vector functions */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 174a77706b..abf275d2c6 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -102,24 +102,16 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, 
target_ulong *pc,
 fs = get_field(env->mstatus, MSTATUS_FS);
 vs = get_field(env->mstatus, MSTATUS_VS);
 
-if (riscv_has_ext(env, RVH)) {
-if (env->priv == PRV_M ||
-(env->priv == PRV_S && !env->virt_enabled) ||
-(env->priv == PRV_U && !env->virt_enabled &&
- get_field(env->hstatus, HSTATUS_HU))) {
-flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
-}
-
-if (env->virt_enabled) {
-flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
-/*
- * Merge DISABLED and !DIRTY states using MIN.
- * We will set both fields when dirtying.
- */
-fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
-vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
-}
+if (env->virt_enabled) {
+flags = FIELD_DP32(flags, TB_FLAGS, VIRT_ENABLED, 1);
+/*
+ * Merge DISABLED and !DIRTY states using MIN.
+ * We will set both fields when dirtying.
+ */
+fs = MIN(fs, get_field(env->mstatus_hs, MSTATUS_FS));
+vs = MIN(vs, get_field(env->mstatus_hs, MSTATUS_VS));
 }
+
 if (cpu->cfg.debug && !icount_enabled()) {
 flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
 }
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 49179e7a5a..7f83395370 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -427,6 +427,91 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 helper_hyp_tlb_flush(env);
 }
 
+static int check_access_hlsv(CPURISCVState *env, bool x, uintptr_t ra)
+{
+if (env->priv == PRV_M) {
+/* always allowed */
+} else if (env->virt_enabled) {
+riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, ra);
+} else if (env->priv == PRV_U && 

[PULL 78/89] target/riscv: Don't modify SUM with is_debug

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

If we want to give the debugger a greater view of memory than
the cpu, we should simply disable the access check entirely,
not simply for this one corner case.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-23-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-23-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6dc3fdf594..9a2b944990 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -823,7 +823,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 widened = 2;
 }
-sum = mmuidx_sum(mmu_idx) || is_debug;
+sum = mmuidx_sum(mmu_idx);
 switch (vm) {
 case VM_1_10_SV32:
   levels = 2; ptidxbits = 10; ptesize = 4; break;
-- 
2.40.0




[PULL 65/89] target/riscv: Use cpu_ld*_code_mmu for HLVX

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Use the new functions to properly check execute permission
for the read rather than read permission.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-10-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-10-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/op_helper.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 0adfd1ca9a..49179e7a5a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -427,18 +427,27 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 helper_hyp_tlb_flush(env);
 }
 
+/*
+ * TODO: These implementations are not quite correct.  They perform the
+ * access using execute permission just fine, but the final PMP check
+ * is supposed to have read permission as well.  Without replicating
+ * a fair fraction of cputlb.c, fixing this requires adding new mmu_idx
+ * which would imply that exact check in tlb_fill.
+ */
 target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
 {
 int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
 
-return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
+return cpu_ldw_code_mmu(env, address, oi, GETPC());
 }
 
 target_ulong helper_hyp_hlvx_wu(CPURISCVState *env, target_ulong address)
 {
 int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
+MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
 
-return cpu_ldl_mmuidx_ra(env, address, mmu_idx, GETPC());
+return cpu_ldl_code_mmu(env, address, oi, GETPC());
 }
 
 #endif /* !CONFIG_USER_ONLY */
-- 
2.40.0




[PULL 75/89] target/riscv: Hoist pbmte and hade out of the level loop

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

These values are constant for every level of pte lookup.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-20-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-20-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 5753e4e612..7c9f89d4d3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -856,6 +856,14 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 return TRANSLATE_FAIL;
 }
 
+bool pbmte = env->menvcfg & MENVCFG_PBMTE;
+bool hade = env->menvcfg & MENVCFG_HADE;
+
+if (first_stage && two_stage && env->virt_enabled) {
+pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
+hade = hade && (env->henvcfg & HENVCFG_HADE);
+}
+
 int ptshift = (levels - 1) * ptidxbits;
 int i;
 
@@ -916,14 +924,6 @@ restart:
 return TRANSLATE_FAIL;
 }
 
-bool pbmte = env->menvcfg & MENVCFG_PBMTE;
-bool hade = env->menvcfg & MENVCFG_HADE;
-
-if (first_stage && two_stage && env->virt_enabled) {
-pbmte = pbmte && (env->henvcfg & HENVCFG_PBMTE);
-hade = hade && (env->henvcfg & HENVCFG_HADE);
-}
-
 if (riscv_cpu_sxl(env) == MXL_RV32) {
 ppn = pte >> PTE_PPN_SHIFT;
 } else if (pbmte || riscv_cpu_cfg(env)->ext_svnapot) {
-- 
2.40.0




[PULL 74/89] target/riscv: Hoist second stage mode change to callers

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Move the check from the top of get_physical_address to
the two callers, where passing mmu_idx makes no sense.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-19-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-19-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 38bd83f66d..5753e4e612 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -777,14 +777,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 use_background = true;
 }
 
-if (first_stage == false) {
-/*
- * We are in stage 2 translation, this is similar to stage 1.
- * Stage 2 is always taken as U-mode
- */
-mode = PRV_U;
-}
-
 if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
 *physical = addr;
 *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
@@ -890,7 +882,7 @@ restart:
 /* Do the second stage translation on the base PTE address. */
 int vbase_ret = get_physical_address(env, , _prot,
  base, NULL, MMU_DATA_LOAD,
- mmu_idx, false, true,
+ MMUIdx_U, false, true,
  is_debug);
 
 if (vbase_ret != TRANSLATE_SUCCESS) {
@@ -1271,7 +1263,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 im_address = pa;
 
 ret = get_physical_address(env, , , im_address, NULL,
-   access_type, mmu_idx, false, true,
+   access_type, MMUIdx_U, false, true,
false);
 
 qemu_log_mask(CPU_LOG_MMU,
-- 
2.40.0




[PULL 57/89] target/riscv: fix H extension TVM trap

2023-05-04 Thread Alistair Francis
From: Yi Chen 

- Trap satp/hgatp accesses from HS-mode when MSTATUS.TVM is enabled.
- Trap satp accesses from VS-mode when HSTATUS.VTVM is enabled.
- Raise RISCV_EXCP_ILLEGAL_INST when U-mode executes SFENCE.VMA/SINVAL.VMA.
- Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
  SFENCE.VMA/SINVAL.VMA or VS-mode executes SFENCE.VMA/SINVAL.VMA with
  HSTATUS.VTVM enabled.
- Raise RISCV_EXCP_VIRT_INSTRUCTION_FAULT when VU-mode executes
  HFENCE.GVMA/HFENCE.VVMA/HINVAL.GVMA/HINVAL.VVMA.

Signed-off-by: Yi Chen 
Reviewed-by: Weiwei Li 
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Message-Id: <20230406101559.39632-1-chenyi2...@zju.edu.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c   | 56 +---
 target/riscv/op_helper.c | 12 -
 2 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f4d2dcfdc8..d2271da137 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -449,6 +449,30 @@ static RISCVException sstc_32(CPURISCVState *env, int 
csrno)
 return sstc(env, csrno);
 }
 
+static RISCVException satp(CPURISCVState *env, int csrno)
+{
+if (env->priv == PRV_S && !env->virt_enabled &&
+get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+if (env->priv == PRV_S && env->virt_enabled &&
+get_field(env->hstatus, HSTATUS_VTVM)) {
+return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
+}
+
+return smode(env, csrno);
+}
+
+static RISCVException hgatp(CPURISCVState *env, int csrno)
+{
+if (env->priv == PRV_S && !env->virt_enabled &&
+get_field(env->mstatus, MSTATUS_TVM)) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
+return hmode(env, csrno);
+}
+
 /* Checks if PointerMasking registers could be accessed */
 static RISCVException pointer_masking(CPURISCVState *env, int csrno)
 {
@@ -2679,13 +2703,7 @@ static RISCVException read_satp(CPURISCVState *env, int 
csrno,
 *val = 0;
 return RISCV_EXCP_NONE;
 }
-
-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-} else {
-*val = env->satp;
-}
-
+*val = env->satp;
 return RISCV_EXCP_NONE;
 }
 
@@ -2708,18 +2726,14 @@ static RISCVException write_satp(CPURISCVState *env, 
int csrno,
 }
 
 if (vm && mask) {
-if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
-return RISCV_EXCP_ILLEGAL_INST;
-} else {
-/*
- * The ISA defines SATP.MODE=Bare as "no translation", but we still
- * pass these through QEMU's TLB emulation as it improves
- * performance.  Flushing the TLB on SATP writes with paging
- * enabled avoids leaking those invalid cached mappings.
- */
-tlb_flush(env_cpu(env));
-env->satp = val;
-}
+/*
+ * The ISA defines SATP.MODE=Bare as "no translation", but we still
+ * pass these through QEMU's TLB emulation as it improves
+ * performance.  Flushing the TLB on SATP writes with paging
+ * enabled avoids leaking those invalid cached mappings.
+ */
+tlb_flush(env_cpu(env));
+env->satp = val;
 }
 return RISCV_EXCP_NONE;
 }
@@ -4215,7 +4229,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
  .min_priv_ver = PRIV_VERSION_1_12_0 },
 
 /* Supervisor Protection and Translation */
-[CSR_SATP] = { "satp", smode, read_satp, write_satp },
+[CSR_SATP] = { "satp", satp, read_satp, write_satp },
 
 /* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
 [CSR_SISELECT]   = { "siselect",   aia_smode, NULL, NULL, rmw_xiselect },
@@ -4252,7 +4266,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
   .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_HGEIP]   = { "hgeip",   hmode,   read_hgeip,
   .min_priv_ver = PRIV_VERSION_1_12_0},
-[CSR_HGATP]   = { "hgatp",   hmode,   read_hgatp,   write_hgatp,
+[CSR_HGATP]   = { "hgatp",   hgatp,   read_hgatp,   write_hgatp,
   .min_priv_ver = PRIV_VERSION_1_12_0},
 [CSR_HTIMEDELTA]  = { "htimedelta",  hmode,   read_htimedelta,
   write_htimedelta,
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index bd21c6eeef..0c10dd7a78 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -381,12 +381,12 @@ void helper_wfi(CPURISCVState *env)
 void helper_tlb_flush(CPURISCVState *env)
 {
 CPUState *cs = env_cpu(env);
-if (!(env->priv >= PRV_S) ||
-(env->priv == PRV_S &&
- get_field(env->mstatus, MSTATUS_TVM))) {
+if (!env->virt_enabled &&
+(env->priv == PRV_U ||
+ (env->priv == 

[PULL 68/89] target/riscv: Introduce mmuidx_sum

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

In get_physical_address, we should use the setting passed
via mmu_idx rather than checking env->mstatus directly.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-13-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-13-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/internals.h  | 5 +
 target/riscv/cpu_helper.c | 2 +-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 7b63c0f1b6..0b61f337dd 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -37,6 +37,11 @@
 #define MMUIdx_M3
 #define MMU_2STAGE_BIT  (1 << 2)
 
+static inline bool mmuidx_sum(int mmu_idx)
+{
+return (mmu_idx & 3) == MMUIdx_S_SUM;
+}
+
 /* share data between vector helpers and decode code */
 FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 291a1acbf7..29ee9b1b42 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -842,7 +842,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 widened = 2;
 }
 /* status.SUM will be ignored if execute on background */
-sum = get_field(env->mstatus, MSTATUS_SUM) || use_background || is_debug;
+sum = mmuidx_sum(mmu_idx) || use_background || is_debug;
 switch (vm) {
 case VM_1_10_SV32:
   levels = 2; ptidxbits = 10; ptesize = 4; break;
-- 
2.40.0




[PULL 59/89] target/riscv: Add a general status enum for extensions

2023-05-04 Thread Alistair Francis
From: LIU Zhiwei 

The pointer masking is the only extension that directly use status.
The vector or float extension uses the status in an indirect way.

Replace the pointer masking extension special status fields with
the general status.

Reviewed-by: Richard Henderson 
Signed-off-by: LIU Zhiwei 
Message-Id: <20230324143031.1093-3-zhiwei_...@linux.alibaba.com>
[rth: Add a typedef for the enum]
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-3-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-3-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |  8 
 target/riscv/cpu_bits.h | 12 
 target/riscv/cpu.c  |  2 +-
 target/riscv/csr.c  | 14 +++---
 4 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index aa53d0e256..ba11279716 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -97,6 +97,14 @@ enum {
 TRANSLATE_G_STAGE_FAIL
 };
 
+/* Extension context status */
+typedef enum {
+EXT_STATUS_DISABLED = 0,
+EXT_STATUS_INITIAL,
+EXT_STATUS_CLEAN,
+EXT_STATUS_DIRTY,
+} RISCVExtStatus;
+
 #define MMU_USER_IDX 3
 
 #define MAX_RISCV_PMPS (16)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index a16bfaf43f..fb63b8e125 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -9,6 +9,9 @@
  (((uint64_t)(val) * ((mask) & ~((mask) << 1))) & \
  (uint64_t)(mask)))
 
+/* Extension context status mask */
+#define EXT_STATUS_MASK 0x3ULL
+
 /* Floating point round mode */
 #define FSR_RD_SHIFT5
 #define FSR_RD  (0x7 << FSR_RD_SHIFT)
@@ -735,13 +738,6 @@ typedef enum RISCVException {
 #define PM_ENABLE   0x0001ULL
 #define PM_CURRENT  0x0002ULL
 #define PM_INSN 0x0004ULL
-#define PM_XS_MASK  0x0003ULL
-
-/* PointerMasking XS bits values */
-#define PM_EXT_DISABLE  0xULL
-#define PM_EXT_INITIAL  0x0001ULL
-#define PM_EXT_CLEAN0x0002ULL
-#define PM_EXT_DIRTY0x0003ULL
 
 /* Execution enviornment configuration bits */
 #define MENVCFG_FIOM   BIT(0)
@@ -781,7 +777,7 @@ typedef enum RISCVException {
 #define S_OFFSET 5ULL
 #define M_OFFSET 8ULL
 
-#define PM_XS_BITS   (PM_XS_MASK << XS_OFFSET)
+#define PM_XS_BITS   (EXT_STATUS_MASK << XS_OFFSET)
 #define U_PM_ENABLE  (PM_ENABLE  << U_OFFSET)
 #define U_PM_CURRENT (PM_CURRENT << U_OFFSET)
 #define U_PM_INSN(PM_INSN<< U_OFFSET)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index fab38859ec..32c04214a1 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -759,7 +759,7 @@ static void riscv_cpu_reset_hold(Object *obj)
 i++;
 }
 /* mmte is supposed to have pm.current hardwired to 1 */
-env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
+env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
 #endif
 env->xl = riscv_cpu_mxl(env);
 riscv_cpu_update_mask(env);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index d2271da137..92ad54411b 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3548,7 +3548,7 @@ static RISCVException write_mmte(CPURISCVState *env, int 
csrno,
 
 /* hardwiring pm.instruction bit to 0, since it's not supported yet */
 wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
-env->mmte = wpri_val | PM_EXT_DIRTY;
+env->mmte = wpri_val | EXT_STATUS_DIRTY;
 riscv_cpu_update_mask(env);
 
 /* Set XS and SD bits, since PM CSRs are dirty */
@@ -3628,7 +3628,7 @@ static RISCVException write_mpmmask(CPURISCVState *env, 
int csrno,
 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
 env->cur_pmmask = val;
 }
-env->mmte |= PM_EXT_DIRTY;
+env->mmte |= EXT_STATUS_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are dirty */
 mstatus = env->mstatus | MSTATUS_XS;
@@ -3656,7 +3656,7 @@ static RISCVException write_spmmask(CPURISCVState *env, 
int csrno,
 if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
 env->cur_pmmask = val;
 }
-env->mmte |= PM_EXT_DIRTY;
+env->mmte |= EXT_STATUS_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are dirty */
 mstatus = env->mstatus | MSTATUS_XS;
@@ -3684,7 +3684,7 @@ static RISCVException write_upmmask(CPURISCVState *env, 
int csrno,
 if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
 env->cur_pmmask = val;
 }
-env->mmte |= PM_EXT_DIRTY;
+env->mmte |= EXT_STATUS_DIRTY;
 
 /* Set XS and SD bits, since PM CSRs are dirty */
 mstatus = env->mstatus | MSTATUS_XS;
@@ -3708,7 +3708,7 @@ static RISCVException write_mpmbase(CPURISCVState *env, 
int csrno,
 if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
 env->cur_pmbase = val;
 }
-env->mmte |= PM_EXT_DIRTY;
+

[PULL 62/89] target/riscv: Add a tb flags field for vstart

2023-05-04 Thread Alistair Francis
From: LIU Zhiwei 

Once we mistook the vstart directly from the env->vstart. As env->vstart is not
a constant, we should record it in the tb flags if we want to use
it in translation.

Reported-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Signed-off-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Message-Id: <20230324143031.1093-5-zhiwei_...@linux.alibaba.com>
Reviewed-by: Alistair Francis 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-6-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-6-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |  1 +
 target/riscv/cpu_helper.c   |  1 +
 target/riscv/translate.c|  4 ++--
 target/riscv/insn_trans/trans_rvv.c.inc | 14 +++---
 4 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ab64d5f92d..786ad047ee 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -655,6 +655,7 @@ FIELD(TB_FLAGS, VMA, 21, 1)
 FIELD(TB_FLAGS, ITRIGGER, 22, 1)
 /* Virtual mode enabled */
 FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
+FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index e3e620137b..7579e83c3d 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -74,6 +74,7 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
FIELD_EX64(env->vtype, VTYPE, VTA));
 flags = FIELD_DP32(flags, TB_FLAGS, VMA,
FIELD_EX64(env->vtype, VTYPE, VMA));
+flags = FIELD_DP32(flags, TB_FLAGS, VSTART_EQ_ZERO, env->vstart == 0);
 } else {
 flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
 }
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3092c942ab..3ab8ae 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -99,7 +99,7 @@ typedef struct DisasContext {
 uint8_t vta;
 uint8_t vma;
 bool cfg_vta_all_1s;
-target_ulong vstart;
+bool vstart_eq_zero;
 bool vl_eq_vlmax;
 CPUState *cs;
 TCGv zero;
@@ -1168,7 +1168,7 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 ctx->vta = FIELD_EX32(tb_flags, TB_FLAGS, VTA) && cpu->cfg.rvv_ta_all_1s;
 ctx->vma = FIELD_EX32(tb_flags, TB_FLAGS, VMA) && cpu->cfg.rvv_ma_all_1s;
 ctx->cfg_vta_all_1s = cpu->cfg.rvv_ta_all_1s;
-ctx->vstart = env->vstart;
+ctx->vstart_eq_zero = FIELD_EX32(tb_flags, TB_FLAGS, VSTART_EQ_ZERO);
 ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
 ctx->misa_mxl_max = env->misa_mxl_max;
 ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc 
b/target/riscv/insn_trans/trans_rvv.c.inc
index ecbdf1b3d7..6c07eebc52 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -547,7 +547,7 @@ static bool vext_check_sds(DisasContext *s, int vd, int 
vs1, int vs2, int vm)
  */
 static bool vext_check_reduction(DisasContext *s, int vs2)
 {
-return require_align(vs2, s->lmul) && (s->vstart == 0);
+return require_align(vs2, s->lmul) && s->vstart_eq_zero;
 }
 
 /*
@@ -3083,7 +3083,7 @@ static bool trans_vcpop_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s) &&
-s->vstart == 0) {
+s->vstart_eq_zero) {
 TCGv_ptr src2, mask;
 TCGv dst;
 TCGv_i32 desc;
@@ -3112,7 +3112,7 @@ static bool trans_vfirst_m(DisasContext *s, arg_rmr *a)
 {
 if (require_rvv(s) &&
 vext_check_isa_ill(s) &&
-s->vstart == 0) {
+s->vstart_eq_zero) {
 TCGv_ptr src2, mask;
 TCGv dst;
 TCGv_i32 desc;
@@ -3148,7 +3148,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a) 
 \
 vext_check_isa_ill(s) &&   \
 require_vm(a->vm, a->rd) &&\
 (a->rd != a->rs2) &&   \
-(s->vstart == 0)) {\
+s->vstart_eq_zero) {   \
 uint32_t data = 0; \
 gen_helper_gvec_3_ptr *fn = gen_helper_##NAME; \
 TCGLabel *over = gen_new_label();  \
@@ -3189,7 +3189,7 @@ static bool trans_viota_m(DisasContext *s, arg_viota_m *a)
 !is_overlapped(a->rd, 1 << MAX(s->lmul, 0), a->rs2, 1) &&
 require_vm(a->vm, a->rd) &&
 require_align(a->rd, s->lmul) &&
-(s->vstart == 0)) {
+s->vstart_eq_zero) {
 uint32_t data = 0;
 TCGLabel *over = gen_new_label();
 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
@@ -3638,7 +3638,7 @@ static bool 

Re: [PULL 00/89] riscv-to-apply queue

2023-05-04 Thread Alistair Francis
On Fri, May 5, 2023 at 11:05 AM Alistair Francis  wrote:
>
> On Fri, May 5, 2023 at 11:03 AM Alistair Francis  wrote:
> >
> > The following changes since commit f6b761bdbd8ba63cee7428d52fb6b46e4224ddab:
> >
> >   Merge tag 'qga-pull-2023-05-04' of https://github.com/kostyanf14/qemu 
> > into staging (2023-05-04 12:08:00 +0100)
> >
> > are available in the Git repository at:
> >
> >   https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230505-1
> >
> > for you to fetch changes up to e1d084a8524a9225a46d485e2d164bb258f326f7:
> >
> >   target/riscv: add Ventana's Veyron V1 CPU (2023-05-05 10:49:50 +1000)
>
> In an abundance of caution this has been signed with a new key after a
> recent security incident.
>
> I don't believe anything happened to the old one, but just in case I
> have created a new one. Let me know if there is anything you would
> like me to do to verify the new key. Then I will revoke the old one.

I forgot to add, the new one is here:
https://keyserver.ubuntu.com/pks/lookup?search=AF7C95130C538013=on=index

it should propagate through

Alistair

>
> Alistair
>
> >
> > 
> > First RISC-V PR for 8.1
> >
> > * CPURISCVState related cleanup and simplification
> > * Refactor Zicond and reuse in XVentanaCondOps
> > * Fix invalid riscv,event-to-mhpmcounters entry
> > * Support subsets of code size reduction extension
> > * Fix itrigger when icount is used
> > * Simplification for RVH related check and code style fix
> > * Add signature dump function for spike to run ACT tests
> > * Rework MISA writing
> > * Fix mstatus.MPP related support
> > * Use check for relationship between Zdinx/Zhinx{min} and Zfinx
> > * Fix the H extension TVM trap
> > * A large collection of mstatus sum changes and cleanups
> > * Zero init APLIC internal state
> > * Implement query-cpu-definitions
> > * Restore the predicate() NULL check behavior
> > * Fix Guest Physical Address Translation
> > * Make sure an exception is raised if a pte is malformed
> > * Add Ventana's Veyron V1 CPU
> >
> > 
> > Alexandre Ghiti (1):
> >   riscv: Make sure an exception is raised if a pte is malformed
> >
> > Bin Meng (1):
> >   target/riscv: Restore the predicate() NULL check behavior
> >
> > Conor Dooley (1):
> >   target/riscv: fix invalid riscv,event-to-mhpmcounters entry
> >
> > Daniel Henrique Barboza (23):
> >   target/riscv: sync env->misa_ext* with cpu->cfg in realize()
> >   target/riscv: remove MISA properties from isa_edata_arr[]
> >   target/riscv/cpu.c: remove 'multi_letter' from isa_ext_data
> >   target/riscv: introduce riscv_cpu_add_misa_properties()
> >   target/riscv: remove cpu->cfg.ext_a
> >   target/riscv: remove cpu->cfg.ext_c
> >   target/riscv: remove cpu->cfg.ext_d
> >   target/riscv: remove cpu->cfg.ext_f
> >   target/riscv: remove cpu->cfg.ext_i
> >   target/riscv: remove cpu->cfg.ext_e
> >   target/riscv: remove cpu->cfg.ext_m
> >   target/riscv: remove cpu->cfg.ext_s
> >   target/riscv: remove cpu->cfg.ext_u
> >   target/riscv: remove cpu->cfg.ext_h
> >   target/riscv: remove cpu->cfg.ext_j
> >   target/riscv: remove cpu->cfg.ext_v
> >   target/riscv: remove riscv_cpu_sync_misa_cfg()
> >   target/riscv: remove cfg.ext_g setup from rv64_thead_c906_cpu_init()
> >   target/riscv: add RVG and remove cpu->cfg.ext_g
> >   target/riscv/cpu.c: redesign register_cpu_props()
> >   target/riscv: add CPU QOM header
> >   target/riscv: add query-cpy-definitions support
> >   target/riscv: add TYPE_RISCV_DYNAMIC_CPU
> >
> > Fei Wu (2):
> >   target/riscv: Separate priv from mmu_idx
> >   target/riscv: Reduce overhead of MSTATUS_SUM change
> >
> > Irina Ryapolova (1):
> >   target/riscv: Fix Guest Physical Address Translation
> >
> > Ivan Klokov (1):
> >   hw/intc/riscv_aplic: Zero init APLIC internal state
> >
> > LIU Zhiwei (7):
> >   target/riscv: Fix priv version dependency for vector and zfh
> >   target/riscv: Fix itrigger when icount is used
> >   target/riscv: Convert env->virt to a bool env->virt_enabled
> >   target/riscv: Extract virt enabled state from tb flags
> >   target/riscv: Add a general status enum for extensions
> >   target/riscv: Encode the FS and VS on a normal way for tb flags
> >   target/riscv: Add a tb flags field for vstart
> >
> > Philipp Tomsich (2):
> >   target/riscv: refactor Zicond support
> >   target/riscv: redirect XVentanaCondOps to use the Zicond functions
> >
> > Rahul Pathak (1):
> >   target/riscv: add Ventana's Veyron V1 CPU
> >
> > Richard Henderson (18):
> >   target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags
> >   target/riscv: Use cpu_ld*_code_mmu for HLVX
> >   target/riscv: Handle HLV, HSV via helpers
> >   target/riscv: Rename MMU_HYP_ACCESS_BIT to 

[PULL 49/89] target/riscv: remove riscv_cpu_sync_misa_cfg()

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

This function was created to move the sync between cpu->cfg.ext_N bit
changes to env->misa_ext* from the validation step to an ealier step,
giving us a guarantee that we could use either cpu->cfg.ext_N or
riscv_has_ext(env,N) in the validation.

We don't have any cpu->cfg.ext_N left that has an existing MISA bit
(cfg.ext_g will be handled shortly). The function is now a no-op, simply
copying the existing values of misa_ext* back to misa_ext*.

Remove it.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-18-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 52 --
 1 file changed, 52 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 13ff37250e..1ecb82bb5d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1141,50 +1141,6 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, 
Error **errp)
 #endif
 }
 
-static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
-{
-uint32_t ext = 0;
-
-if (riscv_has_ext(env, RVI)) {
-ext |= RVI;
-}
-if (riscv_has_ext(env, RVE)) {
-ext |= RVE;
-}
-if (riscv_has_ext(env, RVM)) {
-ext |= RVM;
-}
-if (riscv_has_ext(env, RVA)) {
-ext |= RVA;
-}
-if (riscv_has_ext(env, RVF)) {
-ext |= RVF;
-}
-if (riscv_has_ext(env, RVD)) {
-ext |= RVD;
-}
-if (riscv_has_ext(env, RVC)) {
-ext |= RVC;
-}
-if (riscv_has_ext(env, RVS)) {
-ext |= RVS;
-}
-if (riscv_has_ext(env, RVU)) {
-ext |= RVU;
-}
-if (riscv_has_ext(env, RVH)) {
-ext |= RVH;
-}
-if (riscv_has_ext(env, RVV)) {
-ext |= RVV;
-}
-if (riscv_has_ext(env, RVJ)) {
-ext |= RVJ;
-}
-
-env->misa_ext = env->misa_ext_mask = ext;
-}
-
 static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
 {
 if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) {
@@ -1228,14 +1184,6 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 set_priv_version(env, priv_version);
 }
 
-/*
- * We can't be sure of whether we set defaults during cpu_init()
- * or whether the user enabled/disabled some bits via cpu->cfg
- * flags. Sync env->misa_ext with cpu->cfg now to allow us to
- * use just env->misa_ext later.
- */
-riscv_cpu_sync_misa_cfg(env);
-
 riscv_cpu_validate_misa_priv(env, _err);
 if (local_err != NULL) {
 error_propagate(errp, local_err);
-- 
2.40.0




[PULL 67/89] target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

We will enable more uses of this bit in the future.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-12-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-12-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/internals.h  | 6 --
 target/riscv/cpu_helper.c | 2 +-
 target/riscv/op_helper.c  | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index b55152a7dc..7b63c0f1b6 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -27,13 +27,15 @@
  *  - S 0b001
  *  - S+SUM 0b010
  *  - M 0b011
- *  - HLV/HLVX/HSV adds 0b100
+ *  - U+2STAGE  0b100
+ *  - S+2STAGE  0b101
+ *  - S+SUM+2STAGE  0b110
  */
 #define MMUIdx_U0
 #define MMUIdx_S1
 #define MMUIdx_S_SUM2
 #define MMUIdx_M3
-#define MMU_HYP_ACCESS_BIT  (1 << 2)
+#define MMU_2STAGE_BIT  (1 << 2)
 
 /* share data between vector helpers and decode code */
 FIELD(VDATA, VM, 0, 1)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index abf275d2c6..291a1acbf7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -593,7 +593,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 
 bool riscv_cpu_two_stage_lookup(int mmu_idx)
 {
-return mmu_idx & MMU_HYP_ACCESS_BIT;
+return mmu_idx & MMU_2STAGE_BIT;
 }
 
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 7f83395370..6122f5fbe5 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,7 @@ static int check_access_hlsv(CPURISCVState *env, bool x, 
uintptr_t ra)
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
 }
 
-return cpu_mmu_index(env, x) | MMU_HYP_ACCESS_BIT;
+return cpu_mmu_index(env, x) | MMU_2STAGE_BIT;
 }
 
 target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
-- 
2.40.0




[PULL 86/89] target/riscv: Restore the predicate() NULL check behavior

2023-05-04 Thread Alistair Francis
From: Bin Meng 

When reading a non-existent CSR QEMU should raise illegal instruction
exception, but currently it just exits due to the g_assert() check.

This actually reverts commit 0ee342256af9205e7388efdf193a6d8f1ba1a617.
Some comments are also added to indicate that predicate() must be
provided for an implemented CSR.

Reported-by: Fei Wu 
Signed-off-by: Bin Meng 
Reviewed-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Reviewed-by: LIU Zhiwei 
Message-Id: <20230417043054.3125614-1-bm...@tinylab.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/csr.c | 11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 865ee9efda..4451bd1263 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3826,6 +3826,11 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
 return RISCV_EXCP_ILLEGAL_INST;
 }
 
+/* ensure CSR is implemented by checking predicate */
+if (!csr_ops[csrno].predicate) {
+return RISCV_EXCP_ILLEGAL_INST;
+}
+
 /* privileged spec version check */
 if (env->priv_ver < csr_min_priv) {
 return RISCV_EXCP_ILLEGAL_INST;
@@ -3843,7 +3848,6 @@ static inline RISCVException 
riscv_csrrw_check(CPURISCVState *env,
  * illegal instruction exception should be triggered instead of virtual
  * instruction exception. Hence this comes after the read / write check.
  */
-g_assert(csr_ops[csrno].predicate != NULL);
 RISCVException ret = csr_ops[csrno].predicate(env, csrno);
 if (ret != RISCV_EXCP_NONE) {
 return ret;
@@ -4032,7 +4036,10 @@ static RISCVException write_jvt(CPURISCVState *env, int 
csrno,
 return RISCV_EXCP_NONE;
 }
 
-/* Control and Status Register function table */
+/*
+ * Control and Status Register function table
+ * riscv_csr_operations::predicate() must be provided for an implemented CSR
+ */
 riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
 [CSR_FFLAGS]   = { "fflags",   fs, read_fflags,  write_fflags },
-- 
2.40.0




[PULL 83/89] target/riscv: add CPU QOM header

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

QMP CPU commands are usually implemented by a separated file,
-qmp-cmds.c, to allow them to be build only for softmmu targets.
This file uses a CPU QOM header with basic QOM declarations for the
arch.

We'll introduce query-cpu-definitions for RISC-V CPUs in the next patch,
but first we need a cpu-qom.h header with the definitions of
TYPE_RISCV_CPU and RISCVCPUClass declarations. These were moved from
cpu.h to the new file, and cpu.h now includes "cpu-qom.h".

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230411183511.189632-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h | 70 ++
 target/riscv/cpu.h | 46 +--
 2 files changed, 71 insertions(+), 45 deletions(-)
 create mode 100644 target/riscv/cpu-qom.h

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
new file mode 100644
index 00..b9318e0783
--- /dev/null
+++ b/target/riscv/cpu-qom.h
@@ -0,0 +1,70 @@
+/*
+ * QEMU RISC-V CPU QOM header
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * 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 .
+ */
+
+#ifndef RISCV_CPU_QOM_H
+#define RISCV_CPU_QOM_H
+
+#include "hw/core/cpu.h"
+#include "qom/object.h"
+
+#define TYPE_RISCV_CPU "riscv-cpu"
+
+#define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
+#define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
+#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
+
+#define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
+#define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
+#define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
+#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
+#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
+#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
+#define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
+#define TYPE_RISCV_CPU_SIFIVE_E34   RISCV_CPU_TYPE_NAME("sifive-e34")
+#define TYPE_RISCV_CPU_SIFIVE_E51   RISCV_CPU_TYPE_NAME("sifive-e51")
+#define TYPE_RISCV_CPU_SIFIVE_U34   RISCV_CPU_TYPE_NAME("sifive-u34")
+#define TYPE_RISCV_CPU_SIFIVE_U54   RISCV_CPU_TYPE_NAME("sifive-u54")
+#define TYPE_RISCV_CPU_THEAD_C906   RISCV_CPU_TYPE_NAME("thead-c906")
+#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
+
+#if defined(TARGET_RISCV32)
+# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE32
+#elif defined(TARGET_RISCV64)
+# define TYPE_RISCV_CPU_BASETYPE_RISCV_CPU_BASE64
+#endif
+
+typedef struct CPUArchState CPURISCVState;
+
+OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
+
+/**
+ * RISCVCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_phases: The parent class' reset phase handlers.
+ *
+ * A RISCV CPU model.
+ */
+struct RISCVCPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+DeviceRealize parent_realize;
+ResettablePhases parent_phases;
+};
+
+#endif /* RISCV_CPU_QOM_H */
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d1f888a790..de7e43126a 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -28,6 +28,7 @@
 #include "qemu/int128.h"
 #include "cpu_bits.h"
 #include "qapi/qapi-types-common.h"
+#include "cpu-qom.h"
 
 #define TCG_GUEST_DEFAULT_MO 0
 
@@ -37,32 +38,6 @@
  */
 #define TARGET_INSN_START_EXTRA_WORDS 1
 
-#define TYPE_RISCV_CPU "riscv-cpu"
-
-#define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
-#define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
-#define CPU_RESOLVING_TYPE TYPE_RISCV_CPU
-
-#define TYPE_RISCV_CPU_ANY  RISCV_CPU_TYPE_NAME("any")
-#define TYPE_RISCV_CPU_BASE32   RISCV_CPU_TYPE_NAME("rv32")
-#define TYPE_RISCV_CPU_BASE64   RISCV_CPU_TYPE_NAME("rv64")
-#define TYPE_RISCV_CPU_BASE128  RISCV_CPU_TYPE_NAME("x-rv128")
-#define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex")
-#define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c")
-#define TYPE_RISCV_CPU_SIFIVE_E31   RISCV_CPU_TYPE_NAME("sifive-e31")
-#define TYPE_RISCV_CPU_SIFIVE_E34   RISCV_CPU_TYPE_NAME("sifive-e34")
-#define TYPE_RISCV_CPU_SIFIVE_E51   RISCV_CPU_TYPE_NAME("sifive-e51")
-#define TYPE_RISCV_CPU_SIFIVE_U34   

[PULL 33/89] target/riscv: sync env->misa_ext* with cpu->cfg in realize()

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

When riscv_cpu_realize() starts we're guaranteed to have cpu->cfg.ext_N
properties updated. The same can't be said about env->misa_ext*, since
the user might enable/disable MISA extensions in the command line, and
env->misa_ext* won't caught these changes. The current solution is to
sync everything at the end of validate_set_extensions(), checking every
cpu->cfg.ext_N value to do a set_misa() in the end.

The last change we're making in the MISA cfg flags are in the G
extension logic, enabling IMAFG if cpu->cfg_ext.g is enabled. Otherwise
we're not making any changes in MISA bits ever since realize() starts.

There's no reason to postpone misa_ext updates until the end of the
validation. Let's do it earlier, during realize(), in a new helper
called riscv_cpu_sync_misa_cfg(). If cpu->cfg.ext_g is enabled, do it
again by updating env->misa_ext* directly.

This is a pre-requisite to allow riscv_cpu_validate_set_extensions() to
use riscv_has_ext() instead of cpu->cfg.ext_N to validate the MISA
extensions, which is our end goal here.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-2-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 94 +++---
 1 file changed, 56 insertions(+), 38 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index cb68916fce..66de3bb33f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -811,12 +811,11 @@ static void riscv_cpu_disas_set_info(CPUState *s, 
disassemble_info *info)
 
 /*
  * Check consistency between chosen extensions while setting
- * cpu->cfg accordingly, doing a set_misa() in the end.
+ * cpu->cfg accordingly.
  */
 static void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
 {
 CPURISCVState *env = >env;
-uint32_t ext = 0;
 
 /* Do some ISA extension error checking */
 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
@@ -831,6 +830,9 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_d = true;
 cpu->cfg.ext_icsr = true;
 cpu->cfg.ext_ifencei = true;
+
+env->misa_ext |= RVI | RVM | RVA | RVF | RVD;
+env->misa_ext_mask = env->misa_ext;
 }
 
 if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
@@ -1022,39 +1024,8 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksh = true;
 }
 
-if (cpu->cfg.ext_i) {
-ext |= RVI;
-}
-if (cpu->cfg.ext_e) {
-ext |= RVE;
-}
-if (cpu->cfg.ext_m) {
-ext |= RVM;
-}
-if (cpu->cfg.ext_a) {
-ext |= RVA;
-}
-if (cpu->cfg.ext_f) {
-ext |= RVF;
-}
-if (cpu->cfg.ext_d) {
-ext |= RVD;
-}
-if (cpu->cfg.ext_c) {
-ext |= RVC;
-}
-if (cpu->cfg.ext_s) {
-ext |= RVS;
-}
-if (cpu->cfg.ext_u) {
-ext |= RVU;
-}
-if (cpu->cfg.ext_h) {
-ext |= RVH;
-}
 if (cpu->cfg.ext_v) {
 int vext_version = VEXT_VERSION_1_00_0;
-ext |= RVV;
 if (!is_power_of_2(cpu->cfg.vlen)) {
 error_setg(errp,
"Vector extension VLEN must be power of 2");
@@ -1092,11 +1063,6 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 set_vext_version(env, vext_version);
 }
-if (cpu->cfg.ext_j) {
-ext |= RVJ;
-}
-
-set_misa(env, env->misa_mxl, ext);
 }
 
 #ifndef CONFIG_USER_ONLY
@@ -1181,6 +1147,50 @@ static void riscv_cpu_finalize_features(RISCVCPU *cpu, 
Error **errp)
 #endif
 }
 
+static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
+{
+uint32_t ext = 0;
+
+if (riscv_cpu_cfg(env)->ext_i) {
+ext |= RVI;
+}
+if (riscv_cpu_cfg(env)->ext_e) {
+ext |= RVE;
+}
+if (riscv_cpu_cfg(env)->ext_m) {
+ext |= RVM;
+}
+if (riscv_cpu_cfg(env)->ext_a) {
+ext |= RVA;
+}
+if (riscv_cpu_cfg(env)->ext_f) {
+ext |= RVF;
+}
+if (riscv_cpu_cfg(env)->ext_d) {
+ext |= RVD;
+}
+if (riscv_cpu_cfg(env)->ext_c) {
+ext |= RVC;
+}
+if (riscv_cpu_cfg(env)->ext_s) {
+ext |= RVS;
+}
+if (riscv_cpu_cfg(env)->ext_u) {
+ext |= RVU;
+}
+if (riscv_cpu_cfg(env)->ext_h) {
+ext |= RVH;
+}
+if (riscv_cpu_cfg(env)->ext_v) {
+ext |= RVV;
+}
+if (riscv_cpu_cfg(env)->ext_j) {
+ext |= RVJ;
+}
+
+env->misa_ext = env->misa_ext_mask = ext;
+}
+
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
 {
 CPUState *cs = CPU(dev);
@@ -1216,6 +1226,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
 set_priv_version(env, priv_version);
 }
 
+/*
+ * We can't be sure of whether we set defaults during cpu_init()
+ * or whether the 

[PULL 70/89] target/riscv: Introduce mmuidx_2stage

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Move and rename riscv_cpu_two_stage_lookup, to match
the other mmuidx_* functions.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-15-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-15-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h|  1 -
 target/riscv/internals.h  |  5 +
 target/riscv/cpu_helper.c | 20 ++--
 3 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 35cf2e2691..d1f888a790 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -581,7 +581,6 @@ target_ulong riscv_cpu_get_geilen(CPURISCVState *env);
 void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen);
 bool riscv_cpu_vector_enabled(CPURISCVState *env);
 void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
-bool riscv_cpu_two_stage_lookup(int mmu_idx);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
MMUAccessType access_type,
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 4aa1cb409f..b5f823c7ec 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -51,6 +51,11 @@ static inline bool mmuidx_sum(int mmu_idx)
 return (mmu_idx & 3) == MMUIdx_S_SUM;
 }
 
+static inline bool mmuidx_2stage(int mmu_idx)
+{
+return mmu_idx & MMU_2STAGE_BIT;
+}
+
 /* share data between vector helpers and decode code */
 FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 57bb19c76e..9dfd1d739b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -591,11 +591,6 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 }
 }
 
-bool riscv_cpu_two_stage_lookup(int mmu_idx)
-{
-return mmu_idx & MMU_2STAGE_BIT;
-}
-
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
 {
 CPURISCVState *env = >env;
@@ -779,7 +774,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
  * MPRV does not affect the virtual-machine load/store
  * instructions, HLV, HLVX, and HSV.
  */
-if (riscv_cpu_two_stage_lookup(mmu_idx)) {
+if (mmuidx_2stage(mmu_idx)) {
 mode = get_field(env->hstatus, HSTATUS_SPVP);
 }
 
@@ -1175,8 +1170,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 }
 
 env->badaddr = addr;
-env->two_stage_lookup = env->virt_enabled ||
-riscv_cpu_two_stage_lookup(mmu_idx);
+env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
 env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
@@ -1201,8 +1195,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 g_assert_not_reached();
 }
 env->badaddr = addr;
-env->two_stage_lookup = env->virt_enabled ||
-riscv_cpu_two_stage_lookup(mmu_idx);
+env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
 env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
@@ -1256,7 +1249,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
  * MPRV does not affect the virtual-machine load/store
  * instructions, HLV, HLVX, and HSV.
  */
-if (riscv_cpu_two_stage_lookup(mmu_idx)) {
+if (mmuidx_2stage(mmu_idx)) {
 mode = get_field(env->hstatus, HSTATUS_SPVP);
 } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV)) {
@@ -1268,7 +1261,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 
 pmu_tlb_fill_incr_ctr(cpu, access_type);
 if (env->virt_enabled ||
-((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
+((mmuidx_2stage(mmu_idx) || two_stage_lookup) &&
  access_type != MMU_INST_FETCH)) {
 /* Two stage lookup */
 ret = get_physical_address(env, , , address,
@@ -1366,8 +1359,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 } else {
 raise_mmu_exception(env, address, access_type, pmp_violation,
 first_stage_error,
-env->virt_enabled ||
-riscv_cpu_two_stage_lookup(mmu_idx),
+env->virt_enabled || mmuidx_2stage(mmu_idx),
 two_stage_indirect_error);
 cpu_loop_exit_restore(cs, retaddr);
 }
-- 
2.40.0




[PULL 89/89] target/riscv: add Ventana's Veyron V1 CPU

2023-05-04 Thread Alistair Francis
From: Rahul Pathak 

Add a virtual CPU for Ventana's first CPU named veyron-v1. It runs
exclusively for the rv64 target. It's tested with the 'virt' board.

CPU specs and general information can be found here:

https://www.nextplatform.com/2023/02/02/the-first-risc-v-shot-across-the-datacenter-bow/

Signed-off-by: Rahul Pathak 
Signed-off-by: Mayuresh Chitale 
Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Message-Id: <20230418123624.16414-1-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h  |  1 +
 target/riscv/cpu_vendorid.h |  4 
 target/riscv/cpu.c  | 38 +
 3 files changed, 43 insertions(+)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index b29090ad86..04af50983e 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -41,6 +41,7 @@
 #define TYPE_RISCV_CPU_SIFIVE_U34   RISCV_CPU_TYPE_NAME("sifive-u34")
 #define TYPE_RISCV_CPU_SIFIVE_U54   RISCV_CPU_TYPE_NAME("sifive-u54")
 #define TYPE_RISCV_CPU_THEAD_C906   RISCV_CPU_TYPE_NAME("thead-c906")
+#define TYPE_RISCV_CPU_VEYRON_V1RISCV_CPU_TYPE_NAME("veyron-v1")
 #define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
 
 #if defined(TARGET_RISCV32)
diff --git a/target/riscv/cpu_vendorid.h b/target/riscv/cpu_vendorid.h
index a5aa249bc9..96b6b9c2cb 100644
--- a/target/riscv/cpu_vendorid.h
+++ b/target/riscv/cpu_vendorid.h
@@ -3,4 +3,8 @@
 
 #define THEAD_VENDOR_ID 0x5b7
 
+#define VEYRON_V1_MARCHID   0x8001
+#define VEYRON_V1_MIMPID0x111
+#define VEYRON_V1_MVENDORID 0x61f
+
 #endif /*  TARGET_RISCV_CPU_VENDORID_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index befa64528f..db0875fb43 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -422,6 +422,43 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 #endif
 }
 
+static void rv64_veyron_v1_cpu_init(Object *obj)
+{
+CPURISCVState *env = _CPU(obj)->env;
+RISCVCPU *cpu = RISCV_CPU(obj);
+
+set_misa(env, MXL_RV64, RVG | RVC | RVS | RVU | RVH);
+env->priv_ver = PRIV_VERSION_1_12_0;
+
+/* Enable ISA extensions */
+cpu->cfg.mmu = true;
+cpu->cfg.ext_icbom = true;
+cpu->cfg.cbom_blocksize = 64;
+cpu->cfg.cboz_blocksize = 64;
+cpu->cfg.ext_icboz = true;
+cpu->cfg.ext_smaia = true;
+cpu->cfg.ext_ssaia = true;
+cpu->cfg.ext_sscofpmf = true;
+cpu->cfg.ext_sstc = true;
+cpu->cfg.ext_svinval = true;
+cpu->cfg.ext_svnapot = true;
+cpu->cfg.ext_svpbmt = true;
+cpu->cfg.ext_smstateen = true;
+cpu->cfg.ext_zba = true;
+cpu->cfg.ext_zbb = true;
+cpu->cfg.ext_zbc = true;
+cpu->cfg.ext_zbs = true;
+cpu->cfg.ext_XVentanaCondOps = true;
+
+cpu->cfg.mvendorid = VEYRON_V1_MVENDORID;
+cpu->cfg.marchid = VEYRON_V1_MARCHID;
+cpu->cfg.mimpid = VEYRON_V1_MIMPID;
+
+#ifndef CONFIG_USER_ONLY
+set_satp_mode_max_supported(cpu, VM_1_10_SV48);
+#endif
+}
+
 static void rv128_base_cpu_init(Object *obj)
 {
 if (qemu_tcg_mttcg_enabled()) {
@@ -1827,6 +1864,7 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,   rv64_sifive_u_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,   rv64_thead_c906_cpu_init),
+DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1,rv64_veyron_v1_cpu_init),
 DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 #endif
 };
-- 
2.40.0




Re: [PULL 00/89] riscv-to-apply queue

2023-05-04 Thread Alistair Francis
On Fri, May 5, 2023 at 11:03 AM Alistair Francis  wrote:
>
> The following changes since commit f6b761bdbd8ba63cee7428d52fb6b46e4224ddab:
>
>   Merge tag 'qga-pull-2023-05-04' of https://github.com/kostyanf14/qemu into 
> staging (2023-05-04 12:08:00 +0100)
>
> are available in the Git repository at:
>
>   https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20230505-1
>
> for you to fetch changes up to e1d084a8524a9225a46d485e2d164bb258f326f7:
>
>   target/riscv: add Ventana's Veyron V1 CPU (2023-05-05 10:49:50 +1000)

In an abundance of caution this has been signed with a new key after a
recent security incident.

I don't believe anything happened to the old one, but just in case I
have created a new one. Let me know if there is anything you would
like me to do to verify the new key. Then I will revoke the old one.

Alistair

>
> 
> First RISC-V PR for 8.1
>
> * CPURISCVState related cleanup and simplification
> * Refactor Zicond and reuse in XVentanaCondOps
> * Fix invalid riscv,event-to-mhpmcounters entry
> * Support subsets of code size reduction extension
> * Fix itrigger when icount is used
> * Simplification for RVH related check and code style fix
> * Add signature dump function for spike to run ACT tests
> * Rework MISA writing
> * Fix mstatus.MPP related support
> * Use check for relationship between Zdinx/Zhinx{min} and Zfinx
> * Fix the H extension TVM trap
> * A large collection of mstatus sum changes and cleanups
> * Zero init APLIC internal state
> * Implement query-cpu-definitions
> * Restore the predicate() NULL check behavior
> * Fix Guest Physical Address Translation
> * Make sure an exception is raised if a pte is malformed
> * Add Ventana's Veyron V1 CPU
>
> 
> Alexandre Ghiti (1):
>   riscv: Make sure an exception is raised if a pte is malformed
>
> Bin Meng (1):
>   target/riscv: Restore the predicate() NULL check behavior
>
> Conor Dooley (1):
>   target/riscv: fix invalid riscv,event-to-mhpmcounters entry
>
> Daniel Henrique Barboza (23):
>   target/riscv: sync env->misa_ext* with cpu->cfg in realize()
>   target/riscv: remove MISA properties from isa_edata_arr[]
>   target/riscv/cpu.c: remove 'multi_letter' from isa_ext_data
>   target/riscv: introduce riscv_cpu_add_misa_properties()
>   target/riscv: remove cpu->cfg.ext_a
>   target/riscv: remove cpu->cfg.ext_c
>   target/riscv: remove cpu->cfg.ext_d
>   target/riscv: remove cpu->cfg.ext_f
>   target/riscv: remove cpu->cfg.ext_i
>   target/riscv: remove cpu->cfg.ext_e
>   target/riscv: remove cpu->cfg.ext_m
>   target/riscv: remove cpu->cfg.ext_s
>   target/riscv: remove cpu->cfg.ext_u
>   target/riscv: remove cpu->cfg.ext_h
>   target/riscv: remove cpu->cfg.ext_j
>   target/riscv: remove cpu->cfg.ext_v
>   target/riscv: remove riscv_cpu_sync_misa_cfg()
>   target/riscv: remove cfg.ext_g setup from rv64_thead_c906_cpu_init()
>   target/riscv: add RVG and remove cpu->cfg.ext_g
>   target/riscv/cpu.c: redesign register_cpu_props()
>   target/riscv: add CPU QOM header
>   target/riscv: add query-cpy-definitions support
>   target/riscv: add TYPE_RISCV_DYNAMIC_CPU
>
> Fei Wu (2):
>   target/riscv: Separate priv from mmu_idx
>   target/riscv: Reduce overhead of MSTATUS_SUM change
>
> Irina Ryapolova (1):
>   target/riscv: Fix Guest Physical Address Translation
>
> Ivan Klokov (1):
>   hw/intc/riscv_aplic: Zero init APLIC internal state
>
> LIU Zhiwei (7):
>   target/riscv: Fix priv version dependency for vector and zfh
>   target/riscv: Fix itrigger when icount is used
>   target/riscv: Convert env->virt to a bool env->virt_enabled
>   target/riscv: Extract virt enabled state from tb flags
>   target/riscv: Add a general status enum for extensions
>   target/riscv: Encode the FS and VS on a normal way for tb flags
>   target/riscv: Add a tb flags field for vstart
>
> Philipp Tomsich (2):
>   target/riscv: refactor Zicond support
>   target/riscv: redirect XVentanaCondOps to use the Zicond functions
>
> Rahul Pathak (1):
>   target/riscv: add Ventana's Veyron V1 CPU
>
> Richard Henderson (18):
>   target/riscv: Remove mstatus_hs_{fs, vs} from tb_flags
>   target/riscv: Use cpu_ld*_code_mmu for HLVX
>   target/riscv: Handle HLV, HSV via helpers
>   target/riscv: Rename MMU_HYP_ACCESS_BIT to MMU_2STAGE_BIT
>   target/riscv: Introduce mmuidx_sum
>   target/riscv: Introduce mmuidx_priv
>   target/riscv: Introduce mmuidx_2stage
>   target/riscv: Move hstatus.spvp check to check_access_hlsv
>   target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index
>   target/riscv: Check SUM in the correct register
>   target/riscv: Hoist second stage mode change to callers
>   target/riscv: Hoist pbmte and hade 

[PULL 63/89] target/riscv: Separate priv from mmu_idx

2023-05-04 Thread Alistair Francis
From: Fei Wu 

Currently it's assumed the 2 low bits of mmu_idx map to privilege mode,
this assumption won't last as we are about to add more mmu_idx. Here an
individual priv field is added into TB_FLAGS.

Reviewed-by: Richard Henderson 
Signed-off-by: Fei Wu 
Message-Id: <20230324054154.414846-2-fei2...@intel.com>
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-7-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-7-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  2 +-
 target/riscv/cpu_helper.c  |  4 +++-
 target/riscv/translate.c   |  2 ++
 target/riscv/insn_trans/trans_privileged.c.inc |  2 +-
 target/riscv/insn_trans/trans_xthead.c.inc | 14 +-
 5 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 786ad047ee..9b971ee1b0 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -629,7 +629,6 @@ G_NORETURN void 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_PRIV_MMU_MASK3
 #define TB_FLAGS_PRIV_HYP_ACCESS_MASK   (1 << 2)
 
 #include "exec/cpu-all.h"
@@ -656,6 +655,7 @@ FIELD(TB_FLAGS, ITRIGGER, 22, 1)
 /* Virtual mode enabled */
 FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
 FIELD(TB_FLAGS, VSTART_EQ_ZERO, 24, 1)
+FIELD(TB_FLAGS, PRIV, 25, 2)
 
 #ifdef TARGET_RISCV32
 #define riscv_cpu_mxl(env)  ((void)(env), MXL_RV32)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7579e83c3d..36d6e422d7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -83,6 +83,8 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong 
*pc,
 fs = EXT_STATUS_DIRTY;
 vs = EXT_STATUS_DIRTY;
 #else
+flags = FIELD_DP32(flags, TB_FLAGS, PRIV, env->priv);
+
 flags |= cpu_mmu_index(env, 0);
 fs = get_field(env->mstatus, MSTATUS_FS);
 vs = get_field(env->mstatus, MSTATUS_VS);
@@ -751,7 +753,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
  */
 MemTxResult res;
 MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
-int mode = mmu_idx & TB_FLAGS_PRIV_MMU_MASK;
+int mode = env->priv;
 bool use_background = false;
 hwaddr ppn;
 int napot_bits = 0;
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 3ab8ae..6d59348f0c 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -67,6 +67,7 @@ typedef struct DisasContext {
 RISCVExtStatus mstatus_fs;
 RISCVExtStatus mstatus_vs;
 uint32_t mem_idx;
+uint32_t priv;
 /*
  * Remember the rounding mode encoded in the previous fp instruction,
  * which we have already installed into env->fp_status.  Or -1 for
@@ -1153,6 +1154,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->priv = FIELD_EX32(tb_flags, TB_FLAGS, PRIV);
 ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
 ctx->mstatus_fs = FIELD_EX32(tb_flags, TB_FLAGS, FS);
 ctx->mstatus_vs = FIELD_EX32(tb_flags, TB_FLAGS, VS);
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc 
b/target/riscv/insn_trans/trans_privileged.c.inc
index e3bee971c6..7c2837194c 100644
--- a/target/riscv/insn_trans/trans_privileged.c.inc
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
@@ -52,7 +52,7 @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
  * that no exception will be raised when fetching them.
  */
 
-if (semihosting_enabled(ctx->mem_idx < PRV_S) &&
+if (semihosting_enabled(ctx->priv == PRV_U) &&
 (pre_addr & TARGET_PAGE_MASK) == (post_addr & TARGET_PAGE_MASK)) {
 pre= opcode_at(>base, pre_addr);
 ebreak = opcode_at(>base, ebreak_addr);
diff --git a/target/riscv/insn_trans/trans_xthead.c.inc 
b/target/riscv/insn_trans/trans_xthead.c.inc
index df504c3f2c..3e13b1d74d 100644
--- a/target/riscv/insn_trans/trans_xthead.c.inc
+++ b/target/riscv/insn_trans/trans_xthead.c.inc
@@ -263,25 +263,13 @@ static bool trans_th_tst(DisasContext *ctx, arg_th_tst *a)
 
 /* XTheadCmo */
 
-static inline int priv_level(DisasContext *ctx)
-{
-#ifdef CONFIG_USER_ONLY
-return PRV_U;
-#else
- /* Priv level is part of mem_idx. */
-return ctx->mem_idx & TB_FLAGS_PRIV_MMU_MASK;
-#endif
-}
-
 /* Test if priv level is M, S, or U (cannot fail). */
 #define REQUIRE_PRIV_MSU(ctx)
 
 /* Test if priv level is M or S. */
 #define REQUIRE_PRIV_MS(ctx)\
 do {\
-int priv = priv_level(ctx); \
-if (!(priv == PRV_M ||  

[PULL 44/89] target/riscv: remove cpu->cfg.ext_s

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "s" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVS. Instances of cpu->cfg.ext_s and similar are
replaced with riscv_has_ext(env, RVS).

Remove the old "s" property and 'ext_s' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-13-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 -
 target/riscv/cpu.c | 11 +--
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 71540a33ec..8b8e541e5f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -423,7 +423,6 @@ typedef struct {
 
 struct RISCVCPUConfig {
 bool ext_g;
-bool ext_s;
 bool ext_u;
 bool ext_h;
 bool ext_j;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 24640450c7..cded82ac7a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -408,7 +408,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 
 cpu->cfg.ext_g = true;
 cpu->cfg.ext_u = true;
-cpu->cfg.ext_s = true;
 cpu->cfg.ext_icsr = true;
 cpu->cfg.ext_zfh = true;
 cpu->cfg.mmu = true;
@@ -843,7 +842,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_s && !cpu->cfg.ext_u) {
+if (riscv_has_ext(env, RVS) && !cpu->cfg.ext_u) {
 error_setg(errp,
"Setting S extension without U extension is illegal");
 return;
@@ -855,7 +854,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_h && !cpu->cfg.ext_s) {
+if (cpu->cfg.ext_h && !riscv_has_ext(env, RVS)) {
 error_setg(errp, "H extension implicitly requires S-mode");
 return;
 }
@@ -1168,7 +1167,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 if (riscv_has_ext(env, RVC)) {
 ext |= RVC;
 }
-if (riscv_cpu_cfg(env)->ext_s) {
+if (riscv_has_ext(env, RVS)) {
 ext |= RVS;
 }
 if (riscv_cpu_cfg(env)->ext_u) {
@@ -1507,6 +1506,8 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  .misa_bit = RVE, .enabled = false},
 {.name = "m", .description = "Integer multiplication and division",
  .misa_bit = RVM, .enabled = true},
+{.name = "s", .description = "Supervisor-level instructions",
+ .misa_bit = RVS, .enabled = true},
 };
 
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
@@ -1530,7 +1531,6 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
 DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false),
-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("h", RISCVCPU, cfg.ext_h, true),
@@ -1647,7 +1647,6 @@ static void register_cpu_props(Object *obj)
  */
 if (cpu->env.misa_ext != 0) {
 cpu->cfg.ext_v = misa_ext & RVV;
-cpu->cfg.ext_s = misa_ext & RVS;
 cpu->cfg.ext_u = misa_ext & RVU;
 cpu->cfg.ext_h = misa_ext & RVH;
 cpu->cfg.ext_j = misa_ext & RVJ;
-- 
2.40.0




[PULL 80/89] target/riscv: Reorg access check in get_physical_address

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

We were effectively computing the protection bits twice,
once while performing access checks and once while returning
the valid bits to the caller.  Reorg so we do this once.

Move the computation of mxr close to its single use.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-25-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-25-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 69 ---
 1 file changed, 36 insertions(+), 33 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index c7c384bae3..7849e18554 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -747,7 +747,7 @@ static int get_physical_address_pmp(CPURISCVState *env, int 
*prot,
  * @is_debug: Is this access from a debugger or the monitor?
  */
 static int get_physical_address(CPURISCVState *env, hwaddr *physical,
-int *prot, vaddr addr,
+int *ret_prot, vaddr addr,
 target_ulong *fault_pte_addr,
 int access_type, int mmu_idx,
 bool first_stage, bool two_stage,
@@ -779,20 +779,14 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
 
 if (mode == PRV_M || !riscv_cpu_cfg(env)->mmu) {
 *physical = addr;
-*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+*ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TRANSLATE_SUCCESS;
 }
 
-*prot = 0;
+*ret_prot = 0;
 
 hwaddr base;
-int levels, ptidxbits, ptesize, vm, sum, mxr, widened;
-
-if (first_stage == true) {
-mxr = get_field(env->mstatus, MSTATUS_MXR);
-} else {
-mxr = get_field(env->vsstatus, MSTATUS_MXR);
-}
+int levels, ptidxbits, ptesize, vm, sum, widened;
 
 if (first_stage == true) {
 if (use_background) {
@@ -835,7 +829,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
   levels = 5; ptidxbits = 9; ptesize = 8; break;
 case VM_1_10_MBARE:
 *physical = addr;
-*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
+*ret_prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
 return TRANSLATE_SUCCESS;
 default:
   g_assert_not_reached();
@@ -970,6 +964,27 @@ restart:
 return TRANSLATE_FAIL;
 }
 
+int prot = 0;
+if (pte & PTE_R) {
+prot |= PAGE_READ;
+}
+if (pte & PTE_W) {
+prot |= PAGE_WRITE;
+}
+if (pte & PTE_X) {
+bool mxr;
+
+if (first_stage == true) {
+mxr = get_field(env->mstatus, MSTATUS_MXR);
+} else {
+mxr = get_field(env->vsstatus, MSTATUS_MXR);
+}
+if (mxr) {
+prot |= PAGE_READ;
+}
+prot |= PAGE_EXEC;
+}
+
 if ((pte & PTE_U) &&
 ((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
 /*
@@ -982,17 +997,9 @@ restart:
 /* Supervisor PTE flags when not S mode */
 return TRANSLATE_FAIL;
 }
-if (access_type == MMU_DATA_LOAD &&
-!((pte & PTE_R) || ((pte & PTE_X) && mxr))) {
-/* Read access check failed */
-return TRANSLATE_FAIL;
-}
-if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
-/* Write access check failed */
-return TRANSLATE_FAIL;
-}
-if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
-/* Fetch access check failed */
+
+if (!((prot >> access_type) & 1)) {
+/* Access check failed */
 return TRANSLATE_FAIL;
 }
 
@@ -1057,20 +1064,16 @@ restart:
   (vpn & (((target_ulong)1 << ptshift) - 1))
  ) << PGSHIFT) | (addr & ~TARGET_PAGE_MASK);
 
-/* set permissions on the TLB entry */
-if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) {
-*prot |= PAGE_READ;
-}
-if (pte & PTE_X) {
-*prot |= PAGE_EXEC;
-}
 /*
- * Add write permission on stores or if the page is already dirty,
- * so that we TLB miss on later writes to update the dirty bit.
+ * Remove write permission unless this is a store, or the page is
+ * already dirty, so that we TLB miss on later writes to update
+ * the dirty bit.
  */
-if ((pte & PTE_W) && (access_type == MMU_DATA_STORE || (pte & PTE_D))) {
-*prot |= PAGE_WRITE;
+if (access_type != MMU_DATA_STORE && !(pte & PTE_D)) {
+prot &= ~PAGE_WRITE;
 }
+*ret_prot = prot;
+
 return TRANSLATE_SUCCESS;
 }
 
-- 
2.40.0




[PULL 84/89] target/riscv: add query-cpy-definitions support

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

This command is used by tooling like libvirt to retrieve a list of
supported CPUs. Each entry returns a CpuDefinitionInfo object that
contains more information about each CPU.

This initial support includes only the name of the CPU and its typename.
Here's what the command produces for the riscv64 target:

$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": 
false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": false, 
"deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": 
false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, 
"deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": false, 
"deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": false, 
"deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": false, 
"deprecated": false}]
}

Next patch will introduce a way to tell whether a given CPU is static or
not.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Message-Id: <20230411183511.189632-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 qapi/machine-target.json  |  6 ++--
 target/riscv/riscv-qmp-cmds.c | 53 +++
 target/riscv/meson.build  |  3 +-
 3 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 target/riscv/riscv-qmp-cmds.c

diff --git a/qapi/machine-target.json b/qapi/machine-target.json
index b94fbdb65e..afc8c40894 100644
--- a/qapi/machine-target.json
+++ b/qapi/machine-target.json
@@ -324,7 +324,8 @@
'TARGET_I386',
'TARGET_S390X',
'TARGET_MIPS',
-   'TARGET_LOONGARCH64' ] } }
+   'TARGET_LOONGARCH64',
+   'TARGET_RISCV' ] } }
 
 ##
 # @query-cpu-definitions:
@@ -341,4 +342,5 @@
'TARGET_I386',
'TARGET_S390X',
'TARGET_MIPS',
-   'TARGET_LOONGARCH64' ] } }
+   'TARGET_LOONGARCH64',
+   'TARGET_RISCV' ] } }
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
new file mode 100644
index 00..128677add9
--- /dev/null
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -0,0 +1,53 @@
+/*
+ * QEMU CPU QMP commands for RISC-V
+ *
+ * Copyright (c) 2023 Ventana Micro Systems Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+
+#include "qapi/qapi-commands-machine-target.h"
+#include "cpu-qom.h"
+
+static void riscv_cpu_add_definition(gpointer data, gpointer user_data)
+{
+ObjectClass *oc = data;
+CpuDefinitionInfoList **cpu_list = user_data;
+CpuDefinitionInfo *info = g_malloc0(sizeof(*info));
+const char *typename = object_class_get_name(oc);
+
+info->name = g_strndup(typename,
+   strlen(typename) - strlen("-" TYPE_RISCV_CPU));
+info->q_typename = g_strdup(typename);
+
+QAPI_LIST_PREPEND(*cpu_list, info);
+}
+
+CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
+{
+CpuDefinitionInfoList *cpu_list = NULL;
+GSList *list = object_class_get_list(TYPE_RISCV_CPU, false);
+
+g_slist_foreach(list, riscv_cpu_add_definition, _list);
+g_slist_free(list);
+
+return cpu_list;
+}
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
index 5b7f813a3e..e1ff6d9b95 100644
--- a/target/riscv/meson.build
+++ b/target/riscv/meson.build
@@ -32,7 +32,8 @@ riscv_softmmu_ss.add(files(
   'monitor.c',
   'machine.c',
   'pmu.c',
-  'time_helper.c'

[PULL 71/89] target/riscv: Move hstatus.spvp check to check_access_hlsv

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

The current cpu_mmu_index value is really irrelevant to
the HLV/HSV lookup.  Provide the correct priv level directly.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-16-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-16-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 10 +-
 target/riscv/op_helper.c  |  2 +-
 2 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9dfd1d739b..ccba3c45e7 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -770,14 +770,6 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 use_background = true;
 }
 
-/*
- * MPRV does not affect the virtual-machine load/store
- * instructions, HLV, HLVX, and HSV.
- */
-if (mmuidx_2stage(mmu_idx)) {
-mode = get_field(env->hstatus, HSTATUS_SPVP);
-}
-
 if (first_stage == false) {
 /*
  * We are in stage 2 translation, this is similar to stage 1.
@@ -1250,7 +1242,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
  * instructions, HLV, HLVX, and HSV.
  */
 if (mmuidx_2stage(mmu_idx)) {
-mode = get_field(env->hstatus, HSTATUS_SPVP);
+;
 } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
get_field(env->mstatus, MSTATUS_MPRV)) {
 mode = get_field(env->mstatus, MSTATUS_MPP);
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 6122f5fbe5..f83f7b5347 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -437,7 +437,7 @@ static int check_access_hlsv(CPURISCVState *env, bool x, 
uintptr_t ra)
 riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra);
 }
 
-return cpu_mmu_index(env, x) | MMU_2STAGE_BIT;
+return get_field(env->hstatus, HSTATUS_SPVP) | MMU_2STAGE_BIT;
 }
 
 target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
-- 
2.40.0




[PULL 88/89] riscv: Make sure an exception is raised if a pte is malformed

2023-05-04 Thread Alistair Francis
From: Alexandre Ghiti 

As per the specification, in 64-bit, if any of the pte reserved bits
60-54 is set an exception should be triggered (see 4.4.1, "Addressing and
Memory Protection"). In addition, we must check the napot/pbmt bits are
not set if those extensions are not active.

Reported-by: Andrea Parri 
Signed-off-by: Alexandre Ghiti 
Reviewed-by: Alistair Francis 
Message-Id: <20230420150220.60919-1-alexgh...@rivosinc.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_bits.h   |  1 +
 target/riscv/cpu_helper.c | 15 +++
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index fb63b8e125..59f0ffd9e1 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -644,6 +644,7 @@ typedef enum {
 #define PTE_SOFT0x300 /* Reserved for Software */
 #define PTE_PBMT0x6000ULL /* Page-based memory types */
 #define PTE_N   0x8000ULL /* NAPOT translation */
+#define PTE_RESERVED0x1FC0ULL /* Reserved bits */
 #define PTE_ATTR(PTE_N | PTE_PBMT) /* All attributes bits */
 
 /* Page table PPN shift amount */
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b68dcfe7b6..57d04385f1 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -927,13 +927,20 @@ restart:
 
 if (riscv_cpu_sxl(env) == MXL_RV32) {
 ppn = pte >> PTE_PPN_SHIFT;
-} else if (pbmte || riscv_cpu_cfg(env)->ext_svnapot) {
-ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
 } else {
-ppn = pte >> PTE_PPN_SHIFT;
-if ((pte & ~(target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT) {
+if (pte & PTE_RESERVED) {
+return TRANSLATE_FAIL;
+}
+
+if (!pbmte && (pte & PTE_PBMT)) {
 return TRANSLATE_FAIL;
 }
+
+if (!riscv_cpu_cfg(env)->ext_svnapot && (pte & PTE_N)) {
+return TRANSLATE_FAIL;
+}
+
+ppn = (pte & (target_ulong)PTE_PPN_MASK) >> PTE_PPN_SHIFT;
 }
 
 if (!(pte & PTE_V)) {
-- 
2.40.0




[PULL 52/89] target/riscv/cpu.c: redesign register_cpu_props()

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

The function is now a no-op for all cpu_init() callers that are setting
a non-zero misa value in set_misa(), since it's no longer used to sync
cpu->cfg props with env->misa_ext bits. Remove it in those cases.

While we're at it, rename the function to match what it's actually
doing: create user properties to set/remove CPU extensions. Make a note
that it will overwrite env->misa_ext with the defaults set by each user
property.

Update the MISA bits comment in cpu.h as well.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-21-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  5 +
 target/riscv/cpu.c | 41 ++---
 2 files changed, 11 insertions(+), 35 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 070547234b..f47c3fc139 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -65,10 +65,7 @@
 
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
-/*
- * Consider updating register_cpu_props() when adding
- * new MISA bits here.
- */
+/* Consider updating misa_ext_cfgs[] when adding new MISA bits here */
 #define RVI RV('I')
 #define RVE RV('E') /* E and I are mutually exclusive */
 #define RVM RV('M')
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 143079a8df..d1769fd218 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -228,7 +228,7 @@ static const char * const riscv_intr_names[] = {
 "reserved"
 };
 
-static void register_cpu_props(Object *obj);
+static void riscv_cpu_add_user_properties(Object *obj);
 
 const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
 {
@@ -356,7 +356,6 @@ static void riscv_any_cpu_init(Object *obj)
 #endif
 
 set_priv_version(env, PRIV_VERSION_1_12_0);
-register_cpu_props(obj);
 }
 
 #if defined(TARGET_RISCV64)
@@ -365,7 +364,7 @@ static void rv64_base_cpu_init(Object *obj)
 CPURISCVState *env = _CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV64, 0);
-register_cpu_props(obj);
+riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
 set_priv_version(env, PRIV_VERSION_1_12_0);
 #ifndef CONFIG_USER_ONLY
@@ -377,7 +376,6 @@ static void rv64_sifive_u_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_10_0);
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV39);
@@ -390,7 +388,6 @@ static void rv64_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_10_0);
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
@@ -436,7 +433,7 @@ static void rv128_base_cpu_init(Object *obj)
 CPURISCVState *env = _CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV128, 0);
-register_cpu_props(obj);
+riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
 set_priv_version(env, PRIV_VERSION_1_12_0);
 #ifndef CONFIG_USER_ONLY
@@ -449,7 +446,7 @@ static void rv32_base_cpu_init(Object *obj)
 CPURISCVState *env = _CPU(obj)->env;
 /* We set this in the realise function */
 set_misa(env, MXL_RV32, 0);
-register_cpu_props(obj);
+riscv_cpu_add_user_properties(obj);
 /* Set latest version of privileged specification */
 set_priv_version(env, PRIV_VERSION_1_12_0);
 #ifndef CONFIG_USER_ONLY
@@ -461,7 +458,6 @@ static void rv32_sifive_u_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_10_0);
 #ifndef CONFIG_USER_ONLY
 set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV32);
@@ -474,7 +470,6 @@ static void rv32_sifive_e_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_10_0);
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
@@ -488,7 +483,6 @@ static void rv32_ibex_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_11_0);
 cpu->cfg.mmu = false;
 #ifndef CONFIG_USER_ONLY
@@ -503,7 +497,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
 RISCVCPU *cpu = RISCV_CPU(obj);
 
 set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
-register_cpu_props(obj);
 set_priv_version(env, PRIV_VERSION_1_10_0);
 cpu->cfg.mmu = false;
 #ifndef 

[PULL 85/89] target/riscv: add TYPE_RISCV_DYNAMIC_CPU

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

This new abstract type will be used to differentiate between static and
non-static CPUs in query-cpu-definitions.

All generic CPUs were changed to be of this type. Named CPUs are kept as
TYPE_RISCV_CPU and will still be considered static.

This is the output of query-cpu-definitions after this change for the
riscv64 target:

$ ./build/qemu-system-riscv64 -S -M virt -display none -qmp stdio
{"QMP": {"version": (...)}
{"execute": "qmp_capabilities", "arguments": {"enable": ["oob"]}}
{"return": {}}
{"execute": "query-cpu-definitions"}
{"return": [
{"name": "rv64", "typename": "rv64-riscv-cpu", "static": false, "deprecated": 
false},
{"name": "sifive-e51", "typename": "sifive-e51-riscv-cpu", "static": true, 
"deprecated": false},
{"name": "any", "typename": "any-riscv-cpu", "static": false, "deprecated": 
false},
{"name": "x-rv128", "typename": "x-rv128-riscv-cpu", "static": false, 
"deprecated": false},
{"name": "shakti-c", "typename": "shakti-c-riscv-cpu", "static": true, 
"deprecated": false},
{"name": "thead-c906", "typename": "thead-c906-riscv-cpu", "static": true, 
"deprecated": false},
{"name": "sifive-u54", "typename": "sifive-u54-riscv-cpu", "static": true, 
"deprecated": false}
]}

Suggested-by: Richard Henderson 
Signed-off-by: Daniel Henrique Barboza 
Acked-by: Alistair Francis 
Reviewed-by: Richard Henderson 
Message-Id: <20230411183511.189632-4-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu-qom.h|  2 +-
 target/riscv/cpu.c| 20 
 target/riscv/riscv-qmp-cmds.c |  4 
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
index b9318e0783..b29090ad86 100644
--- a/target/riscv/cpu-qom.h
+++ b/target/riscv/cpu-qom.h
@@ -23,6 +23,7 @@
 #include "qom/object.h"
 
 #define TYPE_RISCV_CPU "riscv-cpu"
+#define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu"
 
 #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU
 #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX)
@@ -66,5 +67,4 @@ struct RISCVCPUClass {
 DeviceRealize parent_realize;
 ResettablePhases parent_phases;
 };
-
 #endif /* RISCV_CPU_QOM_H */
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 32c04214a1..befa64528f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1788,6 +1788,13 @@ void riscv_cpu_list(void)
 .instance_init = initfn\
 }
 
+#define DEFINE_DYNAMIC_CPU(type_name, initfn) \
+{ \
+.name = type_name,\
+.parent = TYPE_RISCV_DYNAMIC_CPU, \
+.instance_init = initfn   \
+}
+
 static const TypeInfo riscv_cpu_type_infos[] = {
 {
 .name = TYPE_RISCV_CPU,
@@ -1799,23 +1806,28 @@ static const TypeInfo riscv_cpu_type_infos[] = {
 .class_size = sizeof(RISCVCPUClass),
 .class_init = riscv_cpu_class_init,
 },
-DEFINE_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
+{
+.name = TYPE_RISCV_DYNAMIC_CPU,
+.parent = TYPE_RISCV_CPU,
+.abstract = true,
+},
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init),
 #if defined(CONFIG_KVM)
 DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
 #endif
 #if defined(TARGET_RISCV32)
-DEFINE_CPU(TYPE_RISCV_CPU_BASE32,   rv32_base_cpu_init),
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32,   rv32_base_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31,   rv32_sifive_e_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34,   rv32_imafcu_nommu_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34,   rv32_sifive_u_cpu_init),
 #elif defined(TARGET_RISCV64)
-DEFINE_CPU(TYPE_RISCV_CPU_BASE64,   rv64_base_cpu_init),
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64,   rv64_base_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51,   rv64_sifive_e_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54,   rv64_sifive_u_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init),
 DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906,   rv64_thead_c906_cpu_init),
-DEFINE_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
+DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128,  rv128_base_cpu_init),
 #endif
 };
 
diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c
index 128677add9..5ecff1afb3 100644
--- a/target/riscv/riscv-qmp-cmds.c
+++ b/target/riscv/riscv-qmp-cmds.c
@@ -33,11 +33,15 @@ static void riscv_cpu_add_definition(gpointer data, 
gpointer user_data)
 CpuDefinitionInfoList **cpu_list = user_data;
 CpuDefinitionInfo *info = g_malloc0(sizeof(*info));
 const char *typename = object_class_get_name(oc);
+ObjectClass *dyn_class;
 
 info->name = g_strndup(typename,
strlen(typename) - strlen("-" 

[PULL 79/89] target/riscv: Merge checks for reserved pte flags

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-24-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-24-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 12 ++--
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 9a2b944990..c7c384bae3 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -962,14 +962,14 @@ restart:
 /* Reserved without Svpbmt. */
 return TRANSLATE_FAIL;
 }
-if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
-/* Reserved leaf PTE flags: PTE_W */
-return TRANSLATE_FAIL;
-}
-if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
-/* Reserved leaf PTE flags: PTE_W + PTE_X */
+
+/* Check for reserved combinations of RWX flags. */
+switch (pte & (PTE_R | PTE_W | PTE_X)) {
+case PTE_W:
+case PTE_W | PTE_X:
 return TRANSLATE_FAIL;
 }
+
 if ((pte & PTE_U) &&
 ((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
 /*
-- 
2.40.0




[PULL 10/89] target/riscv: add support for Zca extension

2023-05-04 Thread Alistair Francis
From: Weiwei Li 

Modify the check for C extension to Zca (C implies Zca).

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Wilfred Mallawa 
Message-Id: <20230307081403.61950-3-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/translate.c| 8 ++--
 target/riscv/insn_trans/trans_rvi.c.inc | 4 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 0ee8ee147d..d1fdd0c2d7 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -549,7 +549,7 @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong 
imm)
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -1122,7 +1122,11 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx, uint16_t opcode)
 if (insn_len(opcode) == 2) {
 ctx->opcode = opcode;
 ctx->pc_succ_insn = ctx->base.pc_next + 2;
-if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
+/*
+ * The Zca extension is added as way to refer to instructions in the C
+ * extension that do not include the floating-point loads and stores
+ */
+if (ctx->cfg_ptr->ext_zca && decode_insn16(ctx, opcode)) {
 return;
 }
 } else {
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc 
b/target/riscv/insn_trans/trans_rvi.c.inc
index 4ad54e8a49..c70c495fc5 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -56,7 +56,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
 gen_set_pc(ctx, cpu_pc);
-if (!has_ext(ctx, RVC)) {
+if (!ctx->cfg_ptr->ext_zca) {
 TCGv t0 = tcg_temp_new();
 
 misaligned = gen_new_label();
@@ -169,7 +169,7 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond 
cond)
 
 gen_set_label(l); /* branch taken */
 
-if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
+if (!ctx->cfg_ptr->ext_zca && ((ctx->base.pc_next + a->imm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
-- 
2.40.0




[PULL 72/89] target/riscv: Set MMU_2STAGE_BIT in riscv_cpu_mmu_index

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Incorporate the virt_enabled and MPV checks into the cpu_mmu_index
function, so we don't have to keep doing it within tlb_fill and
subroutines.  This also elides a flush on changes to MPV.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-17-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-17-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 49 ++-
 target/riscv/csr.c|  6 +
 2 files changed, 18 insertions(+), 37 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index ccba3c45e7..baa4b3a1d2 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -37,19 +37,21 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #ifdef CONFIG_USER_ONLY
 return 0;
 #else
-if (ifetch) {
-return env->priv;
-}
+bool virt = env->virt_enabled;
+int mode = env->priv;
 
 /* All priv -> mmu_idx mapping are here */
-int mode = env->priv;
-if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
-mode = get_field(env->mstatus, MSTATUS_MPP);
-}
-if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
-return MMUIdx_S_SUM;
+if (!ifetch) {
+if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+mode = get_field(env->mstatus, MSTATUS_MPP);
+virt = get_field(env->mstatus, MSTATUS_MPV);
+}
+if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+mode = MMUIdx_S_SUM;
+}
 }
-return mode;
+
+return mode | (virt ? MMU_2STAGE_BIT : 0);
 #endif
 }
 
@@ -1162,7 +1164,7 @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
 }
 
 env->badaddr = addr;
-env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
+env->two_stage_lookup = mmuidx_2stage(mmu_idx);
 env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
@@ -1187,7 +1189,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 g_assert_not_reached();
 }
 env->badaddr = addr;
-env->two_stage_lookup = env->virt_enabled || mmuidx_2stage(mmu_idx);
+env->two_stage_lookup = mmuidx_2stage(mmu_idx);
 env->two_stage_indirect_lookup = false;
 cpu_loop_exit_restore(cs, retaddr);
 }
@@ -1225,7 +1227,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 int prot, prot2, prot_pmp;
 bool pmp_violation = false;
 bool first_stage_error = true;
-bool two_stage_lookup = false;
+bool two_stage_lookup = mmuidx_2stage(mmu_idx);
 bool two_stage_indirect_error = false;
 int ret = TRANSLATE_FAIL;
 int mode = mmu_idx;
@@ -1237,24 +1239,8 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
   __func__, address, access_type, mmu_idx);
 
-/*
- * MPRV does not affect the virtual-machine load/store
- * instructions, HLV, HLVX, and HSV.
- */
-if (mmuidx_2stage(mmu_idx)) {
-;
-} else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
-   get_field(env->mstatus, MSTATUS_MPRV)) {
-mode = get_field(env->mstatus, MSTATUS_MPP);
-if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) {
-two_stage_lookup = true;
-}
-}
-
 pmu_tlb_fill_incr_ctr(cpu, access_type);
-if (env->virt_enabled ||
-((mmuidx_2stage(mmu_idx) || two_stage_lookup) &&
- access_type != MMU_INST_FETCH)) {
+if (two_stage_lookup) {
 /* Two stage lookup */
 ret = get_physical_address(env, , , address,
>guest_phys_fault_addr, access_type,
@@ -1350,8 +1336,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int 
size,
 return false;
 } else {
 raise_mmu_exception(env, address, access_type, pmp_violation,
-first_stage_error,
-env->virt_enabled || mmuidx_2stage(mmu_idx),
+first_stage_error, two_stage_lookup,
 two_stage_indirect_error);
 cpu_loop_exit_restore(cs, retaddr);
 }
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 4a4d852bd1..865ee9efda 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1294,7 +1294,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
 
 /* flush tlb on mstatus fields that affect VM */
-if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPV)) {
+if ((val ^ mstatus) & MSTATUS_MXR) {
 tlb_flush(env_cpu(env));
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | 

[PULL 48/89] target/riscv: remove cpu->cfg.ext_v

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "v" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVV. Instances of cpu->cfg.ext_v and similar are
replaced with riscv_has_ext(env, RVV).

Remove the old "v" property and 'ext_v' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-17-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 -
 target/riscv/cpu.c | 12 +---
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1aff93ba91..e011cf6ca4 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -423,7 +423,6 @@ typedef struct {
 
 struct RISCVCPUConfig {
 bool ext_g;
-bool ext_v;
 bool ext_zba;
 bool ext_zbb;
 bool ext_zbc;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3bdd6875a8..13ff37250e 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -883,7 +883,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 
 /* The V vector extension depends on the Zve64d extension */
-if (cpu->cfg.ext_v) {
+if (riscv_has_ext(env, RVV)) {
 cpu->cfg.ext_zve64d = true;
 }
 
@@ -1018,7 +1018,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zksh = true;
 }
 
-if (cpu->cfg.ext_v) {
+if (riscv_has_ext(env, RVV)) {
 int vext_version = VEXT_VERSION_1_00_0;
 if (!is_power_of_2(cpu->cfg.vlen)) {
 error_setg(errp,
@@ -1175,7 +1175,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 if (riscv_has_ext(env, RVH)) {
 ext |= RVH;
 }
-if (riscv_cpu_cfg(env)->ext_v) {
+if (riscv_has_ext(env, RVV)) {
 ext |= RVV;
 }
 if (riscv_has_ext(env, RVJ)) {
@@ -1513,6 +1513,8 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  .misa_bit = RVH, .enabled = true},
 {.name = "x-j", .description = "Dynamic translated languages",
  .misa_bit = RVJ, .enabled = false},
+{.name = "v", .description = "Vector operations",
+ .misa_bit = RVV, .enabled = false},
 };
 
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
@@ -1536,7 +1538,6 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
 DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false),
-DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
 DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
 DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
 DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
@@ -1638,7 +1639,6 @@ static Property riscv_cpu_extensions[] = {
 static void register_cpu_props(Object *obj)
 {
 RISCVCPU *cpu = RISCV_CPU(obj);
-uint32_t misa_ext = cpu->env.misa_ext;
 Property *prop;
 DeviceState *dev = DEVICE(obj);
 
@@ -1648,8 +1648,6 @@ static void register_cpu_props(Object *obj)
  * later on.
  */
 if (cpu->env.misa_ext != 0) {
-cpu->cfg.ext_v = misa_ext & RVV;
-
 /*
  * We don't want to set the default riscv_cpu_extensions
  * in this case.
-- 
2.40.0




[PULL 60/89] target/riscv: Encode the FS and VS on a normal way for tb flags

2023-05-04 Thread Alistair Francis
From: LIU Zhiwei 

Reuse the MSTATUS_FS and MSTATUS_VS for the tb flags positions is not a
normal way.

It will make it hard to change the tb flags layout. And even worse, if we
want to keep tb flags for a same extension togather without a hole.

Reviewed-by: Richard Henderson 
Signed-off-by: LIU Zhiwei 
Reviewed-by: Weiwei Li 
Message-Id: <20230324143031.1093-4-zhiwei_...@linux.alibaba.com>
[rth: Adjust trans_rvf.c.inc as well; use the typedef]
Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-4-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-4-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  | 15 ++--
 target/riscv/cpu_helper.c   | 11 +
 target/riscv/translate.c| 32 +++--
 target/riscv/insn_trans/trans_rvf.c.inc |  2 +-
 target/riscv/insn_trans/trans_rvv.c.inc |  8 +++
 5 files changed, 32 insertions(+), 36 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ba11279716..51d39687fe 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -631,18 +631,17 @@ 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
 
 #include "exec/cpu-all.h"
 
 FIELD(TB_FLAGS, MEM_IDX, 0, 3)
-FIELD(TB_FLAGS, LMUL, 3, 3)
-FIELD(TB_FLAGS, SEW, 6, 3)
-/* Skip MSTATUS_VS (0x600) bits */
-FIELD(TB_FLAGS, VL_EQ_VLMAX, 11, 1)
-FIELD(TB_FLAGS, VILL, 12, 1)
-/* Skip MSTATUS_FS (0x6000) bits */
+FIELD(TB_FLAGS, FS, 3, 2)
+/* Vector flags */
+FIELD(TB_FLAGS, VS, 5, 2)
+FIELD(TB_FLAGS, LMUL, 7, 3)
+FIELD(TB_FLAGS, SEW, 10, 3)
+FIELD(TB_FLAGS, VL_EQ_VLMAX, 13, 1)
+FIELD(TB_FLAGS, VILL, 14, 1)
 /* Is a Hypervisor instruction load/store allowed? */
 FIELD(TB_FLAGS, HLSX, 15, 1)
 FIELD(TB_FLAGS, MSTATUS_HS_FS, 16, 2)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 1d90977d46..8412ef26ee 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -79,16 +79,17 @@ 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;
+flags = FIELD_DP32(flags, TB_FLAGS, FS, EXT_STATUS_DIRTY);
+flags = FIELD_DP32(flags, TB_FLAGS, VS, EXT_STATUS_DIRTY);
 #else
 flags |= cpu_mmu_index(env, 0);
 if (riscv_cpu_fp_enabled(env)) {
-flags |= env->mstatus & MSTATUS_FS;
+flags = FIELD_DP32(flags, TB_FLAGS, FS,
+   get_field(env->mstatus, MSTATUS_FS));
 }
-
 if (riscv_cpu_vector_enabled(env)) {
-flags |= env->mstatus & MSTATUS_VS;
+flags = FIELD_DP32(flags, TB_FLAGS, VS,
+   get_field(env->mstatus, MSTATUS_VS));
 }
 
 if (riscv_has_ext(env, RVH)) {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ebd00529ff..411e771e6f 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -64,10 +64,10 @@ typedef struct DisasContext {
 RISCVMXL xl;
 uint32_t misa_ext;
 uint32_t opcode;
-uint32_t mstatus_fs;
-uint32_t mstatus_vs;
-uint32_t mstatus_hs_fs;
-uint32_t mstatus_hs_vs;
+RISCVExtStatus mstatus_fs;
+RISCVExtStatus mstatus_vs;
+RISCVExtStatus mstatus_hs_fs;
+RISCVExtStatus mstatus_hs_vs;
 uint32_t mem_idx;
 /*
  * Remember the rounding mode encoded in the previous fp instruction,
@@ -601,8 +601,6 @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, 
TCGv offs)
 
 #ifndef CONFIG_USER_ONLY
 /*
- * The states of mstatus_fs are:
- * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
  * We will have already diagnosed disabled state,
  * and need to turn initial/clean into dirty.
  */
@@ -614,9 +612,9 @@ static void mark_fs_dirty(DisasContext *ctx)
 return;
 }
 
-if (ctx->mstatus_fs != MSTATUS_FS) {
+if (ctx->mstatus_fs != EXT_STATUS_DIRTY) {
 /* Remember the state change for the rest of the TB. */
-ctx->mstatus_fs = MSTATUS_FS;
+ctx->mstatus_fs = EXT_STATUS_DIRTY;
 
 tmp = tcg_temp_new();
 tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
@@ -624,9 +622,9 @@ static void mark_fs_dirty(DisasContext *ctx)
 tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
 }
 
-if (ctx->virt_enabled && ctx->mstatus_hs_fs != MSTATUS_FS) {
+if (ctx->virt_enabled && ctx->mstatus_hs_fs != EXT_STATUS_DIRTY) {
 /* Remember the stage change for the rest of the TB. */
-ctx->mstatus_hs_fs = MSTATUS_FS;
+ctx->mstatus_hs_fs = EXT_STATUS_DIRTY;
 
 tmp = tcg_temp_new();
 tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
@@ -640,8 +638,6 @@ static inline void 

[PULL 40/89] target/riscv: remove cpu->cfg.ext_f

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "f" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVF. Instances of cpu->cfg.ext_f and similar are
replaced with riscv_has_ext(env, RVF).

Remove the old "f" property and 'ext_f' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-9-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 -
 target/riscv/cpu.c | 26 +-
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index fba5e9a33c..e5680b0709 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -426,7 +426,6 @@ struct RISCVCPUConfig {
 bool ext_e;
 bool ext_g;
 bool ext_m;
-bool ext_f;
 bool ext_s;
 bool ext_u;
 bool ext_h;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 5bb03e2ee5..715cbca1b3 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -819,12 +819,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 /* Do some ISA extension error checking */
 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
 riscv_has_ext(env, RVA) &&
-cpu->cfg.ext_f && riscv_has_ext(env, RVD) &&
+riscv_has_ext(env, RVF) &&
+riscv_has_ext(env, RVD) &&
 cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
 warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
 cpu->cfg.ext_i = true;
 cpu->cfg.ext_m = true;
-cpu->cfg.ext_f = true;
 cpu->cfg.ext_icsr = true;
 cpu->cfg.ext_ifencei = true;
 
@@ -861,7 +861,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_f && !cpu->cfg.ext_icsr) {
+if (riscv_has_ext(env, RVF) && !cpu->cfg.ext_icsr) {
 error_setg(errp, "F extension requires Zicsr");
 return;
 }
@@ -875,12 +875,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zfhmin = true;
 }
 
-if (cpu->cfg.ext_zfhmin && !cpu->cfg.ext_f) {
+if (cpu->cfg.ext_zfhmin && !riscv_has_ext(env, RVF)) {
 error_setg(errp, "Zfh/Zfhmin extensions require F extension");
 return;
 }
 
-if (riscv_has_ext(env, RVD) && !cpu->cfg.ext_f) {
+if (riscv_has_ext(env, RVD) && !riscv_has_ext(env, RVF)) {
 error_setg(errp, "D extension requires F extension");
 return;
 }
@@ -905,7 +905,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_zve32f && !cpu->cfg.ext_f) {
+if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
 error_setg(errp, "Zve32f/Zve64f extensions require F extension");
 return;
 }
@@ -938,7 +938,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 error_setg(errp, "Zfinx extension requires Zicsr");
 return;
 }
-if (cpu->cfg.ext_f) {
+if (riscv_has_ext(env, RVF)) {
 error_setg(errp,
"Zfinx cannot be supported together with F extension");
 return;
@@ -950,14 +950,14 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 cpu->cfg.ext_zcb = true;
 cpu->cfg.ext_zcmp = true;
 cpu->cfg.ext_zcmt = true;
-if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
 cpu->cfg.ext_zcf = true;
 }
 }
 
 if (riscv_has_ext(env, RVC)) {
 cpu->cfg.ext_zca = true;
-if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
+if (riscv_has_ext(env, RVF) && env->misa_mxl_max == MXL_RV32) {
 cpu->cfg.ext_zcf = true;
 }
 if (riscv_has_ext(env, RVD)) {
@@ -970,7 +970,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (!cpu->cfg.ext_f && cpu->cfg.ext_zcf) {
+if (!riscv_has_ext(env, RVF) && cpu->cfg.ext_zcf) {
 error_setg(errp, "Zcf extension requires F extension");
 return;
 }
@@ -1160,7 +1160,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 if (riscv_has_ext(env, RVA)) {
 ext |= RVA;
 }
-if (riscv_cpu_cfg(env)->ext_f) {
+if (riscv_has_ext(env, RVF)) {
 ext |= RVF;
 }
 if (riscv_has_ext(env, RVD)) {
@@ -1500,6 +1500,8 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  .misa_bit = RVC, .enabled = true},
 {.name = "d", .description = "Double-precision float point",
  .misa_bit = RVD, .enabled = true},
+{.name = "f", .description = "Single-precision float point",
+ .misa_bit 

[PULL 37/89] target/riscv: remove cpu->cfg.ext_a

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "a" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVA. Instances of cpu->cfg.ext_a and similar are
replaced with riscv_has_ext(env, RVA).

Remove the old "a" property and 'ext_a' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-6-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 -
 target/riscv/cpu.c | 16 
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index cbf3de2708..1d1a17d85b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -426,7 +426,6 @@ struct RISCVCPUConfig {
 bool ext_e;
 bool ext_g;
 bool ext_m;
-bool ext_a;
 bool ext_f;
 bool ext_d;
 bool ext_c;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3b234a03d0..3770fd4f6f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -819,13 +819,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 
 /* Do some ISA extension error checking */
 if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
-cpu->cfg.ext_a && cpu->cfg.ext_f &&
-cpu->cfg.ext_d &&
+riscv_has_ext(env, RVA) &&
+cpu->cfg.ext_f && cpu->cfg.ext_d &&
 cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
 warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
 cpu->cfg.ext_i = true;
 cpu->cfg.ext_m = true;
-cpu->cfg.ext_a = true;
 cpu->cfg.ext_f = true;
 cpu->cfg.ext_d = true;
 cpu->cfg.ext_icsr = true;
@@ -869,7 +868,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
+if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) {
 error_setg(errp, "Zawrs extension requires A extension");
 return;
 }
@@ -1160,7 +1159,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 if (riscv_cpu_cfg(env)->ext_m) {
 ext |= RVM;
 }
-if (riscv_cpu_cfg(env)->ext_a) {
+if (riscv_has_ext(env, RVA)) {
 ext |= RVA;
 }
 if (riscv_cpu_cfg(env)->ext_f) {
@@ -1496,7 +1495,10 @@ static void cpu_get_misa_ext_cfg(Object *obj, Visitor 
*v, const char *name,
 visit_type_bool(v, name, , errp);
 }
 
-static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {};
+static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
+{.name = "a", .description = "Atomic instructions",
+ .misa_bit = RVA, .enabled = true},
+};
 
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 {
@@ -1522,7 +1524,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
 DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false),
 DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
-DEFINE_PROP_BOOL("a", RISCVCPU, cfg.ext_a, true),
 DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
 DEFINE_PROP_BOOL("d", RISCVCPU, cfg.ext_d, true),
 DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
@@ -1645,7 +1646,6 @@ static void register_cpu_props(Object *obj)
 cpu->cfg.ext_i = misa_ext & RVI;
 cpu->cfg.ext_e = misa_ext & RVE;
 cpu->cfg.ext_m = misa_ext & RVM;
-cpu->cfg.ext_a = misa_ext & RVA;
 cpu->cfg.ext_f = misa_ext & RVF;
 cpu->cfg.ext_d = misa_ext & RVD;
 cpu->cfg.ext_v = misa_ext & RVV;
-- 
2.40.0




[PULL 76/89] target/riscv: Move leaf pte processing out of level loop

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Move the code that never loops outside of the loop.
Unchain the if-return-else statements.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-21-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-21-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 234 --
 1 file changed, 123 insertions(+), 111 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7c9f89d4d3..c2d083f029 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -865,6 +865,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 
 int ptshift = (levels - 1) * ptidxbits;
+target_ulong pte;
+hwaddr pte_addr;
 int i;
 
 #if !TCG_OVERSIZED_GUEST
@@ -881,7 +883,6 @@ restart:
 }
 
 /* check that physical address of PTE is legal */
-hwaddr pte_addr;
 
 if (two_stage && first_stage) {
 int vbase_prot;
@@ -913,7 +914,6 @@ restart:
 return TRANSLATE_PMP_FAIL;
 }
 
-target_ulong pte;
 if (riscv_cpu_mxl(env) == MXL_RV32) {
 pte = address_space_ldl(cs->as, pte_addr, attrs, );
 } else {
@@ -938,128 +938,140 @@ restart:
 if (!(pte & PTE_V)) {
 /* Invalid PTE */
 return TRANSLATE_FAIL;
-} else if (!pbmte && (pte & PTE_PBMT)) {
-return TRANSLATE_FAIL;
-} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
-/* Inner PTE, continue walking */
-if (pte & (PTE_D | PTE_A | PTE_U | PTE_ATTR)) {
-return TRANSLATE_FAIL;
-}
-base = ppn << PGSHIFT;
-} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
-/* Reserved leaf PTE flags: PTE_W */
-return TRANSLATE_FAIL;
-} else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
-/* Reserved leaf PTE flags: PTE_W + PTE_X */
-return TRANSLATE_FAIL;
-} else if ((pte & PTE_U) && ((mode != PRV_U) &&
-   (!sum || access_type == MMU_INST_FETCH))) {
-/* User PTE flags when not U mode and mstatus.SUM is not set,
-   or the access type is an instruction fetch */
-return TRANSLATE_FAIL;
-} else if (!(pte & PTE_U) && (mode != PRV_S)) {
-/* Supervisor PTE flags when not S mode */
-return TRANSLATE_FAIL;
-} else if (ppn & ((1ULL << ptshift) - 1)) {
-/* Misaligned PPN */
-return TRANSLATE_FAIL;
-} else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
-   ((pte & PTE_X) && mxr))) {
-/* Read access check failed */
-return TRANSLATE_FAIL;
-} else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
-/* Write access check failed */
-return TRANSLATE_FAIL;
-} else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
-/* Fetch access check failed */
+}
+if (pte & (PTE_R | PTE_W | PTE_X)) {
+goto leaf;
+}
+
+/* Inner PTE, continue walking */
+if (pte & (PTE_D | PTE_A | PTE_U | PTE_ATTR)) {
 return TRANSLATE_FAIL;
-} else {
-/* if necessary, set accessed and dirty bits. */
-target_ulong updated_pte = pte | PTE_A |
+}
+base = ppn << PGSHIFT;
+}
+
+/* No leaf pte at any translation level. */
+return TRANSLATE_FAIL;
+
+ leaf:
+if (ppn & ((1ULL << ptshift) - 1)) {
+/* Misaligned PPN */
+return TRANSLATE_FAIL;
+}
+if (!pbmte && (pte & PTE_PBMT)) {
+/* Reserved without Svpbmt. */
+return TRANSLATE_FAIL;
+}
+if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+/* Reserved leaf PTE flags: PTE_W */
+return TRANSLATE_FAIL;
+}
+if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+/* Reserved leaf PTE flags: PTE_W + PTE_X */
+return TRANSLATE_FAIL;
+}
+if ((pte & PTE_U) &&
+((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
+/*
+ * User PTE flags when not U mode and mstatus.SUM is not set,
+ * or the access type is an instruction fetch.
+ */
+return TRANSLATE_FAIL;
+}
+if (!(pte & PTE_U) && (mode != PRV_S)) {
+/* Supervisor PTE flags when not S mode */
+return TRANSLATE_FAIL;
+}
+if (access_type == MMU_DATA_LOAD &&
+!((pte & PTE_R) || ((pte & PTE_X) && mxr))) {
+/* Read access check failed */
+return TRANSLATE_FAIL;
+}
+if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
+/* Write access check failed */
+return TRANSLATE_FAIL;
+}
+if (access_type == 

[PULL 81/89] target/riscv: Reorg sum check in get_physical_address

2023-05-04 Thread Alistair Francis
From: Richard Henderson 

Implement this by adjusting prot, which reduces the set of
checks required.  This prevents exec to be set for U pages
in MMUIdx_S_SUM.  While it had been technically incorrect,
it did not manifest as a bug, because we will never attempt
to execute from MMUIdx_S_SUM.

Signed-off-by: Richard Henderson 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-26-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-26-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 22 +++---
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 7849e18554..32a65f8007 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -786,7 +786,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 *ret_prot = 0;
 
 hwaddr base;
-int levels, ptidxbits, ptesize, vm, sum, widened;
+int levels, ptidxbits, ptesize, vm, widened;
 
 if (first_stage == true) {
 if (use_background) {
@@ -817,7 +817,7 @@ static int get_physical_address(CPURISCVState *env, hwaddr 
*physical,
 }
 widened = 2;
 }
-sum = mmuidx_sum(mmu_idx);
+
 switch (vm) {
 case VM_1_10_SV32:
   levels = 2; ptidxbits = 10; ptesize = 4; break;
@@ -985,15 +985,15 @@ restart:
 prot |= PAGE_EXEC;
 }
 
-if ((pte & PTE_U) &&
-((mode != PRV_U) && (!sum || access_type == MMU_INST_FETCH))) {
-/*
- * User PTE flags when not U mode and mstatus.SUM is not set,
- * or the access type is an instruction fetch.
- */
-return TRANSLATE_FAIL;
-}
-if (!(pte & PTE_U) && (mode != PRV_S)) {
+if (pte & PTE_U) {
+if (mode != PRV_U) {
+if (!mmuidx_sum(mmu_idx)) {
+return TRANSLATE_FAIL;
+}
+/* SUM allows only read+write, not execute. */
+prot &= PAGE_READ | PAGE_WRITE;
+}
+} else if (mode != PRV_S) {
 /* Supervisor PTE flags when not S mode */
 return TRANSLATE_FAIL;
 }
-- 
2.40.0




[PULL 31/89] target/riscv: Fix lines with over 80 characters

2023-05-04 Thread Alistair Francis
From: Weiwei Li 

Fix lines with over 80 characters for both code and comments.

Signed-off-by: Weiwei Li 
Signed-off-by: Junqiang Wang 
Reviewed-by: LIU Zhiwei 
Acked-by: Alistair Francis 
Reviewed-by: Daniel Henrique Barboza 
Message-Id: <20230405085813.40643-5-liwei...@iscas.ac.cn>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h   |  4 +-
 target/riscv/cpu.c   |  3 +-
 target/riscv/cpu_helper.c|  3 +-
 target/riscv/csr.c   | 38 ++
 target/riscv/debug.c | 11 +++---
 target/riscv/gdbstub.c   |  3 +-
 target/riscv/pmp.c   |  6 ++-
 target/riscv/pmu.c   |  3 +-
 target/riscv/vector_helper.c | 76 
 9 files changed, 91 insertions(+), 56 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 5018a3b1b2..cbf3de2708 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -591,8 +591,8 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable);
 bool riscv_cpu_two_stage_lookup(int mmu_idx);
 int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch);
 G_NORETURN void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
-   MMUAccessType access_type, int 
mmu_idx,
-   uintptr_t retaddr);
+   MMUAccessType access_type,
+   int mmu_idx, uintptr_t retaddr);
 bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
 MMUAccessType access_type, int mmu_idx,
 bool probe, uintptr_t retaddr);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 2e45b1f076..cb68916fce 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -1700,7 +1700,8 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
 device_class_set_props(dc, riscv_cpu_properties);
 }
 
-static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int 
max_str_len)
+static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
+ int max_str_len)
 {
 char *old = *isa_str;
 char *new = *isa_str;
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 445ffe691a..2310c7905f 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1121,7 +1121,8 @@ static void raise_mmu_exception(CPURISCVState *env, 
target_ulong address,
 cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
 } else {
 cs->exception_index = page_fault_exceptions ?
-RISCV_EXCP_STORE_PAGE_FAULT : 
RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
+RISCV_EXCP_STORE_PAGE_FAULT :
+RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
 }
 break;
 default:
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 76755ee128..e0b871f6dc 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1137,7 +1137,8 @@ static const target_ulong sstatus_v1_10_mask = 
SSTATUS_SIE | SSTATUS_SPIE |
 static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP |
   SIP_LCOFIP;
 static const target_ulong hip_writable_mask = MIP_VSSIP;
-static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | 
MIP_VSEIP;
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP |
+   MIP_VSEIP;
 static const target_ulong vsip_writable_mask = MIP_VSSIP;
 
 const bool valid_vm_1_10_32[16] = {
@@ -1298,7 +1299,8 @@ static RISCVException write_mstatush(CPURISCVState *env, 
int csrno,
 static RISCVException read_mstatus_i128(CPURISCVState *env, int csrno,
 Int128 *val)
 {
-*val = int128_make128(env->mstatus, add_status_sd(MXL_RV128, 
env->mstatus));
+*val = int128_make128(env->mstatus, add_status_sd(MXL_RV128,
+  env->mstatus));
 return RISCV_EXCP_NONE;
 }
 
@@ -2823,7 +2825,8 @@ static RISCVException write_hstatus(CPURISCVState *env, 
int csrno,
 {
 env->hstatus = val;
 if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
-qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN 
options.");
+qemu_log_mask(LOG_UNIMP,
+  "QEMU does not support mixed HSXLEN options.");
 }
 if (get_field(val, HSTATUS_VSBE) != 0) {
 qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
@@ -3490,9 +3493,9 @@ static RISCVException write_mmte(CPURISCVState *env, int 
csrno,
 target_ulong wpri_val = val & MMTE_MASK;
 
 if (val != wpri_val) {
-qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s" TARGET_FMT_lx 
"\n",
-  "MMTE: WPRI violation written 0x", val,
-  "vs expected 0x", wpri_val);
+

[PULL 41/89] target/riscv: remove cpu->cfg.ext_i

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "i" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVI. Instances of cpu->cfg.ext_i and similar are
replaced with riscv_has_ext(env, RVI).

Remove the old "i" property and 'ext_i' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-10-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h |  1 -
 target/riscv/cpu.c | 15 +++
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e5680b0709..479b654d54 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -422,7 +422,6 @@ typedef struct {
 } RISCVSATPMap;
 
 struct RISCVCPUConfig {
-bool ext_i;
 bool ext_e;
 bool ext_g;
 bool ext_m;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 715cbca1b3..f082748569 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -817,13 +817,12 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 CPURISCVState *env = >env;
 
 /* Do some ISA extension error checking */
-if (cpu->cfg.ext_g && !(cpu->cfg.ext_i && cpu->cfg.ext_m &&
+if (cpu->cfg.ext_g && !(riscv_has_ext(env, RVI) && cpu->cfg.ext_m &&
 riscv_has_ext(env, RVA) &&
 riscv_has_ext(env, RVF) &&
 riscv_has_ext(env, RVD) &&
 cpu->cfg.ext_icsr && cpu->cfg.ext_ifencei)) {
 warn_report("Setting G will also set IMAFD_Zicsr_Zifencei");
-cpu->cfg.ext_i = true;
 cpu->cfg.ext_m = true;
 cpu->cfg.ext_icsr = true;
 cpu->cfg.ext_ifencei = true;
@@ -832,13 +831,13 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 env->misa_ext_mask = env->misa_ext;
 }
 
-if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
+if (riscv_has_ext(env, RVI) && cpu->cfg.ext_e) {
 error_setg(errp,
"I and E extensions are incompatible");
 return;
 }
 
-if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) {
+if (!riscv_has_ext(env, RVI) && !cpu->cfg.ext_e) {
 error_setg(errp,
"Either I or E extension must be set");
 return;
@@ -850,7 +849,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 return;
 }
 
-if (cpu->cfg.ext_h && !cpu->cfg.ext_i) {
+if (cpu->cfg.ext_h && !riscv_has_ext(env, RVI)) {
 error_setg(errp,
"H depends on an I base integer ISA with 32 x registers");
 return;
@@ -1148,7 +1147,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 {
 uint32_t ext = 0;
 
-if (riscv_cpu_cfg(env)->ext_i) {
+if (riscv_has_ext(env, RVI)) {
 ext |= RVI;
 }
 if (riscv_cpu_cfg(env)->ext_e) {
@@ -1502,6 +1501,8 @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
  .misa_bit = RVD, .enabled = true},
 {.name = "f", .description = "Single-precision float point",
  .misa_bit = RVF, .enabled = true},
+{.name = "i", .description = "Base integer instruction set",
+ .misa_bit = RVI, .enabled = true},
 };
 
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
@@ -1524,7 +1525,6 @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj)
 
 static Property riscv_cpu_extensions[] = {
 /* Defaults for standard extensions */
-DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
 DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
 DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, false),
 DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
@@ -1644,7 +1644,6 @@ static void register_cpu_props(Object *obj)
  * later on.
  */
 if (cpu->env.misa_ext != 0) {
-cpu->cfg.ext_i = misa_ext & RVI;
 cpu->cfg.ext_e = misa_ext & RVE;
 cpu->cfg.ext_m = misa_ext & RVM;
 cpu->cfg.ext_v = misa_ext & RVV;
-- 
2.40.0




[PULL 38/89] target/riscv: remove cpu->cfg.ext_c

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

Create a new "c" RISCVCPUMisaExtConfig property that will update
env->misa_ext* with RVC. Instances of cpu->cfg.ext_c and similar are
replaced with riscv_has_ext(env, RVC).

Remove the old "c" property and 'ext_c' from RISCVCPUConfig.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-7-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h | 1 -
 target/riscv/cpu.c | 9 -
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1d1a17d85b..9a3847329c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -428,7 +428,6 @@ struct RISCVCPUConfig {
 bool ext_m;
 bool ext_f;
 bool ext_d;
-bool ext_c;
 bool ext_s;
 bool ext_u;
 bool ext_h;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 3770fd4f6f..2e00b8f20a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -407,7 +407,6 @@ static void rv64_thead_c906_cpu_init(Object *obj)
 set_priv_version(env, PRIV_VERSION_1_11_0);
 
 cpu->cfg.ext_g = true;
-cpu->cfg.ext_c = true;
 cpu->cfg.ext_u = true;
 cpu->cfg.ext_s = true;
 cpu->cfg.ext_icsr = true;
@@ -957,7 +956,7 @@ static void riscv_cpu_validate_set_extensions(RISCVCPU 
*cpu, Error **errp)
 }
 }
 
-if (cpu->cfg.ext_c) {
+if (riscv_has_ext(env, RVC)) {
 cpu->cfg.ext_zca = true;
 if (cpu->cfg.ext_f && env->misa_mxl_max == MXL_RV32) {
 cpu->cfg.ext_zcf = true;
@@ -1168,7 +1167,7 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 if (riscv_cpu_cfg(env)->ext_d) {
 ext |= RVD;
 }
-if (riscv_cpu_cfg(env)->ext_c) {
+if (riscv_has_ext(env, RVC)) {
 ext |= RVC;
 }
 if (riscv_cpu_cfg(env)->ext_s) {
@@ -1498,6 +1497,8 @@ static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, 
const char *name,
 static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
 {.name = "a", .description = "Atomic instructions",
  .misa_bit = RVA, .enabled = true},
+{.name = "c", .description = "Compressed instructions",
+ .misa_bit = RVC, .enabled = true},
 };
 
 static void riscv_cpu_add_misa_properties(Object *cpu_obj)
@@ -1526,7 +1527,6 @@ static Property riscv_cpu_extensions[] = {
 DEFINE_PROP_BOOL("m", RISCVCPU, cfg.ext_m, true),
 DEFINE_PROP_BOOL("f", RISCVCPU, cfg.ext_f, true),
 DEFINE_PROP_BOOL("d", RISCVCPU, cfg.ext_d, true),
-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),
@@ -1649,7 +1649,6 @@ static void register_cpu_props(Object *obj)
 cpu->cfg.ext_f = misa_ext & RVF;
 cpu->cfg.ext_d = misa_ext & RVD;
 cpu->cfg.ext_v = misa_ext & RVV;
-cpu->cfg.ext_c = misa_ext & RVC;
 cpu->cfg.ext_s = misa_ext & RVS;
 cpu->cfg.ext_u = misa_ext & RVU;
 cpu->cfg.ext_h = misa_ext & RVH;
-- 
2.40.0




[PULL 87/89] target/riscv: Fix Guest Physical Address Translation

2023-05-04 Thread Alistair Francis
From: Irina Ryapolova 

Before changing the flow check for sv39/48/57.

According to specification (for Supervisor mode):
Sv39 implementations support a 39-bit virtual address space, divided into 4 KiB
pages.
Instruction fetch addresses and load and store effective addresses, which are
64 bits,
must have bits 63–39 all equal to bit 38, or else a page-fault exception will
occur.
Likewise for Sv48 and Sv57.

So the high bits are equal to bit 38 for sv39.

According to specification (for Hypervisor mode):
For Sv39x4, address bits of the guest physical address 63:41 must all be zeros,
or else a
guest-page-fault exception occurs.

Likewise for Sv48x4 and Sv57x4.
For Sv48x4 address bits 63:50 must all be zeros, or else a guest-page-fault
exception occurs.
For Sv57x4 address bits 63:59 must all be zeros, or else a guest-page-fault
exception occurs.

For example we are trying to access address 0x__ff01_ with only
G-translation enabled.
So expected behavior is to generate exception. But qemu doesn't generate such
exception.

For the old check, we get
va_bits == 41, mask == (1 << 24) - 1, masked_msbs == (0x__ff01_ >>
40) & mask == mask.
Accordingly, the condition masked_msbs != 0 && masked_msbs != mask is not
fulfilled
and the check passes.

Signed-off-by: Irina Ryapolova 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230418075423.26217-1-irina.ryapol...@syntacore.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu_helper.c | 25 -
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 32a65f8007..b68dcfe7b6 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -837,17 +837,24 @@ static int get_physical_address(CPURISCVState *env, 
hwaddr *physical,
 
 CPUState *cs = env_cpu(env);
 int va_bits = PGSHIFT + levels * ptidxbits + widened;
-target_ulong mask, masked_msbs;
 
-if (TARGET_LONG_BITS > (va_bits - 1)) {
-mask = (1L << (TARGET_LONG_BITS - (va_bits - 1))) - 1;
-} else {
-mask = 0;
-}
-masked_msbs = (addr >> (va_bits - 1)) & mask;
+if (first_stage == true) {
+target_ulong mask, masked_msbs;
 
-if (masked_msbs != 0 && masked_msbs != mask) {
-return TRANSLATE_FAIL;
+if (TARGET_LONG_BITS > (va_bits - 1)) {
+mask = (1L << (TARGET_LONG_BITS - (va_bits - 1))) - 1;
+} else {
+mask = 0;
+}
+masked_msbs = (addr >> (va_bits - 1)) & mask;
+
+if (masked_msbs != 0 && masked_msbs != mask) {
+return TRANSLATE_FAIL;
+}
+} else {
+if (vm != VM_1_10_SV32 && addr >> va_bits != 0) {
+return TRANSLATE_FAIL;
+}
 }
 
 bool pbmte = env->menvcfg & MENVCFG_PBMTE;
-- 
2.40.0




[PULL 34/89] target/riscv: remove MISA properties from isa_edata_arr[]

2023-05-04 Thread Alistair Francis
From: Daniel Henrique Barboza 

The code that disables extensions if there's a priv version mismatch
uses cpu->cfg.ext_N properties to do its job.

We're aiming to not rely on cpu->cfg.ext_N props for MISA bits. Split
the MISA related verifications in a new function, removing it from
isa_edata_arr[].

We're also erroring it out instead of disabling, making the cpu_init()
function responsible for running an adequate priv spec for the MISA
extensions it wants to use.

Note that the RVV verification is being ignored since we're always have
at least PRIV_VERSION_1_10_0.

Signed-off-by: Daniel Henrique Barboza 
Reviewed-by: Weiwei Li 
Reviewed-by: Alistair Francis 
Message-Id: <20230406180351.570807-3-dbarb...@ventanamicro.com>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 66de3bb33f..ed8f36c649 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -72,10 +72,11 @@ struct isa_ext_data {
  * 4. Non-standard extensions (starts with 'X') must be listed after all
  *standard extensions. They must be separated from other multi-letter
  *extensions by an underscore.
+ *
+ * Single letter extensions are checked in riscv_cpu_validate_misa_priv()
+ * instead.
  */
 static const struct isa_ext_data isa_edata_arr[] = {
-ISA_EXT_DATA_ENTRY(h, false, PRIV_VERSION_1_12_0, ext_h),
-ISA_EXT_DATA_ENTRY(v, false, PRIV_VERSION_1_10_0, ext_v),
 ISA_EXT_DATA_ENTRY(zicbom, true, PRIV_VERSION_1_12_0, ext_icbom),
 ISA_EXT_DATA_ENTRY(zicboz, true, PRIV_VERSION_1_12_0, ext_icboz),
 ISA_EXT_DATA_ENTRY(zicond, true, PRIV_VERSION_1_12_0, ext_zicond),
@@ -1191,6 +1192,14 @@ static void riscv_cpu_sync_misa_cfg(CPURISCVState *env)
 env->misa_ext = env->misa_ext_mask = ext;
 }
 
+static void riscv_cpu_validate_misa_priv(CPURISCVState *env, Error **errp)
+{
+if (riscv_has_ext(env, RVH) && env->priv_ver < PRIV_VERSION_1_12_0) {
+error_setg(errp, "H extension requires priv spec 1.12.0");
+return;
+}
+}
+
 static void riscv_cpu_realize(DeviceState *dev, Error **errp)
 {
 CPUState *cs = CPU(dev);
@@ -1234,6 +1243,12 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
**errp)
  */
 riscv_cpu_sync_misa_cfg(env);
 
+riscv_cpu_validate_misa_priv(env, _err);
+if (local_err != NULL) {
+error_propagate(errp, local_err);
+return;
+}
+
 /* Force disable extensions if priv spec version does not match */
 for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
 if (isa_ext_is_enabled(cpu, _edata_arr[i]) &&
-- 
2.40.0




[PULL 64/89] target/riscv: Reduce overhead of MSTATUS_SUM change

2023-05-04 Thread Alistair Francis
From: Fei Wu 

Kernel needs to access user mode memory e.g. during syscalls, the window
is usually opened up for a very limited time through MSTATUS.SUM, the
overhead is too much if tlb_flush() gets called for every SUM change.

This patch creates a separate MMU index for S+SUM, so that it's not
necessary to flush tlb anymore when SUM changes. This is similar to how
ARM handles Privileged Access Never (PAN).

Result of 'pipe 10' from unixbench boosts from 223656 to 1705006. Many
other syscalls benefit a lot from this too.

Reviewed-by: Richard Henderson 
Signed-off-by: Fei Wu 
Message-Id: <20230324054154.414846-3-fei2...@intel.com>
Reviewed-by: LIU Zhiwei 
Reviewed-by: Alistair Francis 
Reviewed-by: Weiwei Li 
Tested-by: Daniel Henrique Barboza 
Message-Id: <20230325105429.1142530-8-richard.hender...@linaro.org>
Message-Id: <20230412114333.118895-8-richard.hender...@linaro.org>
Signed-off-by: Alistair Francis 
---
 target/riscv/cpu.h  |  2 --
 target/riscv/internals.h| 14 ++
 target/riscv/cpu_helper.c   | 17 +++--
 target/riscv/csr.c  |  3 +--
 target/riscv/op_helper.c|  5 +++--
 target/riscv/insn_trans/trans_rvh.c.inc |  4 ++--
 6 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 9b971ee1b0..6239c99f4c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -629,8 +629,6 @@ G_NORETURN void 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_PRIV_HYP_ACCESS_MASK   (1 << 2)
-
 #include "exec/cpu-all.h"
 
 FIELD(TB_FLAGS, MEM_IDX, 0, 3)
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
index 5620fbffb6..b55152a7dc 100644
--- a/target/riscv/internals.h
+++ b/target/riscv/internals.h
@@ -21,6 +21,20 @@
 
 #include "hw/registerfields.h"
 
+/*
+ * The current MMU Modes are:
+ *  - U 0b000
+ *  - S 0b001
+ *  - S+SUM 0b010
+ *  - M 0b011
+ *  - HLV/HLVX/HSV adds 0b100
+ */
+#define MMUIdx_U0
+#define MMUIdx_S1
+#define MMUIdx_S_SUM2
+#define MMUIdx_M3
+#define MMU_HYP_ACCESS_BIT  (1 << 2)
+
 /* share data between vector helpers and decode code */
 FIELD(VDATA, VM, 0, 1)
 FIELD(VDATA, LMUL, 1, 3)
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 36d6e422d7..174a77706b 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -21,6 +21,7 @@
 #include "qemu/log.h"
 #include "qemu/main-loop.h"
 #include "cpu.h"
+#include "internals.h"
 #include "pmu.h"
 #include "exec/exec-all.h"
 #include "instmap.h"
@@ -36,7 +37,19 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 #ifdef CONFIG_USER_ONLY
 return 0;
 #else
-return env->priv;
+if (ifetch) {
+return env->priv;
+}
+
+/* All priv -> mmu_idx mapping are here */
+int mode = env->priv;
+if (mode == PRV_M && get_field(env->mstatus, MSTATUS_MPRV)) {
+mode = get_field(env->mstatus, MSTATUS_MPP);
+}
+if (mode == PRV_S && get_field(env->mstatus, MSTATUS_SUM)) {
+return MMUIdx_S_SUM;
+}
+return mode;
 #endif
 }
 
@@ -588,7 +601,7 @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool 
enable)
 
 bool riscv_cpu_two_stage_lookup(int mmu_idx)
 {
-return mmu_idx & TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+return mmu_idx & MMU_HYP_ACCESS_BIT;
 }
 
 int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 92ad54411b..4a4d852bd1 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -1294,8 +1294,7 @@ static RISCVException write_mstatus(CPURISCVState *env, 
int csrno,
 val = legalize_mpp(env, get_field(mstatus, MSTATUS_MPP), val);
 
 /* flush tlb on mstatus fields that affect VM */
-if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
-MSTATUS_MPRV | MSTATUS_SUM)) {
+if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPV)) {
 tlb_flush(env_cpu(env));
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 0c10dd7a78..0adfd1ca9a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -20,6 +20,7 @@
 
 #include "qemu/osdep.h"
 #include "cpu.h"
+#include "internals.h"
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
@@ -428,14 +429,14 @@ void helper_hyp_gvma_tlb_flush(CPURISCVState *env)
 
 target_ulong helper_hyp_hlvx_hu(CPURISCVState *env, target_ulong address)
 {
-int mmu_idx = cpu_mmu_index(env, true) | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+int mmu_idx = cpu_mmu_index(env, true) | MMU_HYP_ACCESS_BIT;
 
 return cpu_lduw_mmuidx_ra(env, address, mmu_idx, GETPC());
 }
 
 target_ulong 

[PULL 82/89] hw/intc/riscv_aplic: Zero init APLIC internal state

2023-05-04 Thread Alistair Francis
From: Ivan Klokov 

Since g_new is used to initialize the RISCVAPLICState->state structure,
in some case we get behavior that is not as expected. This patch
changes this to g_new0, which allows to initialize the APLIC in the correct 
state.

Signed-off-by: Ivan Klokov 
Reviewed-by: Alistair Francis 
Reviewed-by: Anup Patel 
Message-Id: <20230413133432.53771-1-ivan.klo...@syntacore.com>
Signed-off-by: Alistair Francis 
---
 hw/intc/riscv_aplic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index cd7efc4ad4..afc5b54dbb 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -803,7 +803,7 @@ static void riscv_aplic_realize(DeviceState *dev, Error 
**errp)
 
 aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
 aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
-aplic->state = g_new(uint32_t, aplic->num_irqs);
+aplic->state = g_new0(uint32_t, aplic->num_irqs);
 aplic->target = g_new0(uint32_t, aplic->num_irqs);
 if (!aplic->msimode) {
 for (i = 0; i < aplic->num_irqs; i++) {
-- 
2.40.0




  1   2   3   4   5   >