This patch includes: - XVFCMP.cond.{S/D}. Signed-off-by: Song Gao <gaos...@loongson.cn> --- target/loongarch/helper.h | 8 +- target/loongarch/insns.decode | 3 + target/loongarch/disas.c | 94 ++++++++++++++++++++ target/loongarch/vec_helper.c | 4 +- target/loongarch/insn_trans/trans_lasx.c.inc | 3 + target/loongarch/insn_trans/trans_lsx.c.inc | 17 ++-- 6 files changed, 117 insertions(+), 12 deletions(-)
diff --git a/target/loongarch/helper.h b/target/loongarch/helper.h index e9c5412267..b54ce68077 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -652,10 +652,10 @@ 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) +DEF_HELPER_6(vfcmp_c_s, void, env, i32, i32, i32, i32, i32) +DEF_HELPER_6(vfcmp_s_s, void, env, i32, i32, i32, i32, i32) +DEF_HELPER_6(vfcmp_c_d, void, env, i32, i32, i32, i32, i32) +DEF_HELPER_6(vfcmp_s_d, void, env, i32, i32, i32, i32, i32) DEF_HELPER_FLAGS_4(vbitseli_b, TCG_CALL_NO_RWG, void, ptr, ptr, i64, i32) diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 82c26a318b..0d46bd5e5e 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -1958,6 +1958,9 @@ xvslti_hu 0111 01101000 10001 ..... ..... ..... @vv_ui5 xvslti_wu 0111 01101000 10010 ..... ..... ..... @vv_ui5 xvslti_du 0111 01101000 10011 ..... ..... ..... @vv_ui5 +xvfcmp_cond_s 0000 11001001 ..... ..... ..... ..... @vvv_fcond +xvfcmp_cond_d 0000 11001010 ..... ..... ..... ..... @vvv_fcond + xvreplgr2vr_b 0111 01101001 11110 00000 ..... ..... @vr xvreplgr2vr_h 0111 01101001 11110 00001 ..... ..... @vr xvreplgr2vr_w 0111 01101001 11110 00010 ..... ..... @vr diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index 295ba74f2b..607774375c 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -2385,6 +2385,100 @@ INSN_LASX(xvslti_hu, vv_i) INSN_LASX(xvslti_wu, vv_i) INSN_LASX(xvslti_du, vv_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->vd, \ + a->vj, a->vk); \ +} + +static bool output_xxx_fcond(DisasContext *ctx, arg_vvv_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_vvv_fcond * a) \ +{ \ + return output_xxx_fcond(ctx, a, #suffix); \ +} + +LASX_FCMP_INSN(s) +LASX_FCMP_INSN(d) + INSN_LASX(xvreplgr2vr_b, vr) INSN_LASX(xvreplgr2vr_h, vr) INSN_LASX(xvreplgr2vr_w, vr) diff --git a/target/loongarch/vec_helper.c b/target/loongarch/vec_helper.c index 19958c054c..4970a4b39a 100644 --- a/target/loongarch/vec_helper.c +++ b/target/loongarch/vec_helper.c @@ -3001,7 +3001,7 @@ static uint64_t vfcmp_common(CPULoongArchState *env, } #define VFCMP(NAME, BIT, E, FN) \ -void HELPER(NAME)(CPULoongArchState *env, \ +void HELPER(NAME)(CPULoongArchState *env, uint32_t oprsz, \ uint32_t vd, uint32_t vj, uint32_t vk, uint32_t flags) \ { \ int i; \ @@ -3011,7 +3011,7 @@ void HELPER(NAME)(CPULoongArchState *env, \ VReg *Vk = &(env->fpr[vk].vreg); \ \ vec_clear_cause(env); \ - for (i = 0; i < LSX_LEN/BIT ; i++) { \ + for (i = 0; i < oprsz / (BIT / 8) ; i++) { \ FloatRelation cmp; \ cmp = FN(Vj->E(i), Vk->E(i), &env->fp_status); \ t.E(i) = vfcmp_common(env, cmp, flags); \ diff --git a/target/loongarch/insn_trans/trans_lasx.c.inc b/target/loongarch/insn_trans/trans_lasx.c.inc index c1cd02d6a1..6efb9733a3 100644 --- a/target/loongarch/insn_trans/trans_lasx.c.inc +++ b/target/loongarch/insn_trans/trans_lasx.c.inc @@ -705,6 +705,9 @@ TRANS(xvslti_hu, LASX, do_vslti_u, 32, MO_16) TRANS(xvslti_wu, LASX, do_vslti_u, 32, MO_32) TRANS(xvslti_du, LASX, do_vslti_u, 32, MO_64) +TRANS(xvfcmp_cond_s, LASX, do_vfcmp_cond_s, 32) +TRANS(xvfcmp_cond_d, LASX, do_vfcmp_cond_d, 32) + TRANS(xvreplgr2vr_b, LASX, gvec_dup, 32, MO_8) TRANS(xvreplgr2vr_h, LASX, gvec_dup, 32, MO_16) TRANS(xvreplgr2vr_w, LASX, gvec_dup, 32, MO_32) diff --git a/target/loongarch/insn_trans/trans_lsx.c.inc b/target/loongarch/insn_trans/trans_lsx.c.inc index f757db7a76..a5d6cc834d 100644 --- a/target/loongarch/insn_trans/trans_lsx.c.inc +++ b/target/loongarch/insn_trans/trans_lsx.c.inc @@ -3921,13 +3921,14 @@ TRANS(vslti_hu, LSX, do_vslti_u, 16, MO_16) TRANS(vslti_wu, LSX, do_vslti_u, 16, MO_32) TRANS(vslti_du, LSX, do_vslti_u, 16, MO_64) -static bool trans_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a) +static bool do_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a, uint32_t sz) { uint32_t flags; - void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32); + void (*fn)(TCGv_env, TCGv_i32, 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); + TCGv_i32 oprsz = tcg_constant_i32(sz); if (!avail_LSX(ctx)) { return false; @@ -3937,18 +3938,19 @@ static bool trans_vfcmp_cond_s(DisasContext *ctx, arg_vvv_fcond *a) 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)); + fn(cpu_env, oprsz, vd, vj, vk, tcg_constant_i32(flags)); return true; } -static bool trans_vfcmp_cond_d(DisasContext *ctx, arg_vvv_fcond *a) +static bool do_vfcmp_cond_d(DisasContext *ctx, arg_vvv_fcond *a, uint32_t sz) { uint32_t flags; - void (*fn)(TCGv_env, TCGv_i32, TCGv_i32, TCGv_i32, TCGv_i32); + void (*fn)(TCGv_env, TCGv_i32, 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); + TCGv_i32 oprsz = tcg_constant_i32(sz); if (!avail_LSX(ctx)) { return false; @@ -3958,11 +3960,14 @@ static bool trans_vfcmp_cond_d(DisasContext *ctx, arg_vvv_fcond *a) 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)); + fn(cpu_env, oprsz, vd, vj, vk, tcg_constant_i32(flags)); return true; } +TRANS(vfcmp_cond_s, LSX, do_vfcmp_cond_s, 16) +TRANS(vfcmp_cond_d, LSX, do_vfcmp_cond_d, 16) + static bool trans_vbitsel_v(DisasContext *ctx, arg_vvvv *a) { if (!avail_LSX(ctx)) { -- 2.39.1