On 8/30/23 01:48, Song Gao wrote:
+#ifndef CONFIG_USER_ONLY
+ #define CHECK_VEC do { \
+     if ((ctx->vl == LSX_LEN) && \
+         (ctx->base.tb->flags & HW_FLAGS_EUEN_SXE) == 0) { \
+         generate_exception(ctx, EXCCODE_SXD); \
+         return true; \
+     } \
+     if ((ctx->vl == LASX_LEN) && \
+         (ctx->base.tb->flags & HW_FLAGS_EUEN_ASXE) == 0) { \
+         generate_exception(ctx, EXCCODE_ASXD); \
+         return true; \
+     } \
+ } while (0)
+#else
+ #define CHECK_VEC
+#endif /*!CONFIG_USER_ONLY */

I think this is wrong. The check would seem to be determined by the instruction (oprsz) rather than a fixed configuration of the cpu (vl).

You're also replacing

-#ifndef CONFIG_USER_ONLY
-#define CHECK_ASXE do { \
-    if ((ctx->base.tb->flags & HW_FLAGS_EUEN_ASXE) == 0) { \
-        generate_exception(ctx, EXCCODE_ASXD); \
-        return true; \
-    } \
-} while (0)
-#else
-#define CHECK_ASXE
-#endif

this, the correct test, which you just added in patch 3.


+TRANS(xvadd_b, LASX, gvec_vvv, 32, MO_8, tcg_gen_gvec_add)
+TRANS(xvadd_h, LASX, gvec_vvv, 32, MO_16, tcg_gen_gvec_add)
+TRANS(xvadd_w, LASX, gvec_vvv, 32, MO_32, tcg_gen_gvec_add)
+TRANS(xvadd_d, LASX, gvec_vvv, 32, MO_64, tcg_gen_gvec_add)

The size of the changes required to add oprsz to gen_vvv would seem to be an poor choice. If you do go that way, all of the LSX changes would need to be a separate patch.

Perhaps better as

static bool gvec_vvv_vl(DisasContext *ctx, arg_vvv *a, uint32_t oprsz, MemOp 
mop,
                        void (*func)(unsigned, uint32_t, uint32_t,
                                     uint32_t, uint32_t, uint32_t))
{
    uint32_t vd_ofs = vec_full_offset(a->vd);
    uint32_t vj_ofs = vec_full_offset(a->vj);
    uint32_t vk_ofs = vec_full_offset(a->vk);

    func(mop, vd_ofs, vj_ofs, vk_ofs, oprsz, ctx->vl / 8);
    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))
{
    CHECK_SXE;
    return gvec_vvv_vl(ctx, a, 16, mop, func);
}

static bool gvec_xxx(DisasContext *ctx, arg_vvv *a, MemOp mop,
                     void (*func)(unsigned, uint32_t, uint32_t,
                                  uint32_t, uint32_t, uint32_t))
{
    CHECK_ASXE;
    return gvec_vvv_vl(ctx, a, 32, mop, func);
}

so that you don't have to replicate "16" or "32" across each instruction.


+#define XVADDSUB_Q(NAME)                                         \
+static bool trans_xv## NAME ##_q(DisasContext *ctx, arg_vvv * a) \
+{                                                                \
+    TCGv_i64 rh, rl, ah, al, bh, bl;                             \
+    int i;                                                       \
+                                                                 \
+    if (!avail_LASX(ctx)) {                                      \
+        return false;                                            \
+    }                                                            \
+                                                                 \
+    CHECK_VEC;                                                   \
+                                                                 \
+    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();                                     \
+                                                                 \
+    for (i = 0; i < 2; i++) {                                    \
+        get_vreg64(ah, a->vj, 1 + i * 2);                        \
+        get_vreg64(al, a->vj, 0 + i * 2);                        \
+        get_vreg64(bh, a->vk, 1 + i * 2);                        \
+        get_vreg64(bl, a->vk, 0 + i * 2);                        \
+                                                                 \
+        tcg_gen_## NAME ##2_i64(rl, rh, al, ah, bl, bh);         \
+                                                                 \
+        set_vreg64(rh, a->vd, 1 + i * 2);                        \
+        set_vreg64(rl, a->vd, 0 + i * 2);                        \
+   }                                                             \
+                                                                 \
+    return true;                                                 \
+}

This should be a function, not a macro, passing in tcg_gen_{add,sub}2_i64.

+
+XVADDSUB_Q(add)
+XVADDSUB_Q(sub)

Which lets these be normal TRANS expansions.



r~

Reply via email to