[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[RFC PATCH v2 37/44] target/loongarch: Implement vfcmp
From: |
Song Gao |
Subject: |
[RFC PATCH v2 37/44] target/loongarch: Implement vfcmp |
Date: |
Tue, 28 Mar 2023 11:06:24 +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 | 5 ++
target/loongarch/insn_trans/trans_lsx.c.inc | 32 +++++++
target/loongarch/insns.decode | 5 ++
target/loongarch/lsx_helper.c | 51 +++++++++++
5 files changed, 187 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 25ea9b633d..ef0b67349d 100644
--- a/target/loongarch/helper.h
+++ b/target/loongarch/helper.h
@@ -650,3 +650,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 7368731424..593b8b481d 100644
--- a/target/loongarch/insn_trans/trans_lsx.c.inc
+++ b/target/loongarch/insn_trans/trans_lsx.c.inc
@@ -3131,3 +3131,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);
+
+ CHECK_SXE;
+
+ 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 a090a7d22b..d018b110cd 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -494,6 +494,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
@@ -508,6 +509,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
@@ -1145,3 +1147,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 9ed7afdf6d..51b784e885 100644
--- a/target/loongarch/lsx_helper.c
+++ b/target/loongarch/lsx_helper.c
@@ -2921,3 +2921,54 @@ VCMPI(vslti_bu, 8, uint8_t, B, VSLT)
VCMPI(vslti_hu, 16, uint16_t, H, VSLT)
VCMPI(vslti_wu, 32, uint32_t, W, VSLT)
VCMPI(vslti_du, 64, uint64_t, D, VSLT)
+
+static uint64_t vfcmp_common(CPULoongArchState *env,
+ FloatRelation cmp, uint32_t flags)
+{
+ bool ret;
+
+ switch (cmp) {
+ case float_relation_less:
+ ret = (flags & FCMP_LT);
+ break;
+ case float_relation_equal:
+ ret = (flags & FCMP_EQ);
+ break;
+ case float_relation_greater:
+ ret = (flags & FCMP_GT);
+ break;
+ case float_relation_unordered:
+ ret = (flags & FCMP_UN);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+
+ return ret;
+}
+
+#define VFCMP(NAME, BIT, T, E, FN) \
+void HELPER(NAME)(CPULoongArchState *env, \
+ uint32_t vd, uint32_t vj, uint32_t vk, uint32_t flags) \
+{ \
+ int i; \
+ VReg t; \
+ VReg *Vd = &(env->fpr[vd].vreg); \
+ VReg *Vj = &(env->fpr[vj].vreg); \
+ VReg *Vk = &(env->fpr[vk].vreg); \
+ \
+ vec_clear_cause(env); \
+ for (i = 0; i < LSX_LEN/BIT ; i++) { \
+ FloatRelation cmp; \
+ cmp = FN(Vj->E(i), Vk->E(i), &env->fp_status); \
+ t.E(i) = (vfcmp_common(env, cmp, flags)) ? -1 : 0; \
+ vec_update_fcsr0(env, GETPC()); \
+ } \
+ Vd->D(0) = t.D(0); \
+ Vd->D(1) = t.D(1); \
+}
+
+VFCMP(vfcmp_c_s, 32, uint32_t, W, float32_compare_quiet)
+VFCMP(vfcmp_s_s, 32, uint32_t, W, float32_compare)
+VFCMP(vfcmp_c_d, 64, uint64_t, D, float64_compare_quiet)
+VFCMP(vfcmp_s_d, 64, uint64_t, D, float64_compare)
--
2.31.1
- [RFC PATCH v2 21/44] target/loongarch: Implement vmskltz/vmskgez/vmsknz, (continued)
- [RFC PATCH v2 21/44] target/loongarch: Implement vmskltz/vmskgez/vmsknz, Song Gao, 2023/03/27
- [RFC PATCH v2 22/44] target/loongarch: Implement LSX logic instructions, Song Gao, 2023/03/27
- [RFC PATCH v2 14/44] target/loongarch: Implement vmax/vmin, Song Gao, 2023/03/27
- [RFC PATCH v2 20/44] target/loongarch: Implement vsigncov, Song Gao, 2023/03/27
- [RFC PATCH v2 24/44] target/loongarch: Implement vsllwil vextl, Song Gao, 2023/03/27
- [RFC PATCH v2 23/44] target/loongarch: Implement vsll vsrl vsra vrotr, Song Gao, 2023/03/27
- [RFC PATCH v2 31/44] target/loongarch: Implement vpcnt, Song Gao, 2023/03/27
- [RFC PATCH v2 30/44] target/loongarch: Implement vclo vclz, Song Gao, 2023/03/27
- [RFC PATCH v2 33/44] target/loongarch: Implement vfrstp, Song Gao, 2023/03/27
- [RFC PATCH v2 36/44] target/loongarch: Implement vseq vsle vslt, Song Gao, 2023/03/27
- [RFC PATCH v2 37/44] target/loongarch: Implement vfcmp,
Song Gao <=
- [RFC PATCH v2 38/44] target/loongarch: Implement vbitsel vset, Song Gao, 2023/03/27
- [RFC PATCH v2 18/44] target/loongarch: Implement vsat, Song Gao, 2023/03/27
- [RFC PATCH v2 42/44] target/loongarch: Implement vld vst, Song Gao, 2023/03/27
- [RFC PATCH v2 40/44] target/loongarch: Implement vreplve vpack vpick, Song Gao, 2023/03/27
- [RFC PATCH v2 43/44] target/loongarch: Implement vldi, Song Gao, 2023/03/27
- [RFC PATCH v2 41/44] target/loongarch: Implement vilvl vilvh vextrins vshuf, Song Gao, 2023/03/27
- [RFC PATCH v2 44/44] target/loongarch: Use {set/get}_gpr replace to cpu_fpr, Song Gao, 2023/03/27
- [RFC PATCH v2 26/44] target/loongarch: Implement vsrln vsran, Song Gao, 2023/03/27
- [RFC PATCH v2 25/44] target/loongarch: Implement vsrlr vsrar, Song Gao, 2023/03/27
- [RFC PATCH v2 17/44] target/loongarch: Implement vdiv/vmod, Song Gao, 2023/03/27