diff options
author | Song Gao <gaosong@loongson.cn> | 2023-09-14 10:26:37 +0800 |
---|---|---|
committer | Song Gao <gaosong@loongson.cn> | 2023-09-20 14:33:42 +0800 |
commit | 3eeda5fe4e95eef91dd87074388d844133623a86 (patch) | |
tree | ba718105e4f0ba39c93d6cdfead07da9200b21b9 | |
parent | 4da72d4306105b3d5649133545df8e59975ac65f (diff) | |
download | qemu-3eeda5fe4e95eef91dd87074388d844133623a86.zip qemu-3eeda5fe4e95eef91dd87074388d844133623a86.tar.gz qemu-3eeda5fe4e95eef91dd87074388d844133623a86.tar.bz2 |
target/loongarch: Implement xvfcmp
This patch includes:
- XVFCMP.cond.{S/D}.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20230914022645.1151356-50-gaosong@loongson.cn>
-rw-r--r-- | target/loongarch/disas.c | 93 | ||||
-rw-r--r-- | target/loongarch/helper.h | 8 | ||||
-rw-r--r-- | target/loongarch/insn_trans/trans_vec.c.inc | 31 | ||||
-rw-r--r-- | target/loongarch/insns.decode | 3 | ||||
-rw-r--r-- | target/loongarch/vec_helper.c | 4 |
5 files changed, 117 insertions, 22 deletions
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index 48e0b55..4ab51b7 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -2385,6 +2385,99 @@ 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/helper.h b/target/loongarch/helper.h index e9c5412..b54ce68 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/insn_trans/trans_vec.c.inc b/target/loongarch/insn_trans/trans_vec.c.inc index 63d71e2..9b89b81 100644 --- a/target/loongarch/insn_trans/trans_vec.c.inc +++ b/target/loongarch/insn_trans/trans_vec.c.inc @@ -4645,52 +4645,51 @@ TRANS(xvslti_hu, LASX, do_xcmpi, MO_16, TCG_COND_LTU) TRANS(xvslti_wu, LASX, do_xcmpi, MO_32, TCG_COND_LTU) TRANS(xvslti_du, LASX, do_xcmpi, MO_64, TCG_COND_LTU) -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; - } - - if (!check_vec(ctx, 16)) { + if (!check_vec(ctx, sz)) { return true; } 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; - } - - if (!check_vec(ctx, 16)) { + if (!check_vec(ctx, sz)) { return true; } 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) +TRANS(xvfcmp_cond_s, LASX, do_vfcmp_cond_s, 32) +TRANS(xvfcmp_cond_d, LASX, do_vfcmp_cond_d, 32) + static bool trans_vbitsel_v(DisasContext *ctx, arg_vvvv *a) { if (!avail_LSX(ctx)) { diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode index 82c26a3..0d46bd5 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/vec_helper.c b/target/loongarch/vec_helper.c index 960b3d1..5188b7f 100644 --- a/target/loongarch/vec_helper.c +++ b/target/loongarch/vec_helper.c @@ -3122,7 +3122,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; \ @@ -3132,7 +3132,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); \ |