/*
 * HPPA emulation cpu translation for qemu.
 *
 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "disas/disas.h"
#include "qemu/host-utils.h"
#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 "trace-tcg.h"
#include "exec/log.h"

typedef struct DisasCond {
    TCGCond c;
    TCGv a0, a1;
    bool a0_is_n;
    bool a1_is_0;
} DisasCond;

typedef struct DisasContext {
    struct TranslationBlock *tb;
    CPUState *cs;

    target_ulong iaoq_f;
    target_ulong iaoq_b;
    target_ulong iaoq_n;
    TCGv iaoq_n_var;

    int ntemps;
    TCGv temps[8];

    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,

    /* 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 ending the TB with a noreturn function call, e.g. longjmp.
       No following code will be executed.  */
    EXIT_NORETURN,
} ExitStatus;

typedef struct DisasInsn {
    uint32_t insn, mask;
    ExitStatus (*trans)(DisasContext *ctx, uint32_t insn,
                        const struct DisasInsn *f);
    union {
        void (*f_ttt)(TCGv, TCGv, TCGv);
        void (*f_weww)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32);
        void (*f_dedd)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64);
        void (*f_wew)(TCGv_i32, TCGv_env, TCGv_i32);
        void (*f_ded)(TCGv_i64, TCGv_env, TCGv_i64);
        void (*f_wed)(TCGv_i32, TCGv_env, TCGv_i64);
        void (*f_dew)(TCGv_i64, TCGv_env, TCGv_i32);
    };
} DisasInsn;

/* global register indexes */
static TCGv_env cpu_env;
static TCGv cpu_gr[32];
static TCGv cpu_iaoq_f;
static TCGv cpu_iaoq_b;
static TCGv cpu_sar;
static TCGv cpu_psw_n;
static TCGv cpu_psw_v;
static TCGv cpu_psw_cb;
static TCGv cpu_psw_cb_msb;
static TCGv cpu_cr26;
static TCGv cpu_cr27;

#include "exec/gen-icount.h"

void hppa_translate_init(void)
{
#define DEF_VAR(V)  { &cpu_##V, #V, offsetof(CPUHPPAState, V) }

    typedef struct { TCGv *var; const char *name; int ofs; } GlobalVar;
    static const GlobalVar vars[] = {
        DEF_VAR(sar),
        DEF_VAR(cr26),
        DEF_VAR(cr27),
        DEF_VAR(psw_n),
        DEF_VAR(psw_v),
        DEF_VAR(psw_cb),
        DEF_VAR(psw_cb_msb),
        DEF_VAR(iaoq_f),
        DEF_VAR(iaoq_b),
    };

#undef DEF_VAR

    /* Use the symbolic register names that match the disassembler.  */
    static const char gr_names[32][4] = {
        "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
        "r8",  "r9",  "r10", "r11", "r12", "r13", "r14", "r15",
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
    };

    static bool done_init = 0;
    int i;

    if (done_init) {
        return;
    }
    done_init = 1;

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
    tcg_ctx.tcg_env = cpu_env;

    TCGV_UNUSED(cpu_gr[0]);
    for (i = 1; i < 32; i++) {
        cpu_gr[i] = tcg_global_mem_new(cpu_env,
                                       offsetof(CPUHPPAState, gr[i]),
                                       gr_names[i]);
    }

    for (i = 0; i < ARRAY_SIZE(vars); ++i) {
        const GlobalVar *v = &vars[i];
        *v->var = tcg_global_mem_new(cpu_env, v->ofs, v->name);
    }
}

static DisasCond cond_make_f(void)
{
    DisasCond r = { .c = TCG_COND_NEVER };
    TCGV_UNUSED(r.a0);
    TCGV_UNUSED(r.a1);
    return r;
}

static DisasCond cond_make_n(void)
{
    DisasCond r = { .c = TCG_COND_NE, .a0_is_n = true, .a1_is_0 = true };
    r.a0 = cpu_psw_n;
    TCGV_UNUSED(r.a1);
    return r;
}

static DisasCond cond_make_0(TCGCond c, TCGv a0)
{
    DisasCond r = { .c = c, .a1_is_0 = true };

    assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
    r.a0 = tcg_temp_new();
    tcg_gen_mov_tl(r.a0, a0);
    TCGV_UNUSED(r.a1);

    return r;
}

static DisasCond cond_make(TCGCond c, TCGv a0, TCGv a1)
{
    DisasCond r = { .c = c };

    assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
    r.a0 = tcg_temp_new();
    tcg_gen_mov_tl(r.a0, a0);
    r.a1 = tcg_temp_new();
    tcg_gen_mov_tl(r.a1, a1);

    return r;
}

static void cond_prep(DisasCond *cond)
{
    if (cond->a1_is_0) {
        cond->a1_is_0 = false;
        cond->a1 = tcg_const_tl(0);
    }
}

static void cond_free(DisasCond *cond)
{
    switch (cond->c) {
    default:
        if (!cond->a0_is_n) {
            tcg_temp_free(cond->a0);
        }
        if (!cond->a1_is_0) {
            tcg_temp_free(cond->a1);
        }
        cond->a0_is_n = false;
        cond->a1_is_0 = false;
        TCGV_UNUSED(cond->a0);
        TCGV_UNUSED(cond->a1);
        /* fallthru */
    case TCG_COND_ALWAYS:
        cond->c = TCG_COND_NEVER;
        break;
    case TCG_COND_NEVER:
        break;
    }
}

static TCGv get_temp(DisasContext *ctx)
{
    unsigned i = ctx->ntemps++;
    g_assert(i < ARRAY_SIZE(ctx->temps));
    return ctx->temps[i] = tcg_temp_new();
}

static TCGv load_const(DisasContext *ctx, target_long v)
{
    TCGv t = get_temp(ctx);
    tcg_gen_movi_tl(t, v);
    return t;
}

static TCGv load_gpr(DisasContext *ctx, unsigned reg)
{
    if (reg == 0) {
        TCGv t = get_temp(ctx);
        tcg_gen_movi_tl(t, 0);
        return t;
    } else {
        return cpu_gr[reg];
    }
}

static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
{
    if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) {
        return get_temp(ctx);
    } else {
        return cpu_gr[reg];
    }
}

static void save_or_nullify(DisasContext *ctx, TCGv dest, TCGv t)
{
    if (ctx->null_cond.c != TCG_COND_NEVER) {
        cond_prep(&ctx->null_cond);
        tcg_gen_movcond_tl(ctx->null_cond.c, dest, ctx->null_cond.a0,
                           ctx->null_cond.a1, dest, t);
    } else {
        tcg_gen_mov_tl(dest, t);
    }
}

static void save_gpr(DisasContext *ctx, unsigned reg, TCGv t)
{
    if (reg != 0) {
        save_or_nullify(ctx, cpu_gr[reg], t);
    }
}

#ifdef HOST_WORDS_BIGENDIAN
# define HI_OFS  0
# define LO_OFS  4
#else
# define HI_OFS  4
# define LO_OFS  0
#endif

static TCGv_i32 load_frw_i32(unsigned rt)
{
    TCGv_i32 ret = tcg_temp_new_i32();
    tcg_gen_ld_i32(ret, cpu_env,
                   offsetof(CPUHPPAState, fr[rt & 31])
                   + (rt & 32 ? LO_OFS : HI_OFS));
    return ret;
}

static TCGv_i32 load_frw0_i32(unsigned rt)
{
    if (rt == 0) {
        return tcg_const_i32(0);
    } else {
        return load_frw_i32(rt);
    }
}

static TCGv_i64 load_frw0_i64(unsigned rt)
{
    if (rt == 0) {
        return tcg_const_i64(0);
    } else {
        TCGv_i64 ret = tcg_temp_new_i64();
        tcg_gen_ld32u_i64(ret, cpu_env,
                          offsetof(CPUHPPAState, fr[rt & 31])
                          + (rt & 32 ? LO_OFS : HI_OFS));
        return ret;
    }
}

static void save_frw_i32(unsigned rt, TCGv_i32 val)
{
    tcg_gen_st_i32(val, cpu_env,
                   offsetof(CPUHPPAState, fr[rt & 31])
                   + (rt & 32 ? LO_OFS : HI_OFS));
}

#undef HI_OFS
#undef LO_OFS

static TCGv_i64 load_frd(unsigned rt)
{
    TCGv_i64 ret = tcg_temp_new_i64();
    tcg_gen_ld_i64(ret, cpu_env, offsetof(CPUHPPAState, fr[rt]));
    return ret;
}

static TCGv_i64 load_frd0(unsigned rt)
{
    if (rt == 0) {
        return tcg_const_i64(0);
    } else {
        return load_frd(rt);
    }
}

static void save_frd(unsigned rt, TCGv_i64 val)
{
    tcg_gen_st_i64(val, cpu_env, offsetof(CPUHPPAState, fr[rt]));
}

/* Skip over the implementation of an insn that has been nullified.
   Use this when the insn is too complex for a conditional move.  */
static void nullify_over(DisasContext *ctx)
{
    if (ctx->null_cond.c != TCG_COND_NEVER) {
        /* The always condition should have been handled in the main loop.  */
        assert(ctx->null_cond.c != TCG_COND_ALWAYS);

        ctx->null_lab = gen_new_label();
        cond_prep(&ctx->null_cond);

        /* If we're using PSW[N], copy it to a temp because... */
        if (ctx->null_cond.a0_is_n) {
            ctx->null_cond.a0_is_n = false;
            ctx->null_cond.a0 = tcg_temp_new();
            tcg_gen_mov_tl(ctx->null_cond.a0, cpu_psw_n);
        }
        /* ... we clear it before branching over the implementation,
           so that (1) it's clear after nullifying this insn and
           (2) if this insn nullifies the next, PSW[N] is valid.  */
        if (ctx->psw_n_nonzero) {
            ctx->psw_n_nonzero = false;
            tcg_gen_movi_tl(cpu_psw_n, 0);
        }

        tcg_gen_brcond_tl(ctx->null_cond.c, ctx->null_cond.a0,
                          ctx->null_cond.a1, ctx->null_lab);
        cond_free(&ctx->null_cond);
    }
}

/* Save the current nullification state to PSW[N].  */
static void nullify_save(DisasContext *ctx)
{
    if (ctx->null_cond.c == TCG_COND_NEVER) {
        if (ctx->psw_n_nonzero) {
            tcg_gen_movi_tl(cpu_psw_n, 0);
        }
        return;
    }
    if (!ctx->null_cond.a0_is_n) {
        cond_prep(&ctx->null_cond);
        tcg_gen_setcond_tl(ctx->null_cond.c, cpu_psw_n,
                           ctx->null_cond.a0, ctx->null_cond.a1);
        ctx->psw_n_nonzero = true;
    }
    cond_free(&ctx->null_cond);
}

/* Set a PSW[N] to X.  The intention is that this is used immediately
   before a goto_tb/exit_tb, so that there is no fallthru path to other
   code within the TB.  Therefore we do not update psw_n_nonzero.  */
static void nullify_set(DisasContext *ctx, bool x)
{
    if (ctx->psw_n_nonzero || x) {
        tcg_gen_movi_tl(cpu_psw_n, 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)
{
    TCGLabel *null_lab = ctx->null_lab;

    if (likely(null_lab == NULL)) {
        /* The current insn wasn't conditional or handled the condition
           applied to it without a branch, so the (new) setting of
           NULL_COND can be applied directly to the next insn.  */
        return status;
    }
    ctx->null_lab = NULL;

    if (likely(ctx->null_cond.c == TCG_COND_NEVER)) {
        /* The next instruction will be unconditional,
           and NULL_COND already reflects that.  */
        gen_set_label(null_lab);
    } else {
        /* The insn that we just executed is itself nullifying the next
           instruction.  Store the condition in the PSW[N] global.
           We asserted PSW[N] = 0 in nullify_over, so that after the
           label we have the proper value in place.  */
        nullify_save(ctx);
        gen_set_label(null_lab);
        ctx->null_cond = cond_make_n();
    }

    assert(status != EXIT_GOTO_TB && status != EXIT_IAQ_N_UPDATED);
    if (status == EXIT_NORETURN) {
        status = NO_EXIT;
    }
    return status;
}

static void copy_iaoq_entry(TCGv dest, target_ulong ival, TCGv vval)
{
    if (unlikely(ival == -1)) {
        tcg_gen_mov_tl(dest, vval);
    } else {
        tcg_gen_movi_tl(dest, ival);
    }
}

static inline target_ulong iaoq_dest(DisasContext *ctx, target_long disp)
{
    return ctx->iaoq_f + disp + 8;
}

static void gen_excp_1(int exception)
{
    TCGv_i32 t = tcg_const_i32(exception);
    gen_helper_excp(cpu_env, t);
    tcg_temp_free_i32(t);
}

static ExitStatus 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;
}

static ExitStatus gen_illegal(DisasContext *ctx)
{
    nullify_over(ctx);
    return nullify_end(ctx, gen_excp(ctx, EXCP_SIGILL));
}

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) {
        return false;
    }
    return true;
}

/* If the next insn is to be nullified, and it's on the same page,
   and we're not attempting to set a breakpoint on it, then we can
   totally skip the nullified insn.  This avoids creating and
   executing a TB that merely branches to the next TB.  */
static bool use_nullify_skip(DisasContext *ctx)
{
    return (((ctx->iaoq_b ^ ctx->iaoq_f) & TARGET_PAGE_MASK) == 0
            && !cpu_breakpoint_test(ctx->cs, ctx->iaoq_b, BP_ANY));
}

static void gen_goto_tb(DisasContext *ctx, int which,
                        target_ulong f, target_ulong b)
{
    if (f != -1 && b != -1 && use_goto_tb(ctx, f)) {
        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);
    } 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) {
            gen_excp_1(EXCP_DEBUG);
        } else {
            tcg_gen_exit_tb(0);
        }
    }
}

/* PA has a habit of taking the LSB of a field and using that as the sign,
   with the rest of the field becoming the least significant bits.  */
static target_long low_sextract(uint32_t val, int pos, int len)
{
    target_ulong x = -(target_ulong)extract32(val, pos, 1);
    x = (x << (len - 1)) | extract32(val, pos + 1, len - 1);
    return x;
}

static unsigned assemble_rt64(uint32_t insn)
{
    unsigned r1 = extract32(insn, 6, 1);
    unsigned r0 = extract32(insn, 0, 5);
    return r1 * 32 + r0;
}

static unsigned assemble_ra64(uint32_t insn)
{
    unsigned r1 = extract32(insn, 7, 1);
    unsigned r0 = extract32(insn, 21, 5);
    return r1 * 32 + r0;
}

static unsigned assemble_rb64(uint32_t insn)
{
    unsigned r1 = extract32(insn, 12, 1);
    unsigned r0 = extract32(insn, 16, 5);
    return r1 * 32 + r0;
}

static unsigned assemble_rc64(uint32_t insn)
{
    unsigned r2 = extract32(insn, 8, 1);
    unsigned r1 = extract32(insn, 13, 3);
    unsigned r0 = extract32(insn, 9, 2);
    return r2 * 32 + r1 * 4 + r0;
}

static target_long assemble_12(uint32_t insn)
{
    target_ulong x = -(target_ulong)(insn & 1);
    x = (x <<  1) | extract32(insn, 2, 1);
    x = (x << 10) | extract32(insn, 3, 10);
    return x;
}

static target_long assemble_16(uint32_t insn)
{
    /* Take the name from PA2.0, which produces a 16-bit number
       only with wide mode; otherwise a 14-bit number.  Since we don't
       implement wide mode, this is always the 14-bit number.  */
    return low_sextract(insn, 0, 14);
}

static target_long assemble_16a(uint32_t insn)
{
    /* Take the name from PA2.0, which produces a 14-bit shifted number
       only with wide mode; otherwise a 12-bit shifted number.  Since we
       don't implement wide mode, this is always the 12-bit number.  */
    target_ulong x = -(target_ulong)(insn & 1);
    x = (x << 11) | extract32(insn, 2, 11);
    return x << 2;
}

static target_long assemble_17(uint32_t insn)
{
    target_ulong x = -(target_ulong)(insn & 1);
    x = (x <<  5) | extract32(insn, 16, 5);
    x = (x <<  1) | extract32(insn, 2, 1);
    x = (x << 10) | extract32(insn, 3, 10);
    return x << 2;
}

static target_long assemble_21(uint32_t insn)
{
    target_ulong x = -(target_ulong)(insn & 1);
    x = (x << 11) | extract32(insn, 1, 11);
    x = (x <<  2) | extract32(insn, 14, 2);
    x = (x <<  5) | extract32(insn, 16, 5);
    x = (x <<  2) | extract32(insn, 12, 2);
    return x << 11;
}

static target_long assemble_22(uint32_t insn)
{
    target_ulong x = -(target_ulong)(insn & 1);
    x = (x << 10) | extract32(insn, 16, 10);
    x = (x <<  1) | extract32(insn, 2, 1);
    x = (x << 10) | extract32(insn, 3, 10);
    return x << 2;
}

/* The parisc documentation describes only the general interpretation of
   the conditions, without describing their exact implementation.  The
   interpretations do not stand up well when considering ADD,C and SUB,B.
   However, considering the Addition, Subtraction and Logical conditions
   as a whole it would appear that these relations are similar to what
   a traditional NZCV set of flags would produce.  */

static DisasCond do_cond(unsigned cf, TCGv res, TCGv cb_msb, TCGv sv)
{
    DisasCond cond;
    TCGv tmp;

    switch (cf >> 1) {
    case 0: /* Never / TR */
        cond = cond_make_f();
        break;
    case 1: /* = / <>        (Z / !Z) */
        cond = cond_make_0(TCG_COND_EQ, res);
        break;
    case 2: /* < / >=        (N / !N) */
        cond = cond_make_0(TCG_COND_LT, res);
        break;
    case 3: /* <= / >        (N | Z / !N & !Z) */
        cond = cond_make_0(TCG_COND_LE, res);
        break;
    case 4: /* NUV / UV      (!C / C) */
        cond = cond_make_0(TCG_COND_EQ, cb_msb);
        break;
    case 5: /* ZNV / VNZ     (!C | Z / C & !Z) */
        tmp = tcg_temp_new();
        tcg_gen_neg_tl(tmp, cb_msb);
        tcg_gen_and_tl(tmp, tmp, res);
        cond = cond_make_0(TCG_COND_EQ, tmp);
        tcg_temp_free(tmp);
        break;
    case 6: /* SV / NSV      (V / !V) */
        cond = cond_make_0(TCG_COND_LT, sv);
        break;
    case 7: /* OD / EV */
        tmp = tcg_temp_new();
        tcg_gen_andi_tl(tmp, res, 1);
        cond = cond_make_0(TCG_COND_NE, tmp);
        tcg_temp_free(tmp);
        break;
    default:
        g_assert_not_reached();
    }
    if (cf & 1) {
        cond.c = tcg_invert_cond(cond.c);
    }

    return cond;
}

/* Similar, but for the special case of subtraction without borrow, we
   can use the inputs directly.  This can allow other computation to be
   deleted as unused.  */

static DisasCond do_sub_cond(unsigned cf, TCGv res, TCGv in1, TCGv in2, TCGv sv)
{
    DisasCond cond;

    switch (cf >> 1) {
    case 1: /* = / <> */
        cond = cond_make(TCG_COND_EQ, in1, in2);
        break;
    case 2: /* < / >= */
        cond = cond_make(TCG_COND_LT, in1, in2);
        break;
    case 3: /* <= / > */
        cond = cond_make(TCG_COND_LE, in1, in2);
        break;
    case 4: /* << / >>= */
        cond = cond_make(TCG_COND_LTU, in1, in2);
        break;
    case 5: /* <<= / >> */
        cond = cond_make(TCG_COND_LEU, in1, in2);
        break;
    default:
        return do_cond(cf, res, sv, sv);
    }
    if (cf & 1) {
        cond.c = tcg_invert_cond(cond.c);
    }

    return cond;
}

/* Similar, but for logicals, where the carry and overflow bits are not
   computed, and use of them is undefined.  */

static DisasCond do_log_cond(unsigned cf, TCGv res)
{
    switch (cf >> 1) {
    case 4: case 5: case 6:
        cf &= 1;
        break;
    }
    return do_cond(cf, res, res, res);
}

/* Similar, but for shift/extract/deposit conditions.  */

static DisasCond do_sed_cond(unsigned orig, TCGv res)
{
    unsigned c, f;

    /* Convert the compressed condition codes to standard.
       0-2 are the same as logicals (nv,<,<=), while 3 is OD.
       4-7 are the reverse of 0-3.  */
    c = orig & 3;
    if (c == 3) {
        c = 7;
    }
    f = (orig & 4) / 4;

    return do_log_cond(c * 2 + f, res);
}

/* Similar, but for unit conditions.  */

static DisasCond do_unit_cond(unsigned cf, TCGv res, TCGv in1, TCGv in2)
{
    DisasCond cond;
    TCGv tmp, cb;

    TCGV_UNUSED(cb);
    if (cf & 8) {
        /* Since we want to test lots of carry-out bits all at once, do not
         * do our normal thing and compute carry-in of bit B+1 since that
         * leaves us with carry bits spread across two words.
         */
        cb = tcg_temp_new();
        tmp = tcg_temp_new();
        tcg_gen_or_tl(cb, in1, in2);
        tcg_gen_and_tl(tmp, in1, in2);
        tcg_gen_andc_tl(cb, cb, res);
        tcg_gen_or_tl(cb, cb, tmp);
        tcg_temp_free(tmp);
    }

    switch (cf >> 1) {
    case 0: /* never / TR */
    case 1: /* undefined */
    case 5: /* undefined */
        cond = cond_make_f();
        break;

    case 2: /* SBZ / NBZ */
        /* See hasless(v,1) from
         * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
         */
        tmp = tcg_temp_new();
        tcg_gen_subi_tl(tmp, res, 0x01010101u);
        tcg_gen_andc_tl(tmp, tmp, res);
        tcg_gen_andi_tl(tmp, tmp, 0x80808080u);
        cond = cond_make_0(TCG_COND_NE, tmp);
        tcg_temp_free(tmp);
        break;

    case 3: /* SHZ / NHZ */
        tmp = tcg_temp_new();
        tcg_gen_subi_tl(tmp, res, 0x00010001u);
        tcg_gen_andc_tl(tmp, tmp, res);
        tcg_gen_andi_tl(tmp, tmp, 0x80008000u);
        cond = cond_make_0(TCG_COND_NE, tmp);
        tcg_temp_free(tmp);
        break;

    case 4: /* SDC / NDC */
        tcg_gen_andi_tl(cb, cb, 0x88888888u);
        cond = cond_make_0(TCG_COND_NE, cb);
        break;

    case 6: /* SBC / NBC */
        tcg_gen_andi_tl(cb, cb, 0x80808080u);
        cond = cond_make_0(TCG_COND_NE, cb);
        break;

    case 7: /* SHC / NHC */
        tcg_gen_andi_tl(cb, cb, 0x80008000u);
        cond = cond_make_0(TCG_COND_NE, cb);
        break;

    default:
        g_assert_not_reached();
    }
    if (cf & 8) {
        tcg_temp_free(cb);
    }
    if (cf & 1) {
        cond.c = tcg_invert_cond(cond.c);
    }

    return cond;
}

/* Compute signed overflow for addition.  */
static TCGv do_add_sv(DisasContext *ctx, TCGv res, TCGv in1, TCGv in2)
{
    TCGv sv = get_temp(ctx);
    TCGv tmp = tcg_temp_new();

    tcg_gen_xor_tl(sv, res, in1);
    tcg_gen_xor_tl(tmp, in1, in2);
    tcg_gen_andc_tl(sv, sv, tmp);
    tcg_temp_free(tmp);

    return sv;
}

/* Compute signed overflow for subtraction.  */
static TCGv do_sub_sv(DisasContext *ctx, TCGv res, TCGv in1, TCGv in2)
{
    TCGv sv = get_temp(ctx);
    TCGv tmp = tcg_temp_new();

    tcg_gen_xor_tl(sv, res, in1);
    tcg_gen_xor_tl(tmp, in1, in2);
    tcg_gen_and_tl(sv, sv, tmp);
    tcg_temp_free(tmp);

    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)
{
    TCGv dest, cb, cb_msb, sv, tmp;
    unsigned c = cf >> 1;
    DisasCond cond;

    dest = tcg_temp_new();
    TCGV_UNUSED(cb);
    TCGV_UNUSED(cb_msb);

    if (shift) {
        tmp = get_temp(ctx);
        tcg_gen_shli_tl(tmp, in1, shift);
        in1 = tmp;
    }

    if (!is_l || c == 4 || c == 5) {
        TCGv zero = tcg_const_tl(0);
        cb_msb = get_temp(ctx);
        tcg_gen_add2_tl(dest, cb_msb, in1, zero, in2, zero);
        if (is_c) {
            tcg_gen_add2_tl(dest, cb_msb, dest, cb_msb, cpu_psw_cb_msb, zero);
        }
        tcg_temp_free(zero);
        if (!is_l) {
            cb = get_temp(ctx);
            tcg_gen_xor_tl(cb, in1, in2);
            tcg_gen_xor_tl(cb, cb, dest);
        }
    } else {
        tcg_gen_add_tl(dest, in1, in2);
        if (is_c) {
            tcg_gen_add_tl(dest, dest, cpu_psw_cb_msb);
        }
    }

    /* Compute signed overflow if required.  */
    TCGV_UNUSED(sv);
    if (is_tsv || c == 6) {
        sv = do_add_sv(ctx, dest, in1, in2);
        if (is_tsv) {
            /* ??? Need to include overflow from shift.  */
            gen_helper_tsv(cpu_env, sv);
        }
    }

    /* Emit any conditional trap before any writeback.  */
    cond = do_cond(cf, dest, cb_msb, sv);
    if (is_tc) {
        cond_prep(&cond);
        tmp = tcg_temp_new();
        tcg_gen_setcond_tl(cond.c, tmp, cond.a0, cond.a1);
        gen_helper_tcond(cpu_env, tmp);
        tcg_temp_free(tmp);
    }

    /* Write back the result.  */
    if (!is_l) {
        save_or_nullify(ctx, cpu_psw_cb, cb);
        save_or_nullify(ctx, cpu_psw_cb_msb, cb_msb);
    }
    save_gpr(ctx, rt, dest);
    tcg_temp_free(dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    ctx->null_cond = cond;
    return NO_EXIT;
}

static ExitStatus 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;
    DisasCond cond;

    dest = tcg_temp_new();
    cb = tcg_temp_new();
    cb_msb = tcg_temp_new();

    zero = tcg_const_tl(0);
    if (is_b) {
        /* DEST,C = IN1 + ~IN2 + C.  */
        tcg_gen_not_tl(cb, in2);
        tcg_gen_add2_tl(dest, cb_msb, in1, zero, cpu_psw_cb_msb, zero);
        tcg_gen_add2_tl(dest, cb_msb, dest, cb_msb, cb, zero);
        tcg_gen_xor_tl(cb, cb, in1);
        tcg_gen_xor_tl(cb, cb, dest);
    } else {
        /* DEST,C = IN1 + ~IN2 + 1.  We can produce the same result in fewer
           operations by seeding the high word with 1 and subtracting.  */
        tcg_gen_movi_tl(cb_msb, 1);
        tcg_gen_sub2_tl(dest, cb_msb, in1, cb_msb, in2, zero);
        tcg_gen_eqv_tl(cb, in1, in2);
        tcg_gen_xor_tl(cb, cb, dest);
    }
    tcg_temp_free(zero);

    /* Compute signed overflow if required.  */
    TCGV_UNUSED(sv);
    if (is_tsv || c == 6) {
        sv = do_sub_sv(ctx, dest, in1, in2);
        if (is_tsv) {
            gen_helper_tsv(cpu_env, sv);
        }
    }

    /* Compute the condition.  We cannot use the special case for borrow.  */
    if (!is_b) {
        cond = do_sub_cond(cf, dest, in1, in2, sv);
    } else {
        cond = do_cond(cf, dest, cb_msb, sv);
    }

    /* Emit any conditional trap before any writeback.  */
    if (is_tc) {
        cond_prep(&cond);
        tmp = tcg_temp_new();
        tcg_gen_setcond_tl(cond.c, tmp, cond.a0, cond.a1);
        gen_helper_tcond(cpu_env, tmp);
        tcg_temp_free(tmp);
    }

    /* Write back the result.  */
    save_or_nullify(ctx, cpu_psw_cb, cb);
    save_or_nullify(ctx, cpu_psw_cb_msb, cb_msb);
    save_gpr(ctx, rt, dest);
    tcg_temp_free(dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    ctx->null_cond = cond;
    return NO_EXIT;
}

static ExitStatus do_cmpclr(DisasContext *ctx, unsigned rt, TCGv in1,
                            TCGv in2, unsigned cf)
{
    TCGv dest, sv;
    DisasCond cond;

    dest = tcg_temp_new();
    tcg_gen_sub_tl(dest, in1, in2);

    /* Compute signed overflow if required.  */
    TCGV_UNUSED(sv);
    if ((cf >> 1) == 6) {
        sv = do_sub_sv(ctx, dest, in1, in2);
    }

    /* Form the condition for the compare.  */
    cond = do_sub_cond(cf, dest, in1, in2, sv);

    /* Clear.  */
    tcg_gen_movi_tl(dest, 0);
    save_gpr(ctx, rt, dest);
    tcg_temp_free(dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    ctx->null_cond = cond;
    return NO_EXIT;
}

static ExitStatus do_log(DisasContext *ctx, unsigned rt, TCGv in1, TCGv in2,
                         unsigned cf, void (*fn)(TCGv, TCGv, TCGv))
{
    TCGv dest = dest_gpr(ctx, rt);

    /* Perform the operation, and writeback.  */
    fn(dest, in1, in2);
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (cf) {
        ctx->null_cond = do_log_cond(cf, dest);
    }
    return NO_EXIT;
}

static ExitStatus do_unit(DisasContext *ctx, unsigned rt, TCGv in1,
                          TCGv in2, unsigned cf, bool is_tc,
                          void (*fn)(TCGv, TCGv, TCGv))
{
    TCGv dest;
    DisasCond cond;

    if (cf == 0) {
        dest = dest_gpr(ctx, rt);
        fn(dest, in1, in2);
        save_gpr(ctx, rt, dest);
        cond_free(&ctx->null_cond);
    } else {
        dest = tcg_temp_new();
        fn(dest, in1, in2);

        cond = do_unit_cond(cf, dest, in1, in2);

        if (is_tc) {
            TCGv tmp = tcg_temp_new();
            cond_prep(&cond);
            tcg_gen_setcond_tl(cond.c, tmp, cond.a0, cond.a1);
            gen_helper_tcond(cpu_env, tmp);
            tcg_temp_free(tmp);
        }
        save_gpr(ctx, rt, dest);

        cond_free(&ctx->null_cond);
        ctx->null_cond = cond;
    }
    return NO_EXIT;
}

/* Emit a memory load.  The modify parameter should be
 * < 0 for pre-modify,
 * > 0 for post-modify,
 * = 0 for no base register update.
 */
static void do_load_32(DisasContext *ctx, TCGv_i32 dest, unsigned rb,
                       unsigned rx, int scale, target_long disp,
                       int modify, TCGMemOp mop)
{
    TCGv addr, base;

    /* Caller uses nullify_over/nullify_end.  */
    assert(ctx->null_cond.c == TCG_COND_NEVER);

    addr = tcg_temp_new();
    base = load_gpr(ctx, rb);

    /* Note that RX is mutually exclusive with DISP.  */
    if (rx) {
        tcg_gen_shli_tl(addr, cpu_gr[rx], scale);
        tcg_gen_add_tl(addr, addr, base);
    } else {
        tcg_gen_addi_tl(addr, base, disp);
    }

    if (modify == 0) {
        tcg_gen_qemu_ld_i32(dest, addr, MMU_USER_IDX, mop);
    } else {
        tcg_gen_qemu_ld_i32(dest, (modify < 0 ? addr : base),
                            MMU_USER_IDX, mop);
        save_gpr(ctx, rb, addr);
    }
    tcg_temp_free(addr);
}

static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb,
                       unsigned rx, int scale, target_long disp,
                       int modify, TCGMemOp mop)
{
    TCGv addr, base;

    /* Caller uses nullify_over/nullify_end.  */
    assert(ctx->null_cond.c == TCG_COND_NEVER);

    addr = tcg_temp_new();
    base = load_gpr(ctx, rb);

    /* Note that RX is mutually exclusive with DISP.  */
    if (rx) {
        tcg_gen_shli_tl(addr, cpu_gr[rx], scale);
        tcg_gen_add_tl(addr, addr, base);
    } else {
        tcg_gen_addi_tl(addr, base, disp);
    }

    if (modify == 0) {
        tcg_gen_qemu_ld_i64(dest, addr, MMU_USER_IDX, mop);
    } else {
        tcg_gen_qemu_ld_i64(dest, (modify < 0 ? addr : base),
                            MMU_USER_IDX, mop);
        save_gpr(ctx, rb, addr);
    }
    tcg_temp_free(addr);
}

static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb,
                        unsigned rx, int scale, target_long disp,
                        int modify, TCGMemOp mop)
{
    TCGv addr, base;

    /* Caller uses nullify_over/nullify_end.  */
    assert(ctx->null_cond.c == TCG_COND_NEVER);

    addr = tcg_temp_new();
    base = load_gpr(ctx, rb);

    /* Note that RX is mutually exclusive with DISP.  */
    if (rx) {
        tcg_gen_shli_tl(addr, cpu_gr[rx], scale);
        tcg_gen_add_tl(addr, addr, base);
    } else {
        tcg_gen_addi_tl(addr, base, disp);
    }

    tcg_gen_qemu_st_i32(src, (modify <= 0 ? addr : base), MMU_USER_IDX, mop);

    if (modify != 0) {
        save_gpr(ctx, rb, addr);
    }
    tcg_temp_free(addr);
}

static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
                        unsigned rx, int scale, target_long disp,
                        int modify, TCGMemOp mop)
{
    TCGv addr, base;

    /* Caller uses nullify_over/nullify_end.  */
    assert(ctx->null_cond.c == TCG_COND_NEVER);

    addr = tcg_temp_new();
    base = load_gpr(ctx, rb);

    /* Note that RX is mutually exclusive with DISP.  */
    if (rx) {
        tcg_gen_shli_tl(addr, cpu_gr[rx], scale);
        tcg_gen_add_tl(addr, addr, base);
    } else {
        tcg_gen_addi_tl(addr, base, disp);
    }

    tcg_gen_qemu_st_i64(src, (modify <= 0 ? addr : base), MMU_USER_IDX, mop);

    if (modify != 0) {
        save_gpr(ctx, rb, addr);
    }
    tcg_temp_free(addr);
}

#if TARGET_LONG_BITS == 64
#define do_load_tl  do_load_64
#define do_store_tl do_store_64
#else
#define do_load_tl  do_load_32
#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)
{
    TCGv dest;

    nullify_over(ctx);

    if (modify == 0) {
        /* No base register update.  */
        dest = dest_gpr(ctx, rt);
    } else {
        /* Make sure if RT == RB, we see the result of the load.  */
        dest = get_temp(ctx);
    }
    do_load_tl(ctx, dest, rb, rx, scale, disp, modify, mop);
    save_gpr(ctx, rt, dest);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_floadw(DisasContext *ctx, unsigned rt, unsigned rb,
                            unsigned rx, int scale, target_long disp,
                            int modify)
{
    TCGv_i32 tmp;

    nullify_over(ctx);

    tmp = tcg_temp_new_i32();
    do_load_32(ctx, tmp, rb, rx, scale, disp, modify, MO_TEUL);
    save_frw_i32(rt, tmp);
    tcg_temp_free_i32(tmp);

    if (rt == 0) {
        gen_helper_loaded_fr0(cpu_env);
    }

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_floadd(DisasContext *ctx, unsigned rt, unsigned rb,
                            unsigned rx, int scale, target_long disp,
                            int modify)
{
    TCGv_i64 tmp;

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    do_load_64(ctx, tmp, rb, rx, scale, disp, modify, MO_TEQ);
    save_frd(rt, tmp);
    tcg_temp_free_i64(tmp);

    if (rt == 0) {
        gen_helper_loaded_fr0(cpu_env);
    }

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus 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);
}

static ExitStatus do_fstorew(DisasContext *ctx, unsigned rt, unsigned rb,
                             unsigned rx, int scale, target_long disp,
                             int modify)
{
    TCGv_i32 tmp;

    nullify_over(ctx);

    tmp = load_frw_i32(rt);
    do_store_32(ctx, tmp, rb, rx, scale, disp, modify, MO_TEUL);
    tcg_temp_free_i32(tmp);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_fstored(DisasContext *ctx, unsigned rt, unsigned rb,
                             unsigned rx, int scale, target_long disp,
                             int modify)
{
    TCGv_i64 tmp;

    nullify_over(ctx);

    tmp = load_frd(rt);
    do_store_64(ctx, tmp, rb, rx, scale, disp, modify, MO_TEQ);
    tcg_temp_free_i64(tmp);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_fop_wew(DisasContext *ctx, unsigned rt, unsigned ra,
                             void (*func)(TCGv_i32, TCGv_env, TCGv_i32))
{
    TCGv_i32 tmp;

    nullify_over(ctx);
    tmp = load_frw0_i32(ra);

    func(tmp, cpu_env, tmp);

    save_frw_i32(rt, tmp);
    tcg_temp_free_i32(tmp);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_fop_wed(DisasContext *ctx, unsigned rt, unsigned ra,
                             void (*func)(TCGv_i32, TCGv_env, TCGv_i64))
{
    TCGv_i32 dst;
    TCGv_i64 src;

    nullify_over(ctx);
    src = load_frd(ra);
    dst = tcg_temp_new_i32();

    func(dst, cpu_env, src);

    tcg_temp_free_i64(src);
    save_frw_i32(rt, dst);
    tcg_temp_free_i32(dst);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_fop_ded(DisasContext *ctx, unsigned rt, unsigned ra,
                             void (*func)(TCGv_i64, TCGv_env, TCGv_i64))
{
    TCGv_i64 tmp;

    nullify_over(ctx);
    tmp = load_frd0(ra);

    func(tmp, cpu_env, tmp);

    save_frd(rt, tmp);
    tcg_temp_free_i64(tmp);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus do_fop_dew(DisasContext *ctx, unsigned rt, unsigned ra,
                             void (*func)(TCGv_i64, TCGv_env, TCGv_i32))
{
    TCGv_i32 src;
    TCGv_i64 dst;

    nullify_over(ctx);
    src = load_frw0_i32(ra);
    dst = tcg_temp_new_i64();

    func(dst, cpu_env, src);

    tcg_temp_free_i32(src);
    save_frd(rt, dst);
    tcg_temp_free_i64(dst);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus 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;

    nullify_over(ctx);
    a = load_frw0_i32(ra);
    b = load_frw0_i32(rb);

    func(a, cpu_env, a, b);

    tcg_temp_free_i32(b);
    save_frw_i32(rt, a);
    tcg_temp_free_i32(a);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus 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;

    nullify_over(ctx);
    a = load_frd0(ra);
    b = load_frd0(rb);

    func(a, cpu_env, a, b);

    tcg_temp_free_i64(b);
    save_frd(rt, a);
    tcg_temp_free_i64(a);
    return nullify_end(ctx, NO_EXIT);
}

/* 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)
{
    if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
        if (link != 0) {
            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }
        ctx->iaoq_n = dest;
        if (is_n) {
            ctx->null_cond.c = TCG_COND_ALWAYS;
        }
        return NO_EXIT;
    } else {
        nullify_over(ctx);

        if (link != 0) {
            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }

        if (is_n && use_nullify_skip(ctx)) {
            nullify_set(ctx, 0);
            gen_goto_tb(ctx, 0, dest, dest + 4);
        } else {
            nullify_set(ctx, is_n);
            gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
        }

        nullify_end(ctx, NO_EXIT);

        nullify_set(ctx, 0);
        gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
        return EXIT_GOTO_TB;
    }
}

/* 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)
{
    target_ulong dest = iaoq_dest(ctx, disp);
    TCGLabel *taken = NULL;
    TCGCond c = cond->c;
    int which = 0;
    bool n;

    assert(ctx->null_cond.c == TCG_COND_NEVER);

    /* Handle TRUE and NEVER as direct branches.  */
    if (c == TCG_COND_ALWAYS) {
        return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
    }
    if (c == TCG_COND_NEVER) {
        return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
    }

    taken = gen_new_label();
    cond_prep(cond);
    tcg_gen_brcond_tl(c, cond->a0, cond->a1, taken);
    cond_free(cond);

    /* Not taken: Condition not satisfied; nullify on backward branches. */
    n = is_n && disp < 0;
    if (n && use_nullify_skip(ctx)) {
        nullify_set(ctx, 0);
        gen_goto_tb(ctx, which++, ctx->iaoq_n, ctx->iaoq_n + 4);
    } else {
        if (!n && ctx->null_lab) {
            gen_set_label(ctx->null_lab);
            ctx->null_lab = NULL;
        }
        nullify_set(ctx, n);
        gen_goto_tb(ctx, which++, ctx->iaoq_b, ctx->iaoq_n);
    }

    gen_set_label(taken);

    /* Taken: Condition satisfied; nullify on forward branches.  */
    n = is_n && disp >= 0;
    if (n && use_nullify_skip(ctx)) {
        nullify_set(ctx, 0);
        gen_goto_tb(ctx, which++, dest, dest + 4);
    } else {
        nullify_set(ctx, n);
        gen_goto_tb(ctx, which++, ctx->iaoq_b, dest);
    }

    /* Not taken: the branch itself was nullified.  */
    if (ctx->null_lab) {
        gen_set_label(ctx->null_lab);
        ctx->null_lab = NULL;
        if (which < 2) {
            nullify_set(ctx, 0);
            gen_goto_tb(ctx, which, ctx->iaoq_b, ctx->iaoq_n);
            return EXIT_GOTO_TB;
        } else {
            return EXIT_IAQ_N_STALE;
        }
    } else {
        return EXIT_GOTO_TB;
    }
}

/* 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)
{
    TCGv a0, a1, next, tmp;
    TCGCond c;

    assert(ctx->null_lab == NULL);

    if (ctx->null_cond.c == TCG_COND_NEVER) {
        if (link != 0) {
            copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }
        next = get_temp(ctx);
        tcg_gen_mov_tl(next, dest);
        ctx->iaoq_n = -1;
        ctx->iaoq_n_var = next;
        if (is_n) {
            ctx->null_cond.c = TCG_COND_ALWAYS;
        }
    } else if (is_n && use_nullify_skip(ctx)) {
        /* The (conditional) branch, B, nullifies the next insn, N,
           and we're allowed to skip execution N (no single-step or
           tracepoint in effect).  Since the exit_tb that we must use
           for the indirect branch consumes no special resources, we
           can (conditionally) skip B and continue execution.  */
        /* The use_nullify_skip test implies we have a known control path.  */
        tcg_debug_assert(ctx->iaoq_b != -1);
        tcg_debug_assert(ctx->iaoq_n != -1);

        /* We do have to handle the non-local temporary, DEST, before
           branching.  Since IOAQ_F is not really live at this point, we
           can simply store DEST optimistically.  Similarly with IAOQ_B.  */
        tcg_gen_mov_tl(cpu_iaoq_f, dest);
        tcg_gen_addi_tl(cpu_iaoq_b, dest, 4);

        nullify_over(ctx);
        if (link != 0) {
            tcg_gen_movi_tl(cpu_gr[link], ctx->iaoq_n);
        }
        tcg_gen_exit_tb(0);
        return nullify_end(ctx, NO_EXIT);
    } else {
        cond_prep(&ctx->null_cond);
        c = ctx->null_cond.c;
        a0 = ctx->null_cond.a0;
        a1 = ctx->null_cond.a1;

        tmp = tcg_temp_new();
        next = get_temp(ctx);

        copy_iaoq_entry(tmp, ctx->iaoq_n, ctx->iaoq_n_var);
        tcg_gen_movcond_tl(c, next, a0, a1, tmp, dest);
        ctx->iaoq_n = -1;
        ctx->iaoq_n_var = next;

        if (link != 0) {
            tcg_gen_movcond_tl(c, cpu_gr[link], a0, a1, cpu_gr[link], tmp);
        }

        if (is_n) {
            /* The branch nullifies the next insn, which means the state of N
               after the branch is the inverse of the state of N that applied
               to the branch.  */
            tcg_gen_setcond_tl(tcg_invert_cond(c), cpu_psw_n, a0, a1);
            cond_free(&ctx->null_cond);
            ctx->null_cond = cond_make_n();
            ctx->psw_n_nonzero = true;
        } else {
            cond_free(&ctx->null_cond);
        }
    }

    return NO_EXIT;
}

/* On Linux, page zero is normally marked execute only + gateway.
   Therefore normal read or write is supposed to fail, but specific
   offsets have kernel code mapped to raise permissions to implement
   system calls.  Handling this via an explicit check here, rather
   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)
{
    /* 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
       next insn within the privilaged page.  */
    switch (ctx->null_cond.c) {
    case TCG_COND_NEVER:
        break;
    case TCG_COND_ALWAYS:
        tcg_gen_movi_tl(cpu_psw_n, 0);
        goto do_sigill;
    default:
        /* Since this is always the first (and only) insn within the
           TB, we should know the state of PSW[N] from TB->FLAGS.  */
        g_assert_not_reached();
    }

    /* Check that we didn't arrive here via some means that allowed
       non-sequential instruction execution.  Normally the PSW[B] bit
       detects this by disallowing the B,GATE instruction to execute
       under such conditions.  */
    if (ctx->iaoq_b != ctx->iaoq_f + 4) {
        goto do_sigill;
    }

    switch (ctx->iaoq_f) {
    case 0x00: /* Null pointer call */
        gen_excp_1(EXCP_SIGSEGV);
        return EXIT_NORETURN;

    case 0xb0: /* LWS */
        gen_excp_1(EXCP_SYSCALL_LWS);
        return EXIT_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;

    case 0x100: /* SYSCALL */
        gen_excp_1(EXCP_SYSCALL);
        return EXIT_NORETURN;

    default:
    do_sigill:
        gen_excp_1(EXCP_SIGILL);
        return EXIT_NORETURN;
    }
}

static ExitStatus trans_nop(DisasContext *ctx, uint32_t insn,
                            const DisasInsn *di)
{
    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus 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)
{
    /* No point in nullifying the memory barrier.  */
    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
                             const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    TCGv tmp = dest_gpr(ctx, rt);
    tcg_gen_movi_tl(tmp, ctx->iaoq_f);
    save_gpr(ctx, rt, tmp);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
                             const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    TCGv tmp = dest_gpr(ctx, rt);

    /* ??? We don't implement space registers.  */
    tcg_gen_movi_tl(tmp, 0);
    save_gpr(ctx, rt, tmp);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
                              const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned ctl = extract32(insn, 21, 5);
    TCGv tmp;

    switch (ctl) {
    case 11: /* SAR */
#ifdef TARGET_HPPA64
        if (extract32(insn, 14, 1) == 0) {
            /* MFSAR without ,W masks low 5 bits.  */
            tmp = dest_gpr(ctx, rt);
            tcg_gen_andi_tl(tmp, cpu_sar, 31);
            save_gpr(ctx, rt, tmp);
            break;
        }
#endif
        save_gpr(ctx, rt, cpu_sar);
        break;
    case 16: /* Interval Timer */
        tmp = dest_gpr(ctx, rt);
        tcg_gen_movi_tl(tmp, 0); /* FIXME */
        save_gpr(ctx, rt, tmp);
        break;
    case 26:
        save_gpr(ctx, rt, cpu_cr26);
        break;
    case 27:
        save_gpr(ctx, rt, cpu_cr27);
        break;
    default:
        /* All other control registers are privileged.  */
        return gen_illegal(ctx);
    }

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
                              const DisasInsn *di)
{
    unsigned rin = extract32(insn, 16, 5);
    unsigned ctl = extract32(insn, 21, 5);
    TCGv tmp;

    if (ctl == 11) { /* SAR */
        tmp = tcg_temp_new();
        tcg_gen_andi_tl(tmp, load_gpr(ctx, rin), TARGET_LONG_BITS - 1);
        save_or_nullify(ctx, cpu_sar, tmp);
        tcg_temp_free(tmp);
    } else {
        /* All other control registers are privileged or read-only.  */
        return gen_illegal(ctx);
    }

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
                                const DisasInsn *di)
{
    unsigned rin = extract32(insn, 16, 5);
    TCGv tmp = tcg_temp_new();

    tcg_gen_not_tl(tmp, load_gpr(ctx, rin));
    tcg_gen_andi_tl(tmp, tmp, TARGET_LONG_BITS - 1);
    save_or_nullify(ctx, cpu_sar, tmp);
    tcg_temp_free(tmp);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
                              const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    TCGv dest = dest_gpr(ctx, rt);

    /* Since we don't implement space registers, this returns zero.  */
    tcg_gen_movi_tl(dest, 0);
    save_gpr(ctx, rt, dest);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static const DisasInsn table_system[] = {
    { 0x00000000u, 0xfc001fe0u, trans_break },
    /* We don't implement space register, so MTSP is a nop.  */
    { 0x00001820u, 0xffe01fffu, trans_nop },
    { 0x00001840u, 0xfc00ffffu, trans_mtctl },
    { 0x016018c0u, 0xffe0ffffu, trans_mtsarcm },
    { 0x000014a0u, 0xffffffe0u, trans_mfia },
    { 0x000004a0u, 0xffff1fe0u, trans_mfsp },
    { 0x000008a0u, 0xfc1fffe0u, trans_mfctl },
    { 0x00000400u, 0xffffffffu, trans_sync },
    { 0x000010a0u, 0xfc1f3fe0u, trans_ldsid },
};

static ExitStatus trans_base_idx_mod(DisasContext *ctx, uint32_t insn,
                                     const DisasInsn *di)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rx = extract32(insn, 16, 5);
    TCGv dest = dest_gpr(ctx, rb);
    TCGv src1 = load_gpr(ctx, rb);
    TCGv src2 = load_gpr(ctx, rx);

    /* The only thing we need to do is the base register modification.  */
    tcg_gen_add_tl(dest, src1, src2);
    save_gpr(ctx, rb, dest);

    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus trans_probe(DisasContext *ctx, uint32_t insn,
                              const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned rb = extract32(insn, 21, 5);
    unsigned is_write = extract32(insn, 6, 1);
    TCGv dest;

    nullify_over(ctx);

    /* ??? Do something with priv level operand.  */
    dest = dest_gpr(ctx, rt);
    if (is_write) {
        gen_helper_probe_w(dest, load_gpr(ctx, rb));
    } else {
        gen_helper_probe_r(dest, load_gpr(ctx, rb));
    }
    save_gpr(ctx, rt, dest);
    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_mem_mgmt[] = {
    { 0x04003280u, 0xfc003fffu, trans_nop },          /* fdc, disp */
    { 0x04001280u, 0xfc003fffu, trans_nop },          /* fdc, index */
    { 0x040012a0u, 0xfc003fffu, trans_base_idx_mod }, /* fdc, index, base mod */
    { 0x040012c0u, 0xfc003fffu, trans_nop },          /* fdce */
    { 0x040012e0u, 0xfc003fffu, trans_base_idx_mod }, /* fdce, base mod */
    { 0x04000280u, 0xfc001fffu, trans_nop },          /* fic 0a */
    { 0x040002a0u, 0xfc001fffu, trans_base_idx_mod }, /* fic 0a, base mod */
    { 0x040013c0u, 0xfc003fffu, trans_nop },          /* fic 4f */
    { 0x040013e0u, 0xfc003fffu, trans_base_idx_mod }, /* fic 4f, base mod */
    { 0x040002c0u, 0xfc001fffu, trans_nop },          /* fice */
    { 0x040002e0u, 0xfc001fffu, trans_base_idx_mod }, /* fice, base mod */
    { 0x04002700u, 0xfc003fffu, trans_nop },          /* pdc */
    { 0x04002720u, 0xfc003fffu, trans_base_idx_mod }, /* pdc, base mod */
    { 0x04001180u, 0xfc003fa0u, trans_probe },        /* probe */
    { 0x04003180u, 0xfc003fa0u, trans_probe },        /* probei */
};

static ExitStatus trans_add(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 ext = extract32(insn, 8, 4);
    unsigned shift = extract32(insn, 6, 2);
    unsigned rt = extract32(insn,  0, 5);
    TCGv tcg_r1, tcg_r2;
    bool is_c = false;
    bool is_l = false;
    bool is_tc = false;
    bool is_tsv = false;
    ExitStatus ret;

    switch (ext) {
    case 0x6: /* ADD, SHLADD */
        break;
    case 0xa: /* ADD,L, SHLADD,L */
        is_l = true;
        break;
    case 0xe: /* ADD,TSV, SHLADD,TSV (1) */
        is_tsv = true;
        break;
    case 0x7: /* ADD,C */
        is_c = true;
        break;
    case 0xf: /* ADD,C,TSV */
        is_c = is_tsv = true;
        break;
    default:
        return gen_illegal(ctx);
    }

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_add(ctx, rt, tcg_r1, tcg_r2, shift, is_l, is_tsv, is_tc, is_c, cf);
    return nullify_end(ctx, ret);
}

static ExitStatus trans_sub(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 ext = extract32(insn, 6, 6);
    unsigned rt = extract32(insn,  0, 5);
    TCGv tcg_r1, tcg_r2;
    bool is_b = false;
    bool is_tc = false;
    bool is_tsv = false;
    ExitStatus ret;

    switch (ext) {
    case 0x10: /* SUB */
        break;
    case 0x30: /* SUB,TSV */
        is_tsv = true;
        break;
    case 0x14: /* SUB,B */
        is_b = true;
        break;
    case 0x34: /* SUB,B,TSV */
        is_b = is_tsv = true;
        break;
    case 0x13: /* SUB,TC */
        is_tc = true;
        break;
    case 0x33: /* SUB,TSV,TC */
        is_tc = is_tsv = true;
        break;
    default:
        return gen_illegal(ctx);
    }

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_sub(ctx, rt, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, cf);
    return nullify_end(ctx, ret);
}

static ExitStatus 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;

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_log(ctx, rt, tcg_r1, tcg_r2, cf, di->f_ttt);
    return nullify_end(ctx, ret);
}

/* OR r,0,t -> COPY (according to gas) */
static ExitStatus trans_copy(DisasContext *ctx, uint32_t insn,
                             const DisasInsn *di)
{
    unsigned r1 = extract32(insn, 16, 5);
    unsigned rt = extract32(insn,  0, 5);

    if (r1 == 0) {
        TCGv dest = dest_gpr(ctx, rt);
        tcg_gen_movi_tl(dest, 0);
        save_gpr(ctx, rt, dest);
    } else {
        save_gpr(ctx, rt, cpu_gr[r1]);
    }
    cond_free(&ctx->null_cond);
    return NO_EXIT;
}

static ExitStatus 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;

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_cmpclr(ctx, rt, tcg_r1, tcg_r2, cf);
    return nullify_end(ctx, ret);
}

static ExitStatus 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;

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_unit(ctx, rt, tcg_r1, tcg_r2, cf, false, tcg_gen_xor_tl);
    return nullify_end(ctx, ret);
}

static ExitStatus trans_uaddcm(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 is_tc = extract32(insn, 6, 1);
    unsigned rt = extract32(insn,  0, 5);
    TCGv tcg_r1, tcg_r2, tmp;
    ExitStatus ret;

    if (cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, r1);
    tcg_r2 = load_gpr(ctx, r2);
    tmp = get_temp(ctx);
    tcg_gen_not_tl(tmp, tcg_r2);
    ret = do_unit(ctx, rt, tcg_r1, tmp, cf, is_tc, tcg_gen_add_tl);
    return nullify_end(ctx, ret);
}

static ExitStatus 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;

    nullify_over(ctx);

    tmp = get_temp(ctx);
    tcg_gen_shri_tl(tmp, cpu_psw_cb, 3);
    if (!is_i) {
        tcg_gen_not_tl(tmp, tmp);
    }
    tcg_gen_andi_tl(tmp, tmp, 0x11111111);
    tcg_gen_muli_tl(tmp, tmp, 6);
    ret = do_unit(ctx, rt, tmp, load_gpr(ctx, r2), cf, false,
                  is_i ? tcg_gen_add_tl : tcg_gen_sub_tl);

    return nullify_end(ctx, ret);
}

static ExitStatus trans_ds(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 dest, add1, add2, addc, zero, in1, in2;

    nullify_over(ctx);

    in1 = load_gpr(ctx, r1);
    in2 = load_gpr(ctx, r2);

    add1 = tcg_temp_new();
    add2 = tcg_temp_new();
    addc = tcg_temp_new();
    dest = tcg_temp_new();
    zero = tcg_const_tl(0);

    /* Form R1 << 1 | PSW[CB]{8}.  */
    tcg_gen_add_tl(add1, in1, in1);
    tcg_gen_add_tl(add1, add1, cpu_psw_cb_msb);

    /* Add or subtract R2, depending on PSW[V].  Proper computation of
       carry{8} requires that we subtract via + ~R2 + 1, as described in
       the manual.  By extracting and masking V, we can produce the
       proper inputs to the addition without movcond.  */
    tcg_gen_sari_tl(addc, cpu_psw_v, TARGET_LONG_BITS - 1);
    tcg_gen_xor_tl(add2, in2, addc);
    tcg_gen_andi_tl(addc, addc, 1);
    /* ??? This is only correct for 32-bit.  */
    tcg_gen_add2_i32(dest, cpu_psw_cb_msb, add1, zero, add2, zero);
    tcg_gen_add2_i32(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb, addc, zero);

    tcg_temp_free(addc);
    tcg_temp_free(zero);

    /* Write back the result register.  */
    save_gpr(ctx, rt, dest);

    /* Write back PSW[CB].  */
    tcg_gen_xor_tl(cpu_psw_cb, add1, add2);
    tcg_gen_xor_tl(cpu_psw_cb, cpu_psw_cb, dest);

    /* Write back PSW[V] for the division step.  */
    tcg_gen_neg_tl(cpu_psw_v, cpu_psw_cb_msb);
    tcg_gen_xor_tl(cpu_psw_v, cpu_psw_v, in2);

    /* Install the new nullification.  */
    if (cf) {
        TCGv sv;
        TCGV_UNUSED(sv);
        if (cf >> 1 == 6) {
            /* ??? The lshift is supposed to contribute to overflow.  */
            sv = do_add_sv(ctx, dest, add1, add2);
        }
        ctx->null_cond = do_cond(cf, dest, cpu_psw_cb_msb, sv);
    }

    tcg_temp_free(add1);
    tcg_temp_free(add2);
    tcg_temp_free(dest);

    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_arith_log[] = {
    { 0x08000240u, 0xfc00ffffu, trans_nop },  /* or x,y,0 */
    { 0x08000240u, 0xffe0ffe0u, trans_copy }, /* or x,0,t */
    { 0x08000000u, 0xfc000fe0u, trans_log, .f_ttt = tcg_gen_andc_tl },
    { 0x08000200u, 0xfc000fe0u, trans_log, .f_ttt = tcg_gen_and_tl },
    { 0x08000240u, 0xfc000fe0u, trans_log, .f_ttt = tcg_gen_or_tl },
    { 0x08000280u, 0xfc000fe0u, trans_log, .f_ttt = tcg_gen_xor_tl },
    { 0x08000880u, 0xfc000fe0u, trans_cmpclr },
    { 0x08000380u, 0xfc000fe0u, trans_uxor },
    { 0x08000980u, 0xfc000fa0u, trans_uaddcm },
    { 0x08000b80u, 0xfc1f0fa0u, trans_dcor },
    { 0x08000440u, 0xfc000fe0u, trans_ds },
    { 0x08000700u, 0xfc0007e0u, trans_add }, /* add */
    { 0x08000400u, 0xfc0006e0u, trans_sub }, /* sub; sub,b; sub,tsv */
    { 0x080004c0u, 0xfc0007e0u, trans_sub }, /* sub,tc; sub,tsv,tc */
    { 0x08000200u, 0xfc000320u, trans_add }, /* shladd */
};

static ExitStatus trans_addi(DisasContext *ctx, uint32_t insn)
{
    target_long im = low_sextract(insn, 0, 11);
    unsigned e1 = extract32(insn, 11, 1);
    unsigned cf = extract32(insn, 12, 4);
    unsigned rt = extract32(insn, 16, 5);
    unsigned r2 = extract32(insn, 21, 5);
    unsigned o1 = extract32(insn, 26, 1);
    TCGv tcg_im, tcg_r2;
    ExitStatus ret;

    if (cf) {
        nullify_over(ctx);
    }

    tcg_im = load_const(ctx, im);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_add(ctx, rt, tcg_im, tcg_r2, 0, false, e1, !o1, false, cf);

    return nullify_end(ctx, ret);
}

static ExitStatus trans_subi(DisasContext *ctx, uint32_t insn)
{
    target_long im = low_sextract(insn, 0, 11);
    unsigned e1 = extract32(insn, 11, 1);
    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;

    if (cf) {
        nullify_over(ctx);
    }

    tcg_im = load_const(ctx, im);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_sub(ctx, rt, tcg_im, tcg_r2, e1, false, false, cf);

    return nullify_end(ctx, ret);
}

static ExitStatus 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;

    if (cf) {
        nullify_over(ctx);
    }

    tcg_im = load_const(ctx, im);
    tcg_r2 = load_gpr(ctx, r2);
    ret = do_cmpclr(ctx, rt, tcg_im, tcg_r2, cf);

    return nullify_end(ctx, ret);
}

static ExitStatus trans_ld_idx_i(DisasContext *ctx, uint32_t insn,
                                 const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned sz = extract32(insn, 6, 2);
    unsigned a = extract32(insn, 13, 1);
    int disp = low_sextract(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    int modify = (m ? (a ? -1 : 1) : 0);
    TCGMemOp mop = MO_TE | sz;

    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)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned sz = extract32(insn, 6, 2);
    unsigned u = extract32(insn, 13, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    TCGMemOp mop = MO_TE | sz;

    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)
{
    int disp = low_sextract(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned sz = extract32(insn, 6, 2);
    unsigned a = extract32(insn, 13, 1);
    unsigned rr = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    int modify = (m ? (a ? -1 : 1) : 0);
    TCGMemOp mop = MO_TE | sz;

    return do_store(ctx, rr, rb, disp, modify, mop);
}

static ExitStatus trans_ldcw(DisasContext *ctx, uint32_t insn,
                             const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned i = extract32(insn, 12, 1);
    unsigned au = extract32(insn, 13, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    TCGMemOp mop = MO_TEUL | MO_ALIGN_16;
    TCGv zero, addr, base, dest;
    int modify, disp = 0, scale = 0;

    nullify_over(ctx);

    /* ??? Share more code with do_load and do_load_{32,64}.  */

    if (i) {
        modify = (m ? (au ? -1 : 1) : 0);
        disp = low_sextract(rx, 0, 5);
        rx = 0;
    } else {
        modify = m;
        if (au) {
            scale = mop & MO_SIZE;
        }
    }
    if (modify) {
        /* Base register modification.  Make sure if RT == RB, we see
           the result of the load.  */
        dest = get_temp(ctx);
    } else {
        dest = dest_gpr(ctx, rt);
    }

    addr = tcg_temp_new();
    base = load_gpr(ctx, rb);
    if (rx) {
        tcg_gen_shli_tl(addr, cpu_gr[rx], scale);
        tcg_gen_add_tl(addr, addr, base);
    } else {
        tcg_gen_addi_tl(addr, base, disp);
    }

    zero = tcg_const_tl(0);
    tcg_gen_atomic_xchg_tl(dest, (modify <= 0 ? addr : base),
                           zero, MMU_USER_IDX, mop);
    if (modify) {
        save_gpr(ctx, rb, addr);
    }
    save_gpr(ctx, rt, dest);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_stby(DisasContext *ctx, uint32_t insn,
                             const DisasInsn *di)
{
    target_long disp = low_sextract(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned a = extract32(insn, 13, 1);
    unsigned rt = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    TCGv addr, val;

    nullify_over(ctx);

    addr = tcg_temp_new();
    if (m || disp == 0) {
        tcg_gen_mov_tl(addr, load_gpr(ctx, rb));
    } else {
        tcg_gen_addi_tl(addr, load_gpr(ctx, rb), disp);
    }
    val = load_gpr(ctx, rt);

    if (a) {
        gen_helper_stby_e(cpu_env, addr, val);
    } else {
        gen_helper_stby_b(cpu_env, addr, val);
    }

    if (m) {
        tcg_gen_addi_tl(addr, addr, disp);
        tcg_gen_andi_tl(addr, addr, ~3);
        save_gpr(ctx, rb, addr);
    }
    tcg_temp_free(addr);

    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_index_mem[] = {
    { 0x0c001000u, 0xfc001300, trans_ld_idx_i }, /* LD[BHWD], im */
    { 0x0c000000u, 0xfc001300, trans_ld_idx_x }, /* LD[BHWD], rx */
    { 0x0c001200u, 0xfc001300, trans_st_idx_i }, /* ST[BHWD] */
    { 0x0c0001c0u, 0xfc0003c0, trans_ldcw },
    { 0x0c001300u, 0xfc0013c0, trans_stby },
};

static ExitStatus trans_ldil(DisasContext *ctx, uint32_t insn)
{
    unsigned rt = extract32(insn, 21, 5);
    target_long i = assemble_21(insn);
    TCGv tcg_rt = dest_gpr(ctx, rt);

    tcg_gen_movi_tl(tcg_rt, i);
    save_gpr(ctx, rt, tcg_rt);
    cond_free(&ctx->null_cond);

    return NO_EXIT;
}

static ExitStatus trans_addil(DisasContext *ctx, uint32_t insn)
{
    unsigned rt = extract32(insn, 21, 5);
    target_long i = assemble_21(insn);
    TCGv tcg_rt = load_gpr(ctx, rt);
    TCGv tcg_r1 = dest_gpr(ctx, 1);

    tcg_gen_addi_tl(tcg_r1, tcg_rt, i);
    save_gpr(ctx, 1, tcg_r1);
    cond_free(&ctx->null_cond);

    return NO_EXIT;
}

static ExitStatus trans_ldo(DisasContext *ctx, uint32_t insn)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = extract32(insn, 16, 5);
    target_long i = assemble_16(insn);
    TCGv tcg_rt = dest_gpr(ctx, rt);

    /* Special case rb == 0, for the LDI pseudo-op.
       The COPY pseudo-op is handled for free within tcg_gen_addi_tl.  */
    if (rb == 0) {
        tcg_gen_movi_tl(tcg_rt, i);
    } else {
        tcg_gen_addi_tl(tcg_rt, cpu_gr[rb], i);
    }
    save_gpr(ctx, rt, tcg_rt);
    cond_free(&ctx->null_cond);

    return NO_EXIT;
}

static ExitStatus trans_load(DisasContext *ctx, uint32_t insn,
                             bool is_mod, TCGMemOp mop)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = extract32(insn, 16, 5);
    target_long i = assemble_16(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)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = extract32(insn, 16, 5);
    target_long i = assemble_16a(insn);
    unsigned ext2 = extract32(insn, 1, 2);

    switch (ext2) {
    case 0:
    case 1:
        /* FLDW without modification.  */
        return do_floadw(ctx, ext2 * 32 + rt, rb, 0, 0, i, 0);
    case 2:
        /* LDW with modification.  Note that the sign of I selects
           post-dec vs pre-inc.  */
        return do_load(ctx, rt, rb, 0, 0, i, (i < 0 ? 1 : -1), MO_TEUL);
    default:
        return gen_illegal(ctx);
    }
}

static ExitStatus trans_fload_mod(DisasContext *ctx, uint32_t insn)
{
    target_long i = assemble_16a(insn);
    unsigned t1 = extract32(insn, 1, 1);
    unsigned a = extract32(insn, 2, 1);
    unsigned t0 = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);

    /* FLDW with modification.  */
    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)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = extract32(insn, 16, 5);
    target_long i = assemble_16(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)
{
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = extract32(insn, 16, 5);
    target_long i = assemble_16a(insn);
    unsigned ext2 = extract32(insn, 1, 2);

    switch (ext2) {
    case 0:
    case 1:
        /* FSTW without modification.  */
        return do_fstorew(ctx, ext2 * 32 + rt, rb, 0, 0, i, 0);
    case 2:
        /* LDW with modification.  */
        return do_store(ctx, rt, rb, i, (i < 0 ? 1 : -1), MO_TEUL);
    default:
        return gen_illegal(ctx);
    }
}

static ExitStatus trans_fstore_mod(DisasContext *ctx, uint32_t insn)
{
    target_long i = assemble_16a(insn);
    unsigned t1 = extract32(insn, 1, 1);
    unsigned a = extract32(insn, 2, 1);
    unsigned t0 = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);

    /* FSTW with modification.  */
    return do_fstorew(ctx, t1 * 32 + t0, rb, 0, 0, i, (a ? -1 : 1));
}

static ExitStatus trans_copr_w(DisasContext *ctx, uint32_t insn)
{
    unsigned t0 = extract32(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned t1 = extract32(insn, 6, 1);
    unsigned ext3 = extract32(insn, 7, 3);
    /* unsigned cc = extract32(insn, 10, 2); */
    unsigned i = extract32(insn, 12, 1);
    unsigned ua = extract32(insn, 13, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    unsigned rt = t1 * 32 + t0;
    int modify = (m ? (ua ? -1 : 1) : 0);
    int disp, scale;

    if (i == 0) {
        scale = (ua ? 2 : 0);
        disp = 0;
        modify = m;
    } else {
        disp = low_sextract(rx, 0, 5);
        scale = 0;
        rx = 0;
        modify = (m ? (ua ? -1 : 1) : 0);
    }

    switch (ext3) {
    case 0: /* FLDW */
        return do_floadw(ctx, rt, rb, rx, scale, disp, modify);
    case 4: /* FSTW */
        return do_fstorew(ctx, rt, rb, rx, scale, disp, modify);
    }
    return gen_illegal(ctx);
}

static ExitStatus trans_copr_dw(DisasContext *ctx, uint32_t insn)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned m = extract32(insn, 5, 1);
    unsigned ext4 = extract32(insn, 6, 4);
    /* unsigned cc = extract32(insn, 10, 2); */
    unsigned i = extract32(insn, 12, 1);
    unsigned ua = extract32(insn, 13, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    int modify = (m ? (ua ? -1 : 1) : 0);
    int disp, scale;

    if (i == 0) {
        scale = (ua ? 3 : 0);
        disp = 0;
        modify = m;
    } else {
        disp = low_sextract(rx, 0, 5);
        scale = 0;
        rx = 0;
        modify = (m ? (ua ? -1 : 1) : 0);
    }

    switch (ext4) {
    case 0: /* FLDD */
        return do_floadd(ctx, rt, rb, rx, scale, disp, modify);
    case 8: /* FSTD */
        return do_fstored(ctx, rt, rb, rx, scale, disp, modify);
    default:
        return gen_illegal(ctx);
    }
}

static ExitStatus 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);
    unsigned c = extract32(insn, 13, 3);
    unsigned r = extract32(insn, 21, 5);
    unsigned cf = c * 2 + !is_true;
    TCGv dest, in1, in2, sv;
    DisasCond cond;

    nullify_over(ctx);

    if (is_imm) {
        in1 = load_const(ctx, low_sextract(insn, 16, 5));
    } else {
        in1 = load_gpr(ctx, extract32(insn, 16, 5));
    }
    in2 = load_gpr(ctx, r);
    dest = get_temp(ctx);

    tcg_gen_sub_tl(dest, in1, in2);

    TCGV_UNUSED(sv);
    if (c == 6) {
        sv = do_sub_sv(ctx, dest, in1, in2);
    }

    cond = do_sub_cond(cf, dest, in1, in2, sv);
    return do_cbranch(ctx, disp, n, &cond);
}

static ExitStatus 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);
    unsigned c = extract32(insn, 13, 3);
    unsigned r = extract32(insn, 21, 5);
    unsigned cf = c * 2 + !is_true;
    TCGv dest, in1, in2, sv, cb_msb;
    DisasCond cond;

    nullify_over(ctx);

    if (is_imm) {
        in1 = load_const(ctx, low_sextract(insn, 16, 5));
    } else {
        in1 = load_gpr(ctx, extract32(insn, 16, 5));
    }
    in2 = load_gpr(ctx, r);
    dest = dest_gpr(ctx, r);
    TCGV_UNUSED(sv);
    TCGV_UNUSED(cb_msb);

    switch (c) {
    default:
        tcg_gen_add_tl(dest, in1, in2);
        break;
    case 4: case 5:
        cb_msb = get_temp(ctx);
        tcg_gen_movi_tl(cb_msb, 0);
        tcg_gen_add2_tl(dest, cb_msb, in1, cb_msb, in2, cb_msb);
        break;
    case 6:
        tcg_gen_add_tl(dest, in1, in2);
        sv = do_add_sv(ctx, dest, in1, in2);
        break;
    }

    cond = do_cond(cf, dest, cb_msb, sv);
    return do_cbranch(ctx, disp, n, &cond);
}

static ExitStatus trans_bb(DisasContext *ctx, uint32_t insn)
{
    target_long disp = assemble_12(insn) * 4;
    unsigned n = extract32(insn, 1, 1);
    unsigned c = extract32(insn, 15, 1);
    unsigned r = extract32(insn, 16, 5);
    unsigned p = extract32(insn, 21, 5);
    unsigned i = extract32(insn, 26, 1);
    TCGv tmp, tcg_r;
    DisasCond cond;

    nullify_over(ctx);

    tmp = tcg_temp_new();
    tcg_r = load_gpr(ctx, r);
    if (i) {
        tcg_gen_shli_tl(tmp, tcg_r, p);
    } else {
        tcg_gen_shl_tl(tmp, tcg_r, cpu_sar);
    }

    cond = cond_make_0(c ? TCG_COND_GE : TCG_COND_LT, tmp);
    tcg_temp_free(tmp);
    return do_cbranch(ctx, disp, n, &cond);
}

static ExitStatus trans_movb(DisasContext *ctx, uint32_t insn, bool is_imm)
{
    target_long disp = assemble_12(insn) * 4;
    unsigned n = extract32(insn, 1, 1);
    unsigned c = extract32(insn, 13, 3);
    unsigned t = extract32(insn, 16, 5);
    unsigned r = extract32(insn, 21, 5);
    TCGv dest;
    DisasCond cond;

    nullify_over(ctx);

    dest = dest_gpr(ctx, r);
    if (is_imm) {
        tcg_gen_movi_tl(dest, low_sextract(t, 0, 5));
    } else if (t == 0) {
        tcg_gen_movi_tl(dest, 0);
    } else {
        tcg_gen_mov_tl(dest, cpu_gr[t]);
    }

    cond = do_sed_cond(c, dest);
    return do_cbranch(ctx, disp, n, &cond);
}

static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
                                 const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned c = extract32(insn, 13, 3);
    unsigned r1 = extract32(insn, 16, 5);
    unsigned r2 = extract32(insn, 21, 5);
    TCGv dest;

    if (c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, rt);
    if (r1 == 0) {
        tcg_gen_ext32u_tl(dest, load_gpr(ctx, r2));
        tcg_gen_shr_tl(dest, dest, cpu_sar);
    } else if (r1 == r2) {
        TCGv_i32 t32 = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(t32, load_gpr(ctx, r2));
        tcg_gen_rotr_i32(t32, t32, cpu_sar);
        tcg_gen_extu_i32_tl(dest, t32);
        tcg_temp_free_i32(t32);
    } else {
        TCGv_i64 t = tcg_temp_new_i64();
        TCGv_i64 s = tcg_temp_new_i64();

        tcg_gen_concat_tl_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1));
        tcg_gen_extu_tl_i64(s, cpu_sar);
        tcg_gen_shr_i64(t, t, s);
        tcg_gen_trunc_i64_tl(dest, t);

        tcg_temp_free_i64(t);
        tcg_temp_free_i64(s);
    }
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
                                  const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned cpos = extract32(insn, 5, 5);
    unsigned c = extract32(insn, 13, 3);
    unsigned r1 = extract32(insn, 16, 5);
    unsigned r2 = extract32(insn, 21, 5);
    unsigned sa = 31 - cpos;
    TCGv dest, t2;

    if (c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, rt);
    t2 = load_gpr(ctx, r2);
    if (r1 == r2) {
        TCGv_i32 t32 = tcg_temp_new_i32();
        tcg_gen_trunc_tl_i32(t32, t2);
        tcg_gen_rotri_i32(t32, t32, sa);
        tcg_gen_extu_i32_tl(dest, t32);
        tcg_temp_free_i32(t32);
    } else if (r1 == 0) {
        tcg_gen_extract_tl(dest, t2, sa, 32 - sa);
    } else {
        TCGv t0 = tcg_temp_new();
        tcg_gen_extract_tl(t0, t2, sa, 32 - sa);
        tcg_gen_deposit_tl(dest, t0, cpu_gr[r1], 32 - sa, sa);
        tcg_temp_free(t0);
    }
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
                                  const DisasInsn *di)
{
    unsigned clen = extract32(insn, 0, 5);
    unsigned is_se = extract32(insn, 10, 1);
    unsigned c = extract32(insn, 13, 3);
    unsigned rt = extract32(insn, 16, 5);
    unsigned rr = extract32(insn, 21, 5);
    unsigned len = 32 - clen;
    TCGv dest, src, tmp;

    if (c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, rt);
    src = load_gpr(ctx, rr);
    tmp = tcg_temp_new();

    /* Recall that SAR is using big-endian bit numbering.  */
    tcg_gen_xori_tl(tmp, cpu_sar, TARGET_LONG_BITS - 1);
    if (is_se) {
        tcg_gen_sar_tl(dest, src, tmp);
        tcg_gen_sextract_tl(dest, dest, 0, len);
    } else {
        tcg_gen_shr_tl(dest, src, tmp);
        tcg_gen_extract_tl(dest, dest, 0, len);
    }
    tcg_temp_free(tmp);
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
                                  const DisasInsn *di)
{
    unsigned clen = extract32(insn, 0, 5);
    unsigned pos = extract32(insn, 5, 5);
    unsigned is_se = extract32(insn, 10, 1);
    unsigned c = extract32(insn, 13, 3);
    unsigned rt = extract32(insn, 16, 5);
    unsigned rr = extract32(insn, 21, 5);
    unsigned len = 32 - clen;
    unsigned cpos = 31 - pos;
    TCGv dest, src;

    if (c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, rt);
    src = load_gpr(ctx, rr);
    if (is_se) {
        tcg_gen_sextract_tl(dest, src, cpos, len);
    } else {
        tcg_gen_extract_tl(dest, src, cpos, len);
    }
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_sh_ex[] = {
    { 0xd0000000u, 0xfc001fe0u, trans_shrpw_sar },
    { 0xd0000800u, 0xfc001c00u, trans_shrpw_imm },
    { 0xd0001000u, 0xfc001be0u, trans_extrw_sar },
    { 0xd0001800u, 0xfc001800u, trans_extrw_imm },
};

static ExitStatus trans_depw_imm_c(DisasContext *ctx, uint32_t insn,
                                   const DisasInsn *di)
{
    unsigned clen = extract32(insn, 0, 5);
    unsigned cpos = extract32(insn, 5, 5);
    unsigned nz = extract32(insn, 10, 1);
    unsigned c = extract32(insn, 13, 3);
    target_long val = low_sextract(insn, 16, 5);
    unsigned rt = extract32(insn, 21, 5);
    unsigned len = 32 - clen;
    target_long mask0, mask1;
    TCGv dest;

    if (c) {
        nullify_over(ctx);
    }
    if (cpos + len > 32) {
        len = 32 - cpos;
    }

    dest = dest_gpr(ctx, rt);
    mask0 = deposit64(0, cpos, len, val);
    mask1 = deposit64(-1, cpos, len, val);

    if (nz) {
        TCGv src = load_gpr(ctx, rt);
        if (mask1 != -1) {
            tcg_gen_andi_tl(dest, src, mask1);
            src = dest;
        }
        tcg_gen_ori_tl(dest, src, mask0);
    } else {
        tcg_gen_movi_tl(dest, mask0);
    }
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_depw_imm(DisasContext *ctx, uint32_t insn,
                                 const DisasInsn *di)
{
    unsigned clen = extract32(insn, 0, 5);
    unsigned cpos = extract32(insn, 5, 5);
    unsigned nz = extract32(insn, 10, 1);
    unsigned c = extract32(insn, 13, 3);
    unsigned rr = extract32(insn, 16, 5);
    unsigned rt = extract32(insn, 21, 5);
    unsigned rs = nz ? rt : 0;
    unsigned len = 32 - clen;
    TCGv dest, val;

    if (c) {
        nullify_over(ctx);
    }
    if (cpos + len > 32) {
        len = 32 - cpos;
    }

    dest = dest_gpr(ctx, rt);
    val = load_gpr(ctx, rr);
    if (rs == 0) {
        tcg_gen_deposit_z_tl(dest, val, cpos, len);
    } else {
        tcg_gen_deposit_tl(dest, cpu_gr[rs], val, cpos, len);
    }
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_depw_sar(DisasContext *ctx, uint32_t insn,
                                 const DisasInsn *di)
{
    unsigned clen = extract32(insn, 0, 5);
    unsigned nz = extract32(insn, 10, 1);
    unsigned i = extract32(insn, 12, 1);
    unsigned c = extract32(insn, 13, 3);
    unsigned rt = extract32(insn, 21, 5);
    unsigned rs = nz ? rt : 0;
    unsigned len = 32 - clen;
    TCGv val, mask, tmp, shift, dest;
    unsigned msb = 1U << (len - 1);

    if (c) {
        nullify_over(ctx);
    }

    if (i) {
        val = load_const(ctx, low_sextract(insn, 16, 5));
    } else {
        val = load_gpr(ctx, extract32(insn, 16, 5));
    }
    dest = dest_gpr(ctx, rt);
    shift = tcg_temp_new();
    tmp = tcg_temp_new();

    /* Convert big-endian bit numbering in SAR to left-shift.  */
    tcg_gen_xori_tl(shift, cpu_sar, TARGET_LONG_BITS - 1);

    mask = tcg_const_tl(msb + (msb - 1));
    tcg_gen_and_tl(tmp, val, mask);
    if (rs) {
        tcg_gen_shl_tl(mask, mask, shift);
        tcg_gen_shl_tl(tmp, tmp, shift);
        tcg_gen_andc_tl(dest, cpu_gr[rs], mask);
        tcg_gen_or_tl(dest, dest, tmp);
    } else {
        tcg_gen_shl_tl(dest, tmp, shift);
    }
    tcg_temp_free(shift);
    tcg_temp_free(mask);
    tcg_temp_free(tmp);
    save_gpr(ctx, rt, dest);

    /* Install the new nullification.  */
    cond_free(&ctx->null_cond);
    if (c) {
        ctx->null_cond = do_sed_cond(c, dest);
    }
    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_depw[] = {
    { 0xd4000000u, 0xfc000be0u, trans_depw_sar },
    { 0xd4000800u, 0xfc001800u, trans_depw_imm },
    { 0xd4001800u, 0xfc001800u, trans_depw_imm_c },
};

static ExitStatus trans_be(DisasContext *ctx, uint32_t insn, bool is_l)
{
    unsigned n = extract32(insn, 1, 1);
    unsigned b = extract32(insn, 21, 5);
    target_long disp = assemble_17(insn);

    /* unsigned s = low_uextract(insn, 13, 3); */
    /* ??? It seems like there should be a good way of using
       "be disp(sr2, r0)", the canonical gateway entry mechanism
       to our advantage.  But that appears to be inconvenient to
       manage along side branch delay slots.  Therefore we handle
       entry into the gateway page via absolute address.  */

    /* Since we don't implement spaces, just branch.  Do notice the special
       case of "be disp(*,r0)" using a direct branch to disp, so that we can
       goto_tb to the TB containing the syscall.  */
    if (b == 0) {
        return do_dbranch(ctx, disp, is_l ? 31 : 0, n);
    } else {
        TCGv tmp = get_temp(ctx);
        tcg_gen_addi_tl(tmp, load_gpr(ctx, b), disp);
        return do_ibranch(ctx, tmp, is_l ? 31 : 0, n);
    }
}

static ExitStatus trans_bl(DisasContext *ctx, uint32_t insn,
                           const DisasInsn *di)
{
    unsigned n = extract32(insn, 1, 1);
    unsigned link = extract32(insn, 21, 5);
    target_long disp = assemble_17(insn);

    return do_dbranch(ctx, iaoq_dest(ctx, disp), link, n);
}

static ExitStatus trans_bl_long(DisasContext *ctx, uint32_t insn,
                                const DisasInsn *di)
{
    unsigned n = extract32(insn, 1, 1);
    target_long disp = assemble_22(insn);

    return do_dbranch(ctx, iaoq_dest(ctx, disp), 2, n);
}

static ExitStatus trans_blr(DisasContext *ctx, uint32_t insn,
                            const DisasInsn *di)
{
    unsigned n = extract32(insn, 1, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned link = extract32(insn, 21, 5);
    TCGv tmp = get_temp(ctx);

    tcg_gen_shli_tl(tmp, load_gpr(ctx, rx), 3);
    tcg_gen_addi_tl(tmp, tmp, ctx->iaoq_f + 8);
    return do_ibranch(ctx, tmp, link, n);
}

static ExitStatus trans_bv(DisasContext *ctx, uint32_t insn,
                           const DisasInsn *di)
{
    unsigned n = extract32(insn, 1, 1);
    unsigned rx = extract32(insn, 16, 5);
    unsigned rb = extract32(insn, 21, 5);
    TCGv dest;

    if (rx == 0) {
        dest = load_gpr(ctx, rb);
    } else {
        dest = get_temp(ctx);
        tcg_gen_shli_tl(dest, load_gpr(ctx, rx), 3);
        tcg_gen_add_tl(dest, dest, load_gpr(ctx, rb));
    }
    return do_ibranch(ctx, dest, 0, n);
}

static ExitStatus trans_bve(DisasContext *ctx, uint32_t insn,
                            const DisasInsn *di)
{
    unsigned n = extract32(insn, 1, 1);
    unsigned rb = extract32(insn, 21, 5);
    unsigned link = extract32(insn, 13, 1) ? 2 : 0;

    return do_ibranch(ctx, load_gpr(ctx, rb), link, n);
}

static const DisasInsn table_branch[] = {
    { 0xe8000000u, 0xfc006000u, trans_bl }, /* B,L and B,L,PUSH */
    { 0xe800a000u, 0xfc00e000u, trans_bl_long },
    { 0xe8004000u, 0xfc00fffdu, trans_blr },
    { 0xe800c000u, 0xfc00fffdu, trans_bv },
    { 0xe800d000u, 0xfc00dffcu, trans_bve },
};

static ExitStatus 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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    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)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned rb = extract32(insn, 16, 5);
    unsigned ra = extract32(insn, 21, 5);
    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)
{
    unsigned rt = assemble_rt64(insn);
    unsigned rb = assemble_rb64(insn);
    unsigned ra = assemble_ra64(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)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned rb = extract32(insn, 16, 5);
    unsigned ra = extract32(insn, 21, 5);
    return do_fop_dedd(ctx, rt, ra, rb, di->f_dedd);
}

static void gen_fcpy_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
    tcg_gen_mov_i32(dst, src);
}

static void gen_fcpy_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
    tcg_gen_mov_i64(dst, src);
}

static void gen_fabs_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
    tcg_gen_andi_i32(dst, src, INT32_MAX);
}

static void gen_fabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
    tcg_gen_andi_i64(dst, src, INT64_MAX);
}

static void gen_fneg_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
    tcg_gen_xori_i32(dst, src, INT32_MIN);
}

static void gen_fneg_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
    tcg_gen_xori_i64(dst, src, INT64_MIN);
}

static void gen_fnegabs_s(TCGv_i32 dst, TCGv_env unused, TCGv_i32 src)
{
    tcg_gen_ori_i32(dst, src, INT32_MIN);
}

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)
{
    TCGv_i32 ta, tb, tc, ty;

    nullify_over(ctx);

    ta = load_frw0_i32(ra);
    tb = load_frw0_i32(rb);
    ty = tcg_const_i32(y);
    tc = tcg_const_i32(c);

    gen_helper_fcmp_s(cpu_env, ta, tb, ty, tc);

    tcg_temp_free_i32(ta);
    tcg_temp_free_i32(tb);
    tcg_temp_free_i32(ty);
    tcg_temp_free_i32(tc);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_fcmp_s_0c(DisasContext *ctx, uint32_t insn,
                                  const DisasInsn *di)
{
    unsigned c = extract32(insn, 0, 5);
    unsigned y = extract32(insn, 13, 3);
    unsigned rb = extract32(insn, 16, 5);
    unsigned ra = extract32(insn, 21, 5);
    return do_fcmp_s(ctx, ra, rb, y, c);
}

static ExitStatus trans_fcmp_s_0e(DisasContext *ctx, uint32_t insn,
                                  const DisasInsn *di)
{
    unsigned c = extract32(insn, 0, 5);
    unsigned y = extract32(insn, 13, 3);
    unsigned rb = assemble_rb64(insn);
    unsigned ra = assemble_ra64(insn);
    return do_fcmp_s(ctx, ra, rb, y, c);
}

static ExitStatus trans_fcmp_d(DisasContext *ctx, uint32_t insn,
                               const DisasInsn *di)
{
    unsigned c = extract32(insn, 0, 5);
    unsigned y = extract32(insn, 13, 3);
    unsigned rb = extract32(insn, 16, 5);
    unsigned ra = extract32(insn, 21, 5);
    TCGv_i64 ta, tb;
    TCGv_i32 tc, ty;

    nullify_over(ctx);

    ta = load_frd0(ra);
    tb = load_frd0(rb);
    ty = tcg_const_i32(y);
    tc = tcg_const_i32(c);

    gen_helper_fcmp_d(cpu_env, ta, tb, ty, tc);

    tcg_temp_free_i64(ta);
    tcg_temp_free_i64(tb);
    tcg_temp_free_i32(ty);
    tcg_temp_free_i32(tc);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_ftest_t(DisasContext *ctx, uint32_t insn,
                                const DisasInsn *di)
{
    unsigned y = extract32(insn, 13, 3);
    unsigned cbit = (y ^ 1) - 1;
    TCGv t;

    nullify_over(ctx);

    t = tcg_temp_new();
    tcg_gen_ld32u_tl(t, cpu_env, offsetof(CPUHPPAState, fr0_shadow));
    tcg_gen_extract_tl(t, t, 21 - cbit, 1);
    ctx->null_cond = cond_make_0(TCG_COND_NE, t);
    tcg_temp_free(t);

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_ftest_q(DisasContext *ctx, uint32_t insn,
                                const DisasInsn *di)
{
    unsigned c = extract32(insn, 0, 5);
    int mask;
    bool inv = false;
    TCGv t;

    nullify_over(ctx);

    t = tcg_temp_new();
    tcg_gen_ld32u_tl(t, cpu_env, offsetof(CPUHPPAState, fr0_shadow));

    switch (c) {
    case 0: /* simple */
        tcg_gen_andi_tl(t, t, 0x4000000);
        ctx->null_cond = cond_make_0(TCG_COND_NE, t);
        goto done;
    case 2: /* rej */
        inv = true;
        /* fallthru */
    case 1: /* acc */
        mask = 0x43ff800;
        break;
    case 6: /* rej8 */
        inv = true;
        /* fallthru */
    case 5: /* acc8 */
        mask = 0x43f8000;
        break;
    case 9: /* acc6 */
        mask = 0x43e0000;
        break;
    case 13: /* acc4 */
        mask = 0x4380000;
        break;
    case 17: /* acc2 */
        mask = 0x4200000;
        break;
    default:
        return gen_illegal(ctx);
    }
    if (inv) {
        TCGv c = load_const(ctx, mask);
        tcg_gen_or_tl(t, t, c);
        ctx->null_cond = cond_make(TCG_COND_EQ, t, c);
    } else {
        tcg_gen_andi_tl(t, t, mask);
        ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
    }
 done:
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_xmpyu(DisasContext *ctx, uint32_t insn,
                              const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned rb = assemble_rb64(insn);
    unsigned ra = assemble_ra64(insn);
    TCGv_i64 a, b;

    nullify_over(ctx);

    a = load_frw0_i64(ra);
    b = load_frw0_i64(rb);
    tcg_gen_mul_i64(a, a, b);
    save_frd(rt, a);
    tcg_temp_free_i64(a);
    tcg_temp_free_i64(b);

    return nullify_end(ctx, NO_EXIT);
}

#define FOP_DED  trans_fop_ded, .f_ded
#define FOP_DEDD trans_fop_dedd, .f_dedd

#define FOP_WEW  trans_fop_wew_0c, .f_wew
#define FOP_DEW  trans_fop_dew_0c, .f_dew
#define FOP_WED  trans_fop_wed_0c, .f_wed
#define FOP_WEWW trans_fop_weww_0c, .f_weww

static const DisasInsn table_float_0c[] = {
    /* floating point class zero */
    { 0x30004000, 0xfc1fffe0, FOP_WEW = gen_fcpy_s },
    { 0x30006000, 0xfc1fffe0, FOP_WEW = gen_fabs_s },
    { 0x30008000, 0xfc1fffe0, FOP_WEW = gen_helper_fsqrt_s },
    { 0x3000a000, 0xfc1fffe0, FOP_WEW = gen_helper_frnd_s },
    { 0x3000c000, 0xfc1fffe0, FOP_WEW = gen_fneg_s },
    { 0x3000e000, 0xfc1fffe0, FOP_WEW = gen_fnegabs_s },

    { 0x30004800, 0xfc1fffe0, FOP_DED = gen_fcpy_d },
    { 0x30006800, 0xfc1fffe0, FOP_DED = gen_fabs_d },
    { 0x30008800, 0xfc1fffe0, FOP_DED = gen_helper_fsqrt_d },
    { 0x3000a800, 0xfc1fffe0, FOP_DED = gen_helper_frnd_d },
    { 0x3000c800, 0xfc1fffe0, FOP_DED = gen_fneg_d },
    { 0x3000e800, 0xfc1fffe0, FOP_DED = gen_fnegabs_d },

    /* floating point class three */
    { 0x30000600, 0xfc00ffe0, FOP_WEWW = gen_helper_fadd_s },
    { 0x30002600, 0xfc00ffe0, FOP_WEWW = gen_helper_fsub_s },
    { 0x30004600, 0xfc00ffe0, FOP_WEWW = gen_helper_fmpy_s },
    { 0x30006600, 0xfc00ffe0, FOP_WEWW = gen_helper_fdiv_s },

    { 0x30000e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fadd_d },
    { 0x30002e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fsub_d },
    { 0x30004e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fmpy_d },
    { 0x30006e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fdiv_d },

    /* floating point class one */
    /* float/float */
    { 0x30000a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_s },
    { 0x30002200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_d },
    /* int/float */
    { 0x30008200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_w_s },
    { 0x30008a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_dw_s },
    { 0x3000a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_w_d },
    { 0x3000aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_dw_d },
    /* float/int */
    { 0x30010200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_s_w },
    { 0x30010a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_w },
    { 0x30012200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_dw },
    { 0x30012a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_dw },
    /* float/int truncate */
    { 0x30018200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_t_s_w },
    { 0x30018a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_t_d_w },
    { 0x3001a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_t_s_dw },
    { 0x3001aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_dw },
    /* uint/float */
    { 0x30028200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_uw_s },
    { 0x30028a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_udw_s },
    { 0x3002a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_uw_d },
    { 0x3002aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_udw_d },
    /* float/uint */
    { 0x30030200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_s_uw },
    { 0x30030a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_d_uw },
    { 0x30032200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_s_udw },
    { 0x30032a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_udw },
    /* float/uint truncate */
    { 0x30038200, 0xfc1fffe0, FOP_WEW = gen_helper_fcnv_t_s_uw },
    { 0x30038a00, 0xfc1fffe0, FOP_WED = gen_helper_fcnv_t_d_uw },
    { 0x3003a200, 0xfc1fffe0, FOP_DEW = gen_helper_fcnv_t_s_udw },
    { 0x3003aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_udw },

    /* floating point class two */
    { 0x30000400, 0xfc001fe0, trans_fcmp_s_0c },
    { 0x30000c00, 0xfc001fe0, trans_fcmp_d },
    { 0x30002420, 0xffffffe0, trans_ftest_q },
    { 0x30000420, 0xffff1fff, trans_ftest_t },

    /* FID.  Note that ra == rt == 0, which via fcpy puts 0 into fr0.
       This is machine/revision == 0, which is reserved for simulator.  */
    { 0x30000000, 0xffffffff, FOP_WEW = gen_fcpy_s },
};

#undef FOP_WEW
#undef FOP_DEW
#undef FOP_WED
#undef FOP_WEWW
#define FOP_WEW  trans_fop_wew_0e, .f_wew
#define FOP_DEW  trans_fop_dew_0e, .f_dew
#define FOP_WED  trans_fop_wed_0e, .f_wed
#define FOP_WEWW trans_fop_weww_0e, .f_weww

static const DisasInsn table_float_0e[] = {
    /* floating point class zero */
    { 0x38004000, 0xfc1fff20, FOP_WEW = gen_fcpy_s },
    { 0x38006000, 0xfc1fff20, FOP_WEW = gen_fabs_s },
    { 0x38008000, 0xfc1fff20, FOP_WEW = gen_helper_fsqrt_s },
    { 0x3800a000, 0xfc1fff20, FOP_WEW = gen_helper_frnd_s },
    { 0x3800c000, 0xfc1fff20, FOP_WEW = gen_fneg_s },
    { 0x3800e000, 0xfc1fff20, FOP_WEW = gen_fnegabs_s },

    { 0x38004800, 0xfc1fffe0, FOP_DED = gen_fcpy_d },
    { 0x38006800, 0xfc1fffe0, FOP_DED = gen_fabs_d },
    { 0x38008800, 0xfc1fffe0, FOP_DED = gen_helper_fsqrt_d },
    { 0x3800a800, 0xfc1fffe0, FOP_DED = gen_helper_frnd_d },
    { 0x3800c800, 0xfc1fffe0, FOP_DED = gen_fneg_d },
    { 0x3800e800, 0xfc1fffe0, FOP_DED = gen_fnegabs_d },

    /* floating point class three */
    { 0x38000600, 0xfc00ef20, FOP_WEWW = gen_helper_fadd_s },
    { 0x38002600, 0xfc00ef20, FOP_WEWW = gen_helper_fsub_s },
    { 0x38004600, 0xfc00ef20, FOP_WEWW = gen_helper_fmpy_s },
    { 0x38006600, 0xfc00ef20, FOP_WEWW = gen_helper_fdiv_s },

    { 0x38000e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fadd_d },
    { 0x38002e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fsub_d },
    { 0x38004e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fmpy_d },
    { 0x38006e00, 0xfc00ffe0, FOP_DEDD = gen_helper_fdiv_d },

    { 0x38004700, 0xfc00ef60, trans_xmpyu },

    /* floating point class one */
    /* float/float */
    { 0x38000a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_s },
    { 0x38002200, 0xfc1fffc0, FOP_DEW = gen_helper_fcnv_s_d },
    /* int/float */
    { 0x38008200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_w_s },
    { 0x38008a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_dw_s },
    { 0x3800a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_w_d },
    { 0x3800aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_dw_d },
    /* float/int */
    { 0x38010200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_s_w },
    { 0x38010a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_w },
    { 0x38012200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_s_dw },
    { 0x38012a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_dw },
    /* float/int truncate */
    { 0x38018200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_t_s_w },
    { 0x38018a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_t_d_w },
    { 0x3801a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_t_s_dw },
    { 0x3801aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_dw },
    /* uint/float */
    { 0x38028200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_uw_s },
    { 0x38028a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_udw_s },
    { 0x3802a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_uw_d },
    { 0x3802aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_udw_d },
    /* float/uint */
    { 0x38030200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_s_uw },
    { 0x38030a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_d_uw },
    { 0x38032200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_s_udw },
    { 0x38032a00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_d_udw },
    /* float/uint truncate */
    { 0x38038200, 0xfc1ffe60, FOP_WEW = gen_helper_fcnv_t_s_uw },
    { 0x38038a00, 0xfc1fffa0, FOP_WED = gen_helper_fcnv_t_d_uw },
    { 0x3803a200, 0xfc1fff60, FOP_DEW = gen_helper_fcnv_t_s_udw },
    { 0x3803aa00, 0xfc1fffe0, FOP_DED = gen_helper_fcnv_t_d_udw },

    /* floating point class two */
    { 0x38000400, 0xfc000f60, trans_fcmp_s_0e },
    { 0x38000c00, 0xfc001fe0, trans_fcmp_d },
};

#undef FOP_WEW
#undef FOP_DEW
#undef FOP_WED
#undef FOP_WEWW
#undef FOP_DED
#undef FOP_DEDD

/* Convert the fmpyadd single-precision register encodings to standard.  */
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)
{
    unsigned tm = extract32(insn, 0, 5);
    unsigned f = extract32(insn, 5, 1);
    unsigned ra = extract32(insn, 6, 5);
    unsigned ta = extract32(insn, 11, 5);
    unsigned rm2 = extract32(insn, 16, 5);
    unsigned rm1 = extract32(insn, 21, 5);

    nullify_over(ctx);

    /* Independent multiply & add/sub, with undefined behaviour
       if outputs overlap inputs.  */
    if (f == 0) {
        tm = fmpyadd_s_reg(tm);
        ra = fmpyadd_s_reg(ra);
        ta = fmpyadd_s_reg(ta);
        rm2 = fmpyadd_s_reg(rm2);
        rm1 = fmpyadd_s_reg(rm1);
        do_fop_weww(ctx, tm, rm1, rm2, gen_helper_fmpy_s);
        do_fop_weww(ctx, ta, ta, ra,
                    is_sub ? gen_helper_fsub_s : gen_helper_fadd_s);
    } else {
        do_fop_dedd(ctx, tm, rm1, rm2, gen_helper_fmpy_d);
        do_fop_dedd(ctx, ta, ta, ra,
                    is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);
    }

    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_fmpyfadd_s(DisasContext *ctx, uint32_t insn,
                                   const DisasInsn *di)
{
    unsigned rt = assemble_rt64(insn);
    unsigned neg = extract32(insn, 5, 1);
    unsigned rm1 = assemble_ra64(insn);
    unsigned rm2 = assemble_rb64(insn);
    unsigned ra3 = assemble_rc64(insn);
    TCGv_i32 a, b, c;

    nullify_over(ctx);
    a = load_frw0_i32(rm1);
    b = load_frw0_i32(rm2);
    c = load_frw0_i32(ra3);

    if (neg) {
        gen_helper_fmpynfadd_s(a, cpu_env, a, b, c);
    } else {
        gen_helper_fmpyfadd_s(a, cpu_env, a, b, c);
    }

    tcg_temp_free_i32(b);
    tcg_temp_free_i32(c);
    save_frw_i32(rt, a);
    tcg_temp_free_i32(a);
    return nullify_end(ctx, NO_EXIT);
}

static ExitStatus trans_fmpyfadd_d(DisasContext *ctx, uint32_t insn,
                                   const DisasInsn *di)
{
    unsigned rt = extract32(insn, 0, 5);
    unsigned neg = extract32(insn, 5, 1);
    unsigned rm1 = extract32(insn, 21, 5);
    unsigned rm2 = extract32(insn, 16, 5);
    unsigned ra3 = assemble_rc64(insn);
    TCGv_i64 a, b, c;

    nullify_over(ctx);
    a = load_frd0(rm1);
    b = load_frd0(rm2);
    c = load_frd0(ra3);

    if (neg) {
        gen_helper_fmpynfadd_d(a, cpu_env, a, b, c);
    } else {
        gen_helper_fmpyfadd_d(a, cpu_env, a, b, c);
    }

    tcg_temp_free_i64(b);
    tcg_temp_free_i64(c);
    save_frd(rt, a);
    tcg_temp_free_i64(a);
    return nullify_end(ctx, NO_EXIT);
}

static const DisasInsn table_fp_fused[] = {
    { 0xb8000000u, 0xfc000800u, trans_fmpyfadd_s },
    { 0xb8000800u, 0xfc0019c0u, trans_fmpyfadd_d }
};

static ExitStatus translate_table_int(DisasContext *ctx, uint32_t insn,
                                      const DisasInsn table[], size_t n)
{
    size_t i;
    for (i = 0; i < n; ++i) {
        if ((insn & table[i].mask) == table[i].insn) {
            return table[i].trans(ctx, insn, &table[i]);
        }
    }
    return gen_illegal(ctx);
}

#define translate_table(ctx, insn, table) \
    translate_table_int(ctx, insn, table, ARRAY_SIZE(table))

static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
{
    uint32_t opc = extract32(insn, 26, 6);

    switch (opc) {
    case 0x00: /* system op */
        return translate_table(ctx, insn, table_system);
    case 0x01:
        return translate_table(ctx, insn, table_mem_mgmt);
    case 0x02:
        return translate_table(ctx, insn, table_arith_log);
    case 0x03:
        return translate_table(ctx, insn, table_index_mem);
    case 0x06:
        return trans_fmpyadd(ctx, insn, false);
    case 0x08:
        return trans_ldil(ctx, insn);
    case 0x09:
        return trans_copr_w(ctx, insn);
    case 0x0A:
        return trans_addil(ctx, insn);
    case 0x0B:
        return trans_copr_dw(ctx, insn);
    case 0x0C:
        return translate_table(ctx, insn, table_float_0c);
    case 0x0D:
        return trans_ldo(ctx, insn);
    case 0x0E:
        return translate_table(ctx, insn, table_float_0e);

    case 0x10:
        return trans_load(ctx, insn, false, MO_UB);
    case 0x11:
        return trans_load(ctx, insn, false, MO_TEUW);
    case 0x12:
        return trans_load(ctx, insn, false, MO_TEUL);
    case 0x13:
        return trans_load(ctx, insn, true, MO_TEUL);
    case 0x16:
        return trans_fload_mod(ctx, insn);
    case 0x17:
        return trans_load_w(ctx, insn);
    case 0x18:
        return trans_store(ctx, insn, false, MO_UB);
    case 0x19:
        return trans_store(ctx, insn, false, MO_TEUW);
    case 0x1A:
        return trans_store(ctx, insn, false, MO_TEUL);
    case 0x1B:
        return trans_store(ctx, insn, true, MO_TEUL);
    case 0x1E:
        return trans_fstore_mod(ctx, insn);
    case 0x1F:
        return trans_store_w(ctx, insn);

    case 0x20:
        return trans_cmpb(ctx, insn, true, false, false);
    case 0x21:
        return trans_cmpb(ctx, insn, true, true, false);
    case 0x22:
        return trans_cmpb(ctx, insn, false, false, false);
    case 0x23:
        return trans_cmpb(ctx, insn, false, true, false);
    case 0x24:
        return trans_cmpiclr(ctx, insn);
    case 0x25:
        return trans_subi(ctx, insn);
    case 0x26:
        return trans_fmpyadd(ctx, insn, true);
    case 0x27:
        return trans_cmpb(ctx, insn, true, false, true);
    case 0x28:
        return trans_addb(ctx, insn, true, false);
    case 0x29:
        return trans_addb(ctx, insn, true, true);
    case 0x2A:
        return trans_addb(ctx, insn, false, false);
    case 0x2B:
        return trans_addb(ctx, insn, false, true);
    case 0x2C:
    case 0x2D:
        return trans_addi(ctx, insn);
    case 0x2E:
        return translate_table(ctx, insn, table_fp_fused);
    case 0x2F:
        return trans_cmpb(ctx, insn, false, false, true);

    case 0x30:
    case 0x31:
        return trans_bb(ctx, insn);
    case 0x32:
        return trans_movb(ctx, insn, false);
    case 0x33:
        return trans_movb(ctx, insn, true);
    case 0x34:
        return translate_table(ctx, insn, table_sh_ex);
    case 0x35:
        return translate_table(ctx, insn, table_depw);
    case 0x38:
        return trans_be(ctx, insn, false);
    case 0x39:
        return trans_be(ctx, insn, true);
    case 0x3A:
        return translate_table(ctx, insn, table_branch);

    case 0x04: /* spopn */
    case 0x05: /* diag */
    case 0x0F: /* product specific */
        break;

    case 0x07: /* unassigned */
    case 0x15: /* unassigned */
    case 0x1D: /* unassigned */
    case 0x37: /* unassigned */
    case 0x3F: /* unassigned */
    default:
        break;
    }
    return gen_illegal(ctx);
}

void gen_intermediate_code(CPUHPPAState *env, struct TranslationBlock *tb)
{
    HPPACPU *cpu = hppa_env_get_cpu(env);
    CPUState *cs = CPU(cpu);
    DisasContext ctx;
    ExitStatus ret;
    int num_insns, max_insns, i;

    ctx.tb = tb;
    ctx.cs = cs;
    ctx.iaoq_f = tb->pc;
    ctx.iaoq_b = tb->cs_base;
    ctx.singlestep_enabled = cs->singlestep_enabled;

    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;
    }

    num_insns = 0;
    gen_tb_start(tb);

    /* 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_lab = NULL;

    do {
        tcg_gen_insn_start(ctx.iaoq_f, ctx.iaoq_b);
        num_insns++;

        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();
        }

        if (ctx.iaoq_f < TARGET_PAGE_SIZE) {
            ret = do_page_zero(&ctx);
            assert(ret != NO_EXIT);
        } 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);
            }
        }

        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;
            }
        }

        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);

    if (tb->cflags & CF_LAST_IO) {
        gen_io_end();
    }

    switch (ret) {
    case EXIT_GOTO_TB:
    case EXIT_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);
        /* FALLTHRU */
    case EXIT_IAQ_N_UPDATED:
        if (ctx.singlestep_enabled) {
            gen_excp_1(EXCP_DEBUG);
        } else {
            tcg_gen_exit_tb(0);
        }
        break;
    default:
        abort();
    }

    gen_tb_end(tb, num_insns);

    tb->size = num_insns * 4;
    tb->icount = num_insns;

#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();
    }
#endif
}

void restore_state_to_opc(CPUHPPAState *env, TranslationBlock *tb,
                          target_ulong *data)
{
    env->iaoq_f = data[0];
    if (data[1] != -1) {
        env->iaoq_b = data[1];
    }
    /* Since we were executing the instruction at IAOQ_F, and took some
       sort of action that provoked the cpu_restore_state, we can infer
       that the instruction was not nullified.  */
    env->psw_n = 0;
}
