aboutsummaryrefslogtreecommitdiff
path: root/target/xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-06-30 07:50:14 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2020-08-21 12:48:15 -0700
commit5dbb4c96d50c6ef74d4fd71a5a0fd9763d5a3662 (patch)
tree7283911472ba2cd53f3f92b5efb4a6914669ed0c /target/xtensa
parentff35a7d1a1027bb867ee6f23935100dd105331fe (diff)
target/xtensa: don't access BR regfile directly
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. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target/xtensa')
-rw-r--r--target/xtensa/fpu_helper.c42
-rw-r--r--target/xtensa/helper.h14
-rw-r--r--target/xtensa/translate.c20
3 files changed, 42 insertions, 34 deletions
diff --git a/target/xtensa/fpu_helper.c b/target/xtensa/fpu_helper.c
index 46e231bdaa..35dacbd14d 100644
--- a/target/xtensa/fpu_helper.c
+++ b/target/xtensa/fpu_helper.c
@@ -120,49 +120,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;
}
diff --git a/target/xtensa/helper.h b/target/xtensa/helper.h
index bce31cbd9f..02c00d8461 100644
--- a/target/xtensa/helper.h
+++ b/target/xtensa/helper.h
@@ -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)
diff --git a/target/xtensa/translate.c b/target/xtensa/translate.c
index 1b643881e6..67a92379f9 100644
--- a/target/xtensa/translate.c
+++ b/target/xtensa/translate.c
@@ -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[],