qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC PATCH 37/43] target/loongarch: Implement vfcmp


From: Song Gao
Subject: [RFC PATCH 37/43] target/loongarch: Implement vfcmp
Date: Sat, 24 Dec 2022 16:16:27 +0800

This patch includes:
- VFCMP.cond.{S/D}.

Signed-off-by: Song Gao <gaosong@loongson.cn>
---
 target/loongarch/disas.c                    | 94 +++++++++++++++++++++
 target/loongarch/helper.h                   |  9 ++
 target/loongarch/insn_trans/trans_lsx.c.inc | 30 +++++++
 target/loongarch/insns.decode               |  5 ++
 target/loongarch/lsx_helper.c               | 38 +++++++++
 5 files changed, 176 insertions(+)

diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index c854742f6d..0ea5418e5e 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -1418,3 +1418,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 b8f22a2601..9d8ade9dc8 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -768,3 +768,12 @@ DEF_HELPER_4(vslti_bu, void, env, i32, i32, i32)
 DEF_HELPER_4(vslti_hu, void, env, i32, i32, i32)
 DEF_HELPER_4(vslti_wu, void, env, i32, i32, i32)
 DEF_HELPER_4(vslti_du, void, env, i32, i32, i32)
+
+/* vfcmp.cXXX.s */
+DEF_HELPER_5(vfcmp_c_s, void, env, i32, i32, i32, i32)
+/* vfcmp.sXXX.s */
+DEF_HELPER_5(vfcmp_s_s, void, env, i32, i32, i32, i32)
+/* vfcmp.cXXX.d */
+DEF_HELPER_5(vfcmp_c_d, void, env, i32, i32, i32, i32)
+/* vfcmp.sXXX.d */
+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 90b3e88229..522d660113 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -698,3 +698,33 @@ TRANS(vslti_bu, gen_vv_i, gen_helper_vslti_bu)
 TRANS(vslti_hu, gen_vv_i, gen_helper_vslti_hu)
 TRANS(vslti_wu, gen_vv_i, gen_helper_vslti_wu)
 TRANS(vslti_du, gen_vv_i, gen_helper_vslti_du)
+
+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);
+
+    fn = (a->fcond & 1 ? gen_helper_vfcmp_s_s : gen_helper_vfcmp_c_s);
+    flags = get_fcmp_flags(a->fcond >> 1);
+    fn(cpu_env, vd, vj, vk,  tcg_constant_i32(flags));
+
+    return true;
+}
+
+static bool trans_vfcmp_cond_d(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);
+
+    fn = (a->fcond & 1 ? gen_helper_vfcmp_s_d : gen_helper_vfcmp_c_d);
+    flags = get_fcmp_flags(a->fcond >> 1);
+    fn(cpu_env, vd, vj, vk, tcg_constant_i32(flags));
+
+    return true;
+}
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 965ee486e1..5b4114c39b 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -493,6 +493,7 @@ dbcl             0000 00000010 10101 ...............      
@i15
 &vvv          vd vj vk
 &vv_i         vd vj imm
 &vvvv         vd vj vk va
+&vvv_fcond    vd vj vk fcond
 
 #
 # LSX Formats
@@ -507,6 +508,7 @@ dbcl             0000 00000010 10101 ...............      
@i15
 @vv_ui8              .... ........ .. imm:8 vj:5 vd:5    &vv_i
 @vv_i5           .... ........ ..... imm:s5 vj:5 vd:5    &vv_i
 @vvvv               .... ........ va:5 vk:5 vj:5 vd:5    &vvvv
+@vvv_fcond      .... ........ fcond:5  vk:5 vj:5 vd:5    &vvv_fcond
 
 vadd_b           0111 00000000 10100 ..... ..... .....    @vvv
 vadd_h           0111 00000000 10101 ..... ..... .....    @vvv
@@ -1144,3 +1146,6 @@ vslti_bu         0111 00101000 10000 ..... ..... .....    
@vv_ui5
 vslti_hu         0111 00101000 10001 ..... ..... .....    @vv_ui5
 vslti_wu         0111 00101000 10010 ..... ..... .....    @vv_ui5
 vslti_du         0111 00101000 10011 ..... ..... .....    @vv_ui5
+
+vfcmp_cond_s     0000 11000101 ..... ..... ..... .....    @vvv_fcond
+vfcmp_cond_d     0000 11000110 ..... ..... ..... .....    @vvv_fcond
diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c
index 977a095e79..1e5a1d989a 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -4237,3 +4237,41 @@ DO_HELPER_VVV(vslti_bu, 8, helper_vv_i, do_vslti_u)
 DO_HELPER_VVV(vslti_hu, 16, helper_vv_i, do_vslti_u)
 DO_HELPER_VVV(vslti_wu, 32, helper_vv_i, do_vslti_u)
 DO_HELPER_VVV(vslti_du, 64, helper_vv_i, do_vslti_u)
+
+#define LSX_FCMP_S(name)                                            \
+void helper_v## name ##_s(CPULoongArchState *env, uint32_t vd,      \
+                          uint32_t vj, uint32_t vk, uint32_t flags) \
+{                                                                   \
+    int ret;                                                        \
+    int i;                                                          \
+    vec_t *Vd = &(env->fpr[vd].vec);                                \
+    vec_t *Vj = &(env->fpr[vj].vec);                                \
+    vec_t *Vk = &(env->fpr[vk].vec);                                \
+                                                                    \
+    for (i = 0; i < 4; i++) {                                       \
+        ret = helper_## name ## _s(env, Vj->W[i], Vk->W[i], flags); \
+        Vd->W[i] = (ret == 1) ? -1 : 0;                             \
+    }                                                               \
+}
+
+LSX_FCMP_S(fcmp_c)
+LSX_FCMP_S(fcmp_s)
+
+#define LSX_FCMP_D(name)                                            \
+void helper_v## name ##_d(CPULoongArchState *env, uint32_t vd,      \
+                          uint32_t vj, uint32_t vk, uint32_t flags) \
+{                                                                   \
+    int ret;                                                        \
+    int i;                                                          \
+    vec_t *Vd = &(env->fpr[vd].vec);                                \
+    vec_t *Vj = &(env->fpr[vj].vec);                                \
+    vec_t *Vk = &(env->fpr[vk].vec);                                \
+                                                                    \
+    for (i = 0; i < 2; i++) {                                       \
+        ret = helper_## name ## _d(env, Vj->D[i], Vk->D[i], flags); \
+        Vd->D[i] = (ret == 1) ? -1 : 0;                             \
+    }                                                               \
+}
+
+LSX_FCMP_D(fcmp_c)
+LSX_FCMP_D(fcmp_s)
-- 
2.31.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]