summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-08 11:02:54 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-08 11:02:54 +0100
commite6d767b727324db8efaddfbe896dfa4f8cc500e8 (patch)
tree925e0cbd687feaedb5fcfad78e04034e4e3ac87b
parentb393d2fb026e82df7e7671255d5f90bc4053453f (diff)
parent51b061fbf027f844cc0bfb1eaaf0ae818e3ceb36 (diff)
downloadfocaccia-qemu-e6d767b727324db8efaddfbe896dfa4f8cc500e8.tar.gz
focaccia-qemu-e6d767b727324db8efaddfbe896dfa4f8cc500e8.zip
Merge remote-tracking branch 'remotes/rth/tags/pull-pa-20170907' into staging
Conversion to TranslatorOps

# gpg: Signature made Thu 07 Sep 2017 19:42:48 BST
# gpg:                using RSA key 0x64DF38E8AF7E215F
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A  05C0 64DF 38E8 AF7E 215F

* remotes/rth/tags/pull-pa-20170907:
  target/hppa: Convert to TranslatorOps
  target/hppa: Convert to DisasContextBase
  target/hppa: Convert to DisasJumpType

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--target/hppa/translate.c894
1 files changed, 448 insertions, 446 deletions
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 900870cd5a..b6e2652341 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -24,10 +24,9 @@
 #include "exec/exec-all.h"
 #include "tcg-op.h"
 #include "exec/cpu_ldst.h"
-
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
-
+#include "exec/translator.h"
 #include "trace-tcg.h"
 #include "exec/log.h"
 
@@ -39,7 +38,7 @@ typedef struct DisasCond {
 } DisasCond;
 
 typedef struct DisasContext {
-    struct TranslationBlock *tb;
+    DisasContextBase base;
     CPUState *cs;
 
     target_ulong iaoq_f;
@@ -53,36 +52,25 @@ typedef struct DisasContext {
     DisasCond null_cond;
     TCGLabel *null_lab;
 
-    bool singlestep_enabled;
     bool psw_n_nonzero;
 } DisasContext;
 
-/* Return values from translate_one, indicating the state of the TB.
-   Note that zero indicates that we are not exiting the TB.  */
-
-typedef enum {
-    NO_EXIT,
-
-    /* We have emitted one or more goto_tb.  No fixup required.  */
-    EXIT_GOTO_TB,
-
-    /* We are not using a goto_tb (for whatever reason), but have updated
-       the iaq (for whatever reason), so don't do it again on exit.  */
-    EXIT_IAQ_N_UPDATED,
+/* Target-specific return values from translate_one, indicating the
+   state of the TB.  Note that DISAS_NEXT indicates that we are not
+   exiting the TB.  */
 
-    /* We are exiting the TB, but have neither emitted a goto_tb, nor
-       updated the iaq for the next instruction to be executed.  */
-    EXIT_IAQ_N_STALE,
+/* We are not using a goto_tb (for whatever reason), but have updated
+   the iaq (for whatever reason), so don't do it again on exit.  */
+#define DISAS_IAQ_N_UPDATED  DISAS_TARGET_0
 
-    /* We are ending the TB with a noreturn function call, e.g. longjmp.
-       No following code will be executed.  */
-    EXIT_NORETURN,
-} ExitStatus;
+/* We are exiting the TB, but have neither emitted a goto_tb, nor
+   updated the iaq for the next instruction to be executed.  */
+#define DISAS_IAQ_N_STALE    DISAS_TARGET_1
 
 typedef struct DisasInsn {
     uint32_t insn, mask;
-    ExitStatus (*trans)(DisasContext *ctx, uint32_t insn,
-                        const struct DisasInsn *f);
+    DisasJumpType (*trans)(DisasContext *ctx, uint32_t insn,
+                           const struct DisasInsn *f);
     union {
         void (*ttt)(TCGv, TCGv, TCGv);
         void (*weww)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32);
@@ -415,7 +403,7 @@ static void nullify_set(DisasContext *ctx, bool x)
 
 /* Mark the end of an instruction that may have been nullified.
    This is the pair to nullify_over.  */
-static ExitStatus nullify_end(DisasContext *ctx, ExitStatus status)
+static DisasJumpType nullify_end(DisasContext *ctx, DisasJumpType status)
 {
     TCGLabel *null_lab = ctx->null_lab;
 
@@ -441,9 +429,9 @@ static ExitStatus nullify_end(DisasContext *ctx, ExitStatus status)
         ctx->null_cond = cond_make_n();
     }
 
-    assert(status != EXIT_GOTO_TB && status != EXIT_IAQ_N_UPDATED);
-    if (status == EXIT_NORETURN) {
-        status = NO_EXIT;
+    assert(status != DISAS_NORETURN && status != DISAS_IAQ_N_UPDATED);
+    if (status == DISAS_NORETURN) {
+        status = DISAS_NEXT;
     }
     return status;
 }
@@ -469,16 +457,16 @@ static void gen_excp_1(int exception)
     tcg_temp_free_i32(t);
 }
 
-static ExitStatus gen_excp(DisasContext *ctx, int exception)
+static DisasJumpType gen_excp(DisasContext *ctx, int exception)
 {
     copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
     copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
     nullify_save(ctx);
     gen_excp_1(exception);
-    return EXIT_NORETURN;
+    return DISAS_NORETURN;
 }
 
-static ExitStatus gen_illegal(DisasContext *ctx)
+static DisasJumpType gen_illegal(DisasContext *ctx)
 {
     nullify_over(ctx);
     return nullify_end(ctx, gen_excp(ctx, EXCP_SIGILL));
@@ -487,7 +475,7 @@ static ExitStatus gen_illegal(DisasContext *ctx)
 static bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 {
     /* Suppress goto_tb in the case of single-steping and IO.  */
-    if ((ctx->tb->cflags & CF_LAST_IO) || ctx->singlestep_enabled) {
+    if ((ctx->base.tb->cflags & CF_LAST_IO) || ctx->base.singlestep_enabled) {
         return false;
     }
     return true;
@@ -510,11 +498,11 @@ static void gen_goto_tb(DisasContext *ctx, int which,
         tcg_gen_goto_tb(which);
         tcg_gen_movi_tl(cpu_iaoq_f, f);
         tcg_gen_movi_tl(cpu_iaoq_b, b);
-        tcg_gen_exit_tb((uintptr_t)ctx->tb + which);
+        tcg_gen_exit_tb((uintptr_t)ctx->base.tb + which);
     } else {
         copy_iaoq_entry(cpu_iaoq_f, f, cpu_iaoq_b);
         copy_iaoq_entry(cpu_iaoq_b, b, ctx->iaoq_n_var);
-        if (ctx->singlestep_enabled) {
+        if (ctx->base.singlestep_enabled) {
             gen_excp_1(EXCP_DEBUG);
         } else {
             tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
@@ -839,9 +827,9 @@ static TCGv do_sub_sv(DisasContext *ctx, TCGv res, TCGv in1, TCGv in2)
     return sv;
 }
 
-static ExitStatus do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
-                         unsigned shift, bool is_l, bool is_tsv, bool is_tc,
-                         bool is_c, unsigned cf)
+static DisasJumpType do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
+                            unsigned shift, bool is_l, bool is_tsv, bool is_tc,
+                            bool is_c, unsigned cf)
 {
     TCGv dest, cb, cb_msb, sv, tmp;
     unsigned c = cf >> 1;
@@ -908,11 +896,11 @@ static ExitStatus do_add(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
     /* Install the new nullification.  */
     cond_free(&ctx->null_cond);
     ctx->null_cond = cond;
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
-                         bool is_tsv, bool is_b, bool is_tc, unsigned cf)
+static DisasJumpType do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
+                            bool is_tsv, bool is_b, bool is_tc, unsigned cf)
 {
     TCGv dest, sv, cb, cb_msb, zero, tmp;
     unsigned c = cf >> 1;
@@ -974,11 +962,11 @@ static ExitStatus do_sub(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
     /* Install the new nullification.  */
     cond_free(&ctx->null_cond);
     ctx->null_cond = cond;
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
-                            TCGv in2, unsigned cf)
+static DisasJumpType do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
+                               TCGv in2, unsigned cf)
 {
     TCGv dest, sv;
     DisasCond cond;
@@ -1003,11 +991,11 @@ static ExitStatus do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
     /* Install the new nullification.  */
     cond_free(&ctx->null_cond);
     ctx->null_cond = cond;
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
-                         unsigned cf, void (*fn)(TCGv, TCGv, TCGv))
+static DisasJumpType do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
+                            unsigned cf, void (*fn)(TCGv, TCGv, TCGv))
 {
     TCGv dest = dest_gpr(ctx, rt);
 
@@ -1020,12 +1008,12 @@ static ExitStatus do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
     if (cf) {
         ctx->null_cond = do_log_cond(cf, dest);
     }
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
-                          TCGv in2, unsigned cf, bool is_tc,
-                          void (*fn)(TCGv, TCGv, TCGv))
+static DisasJumpType do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
+                             TCGv in2, unsigned cf, bool is_tc,
+                             void (*fn)(TCGv, TCGv, TCGv))
 {
     TCGv dest;
     DisasCond cond;
@@ -1053,7 +1041,7 @@ static ExitStatus do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
         cond_free(&ctx->null_cond);
         ctx->null_cond = cond;
     }
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
 /* Emit a memory load.  The modify parameter should be
@@ -1185,9 +1173,9 @@ static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
 #define do_store_tl do_store_32
 #endif
 
-static ExitStatus do_load(DisasContext *ctx, unsigned rt, unsigned rb,
-                          unsigned rx, int scale, target_long disp,
-                          int modify, TCGMemOp mop)
+static DisasJumpType do_load(DisasContext *ctx, unsigned rt, unsigned rb,
+                             unsigned rx, int scale, target_long disp,
+                             int modify, TCGMemOp mop)
 {
     TCGv dest;
 
@@ -1203,12 +1191,12 @@ static ExitStatus do_load(DisasContext *ctx, unsigned rt, unsigned rb,
     do_load_tl(ctx, dest, rb, rx, scale, disp, modify, mop);
     save_gpr(ctx, rt, dest);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
-                            unsigned rx, int scale, target_long disp,
-                            int modify)
+static DisasJumpType do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
+                               unsigned rx, int scale, target_long disp,
+                               int modify)
 {
     TCGv_i32 tmp;
 
@@ -1223,12 +1211,12 @@ static ExitStatus do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
         gen_helper_loaded_fr0(cpu_env);
     }
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
-                            unsigned rx, int scale, target_long disp,
-                            int modify)
+static DisasJumpType do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
+                               unsigned rx, int scale, target_long disp,
+                               int modify)
 {
     TCGv_i64 tmp;
 
@@ -1243,20 +1231,20 @@ static ExitStatus do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
         gen_helper_loaded_fr0(cpu_env);
     }
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_store(DisasContext *ctx, unsigned rt, unsigned rb,
-                           target_long disp, int modify, TCGMemOp mop)
+static DisasJumpType do_store(DisasContext *ctx, unsigned rt, unsigned rb,
+                              target_long disp, int modify, TCGMemOp mop)
 {
     nullify_over(ctx);
     do_store_tl(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, modify, mop);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
-                             unsigned rx, int scale, target_long disp,
-                             int modify)
+static DisasJumpType do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
+                                unsigned rx, int scale, target_long disp,
+                                int modify)
 {
     TCGv_i32 tmp;
 
@@ -1266,12 +1254,12 @@ static ExitStatus do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
     do_store_32(ctx, tmp, rb, rx, scale, disp, modify, MO_TEUL);
     tcg_temp_free_i32(tmp);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
-                             unsigned rx, int scale, target_long disp,
-                             int modify)
+static DisasJumpType do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
+                                unsigned rx, int scale, target_long disp,
+                                int modify)
 {
     TCGv_i64 tmp;
 
@@ -1281,11 +1269,11 @@ static ExitStatus do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
     do_store_64(ctx, tmp, rb, rx, scale, disp, modify, MO_TEQ);
     tcg_temp_free_i64(tmp);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
-                             void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
+static DisasJumpType do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
+                                void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
 {
     TCGv_i32 tmp;
 
@@ -1296,11 +1284,11 @@ static ExitStatus do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
 
     save_frw_i32(rt, tmp);
     tcg_temp_free_i32(tmp);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
-                             void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
+static DisasJumpType do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
+                                void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
 {
     TCGv_i32 dst;
     TCGv_i64 src;
@@ -1314,11 +1302,11 @@ static ExitStatus do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
     tcg_temp_free_i64(src);
     save_frw_i32(rt, dst);
     tcg_temp_free_i32(dst);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
-                             void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
+static DisasJumpType do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
+                                void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
 {
     TCGv_i64 tmp;
 
@@ -1329,11 +1317,11 @@ static ExitStatus do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
 
     save_frd(rt, tmp);
     tcg_temp_free_i64(tmp);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
-                             void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
+static DisasJumpType do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
+                                void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
 {
     TCGv_i32 src;
     TCGv_i64 dst;
@@ -1347,13 +1335,13 @@ static ExitStatus do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
     tcg_temp_free_i32(src);
     save_frd(rt, dst);
     tcg_temp_free_i64(dst);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_weww(DisasContext *ctx, unsigned rt,
-                              unsigned ra, unsigned rb,
-                              void (*func)(TCGv_i32, TCGv_env,
-                                           TCGv_i32, TCGv_i32))
+static DisasJumpType do_fop_weww(DisasContext *ctx, unsigned rt,
+                                 unsigned ra, unsigned rb,
+                                 void (*func)(TCGv_i32, TCGv_env,
+                                              TCGv_i32, TCGv_i32))
 {
     TCGv_i32 a, b;
 
@@ -1366,13 +1354,13 @@ static ExitStatus do_fop_weww(DisasContext *ctx, unsigned rt,
     tcg_temp_free_i32(b);
     save_frw_i32(rt, a);
     tcg_temp_free_i32(a);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus do_fop_dedd(DisasContext *ctx, unsigned rt,
-                              unsigned ra, unsigned rb,
-                              void (*func)(TCGv_i64, TCGv_env,
-                                           TCGv_i64, TCGv_i64))
+static DisasJumpType do_fop_dedd(DisasContext *ctx, unsigned rt,
+                                 unsigned ra, unsigned rb,
+                                 void (*func)(TCGv_i64, TCGv_env,
+                                              TCGv_i64, TCGv_i64))
 {
     TCGv_i64 a, b;
 
@@ -1385,13 +1373,13 @@ static ExitStatus do_fop_dedd(DisasContext *ctx, unsigned rt,
     tcg_temp_free_i64(b);
     save_frd(rt, a);
     tcg_temp_free_i64(a);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 /* Emit an unconditional branch to a direct target, which may or may not
    have already had nullification handled.  */
-static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
-                             unsigned link, bool is_n)
+static DisasJumpType do_dbranch(DisasContext *ctx, target_ulong dest,
+                                unsigned link, bool is_n)
 {
     if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
         if (link != 0) {
@@ -1401,7 +1389,7 @@ static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
         if (is_n) {
             ctx->null_cond.c = TCG_COND_ALWAYS;
         }
-        return NO_EXIT;
+        return DISAS_NEXT;
     } else {
         nullify_over(ctx);
 
@@ -1417,18 +1405,18 @@ static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
             gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
         }
 
-        nullify_end(ctx, NO_EXIT);
+        nullify_end(ctx, DISAS_NEXT);
 
         nullify_set(ctx, 0);
         gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
-        return EXIT_GOTO_TB;
+        return DISAS_NORETURN;
     }
 }
 
 /* Emit a conditional branch to a direct target.  If the branch itself
    is nullified, we should have already used nullify_over.  */
-static ExitStatus do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
-                             DisasCond *cond)
+static DisasJumpType do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
+                                DisasCond *cond)
 {
     target_ulong dest = iaoq_dest(ctx, disp);
     TCGLabel *taken = NULL;
@@ -1480,16 +1468,16 @@ static ExitStatus do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
     if (ctx->null_lab) {
         gen_set_label(ctx->null_lab);
         ctx->null_lab = NULL;
-        return EXIT_IAQ_N_STALE;
+        return DISAS_IAQ_N_STALE;
     } else {
-        return EXIT_GOTO_TB;
+        return DISAS_NORETURN;
     }
 }
 
 /* Emit an unconditional branch to an indirect target.  This handles
    nullification of the branch itself.  */
-static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
-                             unsigned link, bool is_n)
+static DisasJumpType do_ibranch(DisasContext *ctx, TCGv dest,
+                                unsigned link, bool is_n)
 {
     TCGv a0, a1, next, tmp;
     TCGCond c;
@@ -1528,7 +1516,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
             tcg_gen_movi_tl(cpu_gr[link], ctx->iaoq_n);
         }
         tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
-        return nullify_end(ctx, NO_EXIT);
+        return nullify_end(ctx, DISAS_NEXT);
     } else {
         cond_prep(&ctx->null_cond);
         c = ctx->null_cond.c;
@@ -1560,7 +1548,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
         }
     }
 
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
 /* On Linux, page zero is normally marked execute only + gateway.
@@ -1570,7 +1558,7 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv dest,
    in than the "be disp(sr2,r0)" instruction that probably sent us
    here, is the easiest way to handle the branch delay slot on the
    aforementioned BE.  */
-static ExitStatus do_page_zero(DisasContext *ctx)
+static DisasJumpType do_page_zero(DisasContext *ctx)
 {
     /* If by some means we get here with PSW[N]=1, that implies that
        the B,GATE instruction would be skipped, and we'd fault on the
@@ -1598,55 +1586,55 @@ static ExitStatus do_page_zero(DisasContext *ctx)
     switch (ctx->iaoq_f) {
     case 0x00: /* Null pointer call */
         gen_excp_1(EXCP_SIGSEGV);
-        return EXIT_NORETURN;
+        return DISAS_NORETURN;
 
     case 0xb0: /* LWS */
         gen_excp_1(EXCP_SYSCALL_LWS);
-        return EXIT_NORETURN;
+        return DISAS_NORETURN;
 
     case 0xe0: /* SET_THREAD_POINTER */
         tcg_gen_mov_tl(cpu_cr27, cpu_gr[26]);
         tcg_gen_mov_tl(cpu_iaoq_f, cpu_gr[31]);
         tcg_gen_addi_tl(cpu_iaoq_b, cpu_iaoq_f, 4);
-        return EXIT_IAQ_N_UPDATED;
+        return DISAS_IAQ_N_UPDATED;
 
     case 0x100: /* SYSCALL */
         gen_excp_1(EXCP_SYSCALL);
-        return EXIT_NORETURN;
+        return DISAS_NORETURN;
 
     default:
     do_sigill:
         gen_excp_1(EXCP_SIGILL);
-        return EXIT_NORETURN;
+        return DISAS_NORETURN;
     }
 }
 
-static ExitStatus trans_nop(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_nop(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_break(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_break(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     nullify_over(ctx);
     return nullify_end(ctx, gen_excp(ctx, EXCP_DEBUG));
 }
 
-static ExitStatus trans_sync(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_sync(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     /* No point in nullifying the memory barrier.  */
     tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_mfia(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     TCGv tmp = dest_gpr(ctx, rt);
@@ -1654,11 +1642,11 @@ static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
     save_gpr(ctx, rt, tmp);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_mfsp(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     TCGv tmp = dest_gpr(ctx, rt);
@@ -1668,11 +1656,11 @@ static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
     save_gpr(ctx, rt, tmp);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_mfctl(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ctl = extract32(insn, 21, 5);
@@ -1708,11 +1696,11 @@ static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
     }
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_mtctl(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     unsigned rin = extract32(insn, 16, 5);
     unsigned ctl = extract32(insn, 21, 5);
@@ -1729,11 +1717,11 @@ static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
     }
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
-                                const DisasInsn *di)
+static DisasJumpType trans_mtsarcm(DisasContext *ctx, uint32_t insn,
+                                   const DisasInsn *di)
 {
     unsigned rin = extract32(insn, 16, 5);
     TCGv tmp = tcg_temp_new();
@@ -1744,11 +1732,11 @@ static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
     tcg_temp_free(tmp);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_ldsid(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     TCGv dest = dest_gpr(ctx, rt);
@@ -1758,7 +1746,7 @@ static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
     save_gpr(ctx, rt, dest);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
 static const DisasInsn table_system[] = {
@@ -1774,8 +1762,8 @@ static const DisasInsn table_system[] = {
     { 0x000010a0u, 0xfc1f3fe0u, trans_ldsid },
 };
 
-static ExitStatus trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
-                                     const DisasInsn *di)
+static DisasJumpType trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
+                                        const DisasInsn *di)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rx = extract32(insn, 16, 5);
@@ -1788,11 +1776,11 @@ static ExitStatus trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
     save_gpr(ctx, rb, dest);
 
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_probe(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_probe(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned rb = extract32(insn, 21, 5);
@@ -1809,7 +1797,7 @@ static ExitStatus trans_probe(DisasContext *ctx, uint32_t insn,
         gen_helper_probe_r(dest, load_gpr(ctx, rb));
     }
     save_gpr(ctx, rt, dest);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_mem_mgmt[] = {
@@ -1830,8 +1818,8 @@ static const DisasInsn table_mem_mgmt[] = {
     { 0x04003180u, 0xfc003fa0u, trans_probe },        /* probei */
 };
 
-static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_add(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
@@ -1844,7 +1832,7 @@ static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
     bool is_l = false;
     bool is_tc = false;
     bool is_tsv = false;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     switch (ext) {
     case 0x6: /* ADD, SHLADD */
@@ -1874,8 +1862,8 @@ static ExitStatus trans_add(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_sub(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
@@ -1886,7 +1874,7 @@ static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
     bool is_b = false;
     bool is_tc = false;
     bool is_tsv = false;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     switch (ext) {
     case 0x10: /* SUB */
@@ -1919,15 +1907,15 @@ static ExitStatus trans_sub(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_log(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_log(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
     unsigned cf = extract32(insn, 12, 4);
     unsigned rt = extract32(insn,  0, 5);
     TCGv tcg_r1, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -1939,8 +1927,8 @@ static ExitStatus trans_log(DisasContext *ctx, uint32_t insn,
 }
 
 /* OR r,0,t -> COPY (according to gas) */
-static ExitStatus trans_copy(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_copy(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned r1 = extract32(insn, 16, 5);
     unsigned rt = extract32(insn,  0, 5);
@@ -1953,18 +1941,18 @@ static ExitStatus trans_copy(DisasContext *ctx, uint32_t insn,
         save_gpr(ctx, rt, cpu_gr[r1]);
     }
     cond_free(&ctx->null_cond);
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_cmpclr(DisasContext *ctx, uint32_t insn,
-                               const DisasInsn *di)
+static DisasJumpType trans_cmpclr(DisasContext *ctx, uint32_t insn,
+                                  const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
     unsigned cf = extract32(insn, 12, 4);
     unsigned rt = extract32(insn,  0, 5);
     TCGv tcg_r1, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -1975,15 +1963,15 @@ static ExitStatus trans_cmpclr(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_uxor(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_uxor(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
     unsigned cf = extract32(insn, 12, 4);
     unsigned rt = extract32(insn,  0, 5);
     TCGv tcg_r1, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -1994,8 +1982,8 @@ static ExitStatus trans_uxor(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
-                               const DisasInsn *di)
+static DisasJumpType trans_uaddcm(DisasContext *ctx, uint32_t insn,
+                                  const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
@@ -2003,7 +1991,7 @@ static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
     unsigned is_tc = extract32(insn, 6, 1);
     unsigned rt = extract32(insn,  0, 5);
     TCGv tcg_r1, tcg_r2, tmp;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -2016,15 +2004,15 @@ static ExitStatus trans_uaddcm(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_dcor(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_dcor(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned cf = extract32(insn, 12, 4);
     unsigned is_i = extract32(insn, 6, 1);
     unsigned rt = extract32(insn,  0, 5);
     TCGv tmp;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     nullify_over(ctx);
 
@@ -2041,8 +2029,8 @@ static ExitStatus trans_dcor(DisasContext *ctx, uint32_t insn,
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_ds(DisasContext *ctx, uint32_t insn,
-                           const DisasInsn *di)
+static DisasJumpType trans_ds(DisasContext *ctx, uint32_t insn,
+                              const DisasInsn *di)
 {
     unsigned r2 = extract32(insn, 21, 5);
     unsigned r1 = extract32(insn, 16, 5);
@@ -2105,7 +2093,7 @@ static ExitStatus trans_ds(DisasContext *ctx, uint32_t insn,
     tcg_temp_free(add2);
     tcg_temp_free(dest);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_arith_log[] = {
@@ -2126,7 +2114,7 @@ static const DisasInsn table_arith_log[] = {
     { 0x08000200u, 0xfc000320u, trans_add }, /* shladd */
 };
 
-static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_addi(DisasContext *ctx, uint32_t insn)
 {
     target_long im = low_sextract(insn, 0, 11);
     unsigned e1 = extract32(insn, 11, 1);
@@ -2135,7 +2123,7 @@ static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
     unsigned r2 = extract32(insn, 21, 5);
     unsigned o1 = extract32(insn, 26, 1);
     TCGv tcg_im, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -2148,7 +2136,7 @@ static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_subi(DisasContext *ctx, uint32_t insn)
 {
     target_long im = low_sextract(insn, 0, 11);
     unsigned e1 = extract32(insn, 11, 1);
@@ -2156,7 +2144,7 @@ static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
     unsigned rt = extract32(insn, 16, 5);
     unsigned r2 = extract32(insn, 21, 5);
     TCGv tcg_im, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -2169,14 +2157,14 @@ static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_cmpiclr(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_cmpiclr(DisasContext *ctx, uint32_t insn)
 {
     target_long im = low_sextract(insn, 0, 11);
     unsigned cf = extract32(insn, 12, 4);
     unsigned rt = extract32(insn, 16, 5);
     unsigned r2 = extract32(insn, 21, 5);
     TCGv tcg_im, tcg_r2;
-    ExitStatus ret;
+    DisasJumpType ret;
 
     if (cf) {
         nullify_over(ctx);
@@ -2189,8 +2177,8 @@ static ExitStatus trans_cmpiclr(DisasContext *ctx, uint32_t insn)
     return nullify_end(ctx, ret);
 }
 
-static ExitStatus trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2204,8 +2192,8 @@ static ExitStatus trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
     return do_load(ctx, rt, rb, 0, 0, disp, modify, mop);
 }
 
-static ExitStatus trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2218,8 +2206,8 @@ static ExitStatus trans_ld_idx_x(DisasContext *ctx, uint32_t insn,
     return do_load(ctx, rt, rb, rx, u ? sz : 0, 0, m, mop);
 }
 
-static ExitStatus trans_st_idx_i(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_st_idx_i(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     int disp = low_sextract(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2233,8 +2221,8 @@ static ExitStatus trans_st_idx_i(DisasContext *ctx, uint32_t insn,
     return do_store(ctx, rr, rb, disp, modify, mop);
 }
 
-static ExitStatus trans_ldcw(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_ldcw(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2285,11 +2273,11 @@ static ExitStatus trans_ldcw(DisasContext *ctx, uint32_t insn,
     }
     save_gpr(ctx, rt, dest);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_stby(DisasContext *ctx, uint32_t insn,
-                             const DisasInsn *di)
+static DisasJumpType trans_stby(DisasContext *ctx, uint32_t insn,
+                                const DisasInsn *di)
 {
     target_long disp = low_sextract(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2321,7 +2309,7 @@ static ExitStatus trans_stby(DisasContext *ctx, uint32_t insn,
     }
     tcg_temp_free(addr);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_index_mem[] = {
@@ -2332,7 +2320,7 @@ static const DisasInsn table_index_mem[] = {
     { 0x0c001300u, 0xfc0013c0, trans_stby },
 };
 
-static ExitStatus trans_ldil(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_ldil(DisasContext *ctx, uint32_t insn)
 {
     unsigned rt = extract32(insn, 21, 5);
     target_long i = assemble_21(insn);
@@ -2342,10 +2330,10 @@ static ExitStatus trans_ldil(DisasContext *ctx, uint32_t insn)
     save_gpr(ctx, rt, tcg_rt);
     cond_free(&ctx->null_cond);
 
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_addil(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_addil(DisasContext *ctx, uint32_t insn)
 {
     unsigned rt = extract32(insn, 21, 5);
     target_long i = assemble_21(insn);
@@ -2356,10 +2344,10 @@ static ExitStatus trans_addil(DisasContext *ctx, uint32_t insn)
     save_gpr(ctx, 1, tcg_r1);
     cond_free(&ctx->null_cond);
 
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_ldo(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_ldo(DisasContext *ctx, uint32_t insn)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rt = extract32(insn, 16, 5);
@@ -2376,11 +2364,11 @@ static ExitStatus trans_ldo(DisasContext *ctx, uint32_t insn)
     save_gpr(ctx, rt, tcg_rt);
     cond_free(&ctx->null_cond);
 
-    return NO_EXIT;
+    return DISAS_NEXT;
 }
 
-static ExitStatus trans_load(DisasContext *ctx, uint32_t insn,
-                             bool is_mod, TCGMemOp mop)
+static DisasJumpType trans_load(DisasContext *ctx, uint32_t insn,
+                                bool is_mod, TCGMemOp mop)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rt = extract32(insn, 16, 5);
@@ -2389,7 +2377,7 @@ static ExitStatus trans_load(DisasContext *ctx, uint32_t insn,
     return do_load(ctx, rt, rb, 0, 0, i, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
 }
 
-static ExitStatus trans_load_w(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_load_w(DisasContext *ctx, uint32_t insn)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rt = extract32(insn, 16, 5);
@@ -2410,7 +2398,7 @@ static ExitStatus trans_load_w(DisasContext *ctx, uint32_t insn)
     }
 }
 
-static ExitStatus trans_fload_mod(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_fload_mod(DisasContext *ctx, uint32_t insn)
 {
     target_long i = assemble_16a(insn);
     unsigned t1 = extract32(insn, 1, 1);
@@ -2422,8 +2410,8 @@ static ExitStatus trans_fload_mod(DisasContext *ctx, uint32_t insn)
     return do_floadw(ctx, t1 * 32 + t0, rb, 0, 0, i, (a ? -1 : 1));
 }
 
-static ExitStatus trans_store(DisasContext *ctx, uint32_t insn,
-                              bool is_mod, TCGMemOp mop)
+static DisasJumpType trans_store(DisasContext *ctx, uint32_t insn,
+                                 bool is_mod, TCGMemOp mop)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rt = extract32(insn, 16, 5);
@@ -2432,7 +2420,7 @@ static ExitStatus trans_store(DisasContext *ctx, uint32_t insn,
     return do_store(ctx, rt, rb, i, is_mod ? (i < 0 ? -1 : 1) : 0, mop);
 }
 
-static ExitStatus trans_store_w(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_store_w(DisasContext *ctx, uint32_t insn)
 {
     unsigned rb = extract32(insn, 21, 5);
     unsigned rt = extract32(insn, 16, 5);
@@ -2452,7 +2440,7 @@ static ExitStatus trans_store_w(DisasContext *ctx, uint32_t insn)
     }
 }
 
-static ExitStatus trans_fstore_mod(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_fstore_mod(DisasContext *ctx, uint32_t insn)
 {
     target_long i = assemble_16a(insn);
     unsigned t1 = extract32(insn, 1, 1);
@@ -2464,7 +2452,7 @@ static ExitStatus trans_fstore_mod(DisasContext *ctx, uint32_t insn)
     return do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, (a ? -1 : 1));
 }
 
-static ExitStatus trans_copr_w(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_copr_w(DisasContext *ctx, uint32_t insn)
 {
     unsigned t0 = extract32(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2499,7 +2487,7 @@ static ExitStatus trans_copr_w(DisasContext *ctx, uint32_t insn)
     return gen_illegal(ctx);
 }
 
-static ExitStatus trans_copr_dw(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_copr_dw(DisasContext *ctx, uint32_t insn)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned m = extract32(insn, 5, 1);
@@ -2533,8 +2521,8 @@ static ExitStatus trans_copr_dw(DisasContext *ctx, uint32_t insn)
     }
 }
 
-static ExitStatus trans_cmpb(DisasContext *ctx, uint32_t insn,
-                             bool is_true, bool is_imm, bool is_dw)
+static DisasJumpType trans_cmpb(DisasContext *ctx, uint32_t insn,
+                                bool is_true, bool is_imm, bool is_dw)
 {
     target_long disp = assemble_12(insn) * 4;
     unsigned n = extract32(insn, 1, 1);
@@ -2565,8 +2553,8 @@ static ExitStatus trans_cmpb(DisasContext *ctx, uint32_t insn,
     return do_cbranch(ctx, disp, n, &cond);
 }
 
-static ExitStatus trans_addb(DisasContext *ctx, uint32_t insn,
-                             bool is_true, bool is_imm)
+static DisasJumpType trans_addb(DisasContext *ctx, uint32_t insn,
+                                bool is_true, bool is_imm)
 {
     target_long disp = assemble_12(insn) * 4;
     unsigned n = extract32(insn, 1, 1);
@@ -2607,7 +2595,7 @@ static ExitStatus trans_addb(DisasContext *ctx, uint32_t insn,
     return do_cbranch(ctx, disp, n, &cond);
 }
 
-static ExitStatus trans_bb(DisasContext *ctx, uint32_t insn)
+static DisasJumpType trans_bb(DisasContext *ctx, uint32_t insn)
 {
     target_long disp = assemble_12(insn) * 4;
     unsigned n = extract32(insn, 1, 1);
@@ -2633,7 +2621,7 @@ static ExitStatus trans_bb(DisasContext *ctx, uint32_t insn)
     return do_cbranch(ctx, disp, n, &cond);
 }
 
-static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
+static DisasJumpType trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
 {
     target_long disp = assemble_12(insn) * 4;
     unsigned n = extract32(insn, 1, 1);
@@ -2658,8 +2646,8 @@ static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
     return do_cbranch(ctx, disp, n, &cond);
 }
 
-static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned c = extract32(insn, 13, 3);
@@ -2700,11 +2688,11 @@ static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
-                                  const DisasInsn *di)
+static DisasJumpType trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
+                                     const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned cpos = extract32(insn, 5, 5);
@@ -2741,11 +2729,11 @@ static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
-                                  const DisasInsn *di)
+static DisasJumpType trans_extrw_sar(DisasContext *ctx, uint32_t insn,
+                                     const DisasInsn *di)
 {
     unsigned clen = extract32(insn, 0, 5);
     unsigned is_se = extract32(insn, 10, 1);
@@ -2780,11 +2768,11 @@ static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
-                                  const DisasInsn *di)
+static DisasJumpType trans_extrw_imm(DisasContext *ctx, uint32_t insn,
+                                     const DisasInsn *di)
 {
     unsigned clen = extract32(insn, 0, 5);
     unsigned pos = extract32(insn, 5, 5);
@@ -2814,7 +2802,7 @@ static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_sh_ex[] = {
@@ -2824,8 +2812,8 @@ static const DisasInsn table_sh_ex[] = {
     { 0xd0001800u, 0xfc001800u, trans_extrw_imm },
 };
 
-static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned clen = extract32(insn, 0, 5);
     unsigned cpos = extract32(insn, 5, 5);
@@ -2865,11 +2853,11 @@ static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_depw_imm(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned clen = extract32(insn, 0, 5);
     unsigned cpos = extract32(insn, 5, 5);
@@ -2902,11 +2890,11 @@ static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_depw_sar(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned clen = extract32(insn, 0, 5);
     unsigned nz = extract32(insn, 10, 1);
@@ -2954,7 +2942,7 @@ static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn,
     if (c) {
         ctx->null_cond = do_sed_cond(c, dest);
     }
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_depw[] = {
@@ -2963,7 +2951,7 @@ static const DisasInsn table_depw[] = {
     { 0xd4001800u, 0xfc001800u, trans_depw_imm_c },
 };
 
-static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
+static DisasJumpType trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
 {
     unsigned n = extract32(insn, 1, 1);
     unsigned b = extract32(insn, 21, 5);
@@ -2988,8 +2976,8 @@ static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
     }
 }
 
-static ExitStatus trans_bl(DisasContext *ctx, uint32_t insn,
-                           const DisasInsn *di)
+static DisasJumpType trans_bl(DisasContext *ctx, uint32_t insn,
+                              const DisasInsn *di)
 {
     unsigned n = extract32(insn, 1, 1);
     unsigned link = extract32(insn, 21, 5);
@@ -2998,8 +2986,8 @@ static ExitStatus trans_bl(DisasContext *ctx, uint32_t insn,
     return do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
 }
 
-static ExitStatus trans_bl_long(DisasContext *ctx, uint32_t insn,
-                                const DisasInsn *di)
+static DisasJumpType trans_bl_long(DisasContext *ctx, uint32_t insn,
+                                   const DisasInsn *di)
 {
     unsigned n = extract32(insn, 1, 1);
     target_long disp = assemble_22(insn);
@@ -3007,8 +2995,8 @@ static ExitStatus trans_bl_long(DisasContext *ctx, uint32_t insn,
     return do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
 }
 
-static ExitStatus trans_blr(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_blr(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     unsigned n = extract32(insn, 1, 1);
     unsigned rx = extract32(insn, 16, 5);
@@ -3020,8 +3008,8 @@ static ExitStatus trans_blr(DisasContext *ctx, uint32_t insn,
     return do_ibranch(ctx, tmp, link, n);
 }
 
-static ExitStatus trans_bv(DisasContext *ctx, uint32_t insn,
-                           const DisasInsn *di)
+static DisasJumpType trans_bv(DisasContext *ctx, uint32_t insn,
+                              const DisasInsn *di)
 {
     unsigned n = extract32(insn, 1, 1);
     unsigned rx = extract32(insn, 16, 5);
@@ -3038,8 +3026,8 @@ static ExitStatus trans_bv(DisasContext *ctx, uint32_t insn,
     return do_ibranch(ctx, dest, 0, n);
 }
 
-static ExitStatus trans_bve(DisasContext *ctx, uint32_t insn,
-                            const DisasInsn *di)
+static DisasJumpType trans_bve(DisasContext *ctx, uint32_t insn,
+                               const DisasInsn *di)
 {
     unsigned n = extract32(insn, 1, 1);
     unsigned rb = extract32(insn, 21, 5);
@@ -3056,64 +3044,64 @@ static const DisasInsn table_branch[] = {
     { 0xe800d000u, 0xfc00dffcu, trans_bve },
 };
 
-static ExitStatus trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_wew_0c(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ra = extract32(insn, 21, 5);
     return do_fop_wew(ctx, rt, ra, di->f.wew);
 }
 
-static ExitStatus trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_wew_0e(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = assemble_rt64(insn);
     unsigned ra = assemble_ra64(insn);
     return do_fop_wew(ctx, rt, ra, di->f.wew);
 }
 
-static ExitStatus trans_fop_ded(DisasContext *ctx, uint32_t insn,
-                                const DisasInsn *di)
+static DisasJumpType trans_fop_ded(DisasContext *ctx, uint32_t insn,
+                                   const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ra = extract32(insn, 21, 5);
     return do_fop_ded(ctx, rt, ra, di->f.ded);
 }
 
-static ExitStatus trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_wed_0c(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ra = extract32(insn, 21, 5);
     return do_fop_wed(ctx, rt, ra, di->f.wed);
 }
 
-static ExitStatus trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_wed_0e(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = assemble_rt64(insn);
     unsigned ra = extract32(insn, 21, 5);
     return do_fop_wed(ctx, rt, ra, di->f.wed);
 }
 
-static ExitStatus trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_dew_0c(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ra = extract32(insn, 21, 5);
     return do_fop_dew(ctx, rt, ra, di->f.dew);
 }
 
-static ExitStatus trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fop_dew_0e(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned ra = assemble_ra64(insn);
     return do_fop_dew(ctx, rt, ra, di->f.dew);
 }
 
-static ExitStatus trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
-                                    const DisasInsn *di)
+static DisasJumpType trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
+                                       const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned rb = extract32(insn, 16, 5);
@@ -3121,8 +3109,8 @@ static ExitStatus trans_fop_weww_0c(DisasContext *ctx, uint32_t insn,
     return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
 }
 
-static ExitStatus trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
-                                    const DisasInsn *di)
+static DisasJumpType trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
+                                       const DisasInsn *di)
 {
     unsigned rt = assemble_rt64(insn);
     unsigned rb = assemble_rb64(insn);
@@ -3130,8 +3118,8 @@ static ExitStatus trans_fop_weww_0e(DisasContext *ctx, uint32_t insn,
     return do_fop_weww(ctx, rt, ra, rb, di->f.weww);
 }
 
-static ExitStatus trans_fop_dedd(DisasContext *ctx, uint32_t insn,
-                                 const DisasInsn *di)
+static DisasJumpType trans_fop_dedd(DisasContext *ctx, uint32_t insn,
+                                    const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned rb = extract32(insn, 16, 5);
@@ -3179,8 +3167,8 @@ static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
     tcg_gen_ori_i64(dst, src, INT64_MIN);
 }
 
-static ExitStatus do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
-                            unsigned y, unsigned c)
+static DisasJumpType do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
+                               unsigned y, unsigned c)
 {
     TCGv_i32 ta, tb, tc, ty;
 
@@ -3198,11 +3186,11 @@ static ExitStatus do_fcmp_s(DisasContext *ctx, unsigned ra, unsigned rb,
     tcg_temp_free_i32(ty);
     tcg_temp_free_i32(tc);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
-                                  const DisasInsn *di)
+static DisasJumpType trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
+                                     const DisasInsn *di)
 {
     unsigned c = extract32(insn, 0, 5);
     unsigned y = extract32(insn, 13, 3);
@@ -3211,8 +3199,8 @@ static ExitStatus trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
     return do_fcmp_s(ctx, ra, rb, y, c);
 }
 
-static ExitStatus trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
-                                  const DisasInsn *di)
+static DisasJumpType trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
+                                     const DisasInsn *di)
 {
     unsigned c = extract32(insn, 0, 5);
     unsigned y = extract32(insn, 13, 3);
@@ -3221,8 +3209,8 @@ static ExitStatus trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
     return do_fcmp_s(ctx, ra, rb, y, c);
 }
 
-static ExitStatus trans_fcmp_d(DisasContext *ctx, uint32_t insn,
-                               const DisasInsn *di)
+static DisasJumpType trans_fcmp_d(DisasContext *ctx, uint32_t insn,
+                                  const DisasInsn *di)
 {
     unsigned c = extract32(insn, 0, 5);
     unsigned y = extract32(insn, 13, 3);
@@ -3245,11 +3233,11 @@ static ExitStatus trans_fcmp_d(DisasContext *ctx, uint32_t insn,
     tcg_temp_free_i32(ty);
     tcg_temp_free_i32(tc);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_ftest_t(DisasContext *ctx, uint32_t insn,
-                                const DisasInsn *di)
+static DisasJumpType trans_ftest_t(DisasContext *ctx, uint32_t insn,
+                                   const DisasInsn *di)
 {
     unsigned y = extract32(insn, 13, 3);
     unsigned cbit = (y ^ 1) - 1;
@@ -3263,11 +3251,11 @@ static ExitStatus trans_ftest_t(DisasContext *ctx, uint32_t insn,
     ctx->null_cond = cond_make_0(TCG_COND_NE, t);
     tcg_temp_free(t);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_ftest_q(DisasContext *ctx, uint32_t insn,
-                                const DisasInsn *di)
+static DisasJumpType trans_ftest_q(DisasContext *ctx, uint32_t insn,
+                                   const DisasInsn *di)
 {
     unsigned c = extract32(insn, 0, 5);
     int mask;
@@ -3317,11 +3305,11 @@ static ExitStatus trans_ftest_q(DisasContext *ctx, uint32_t insn,
         ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
     }
  done:
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_xmpyu(DisasContext *ctx, uint32_t insn,
-                              const DisasInsn *di)
+static DisasJumpType trans_xmpyu(DisasContext *ctx, uint32_t insn,
+                                 const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned rb = assemble_rb64(insn);
@@ -3337,7 +3325,7 @@ static ExitStatus trans_xmpyu(DisasContext *ctx, uint32_t insn,
     tcg_temp_free_i64(a);
     tcg_temp_free_i64(b);
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 #define FOP_DED  trans_fop_ded, .f.ded
@@ -3512,7 +3500,8 @@ static inline int fmpyadd_s_reg(unsigned r)
     return (r & 16) * 2 + 16 + (r & 15);
 }
 
-static ExitStatus trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
+static DisasJumpType trans_fmpyadd(DisasContext *ctx,
+                                   uint32_t insn, bool is_sub)
 {
     unsigned tm = extract32(insn, 0, 5);
     unsigned f = extract32(insn, 5, 1);
@@ -3540,11 +3529,11 @@ static ExitStatus trans_fmpyadd(DisasContext *ctx, uint32_t insn, bool is_sub)
                     is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
     }
 
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = assemble_rt64(insn);
     unsigned neg = extract32(insn, 5, 1);
@@ -3568,11 +3557,11 @@ static ExitStatus trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
     tcg_temp_free_i32(c);
     save_frw_i32(rt, a);
     tcg_temp_free_i32(a);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
-static ExitStatus trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
-                                   const DisasInsn *di)
+static DisasJumpType trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
+                                      const DisasInsn *di)
 {
     unsigned rt = extract32(insn, 0, 5);
     unsigned neg = extract32(insn, 5, 1);
@@ -3596,7 +3585,7 @@ static ExitStatus trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
     tcg_temp_free_i64(c);
     save_frd(rt, a);
     tcg_temp_free_i64(a);
-    return nullify_end(ctx, NO_EXIT);
+    return nullify_end(ctx, DISAS_NEXT);
 }
 
 static const DisasInsn table_fp_fused[] = {
@@ -3604,8 +3593,8 @@ static const DisasInsn table_fp_fused[] = {
     { 0xb8000800u, 0xfc0019c0u, trans_fmpyfadd_d }
 };
 
-static ExitStatus translate_table_int(DisasContext *ctx, uint32_t insn,
-                                      const DisasInsn table[], size_t n)
+static DisasJumpType translate_table_int(DisasContext *ctx, uint32_t insn,
+                                         const DisasInsn table[], size_t n)
 {
     size_t i;
     for (i = 0; i < n; ++i) {
@@ -3619,7 +3608,7 @@ static ExitStatus translate_table_int(DisasContext *ctx, uint32_t insn,
 #define translate_table(ctx, insn, table) \
     translate_table_int(ctx, insn, table, ARRAY_SIZE(table))
 
-static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
+static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
 {
     uint32_t opc = extract32(insn, 26, 6);
 
@@ -3740,188 +3729,201 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
     return gen_illegal(ctx);
 }
 
-void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
+static int hppa_tr_init_disas_context(DisasContextBase *dcbase,
+                                      CPUState *cs, int max_insns)
 {
-    CPUHPPAState *env = cs->env_ptr;
-    DisasContext ctx;
-    ExitStatus ret;
-    int num_insns, max_insns, i;
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+    TranslationBlock *tb = ctx->base.tb;
+    int i, bound;
 
-    ctx.tb = tb;
-    ctx.cs = cs;
-    ctx.iaoq_f = tb->pc;
-    ctx.iaoq_b = tb->cs_base;
-    ctx.singlestep_enabled = cs->singlestep_enabled;
+    ctx->cs = cs;
+    ctx->iaoq_f = tb->pc;
+    ctx->iaoq_b = tb->cs_base;
+    ctx->iaoq_n = -1;
+    TCGV_UNUSED(ctx->iaoq_n_var);
 
-    ctx.ntemps = 0;
-    for (i = 0; i < ARRAY_SIZE(ctx.temps); ++i) {
-        TCGV_UNUSED(ctx.temps[i]);
+    ctx->ntemps = 0;
+    for (i = 0; i < ARRAY_SIZE(ctx->temps); ++i) {
+        TCGV_UNUSED(ctx->temps[i]);
     }
 
-    /* Compute the maximum number of insns to execute, as bounded by
-       (1) icount, (2) single-stepping, (3) branch delay slots, or
-       (4) the number of insns remaining on the current page.  */
-    max_insns = tb->cflags & CF_COUNT_MASK;
-    if (max_insns == 0) {
-        max_insns = CF_COUNT_MASK;
-    }
-    if (ctx.singlestep_enabled || singlestep) {
-        max_insns = 1;
-    } else if (max_insns > TCG_MAX_INSNS) {
-        max_insns = TCG_MAX_INSNS;
-    }
+    bound = -(tb->pc | TARGET_PAGE_MASK) / 4;
+    return MIN(max_insns, bound);
+}
 
-    num_insns = 0;
-    gen_tb_start(tb);
+static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
     /* Seed the nullification status from PSW[N], as shown in TB->FLAGS.  */
-    ctx.null_cond = cond_make_f();
-    ctx.psw_n_nonzero = false;
-    if (tb->flags & 1) {
-        ctx.null_cond.c = TCG_COND_ALWAYS;
-        ctx.psw_n_nonzero = true;
+    ctx->null_cond = cond_make_f();
+    ctx->psw_n_nonzero = false;
+    if (ctx->base.tb->flags & 1) {
+        ctx->null_cond.c = TCG_COND_ALWAYS;
+        ctx->psw_n_nonzero = true;
     }
-    ctx.null_lab = NULL;
+    ctx->null_lab = NULL;
+}
 
-    do {
-        tcg_gen_insn_start(ctx.iaoq_f, ctx.iaoq_b);
-        num_insns++;
+static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-        if (unlikely(cpu_breakpoint_test(cs, ctx.iaoq_f, BP_ANY))) {
-            ret = gen_excp(&ctx, EXCP_DEBUG);
-            break;
-        }
-        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
-            gen_io_start();
-        }
+    tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b);
+}
+
+static bool hppa_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
+                                      const CPUBreakpoint *bp)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-        if (ctx.iaoq_f < TARGET_PAGE_SIZE) {
-            ret = do_page_zero(&ctx);
-            assert(ret != NO_EXIT);
+    ctx->base.is_jmp = gen_excp(ctx, EXCP_DEBUG);
+    ctx->base.pc_next = ctx->iaoq_f + 4;
+    return true;
+}
+
+static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+    CPUHPPAState *env = cs->env_ptr;
+    DisasJumpType ret;
+    int i, n;
+
+    /* Execute one insn.  */
+    if (ctx->iaoq_f < TARGET_PAGE_SIZE) {
+        ret = do_page_zero(ctx);
+        assert(ret != DISAS_NEXT);
+    } else {
+        /* Always fetch the insn, even if nullified, so that we check
+           the page permissions for execute.  */
+        uint32_t insn = cpu_ldl_code(env, ctx->iaoq_f);
+
+        /* Set up the IA queue for the next insn.
+           This will be overwritten by a branch.  */
+        if (ctx->iaoq_b == -1) {
+            ctx->iaoq_n = -1;
+            ctx->iaoq_n_var = get_temp(ctx);
+            tcg_gen_addi_tl(ctx->iaoq_n_var, cpu_iaoq_b, 4);
         } else {
-            /* Always fetch the insn, even if nullified, so that we check
-               the page permissions for execute.  */
-            uint32_t insn = cpu_ldl_code(env, ctx.iaoq_f);
-
-            /* Set up the IA queue for the next insn.
-               This will be overwritten by a branch.  */
-            if (ctx.iaoq_b == -1) {
-                ctx.iaoq_n = -1;
-                ctx.iaoq_n_var = get_temp(&ctx);
-                tcg_gen_addi_tl(ctx.iaoq_n_var, cpu_iaoq_b, 4);
-            } else {
-                ctx.iaoq_n = ctx.iaoq_b + 4;
-                TCGV_UNUSED(ctx.iaoq_n_var);
-            }
-
-            if (unlikely(ctx.null_cond.c == TCG_COND_ALWAYS)) {
-                ctx.null_cond.c = TCG_COND_NEVER;
-                ret = NO_EXIT;
-            } else {
-                ret = translate_one(&ctx, insn);
-                assert(ctx.null_lab == NULL);
-            }
+            ctx->iaoq_n = ctx->iaoq_b + 4;
+            TCGV_UNUSED(ctx->iaoq_n_var);
         }
 
-        for (i = 0; i < ctx.ntemps; ++i) {
-            tcg_temp_free(ctx.temps[i]);
-            TCGV_UNUSED(ctx.temps[i]);
-        }
-        ctx.ntemps = 0;
-
-        /* If we see non-linear instructions, exhaust instruction count,
-           or run out of buffer space, stop generation.  */
-        /* ??? The non-linear instruction restriction is purely due to
-           the debugging dump.  Otherwise we *could* follow unconditional
-           branches within the same page.  */
-        if (ret == NO_EXIT
-            && (ctx.iaoq_b != ctx.iaoq_f + 4
-                || num_insns >= max_insns
-                || tcg_op_buf_full())) {
-            if (ctx.null_cond.c == TCG_COND_NEVER
-                || ctx.null_cond.c == TCG_COND_ALWAYS) {
-                nullify_set(&ctx, ctx.null_cond.c == TCG_COND_ALWAYS);
-                gen_goto_tb(&ctx, 0, ctx.iaoq_b, ctx.iaoq_n);
-                ret = EXIT_GOTO_TB;
-            } else {
-                ret = EXIT_IAQ_N_STALE;
-            }
+        if (unlikely(ctx->null_cond.c == TCG_COND_ALWAYS)) {
+            ctx->null_cond.c = TCG_COND_NEVER;
+            ret = DISAS_NEXT;
+        } else {
+            ret = translate_one(ctx, insn);
+            assert(ctx->null_lab == NULL);
         }
+    }
 
-        ctx.iaoq_f = ctx.iaoq_b;
-        ctx.iaoq_b = ctx.iaoq_n;
-        if (ret == EXIT_NORETURN
-            || ret == EXIT_GOTO_TB
-            || ret == EXIT_IAQ_N_UPDATED) {
-            break;
-        }
-        if (ctx.iaoq_f == -1) {
-            tcg_gen_mov_tl(cpu_iaoq_f, cpu_iaoq_b);
-            copy_iaoq_entry(cpu_iaoq_b, ctx.iaoq_n, ctx.iaoq_n_var);
-            nullify_save(&ctx);
-            ret = EXIT_IAQ_N_UPDATED;
-            break;
-        }
-        if (ctx.iaoq_b == -1) {
-            tcg_gen_mov_tl(cpu_iaoq_b, ctx.iaoq_n_var);
-        }
-    } while (ret == NO_EXIT);
+    /* Free any temporaries allocated.  */
+    for (i = 0, n = ctx->ntemps; i < n; ++i) {
+        tcg_temp_free(ctx->temps[i]);
+        TCGV_UNUSED(ctx->temps[i]);
+    }
+    ctx->ntemps = 0;
 
-    if (tb->cflags & CF_LAST_IO) {
-        gen_io_end();
+    /* Advance the insn queue.  */
+    /* ??? The non-linear instruction restriction is purely due to
+       the debugging dump.  Otherwise we *could* follow unconditional
+       branches within the same page.  */
+    if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
+        if (ctx->null_cond.c == TCG_COND_NEVER
+            || ctx->null_cond.c == TCG_COND_ALWAYS) {
+            nullify_set(ctx, ctx->null_cond.c == TCG_COND_ALWAYS);
+            gen_goto_tb(ctx, 0, ctx->iaoq_b, ctx->iaoq_n);
+            ret = DISAS_NORETURN;
+        } else {
+            ret = DISAS_IAQ_N_STALE;
+       }
+    }
+    ctx->iaoq_f = ctx->iaoq_b;
+    ctx->iaoq_b = ctx->iaoq_n;
+    ctx->base.is_jmp = ret;
+
+    if (ret == DISAS_NORETURN || ret == DISAS_IAQ_N_UPDATED) {
+        return;
+    }
+    if (ctx->iaoq_f == -1) {
+        tcg_gen_mov_tl(cpu_iaoq_f, cpu_iaoq_b);
+        copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
+        nullify_save(ctx);
+        ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
+    } else if (ctx->iaoq_b == -1) {
+        tcg_gen_mov_tl(cpu_iaoq_b, ctx->iaoq_n_var);
     }
+}
 
-    switch (ret) {
-    case EXIT_GOTO_TB:
-    case EXIT_NORETURN:
+static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
+{
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+    switch (ctx->base.is_jmp) {
+    case DISAS_NORETURN:
         break;
-    case EXIT_IAQ_N_STALE:
-        copy_iaoq_entry(cpu_iaoq_f, ctx.iaoq_f, cpu_iaoq_f);
-        copy_iaoq_entry(cpu_iaoq_b, ctx.iaoq_b, cpu_iaoq_b);
-        nullify_save(&ctx);
+    case DISAS_TOO_MANY:
+    case DISAS_IAQ_N_STALE:
+        copy_iaoq_entry(cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
+        copy_iaoq_entry(cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
+        nullify_save(ctx);
         /* FALLTHRU */
-    case EXIT_IAQ_N_UPDATED:
-        if (ctx.singlestep_enabled) {
+    case DISAS_IAQ_N_UPDATED:
+        if (ctx->base.singlestep_enabled) {
             gen_excp_1(EXCP_DEBUG);
         } else {
             tcg_gen_lookup_and_goto_ptr(cpu_iaoq_f);
         }
         break;
     default:
-        abort();
+        g_assert_not_reached();
     }
 
-    gen_tb_end(tb, num_insns);
+    /* We don't actually use this during normal translation,
+       but we should interact with the generic main loop.  */
+    ctx->base.pc_next = ctx->base.tb->pc + 4 * ctx->base.num_insns;
+}
 
-    tb->size = num_insns * 4;
-    tb->icount = num_insns;
+static void hppa_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
+{
+    TranslationBlock *tb = dcbase->tb;
 
-#ifdef DEBUG_DISAS
-    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
-        && qemu_log_in_addr_range(tb->pc)) {
-        qemu_log_lock();
-        switch (tb->pc) {
-        case 0x00:
-            qemu_log("IN:\n0x00000000:  (null)\n\n");
-            break;
-        case 0xb0:
-            qemu_log("IN:\n0x000000b0:  light-weight-syscall\n\n");
-            break;
-        case 0xe0:
-            qemu_log("IN:\n0x000000e0:  set-thread-pointer-syscall\n\n");
-            break;
-        case 0x100:
-            qemu_log("IN:\n0x00000100:  syscall\n\n");
-            break;
-        default:
-            qemu_log("IN: %s\n", lookup_symbol(tb->pc));
-            log_target_disas(cs, tb->pc, tb->size, 1);
-            qemu_log("\n");
-            break;
-        }
-        qemu_log_unlock();
+    switch (tb->pc) {
+    case 0x00:
+        qemu_log("IN:\n0x00000000:  (null)\n");
+        break;
+    case 0xb0:
+        qemu_log("IN:\n0x000000b0:  light-weight-syscall\n");
+        break;
+    case 0xe0:
+        qemu_log("IN:\n0x000000e0:  set-thread-pointer-syscall\n");
+        break;
+    case 0x100:
+        qemu_log("IN:\n0x00000100:  syscall\n");
+        break;
+    default:
+        qemu_log("IN: %s\n", lookup_symbol(tb->pc));
+        log_target_disas(cs, tb->pc, tb->size, 1);
+        break;
     }
-#endif
+}
+
+static const TranslatorOps hppa_tr_ops = {
+    .init_disas_context = hppa_tr_init_disas_context,
+    .tb_start           = hppa_tr_tb_start,
+    .insn_start         = hppa_tr_insn_start,
+    .breakpoint_check   = hppa_tr_breakpoint_check,
+    .translate_insn     = hppa_tr_translate_insn,
+    .tb_stop            = hppa_tr_tb_stop,
+    .disas_log          = hppa_tr_disas_log,
+};
+
+void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
+
+{
+    DisasContext ctx;
+    translator_loop(&hppa_tr_ops, &ctx.base, cs, tb);
 }
 
 void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,