target-arm: Exit cpu loop on wfe
Improves performance of spinlocks.
Change-Id: I449bd348a28814a445b27244e07f9d1f25503e4c
Signed-off-by: Arve Hjønnevåg <arve@android.com>
diff --git a/target-arm/helper.h b/target-arm/helper.h
index 63ae13a..40dea37 100644
--- a/target-arm/helper.h
+++ b/target-arm/helper.h
@@ -50,6 +50,7 @@
i32, i32, i32, i32)
DEF_HELPER_2(exception, void, env, i32)
DEF_HELPER_1(wfi, void, env)
+DEF_HELPER_1(wfe, void, env)
DEF_HELPER_3(cpsr_write, void, env, i32, i32)
DEF_HELPER_1(cpsr_read, i32, env)
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index a918e5b..ca6eb5a 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -225,6 +225,14 @@
cpu_loop_exit(env);
}
+void HELPER(wfe)(CPUARMState *env)
+{
+ /* TODO: Implement WFE to actually wait for an event. For now, just give
+ * the next cpu a chance to run right away. */
+ env->exception_index = EXCP_HLT;
+ cpu_loop_exit(env);
+}
+
void HELPER(exception)(CPUARMState *env, uint32_t excp)
{
env->exception_index = excp;
diff --git a/target-arm/translate.c b/target-arm/translate.c
index b164996..f3dcdf4 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -80,6 +80,7 @@
#define DISAS_WFI 4
#define DISAS_SWI 5
#define DISAS_SMC 6
+#define DISAS_WFE 7
TCGv_ptr cpu_env;
/* We reuse the same 64-bit temporaries for efficiency. */
@@ -3597,9 +3598,12 @@
s->is_jmp = DISAS_WFI;
break;
case 2: /* wfe */
+ gen_set_pc_im(s, s->pc);
+ s->is_jmp = DISAS_WFE;
+ break;
case 4: /* sev */
case 5: /* sevl */
- /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
+ /* TODO: Implement SEV and SEVL. May help SMP performance. */
default: /* nop */
break;
}
@@ -10300,6 +10304,9 @@
case DISAS_WFI:
gen_helper_wfi(cpu_env);
break;
+ case DISAS_WFE:
+ gen_helper_wfe(cpu_env);
+ break;
case DISAS_SWI:
gen_exception(EXCP_SWI);
break;