@@ -2384,6 +2384,100 @@ INSN_LASX(xvslti_hu, xx_i)
INSN_LASX(xvslti_wu, xx_i)
INSN_LASX(xvslti_du, xx_i)
+#define output_xvfcmp(C, PREFIX, SUFFIX) \
+{ \
+ (C)->info->fprintf_func((C)->info->stream, "%08x %s%s\tx%d, x%d, x%d", \
+ (C)->insn, PREFIX, SUFFIX, a->xd, \
+ a->xj, a->xk); \
+}
+
+static bool output_xxx_fcond(DisasContext *ctx, arg_xxx_fcond * a,
+ const char *suffix)
+{
+ bool ret = true;
+ switch (a->fcond) {
+ case 0x0:
+ output_xvfcmp(ctx, "xvfcmp_caf_", suffix);
+ break;
+ case 0x1:
+ output_xvfcmp(ctx, "xvfcmp_saf_", suffix);
+ break;
+ case 0x2:
+ output_xvfcmp(ctx, "xvfcmp_clt_", suffix);
+ break;
+ case 0x3:
+ output_xvfcmp(ctx, "xvfcmp_slt_", suffix);
+ break;
+ case 0x4:
+ output_xvfcmp(ctx, "xvfcmp_ceq_", suffix);
+ break;
+ case 0x5:
+ output_xvfcmp(ctx, "xvfcmp_seq_", suffix);
+ break;
+ case 0x6:
+ output_xvfcmp(ctx, "xvfcmp_cle_", suffix);
+ break;
+ case 0x7:
+ output_xvfcmp(ctx, "xvfcmp_sle_", suffix);
+ break;
+ case 0x8:
+ output_xvfcmp(ctx, "xvfcmp_cun_", suffix);
+ break;
+ case 0x9:
+ output_xvfcmp(ctx, "xvfcmp_sun_", suffix);
+ break;
+ case 0xA:
+ output_xvfcmp(ctx, "xvfcmp_cult_", suffix);
+ break;
+ case 0xB:
+ output_xvfcmp(ctx, "xvfcmp_sult_", suffix);
+ break;
+ case 0xC:
+ output_xvfcmp(ctx, "xvfcmp_cueq_", suffix);
+ break;
+ case 0xD:
+ output_xvfcmp(ctx, "xvfcmp_sueq_", suffix);
+ break;
+ case 0xE:
+ output_xvfcmp(ctx, "xvfcmp_cule_", suffix);
+ break;
+ case 0xF:
+ output_xvfcmp(ctx, "xvfcmp_sule_", suffix);
+ break;
+ case 0x10:
+ output_xvfcmp(ctx, "xvfcmp_cne_", suffix);
+ break;
+ case 0x11:
+ output_xvfcmp(ctx, "xvfcmp_sne_", suffix);
+ break;
+ case 0x14:
+ output_xvfcmp(ctx, "xvfcmp_cor_", suffix);
+ break;
+ case 0x15:
+ output_xvfcmp(ctx, "xvfcmp_sor_", suffix);
+ break;
+ case 0x18:
+ output_xvfcmp(ctx, "xvfcmp_cune_", suffix);
+ break;
+ case 0x19:
+ output_xvfcmp(ctx, "xvfcmp_sune_", suffix);
+ break;
+ default:
+ ret = false;
+ }
+ return ret;
+}
+
+#define LASX_FCMP_INSN(suffix) \
+static bool trans_xvfcmp_cond_##suffix(DisasContext *ctx, \
+ arg_xxx_fcond * a) \
+{ \
+ return output_xxx_fcond(ctx, a, #suffix); \
+}
+
+LASX_FCMP_INSN(s)
+LASX_FCMP_INSN(d)
+
INSN_LASX(xvreplgr2vr_b, xr)
INSN_LASX(xvreplgr2vr_h, xr)
INSN_LASX(xvreplgr2vr_w, xr)
@@ -1216,3 +1216,8 @@ DEF_HELPER_FLAGS_4(xvslti_bu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
DEF_HELPER_FLAGS_4(xvslti_hu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
DEF_HELPER_FLAGS_4(xvslti_wu, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
DEF_HELPER_FLAGS_4(xvslti_du, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32)
+
+DEF_HELPER_5(xvfcmp_c_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(xvfcmp_s_s, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(xvfcmp_c_d, void, env, i32, i32, i32, i32)
+DEF_HELPER_5(xvfcmp_s_d, void, env, i32, i32, i32, i32)
@@ -2674,6 +2674,38 @@ TRANS(xvslti_hu, do_xvslti_u, MO_16)
TRANS(xvslti_wu, do_xvslti_u, MO_32)
TRANS(xvslti_du, do_xvslti_u, MO_64)
+static bool trans_xvfcmp_cond_s(DisasContext *ctx, arg_xxx_fcond * a)
+{
+ uint32_t flags;
+ void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
+ TCGv_i32 xd = tcg_constant_i32(a->xd);
+ TCGv_i32 xj = tcg_constant_i32(a->xj);
+ TCGv_i32 xk = tcg_constant_i32(a->xk);
+
+ CHECK_SXE;
+
+ fn = (a->fcond & 1 ? gen_helper_xvfcmp_s_s : gen_helper_xvfcmp_c_s);
+ flags = get_fcmp_flags(a->fcond >> 1);
+ fn(cpu_env, xd, xj, xk, tcg_constant_i32(flags));
+
+ return true;
+}
+
+static bool trans_xvfcmp_cond_d(DisasContext *ctx, arg_xxx_fcond *a)
+{
+ uint32_t flags;
+ void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32);
+ TCGv_i32 xd = tcg_constant_i32(a->xd);
+ TCGv_i32 xj = tcg_constant_i32(a->xj);
+ TCGv_i32 xk = tcg_constant_i32(a->xk);
+
+ fn = (a->fcond & 1 ? gen_helper_xvfcmp_s_d : gen_helper_xvfcmp_c_d);
+ flags = get_fcmp_flags(a->fcond >> 1);
+ fn(cpu_env, xd, xj, xk, tcg_constant_i32(flags));
+
+ return true;
+}
+
static bool gvec_dupx(DisasContext *ctx, arg_xr *a, MemOp mop)
{
TCGv src = gpr_src(ctx, a->rj, EXT_NONE);
@@ -1307,6 +1307,7 @@ vstelm_b 0011 000110 .... ........ ..... ..... @vr_i8i4
&xx_i xd xj imm
&x_i xd imm
&xxxx xd xj xk xa
+&xxx_fcond xd xj xk fcond
#
# LASX Formats
@@ -1324,6 +1325,7 @@ vstelm_b 0011 000110 .... ........ ..... ..... @vr_i8i4
@xx_ui7 .... ........ ... imm:7 xj:5 xd:5 &xx_i
@xx_ui8 .... ........ .. imm:8 xj:5 xd:5 &xx_i
@xxxx .... ........ xa:5 xk:5 xj:5 xd:5 &xxxx
+@xxx_fcond .... ........ fcond:5 xk:5 xj:5 xd:5 &xxx_fcond
xvadd_b 0111 01000000 10100 ..... ..... ..... @xxx
xvadd_h 0111 01000000 10101 ..... ..... ..... @xxx
@@ -1983,6 +1985,9 @@ xvslti_hu 0111 01101000 10001 ..... ..... ..... @xx_ui5
xvslti_wu 0111 01101000 10010 ..... ..... ..... @xx_ui5
xvslti_du 0111 01101000 10011 ..... ..... ..... @xx_ui5
+xvfcmp_cond_s 0000 11001001 ..... ..... ..... ..... @xxx_fcond
+xvfcmp_cond_d 0000 11001010 ..... ..... ..... ..... @xxx_fcond
+
xvreplgr2vr_b 0111 01101001 11110 00000 ..... ..... @xr
xvreplgr2vr_h 0111 01101001 11110 00001 ..... ..... @xr
xvreplgr2vr_w 0111 01101001 11110 00010 ..... ..... @xr
@@ -2757,3 +2757,28 @@ XVCMPI(xvslti_bu, 8, UXB, VSLT)
XVCMPI(xvslti_hu, 16, UXH, VSLT)
XVCMPI(xvslti_wu, 32, UXW, VSLT)
XVCMPI(xvslti_du, 64, UXD, VSLT)
+
+#define XVFCMP(NAME, BIT, E, FN) \
+void HELPER(NAME)(CPULoongArchState *env, \
+ uint32_t xd, uint32_t xj, uint32_t xk, uint32_t flags) \
+{ \
+ int i; \
+ XReg t; \
+ XReg *Xd = &(env->fpr[xd].xreg); \
+ XReg *Xj = &(env->fpr[xj].xreg); \
+ XReg *Xk = &(env->fpr[xk].xreg); \
+ \
+ vec_clear_cause(env); \
+ for (i = 0; i < LASX_LEN / BIT ; i++) { \
+ FloatRelation cmp; \
+ cmp = FN(Xj->E(i), Xk->E(i), &env->fp_status); \
+ t.E(i) = vfcmp_common(env, cmp, flags); \
+ vec_update_fcsr0(env, GETPC()); \
+ } \
+ *Xd = t; \
+}
+
+XVFCMP(xvfcmp_c_s, 32, UXW, float32_compare_quiet)
+XVFCMP(xvfcmp_s_s, 32, UXW, float32_compare)
+XVFCMP(xvfcmp_c_d, 64, UXD, float64_compare_quiet)
+XVFCMP(xvfcmp_s_d, 64, UXD, float64_compare)
@@ -2622,8 +2622,8 @@ VCMPI(vslti_hu, 16, UH, VSLT)
VCMPI(vslti_wu, 32, UW, VSLT)
VCMPI(vslti_du, 64, UD, VSLT)
-static uint64_t vfcmp_common(CPULoongArchState *env,
- FloatRelation cmp, uint32_t flags)
+uint64_t vfcmp_common(CPULoongArchState *env,
+ FloatRelation cmp, uint32_t flags)
{
uint64_t ret = 0;
@@ -8,6 +8,8 @@
#ifndef LOONGARCH_VEC_H
#define LOONGARCH_VEC_H
+#include "fpu/softfloat.h"
+
#if HOST_BIG_ENDIAN
#define B(x) B[15 - (x)]
#define H(x) H[7 - (x)]
@@ -113,4 +115,7 @@ uint64_t do_frecip_64(CPULoongArchState *env, uint64_t fj);
uint32_t do_frsqrt_32(CPULoongArchState *env, uint32_t fj);
uint64_t do_frsqrt_64(CPULoongArchState *env, uint64_t fj);
+uint64_t vfcmp_common(CPULoongArchState *env,
+ FloatRelation cmp, uint32_t flags);
+
#endif /* LOONGARCH_VEC_H */
This patch includes: - XVFCMP.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_lasx.c.inc | 32 +++++++ target/loongarch/insns.decode | 5 ++ target/loongarch/lasx_helper.c | 25 ++++++ target/loongarch/lsx_helper.c | 4 +- target/loongarch/vec.h | 5 ++ 7 files changed, 168 insertions(+), 2 deletions(-)