Re: [PATCH 11/57] target/arm: Convert Advanced SIMD copy to decodetree

2024-05-23 Thread Peter Maydell
On Mon, 6 May 2024 at 02:06, Richard Henderson
 wrote:
>
> Signed-off-by: Richard Henderson 
> ---
>  target/arm/tcg/a64.decode  |  13 +
>  target/arm/tcg/translate-a64.c | 426 +++--
>  2 files changed, 152 insertions(+), 287 deletions(-)
>

Reviewed-by: Peter Maydell 

thanks
-- PMM



[PATCH 11/57] target/arm: Convert Advanced SIMD copy to decodetree

2024-05-05 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/arm/tcg/a64.decode  |  13 +
 target/arm/tcg/translate-a64.c | 426 +++--
 2 files changed, 152 insertions(+), 287 deletions(-)

diff --git a/target/arm/tcg/a64.decode b/target/arm/tcg/a64.decode
index 7f354af25d..d5bfeae7a8 100644
--- a/target/arm/tcg/a64.decode
+++ b/target/arm/tcg/a64.decode
@@ -658,3 +658,16 @@ SM3TT2B 11001110 010 . 10 .. 11 . . 
@crypto3i
 ### Cryptographic XAR
 
 XAR 1100 1110 100 rm:5 imm:6 rn:5 rd:5
+
+### Advanced SIMD scalar copy
+
+DUP_element_s   0101 1110 000 imm:5 0  1 rn:5 rd:5
+
+### Advanced SIMD copy
+
+DUP_element_v   0 q:1 00 1110 000 imm:5 0  1 rn:5 rd:5
+DUP_general 0 q:1 00 1110 000 imm:5 0 0001 1 rn:5 rd:5
+INS_general 0 1   00 1110 000 imm:5 0 0011 1 rn:5 rd:5
+SMOV0 q:1 00 1110 000 imm:5 0 0101 1 rn:5 rd:5
+UMOV0 q:1 00 1110 000 imm:5 0 0111 1 rn:5 rd:5
+INS_element 0 1   10 1110 000 di:5  0 si:4 1 rn:5 rd:5
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
index 5e99b6494e..4860b59d18 100644
--- a/target/arm/tcg/translate-a64.c
+++ b/target/arm/tcg/translate-a64.c
@@ -4703,6 +4703,145 @@ static bool trans_XAR(DisasContext *s, arg_XAR *a)
 return true;
 }
 
+/*
+ * Advanced SIMD copy
+ */
+
+static bool decode_esz_idx(int imm, MemOp *pesz, unsigned *pidx)
+{
+unsigned esz = ctz32(imm);
+if (esz <= MO_64) {
+*pesz = esz;
+*pidx = imm >> (esz + 1);
+return true;
+}
+return false;
+}
+
+static bool trans_DUP_element_s(DisasContext *s, arg_DUP_element_s *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (fp_access_check(s)) {
+/*
+ * This instruction just extracts the specified element and
+ * zero-extends it into the bottom of the destination register.
+ */
+TCGv_i64 tmp = tcg_temp_new_i64();
+read_vec_element(s, tmp, a->rn, idx, esz);
+write_fp_dreg(s, a->rd, tmp);
+}
+return true;
+}
+
+static bool trans_DUP_element_v(DisasContext *s, arg_DUP_element_v *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (esz == MO_64 && !a->q) {
+return false;
+}
+if (fp_access_check(s)) {
+tcg_gen_gvec_dup_mem(esz, vec_full_reg_offset(s, a->rd),
+ vec_reg_offset(s, a->rn, idx, esz),
+ a->q ? 16 : 8, vec_full_reg_size(s));
+}
+return true;
+}
+
+static bool trans_DUP_general(DisasContext *s, arg_DUP_general *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (esz == MO_64 && !a->q) {
+return false;
+}
+if (fp_access_check(s)) {
+tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
+ a->q ? 16 : 8, vec_full_reg_size(s),
+ cpu_reg(s, a->rn));
+}
+return true;
+}
+
+static bool do_smov_umov(DisasContext *s, arg_SMOV *a, MemOp is_signed)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (is_signed) {
+if (esz == MO_64 || (esz == MO_32 && !a->q)) {
+return false;
+}
+} else {
+if (esz == MO_64 ? !a->q : a->q) {
+return false;
+}
+}
+if (fp_access_check(s)) {
+TCGv_i64 tcg_rd = cpu_reg(s, a->rd);
+read_vec_element(s, tcg_rd, a->rn, idx, esz | is_signed);
+if (is_signed && !a->q) {
+tcg_gen_ext32u_i64(tcg_rd, tcg_rd);
+}
+}
+return true;
+}
+
+TRANS(SMOV, do_smov_umov, a, MO_SIGN)
+TRANS(UMOV, do_smov_umov, a, 0)
+
+static bool trans_INS_general(DisasContext *s, arg_INS_general *a)
+{
+MemOp esz;
+unsigned idx;
+
+if (!decode_esz_idx(a->imm, , )) {
+return false;
+}
+if (fp_access_check(s)) {
+write_vec_element(s, cpu_reg(s, a->rn), a->rd, idx, esz);
+clear_vec_high(s, true, a->rd);
+}
+return true;
+}
+
+static bool trans_INS_element(DisasContext *s, arg_INS_element *a)
+{
+MemOp esz;
+unsigned didx, sidx;
+
+if (!decode_esz_idx(a->di, , )) {
+return false;
+}
+sidx = a->si >> esz;
+if (fp_access_check(s)) {
+TCGv_i64 tmp = tcg_temp_new_i64();
+
+read_vec_element(s, tmp, a->rn, sidx, esz);
+write_vec_element(s, tmp, a->rd, didx, esz);
+
+/* INS is considered a 128-bit write for SVE. */
+clear_vec_high(s, true, a->rd);
+}
+return true;
+}
+
 /* Shift a TCGv src by TCGv shift_amount, put result in dst.
  * Note that it is the caller's responsibility to ensure that the
  * shift amount is in range (ie 0..31 or 0..63) and provide the ARM
@@ -7761,268 +7900,6 @@ static void disas_simd_across_lanes(DisasContext