This patch includes: - XVFCMP.cond.{S/D}. Signed-off-by: Song Gao <gaos...@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(-)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index 5d3904402d..c3bcb9d84a 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -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) diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index fbfd15d711..665bcb812a 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -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) diff --git a/target/loongarch/insn_trans/trans_lasx.c.inc b/target/loongarch/insn_trans/trans_lasx.c.inc index cc1b4fd42a..cdcd4a279a 100644 --- a/target/loongarch/insn_trans/trans_lasx.c.inc +++ b/target/loongarch/insn_trans/trans_lasx.c.inc @@ -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); diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 4e1f0b30a0..df45dc3d76 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -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 diff --git a/target/loongarch/lasx_helper.c b/target/loongarch/lasx_helper.c index d0bc02de72..1d56fe7b22 100644 --- a/target/loongarch/lasx_helper.c +++ b/target/loongarch/lasx_helper.c @@ -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) diff --git a/target/loongarch/lsx_helper.c b/target/loongarch/lsx_helper.c index 22d71cb39e..4a5c1a47a1 100644 --- a/target/loongarch/lsx_helper.c +++ b/target/loongarch/lsx_helper.c @@ -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; diff --git a/target/loongarch/vec.h b/target/loongarch/vec.h index 54fd2689f3..134dd265bf 100644 --- a/target/loongarch/vec.h +++ b/target/loongarch/vec.h @@ -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 */ -- 2.39.1