@@ -118,49 +118,45 @@ float32 HELPER(uitof_s)(CPUXtensaState *env, uint32_t v, uint32_t scale)
(int32_t)scale, &env->fp_status);
}
-static inline void set_br(CPUXtensaState *env, bool v, uint32_t br)
+uint32_t HELPER(un_s)(CPUXtensaState *env, float32 a, float32 b)
{
- if (v) {
- env->sregs[BR] |= br;
- } else {
- env->sregs[BR] &= ~br;
- }
-}
-
-void HELPER(un_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
-{
- set_br(env, float32_unordered_quiet(a, b, &env->fp_status), br);
+ return float32_unordered_quiet(a, b, &env->fp_status);
}
-void HELPER(oeq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(oeq_s)(CPUXtensaState *env, float32 a, float32 b)
{
- set_br(env, float32_eq_quiet(a, b, &env->fp_status), br);
+ return float32_eq_quiet(a, b, &env->fp_status);
}
-void HELPER(ueq_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(ueq_s)(CPUXtensaState *env, float32 a, float32 b)
{
FloatRelation v = float32_compare_quiet(a, b, &env->fp_status);
- set_br(env, v == float_relation_equal || v == float_relation_unordered, br);
+
+ return v == float_relation_equal ||
+ v == float_relation_unordered;
}
-void HELPER(olt_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(olt_s)(CPUXtensaState *env, float32 a, float32 b)
{
- set_br(env, float32_lt_quiet(a, b, &env->fp_status), br);
+ return float32_lt_quiet(a, b, &env->fp_status);
}
-void HELPER(ult_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(ult_s)(CPUXtensaState *env, float32 a, float32 b)
{
FloatRelation v = float32_compare_quiet(a, b, &env->fp_status);
- set_br(env, v == float_relation_less || v == float_relation_unordered, br);
+
+ return v == float_relation_less ||
+ v == float_relation_unordered;
}
-void HELPER(ole_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(ole_s)(CPUXtensaState *env, float32 a, float32 b)
{
- set_br(env, float32_le_quiet(a, b, &env->fp_status), br);
+ return float32_le_quiet(a, b, &env->fp_status);
}
-void HELPER(ule_s)(CPUXtensaState *env, uint32_t br, float32 a, float32 b)
+uint32_t HELPER(ule_s)(CPUXtensaState *env, float32 a, float32 b)
{
FloatRelation v = float32_compare_quiet(a, b, &env->fp_status);
- set_br(env, v != float_relation_greater, br);
+
+ return v != float_relation_greater;
}
@@ -59,13 +59,13 @@ DEF_HELPER_FLAGS_3(ftoui_s, TCG_CALL_NO_RWG_SE, i32, f32, i32, i32)
DEF_HELPER_3(itof_s, f32, env, i32, i32)
DEF_HELPER_3(uitof_s, f32, env, i32, i32)
-DEF_HELPER_4(un_s, void, env, i32, f32, f32)
-DEF_HELPER_4(oeq_s, void, env, i32, f32, f32)
-DEF_HELPER_4(ueq_s, void, env, i32, f32, f32)
-DEF_HELPER_4(olt_s, void, env, i32, f32, f32)
-DEF_HELPER_4(ult_s, void, env, i32, f32, f32)
-DEF_HELPER_4(ole_s, void, env, i32, f32, f32)
-DEF_HELPER_4(ule_s, void, env, i32, f32, f32)
+DEF_HELPER_3(un_s, i32, env, f32, f32)
+DEF_HELPER_3(oeq_s, i32, env, f32, f32)
+DEF_HELPER_3(ueq_s, i32, env, f32, f32)
+DEF_HELPER_3(olt_s, i32, env, f32, f32)
+DEF_HELPER_3(ult_s, i32, env, f32, f32)
+DEF_HELPER_3(ole_s, i32, env, f32, f32)
+DEF_HELPER_3(ule_s, i32, env, f32, f32)
DEF_HELPER_2(rer, i32, env, i32)
DEF_HELPER_3(wer, void, env, i32, i32)
@@ -6319,7 +6319,7 @@ enum {
static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
const uint32_t par[])
{
- static void (* const helper[])(TCGv_env env, TCGv_i32 bit,
+ static void (* const helper[])(TCGv_i32 res, TCGv_env env,
TCGv_i32 s, TCGv_i32 t) = {
[COMPARE_UN] = gen_helper_un_s,
[COMPARE_OEQ] = gen_helper_oeq_s,
@@ -6329,10 +6329,22 @@ static void translate_compare_s(DisasContext *dc, const OpcodeArg arg[],
[COMPARE_OLE] = gen_helper_ole_s,
[COMPARE_ULE] = gen_helper_ule_s,
};
- TCGv_i32 bit = tcg_const_i32(1 << arg[0].imm);
+ TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 res = tcg_temp_new_i32();
+ TCGv_i32 set_br = tcg_temp_new_i32();
+ TCGv_i32 clr_br = tcg_temp_new_i32();
- helper[par[0]](cpu_env, bit, arg[1].in, arg[2].in);
- tcg_temp_free(bit);
+ tcg_gen_ori_i32(set_br, arg[0].in, 1 << arg[0].imm);
+ tcg_gen_andi_i32(clr_br, arg[0].in, ~(1 << arg[0].imm));
+
+ helper[par[0]](res, cpu_env, arg[1].in, arg[2].in);
+ tcg_gen_movcond_i32(TCG_COND_NE,
+ arg[0].out, res, zero,
+ set_br, clr_br);
+ tcg_temp_free(zero);
+ tcg_temp_free(res);
+ tcg_temp_free(set_br);
+ tcg_temp_free(clr_br);
}
static void translate_float_s(DisasContext *dc, const OpcodeArg arg[],
BR registers used in FPU comparison opcodes are available as opcode arguments for translators. Use them. This simplifies comparison helpers interface and makes them usable in FLIX bundles. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> --- target/xtensa/fpu_helper.c | 42 +++++++++++++++++--------------------- target/xtensa/helper.h | 14 ++++++------- target/xtensa/translate.c | 20 ++++++++++++++---- 3 files changed, 42 insertions(+), 34 deletions(-)