aboutsummaryrefslogtreecommitdiff
path: root/target-xtensa
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2013-07-21 12:55:46 +0400
committerMax Filippov <jcmvbkbc@gmail.com>2013-07-29 18:35:45 +0400
commit908c67fca4b2c12a9b2336aa9c188f84468b60b7 (patch)
treef1f9a359b00a690a597d78f10e7cba20db135d4a /target-xtensa
parent0857a06ef784783887e756d4b7b5f874512c506c (diff)
target-xtensa: check register window inline
This lowers time spent in helper_window_check as reported by perf top from ~8% to ~0.15% accelerating register-intensive tests by ~20%. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target-xtensa')
-rw-r--r--target-xtensa/translate.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 15fab1ba30..504cc539e3 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -305,16 +305,21 @@ static void gen_left_shift_sar(DisasContext *dc, TCGv_i32 sa)
tcg_temp_free(tmp);
}
-static void gen_advance_ccount(DisasContext *dc)
+static void gen_advance_ccount_cond(DisasContext *dc)
{
if (dc->ccount_delta > 0) {
TCGv_i32 tmp = tcg_const_i32(dc->ccount_delta);
- dc->ccount_delta = 0;
gen_helper_advance_ccount(cpu_env, tmp);
tcg_temp_free(tmp);
}
}
+static void gen_advance_ccount(DisasContext *dc)
+{
+ gen_advance_ccount_cond(dc);
+ dc->ccount_delta = 0;
+}
+
static void reset_used_window(DisasContext *dc)
{
dc->used_window = 0;
@@ -829,15 +834,27 @@ static void gen_window_check1(DisasContext *dc, unsigned r1)
}
if (option_enabled(dc, XTENSA_OPTION_WINDOWED_REGISTER) &&
r1 / 4 > dc->used_window) {
- TCGv_i32 pc = tcg_const_i32(dc->pc);
- TCGv_i32 w = tcg_const_i32(r1 / 4);
+ int label = gen_new_label();
+ TCGv_i32 ws = tcg_temp_new_i32();
dc->used_window = r1 / 4;
- gen_advance_ccount(dc);
- gen_helper_window_check(cpu_env, pc, w);
+ tcg_gen_deposit_i32(ws, cpu_SR[WINDOW_START], cpu_SR[WINDOW_START],
+ dc->config->nareg / 4, dc->config->nareg / 4);
+ tcg_gen_shr_i32(ws, ws, cpu_SR[WINDOW_BASE]);
+ tcg_gen_andi_i32(ws, ws, (2 << (r1 / 4)) - 2);
+ tcg_gen_brcondi_i32(TCG_COND_EQ, ws, 0, label);
+ {
+ TCGv_i32 pc = tcg_const_i32(dc->pc);
+ TCGv_i32 w = tcg_const_i32(r1 / 4);
+
+ gen_advance_ccount_cond(dc);
+ gen_helper_window_check(cpu_env, pc, w);
- tcg_temp_free(w);
- tcg_temp_free(pc);
+ tcg_temp_free(w);
+ tcg_temp_free(pc);
+ }
+ gen_set_label(label);
+ tcg_temp_free(ws);
}
}