Create a new artificial "next pc" which also indicates
that nothing has changed within the cpu state which
requires returning to the main loop.
Pipe this new value though all pc/npc checks.
Do not produce this new value yet.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
target/sparc/translate.c | 155 ++++++++++++++++++++++++++++-----------
1 file changed, 111 insertions(+), 44 deletions(-)
@@ -5608,20 +5649,46 @@ static void sparc_tr_translate_insn(DisasContextBase
*dcbase, CPUState *cs)
static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
DisasContext *dc = container_of(dcbase, DisasContext, base);
+ bool may_lookup;
switch (dc->base.is_jmp) {
case DISAS_NEXT:
case DISAS_TOO_MANY:
- if (dc->pc != DYNAMIC_PC &&
- (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
+ if (((dc->pc | dc->npc) & 3) == 0) {
/* static PC and NPC: we can use direct chaining */
gen_goto_tb(dc, 0, dc->pc, dc->npc);
- } else {
- if (dc->pc != DYNAMIC_PC) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
+ break;
+ }
+
+ if (dc->pc & 3) {
+ switch (dc->pc) {
+ case DYNAMIC_PC_LOOKUP:
+ may_lookup = true;
+ break;
+ case DYNAMIC_PC:
+ may_lookup = false;
+ break;
+ default:
+ g_assert_not_reached();
}
- save_npc(dc);
+ } else {
+ tcg_gen_movi_tl(cpu_pc, dc->pc);
+ may_lookup = true;
+ }
+
+ save_npc(dc);
+ switch (dc->npc) {