This patch includes: - VFCMP.cond.{S/D}. Signed-off-by: Song Gao <gaos...@loongson.cn> --- target/loongarch/disas.c | 94 +++++++++++++++++++++ target/loongarch/helper.h | 9 ++ target/loongarch/insn_trans/trans_lsx.c.inc | 30 +++++++ target/loongarch/insns.decode | 5 ++ target/loongarch/lsx_helper.c | 38 +++++++++ 5 files changed, 176 insertions(+)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c index c854742f6d..0ea5418e5e 100644 --- a/target/loongarch/disas.c +++ b/target/loongarch/disas.c @@ -1418,3 +1418,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 b8f22a2601..9d8ade9dc8 100644 --- a/target/loongarch/helper.h +++ b/target/loongarch/helper.h @@ -768,3 +768,12 @@ DEF_HELPER_4(vslti_bu, void, env, i32, i32, i32) DEF_HELPER_4(vslti_hu, void, env, i32, i32, i32) DEF_HELPER_4(vslti_wu, void, env, i32, i32, i32) DEF_HELPER_4(vslti_du, void, env, i32, i32, i32) + +/* vfcmp.cXXX.s */ +DEF_HELPER_5(vfcmp_c_s, void, env, i32, i32, i32, i32) +/* vfcmp.sXXX.s */ +DEF_HELPER_5(vfcmp_s_s, void, env, i32, i32, i32, i32) +/* vfcmp.cXXX.d */ +DEF_HELPER_5(vfcmp_c_d, void, env, i32, i32, i32, i32) +/* vfcmp.sXXX.d */ +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 90b3e88229..522d660113 100644 --- a/target/loongarch/insn_trans/trans_lsx.c.inc +++ b/target/loongarch/insn_trans/trans_lsx.c.inc @@ -698,3 +698,33 @@ TRANS(vslti_bu, gen_vv_i, gen_helper_vslti_bu) TRANS(vslti_hu, gen_vv_i, gen_helper_vslti_hu) TRANS(vslti_wu, gen_vv_i, gen_helper_vslti_wu) TRANS(vslti_du, gen_vv_i, gen_helper_vslti_du) + +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); + + 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 965ee486e1..5b4114c39b 100644 --- a/target/loongarch/insns.decode +++ b/target/loongarch/insns.decode @@ -493,6 +493,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 @@ -507,6 +508,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 @@ -1144,3 +1146,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 977a095e79..1e5a1d989a 100644 --- a/target/loongarch/lsx_helper.c +++ b/target/loongarch/lsx_helper.c @@ -4237,3 +4237,41 @@ DO_HELPER_VVV(vslti_bu, 8, helper_vv_i, do_vslti_u) DO_HELPER_VVV(vslti_hu, 16, helper_vv_i, do_vslti_u) DO_HELPER_VVV(vslti_wu, 32, helper_vv_i, do_vslti_u) DO_HELPER_VVV(vslti_du, 64, helper_vv_i, do_vslti_u) + +#define LSX_FCMP_S(name) \ +void helper_v## name ##_s(CPULoongArchState *env, uint32_t vd, \ + uint32_t vj, uint32_t vk, uint32_t flags) \ +{ \ + int ret; \ + int i; \ + vec_t *Vd = &(env->fpr[vd].vec); \ + vec_t *Vj = &(env->fpr[vj].vec); \ + vec_t *Vk = &(env->fpr[vk].vec); \ + \ + for (i = 0; i < 4; i++) { \ + ret = helper_## name ## _s(env, Vj->W[i], Vk->W[i], flags); \ + Vd->W[i] = (ret == 1) ? -1 : 0; \ + } \ +} + +LSX_FCMP_S(fcmp_c) +LSX_FCMP_S(fcmp_s) + +#define LSX_FCMP_D(name) \ +void helper_v## name ##_d(CPULoongArchState *env, uint32_t vd, \ + uint32_t vj, uint32_t vk, uint32_t flags) \ +{ \ + int ret; \ + int i; \ + vec_t *Vd = &(env->fpr[vd].vec); \ + vec_t *Vj = &(env->fpr[vj].vec); \ + vec_t *Vk = &(env->fpr[vk].vec); \ + \ + for (i = 0; i < 2; i++) { \ + ret = helper_## name ## _d(env, Vj->D[i], Vk->D[i], flags); \ + Vd->D[i] = (ret == 1) ? -1 : 0; \ + } \ +} + +LSX_FCMP_D(fcmp_c) +LSX_FCMP_D(fcmp_s) -- 2.31.1