/*
 * 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.1 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/tcg-op.h"
#include "tcg/tcg-op-gvec.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "exec/log.h"

#define HELPER_H "helper.h"
#include "exec/helper-info.c.inc"
#undef  HELPER_H

/* Choose to use explicit sizes within this file. */
#undef tcg_temp_new

typedef struct DisasCond {
    TCGCond c;
    TCGv_i64 a0, a1;
} DisasCond;

typedef struct DisasContext {
    DisasContextBase base;
    CPUState *cs;
    TCGOp *insn_start;

    uint64_t iaoq_f;
    uint64_t iaoq_b;
    uint64_t iaoq_n;
    TCGv_i64 iaoq_n_var;

    DisasCond null_cond;
    TCGLabel *null_lab;

    TCGv_i64 zero;

    uint32_t insn;
    uint32_t tb_flags;
    int mmu_idx;
    int privilege;
    bool psw_n_nonzero;
    bool is_pa20;

#ifdef CONFIG_USER_ONLY
    MemOp unalign;
#endif
} DisasContext;

#ifdef CONFIG_USER_ONLY
#define UNALIGN(C)       (C)->unalign
#define MMU_DISABLED(C)  false
#else
#define UNALIGN(C)       MO_ALIGN
#define MMU_DISABLED(C)  MMU_IDX_MMU_DISABLED((C)->mmu_idx)
#endif

/* Note that ssm/rsm instructions number PSW_W and PSW_E differently.  */
static int expand_sm_imm(DisasContext *ctx, int val)
{
    /* Keep unimplemented bits disabled -- see cpu_hppa_put_psw. */
    if (ctx->is_pa20) {
        if (val & PSW_SM_W) {
            val |= PSW_W;
        }
        val &= ~(PSW_SM_W | PSW_SM_E | PSW_G);
    } else {
        val &= ~(PSW_SM_W | PSW_SM_E | PSW_O);
    }
    return val;
}

/* Inverted space register indicates 0 means sr0 not inferred from base.  */
static int expand_sr3x(DisasContext *ctx, int val)
{
    return ~val;
}

/* Convert the M:A bits within a memory insn to the tri-state value
   we use for the final M.  */
static int ma_to_m(DisasContext *ctx, int val)
{
    return val & 2 ? (val & 1 ? -1 : 1) : 0;
}

/* Convert the sign of the displacement to a pre or post-modify.  */
static int pos_to_m(DisasContext *ctx, int val)
{
    return val ? 1 : -1;
}

static int neg_to_m(DisasContext *ctx, int val)
{
    return val ? -1 : 1;
}

/* Used for branch targets and fp memory ops.  */
static int expand_shl2(DisasContext *ctx, int val)
{
    return val << 2;
}

/* Used for assemble_21.  */
static int expand_shl11(DisasContext *ctx, int val)
{
    return val << 11;
}

static int assemble_6(DisasContext *ctx, int val)
{
    /*
     * Officially, 32 * x + 32 - y.
     * Here, x is already in bit 5, and y is [4:0].
     * Since -y = ~y + 1, in 5 bits 32 - y => y ^ 31 + 1,
     * with the overflow from bit 4 summing with x.
     */
    return (val ^ 31) + 1;
}

/* Expander for assemble_16a(s,cat(im10a,0),i). */
static int expand_11a(DisasContext *ctx, int val)
{
    /*
     * @val is bit 0 and bits [4:15].
     * Swizzle thing around depending on PSW.W.
     */
    int im10a = extract32(val, 1, 10);
    int s = extract32(val, 11, 2);
    int i = (-(val & 1) << 13) | (im10a << 3);

    if (ctx->tb_flags & PSW_W) {
        i ^= s << 13;
    }
    return i;
}

/* Expander for assemble_16a(s,im11a,i). */
static int expand_12a(DisasContext *ctx, int val)
{
    /*
     * @val is bit 0 and bits [3:15].
     * Swizzle thing around depending on PSW.W.
     */
    int im11a = extract32(val, 1, 11);
    int s = extract32(val, 12, 2);
    int i = (-(val & 1) << 13) | (im11a << 2);

    if (ctx->tb_flags & PSW_W) {
        i ^= s << 13;
    }
    return i;
}

/* Expander for assemble_16(s,im14). */
static int expand_16(DisasContext *ctx, int val)
{
    /*
     * @val is bits [0:15], containing both im14 and s.
     * Swizzle thing around depending on PSW.W.
     */
    int s = extract32(val, 14, 2);
    int i = (-(val & 1) << 13) | extract32(val, 1, 13);

    if (ctx->tb_flags & PSW_W) {
        i ^= s << 13;
    }
    return i;
}

/* The sp field is only present with !PSW_W. */
static int sp0_if_wide(DisasContext *ctx, int sp)
{
    return ctx->tb_flags & PSW_W ? 0 : sp;
}

/* Translate CMPI doubleword conditions to standard. */
static int cmpbid_c(DisasContext *ctx, int val)
{
    return val ? val : 4; /* 0 == "*<<" */
}

/*
 * In many places pa1.x did not decode the bit that later became
 * the pa2.0 D bit.  Suppress D unless the cpu is pa2.0.
 */
static int pa20_d(DisasContext *ctx, int val)
{
    return ctx->is_pa20 & val;
}

/* Include the auto-generated decoder.  */
#include "decode-insns.c.inc"

/* We are not using a goto_tb (for whatever reason), but have updated
   the iaq (for whatever reason), so don't do it again on exit.  */
#define DISAS_IAQ_N_UPDATED  DISAS_TARGET_0

/* We are exiting the TB, but have neither emitted a goto_tb, nor
   updated the iaq for the next instruction to be executed.  */
#define DISAS_IAQ_N_STALE    DISAS_TARGET_1

/* Similarly, but we want to return to the main loop immediately
   to recognize unmasked interrupts.  */
#define DISAS_IAQ_N_STALE_EXIT      DISAS_TARGET_2
#define DISAS_EXIT                  DISAS_TARGET_3

/* global register indexes */
static TCGv_i64 cpu_gr[32];
static TCGv_i64 cpu_sr[4];
static TCGv_i64 cpu_srH;
static TCGv_i64 cpu_iaoq_f;
static TCGv_i64 cpu_iaoq_b;
static TCGv_i64 cpu_iasq_f;
static TCGv_i64 cpu_iasq_b;
static TCGv_i64 cpu_sar;
static TCGv_i64 cpu_psw_n;
static TCGv_i64 cpu_psw_v;
static TCGv_i64 cpu_psw_cb;
static TCGv_i64 cpu_psw_cb_msb;

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

    typedef struct { TCGv_i64 *var; const char *name; int ofs; } GlobalVar;
    static const GlobalVar vars[] = {
        { &cpu_sar, "sar", offsetof(CPUHPPAState, cr[CR_SAR]) },
        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"
    };
    /* SR[4-7] are not global registers so that we can index them.  */
    static const char sr_names[5][4] = {
        "sr0", "sr1", "sr2", "sr3", "srH"
    };

    int i;

    cpu_gr[0] = NULL;
    for (i = 1; i < 32; i++) {
        cpu_gr[i] = tcg_global_mem_new(tcg_env,
                                       offsetof(CPUHPPAState, gr[i]),
                                       gr_names[i]);
    }
    for (i = 0; i < 4; i++) {
        cpu_sr[i] = tcg_global_mem_new_i64(tcg_env,
                                           offsetof(CPUHPPAState, sr[i]),
                                           sr_names[i]);
    }
    cpu_srH = tcg_global_mem_new_i64(tcg_env,
                                     offsetof(CPUHPPAState, sr[4]),
                                     sr_names[4]);

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

    cpu_iasq_f = tcg_global_mem_new_i64(tcg_env,
                                        offsetof(CPUHPPAState, iasq_f),
                                        "iasq_f");
    cpu_iasq_b = tcg_global_mem_new_i64(tcg_env,
                                        offsetof(CPUHPPAState, iasq_b),
                                        "iasq_b");
}

static void set_insn_breg(DisasContext *ctx, int breg)
{
    assert(ctx->insn_start != NULL);
    tcg_set_insn_start_param(ctx->insn_start, 2, breg);
    ctx->insn_start = NULL;
}

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

static DisasCond cond_make_t(void)
{
    return (DisasCond){
        .c = TCG_COND_ALWAYS,
        .a0 = NULL,
        .a1 = NULL,
    };
}

static DisasCond cond_make_n(void)
{
    return (DisasCond){
        .c = TCG_COND_NE,
        .a0 = cpu_psw_n,
        .a1 = tcg_constant_i64(0)
    };
}

static DisasCond cond_make_tmp(TCGCond c, TCGv_i64 a0, TCGv_i64 a1)
{
    assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
    return (DisasCond){ .c = c, .a0 = a0, .a1 = a1 };
}

static DisasCond cond_make_0_tmp(TCGCond c, TCGv_i64 a0)
{
    return cond_make_tmp(c, a0, tcg_constant_i64(0));
}

static DisasCond cond_make_0(TCGCond c, TCGv_i64 a0)
{
    TCGv_i64 tmp = tcg_temp_new_i64();
    tcg_gen_mov_i64(tmp, a0);
    return cond_make_0_tmp(c, tmp);
}

static DisasCond cond_make(TCGCond c, TCGv_i64 a0, TCGv_i64 a1)
{
    TCGv_i64 t0 = tcg_temp_new_i64();
    TCGv_i64 t1 = tcg_temp_new_i64();

    tcg_gen_mov_i64(t0, a0);
    tcg_gen_mov_i64(t1, a1);
    return cond_make_tmp(c, t0, t1);
}

static void cond_free(DisasCond *cond)
{
    switch (cond->c) {
    default:
        cond->a0 = NULL;
        cond->a1 = NULL;
        /* fallthru */
    case TCG_COND_ALWAYS:
        cond->c = TCG_COND_NEVER;
        break;
    case TCG_COND_NEVER:
        break;
    }
}

static TCGv_i64 load_gpr(DisasContext *ctx, unsigned reg)
{
    if (reg == 0) {
        return ctx->zero;
    } else {
        return cpu_gr[reg];
    }
}

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

static void save_or_nullify(DisasContext *ctx, TCGv_i64 dest, TCGv_i64 t)
{
    if (ctx->null_cond.c != TCG_COND_NEVER) {
        tcg_gen_movcond_i64(ctx->null_cond.c, dest, ctx->null_cond.a0,
                            ctx->null_cond.a1, dest, t);
    } else {
        tcg_gen_mov_i64(dest, t);
    }
}

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

#if HOST_BIG_ENDIAN
# 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, tcg_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) {
        TCGv_i32 ret = tcg_temp_new_i32();
        tcg_gen_movi_i32(ret, 0);
        return ret;
    } else {
        return load_frw_i32(rt);
    }
}

static TCGv_i64 load_frw0_i64(unsigned rt)
{
    TCGv_i64 ret = tcg_temp_new_i64();
    if (rt == 0) {
        tcg_gen_movi_i64(ret, 0);
    } else {
        tcg_gen_ld32u_i64(ret, tcg_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, tcg_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, tcg_env, offsetof(CPUHPPAState, fr[rt]));
    return ret;
}

static TCGv_i64 load_frd0(unsigned rt)
{
    if (rt == 0) {
        TCGv_i64 ret = tcg_temp_new_i64();
        tcg_gen_movi_i64(ret, 0);
        return ret;
    } else {
        return load_frd(rt);
    }
}

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

static void load_spr(DisasContext *ctx, TCGv_i64 dest, unsigned reg)
{
#ifdef CONFIG_USER_ONLY
    tcg_gen_movi_i64(dest, 0);
#else
    if (reg < 4) {
        tcg_gen_mov_i64(dest, cpu_sr[reg]);
    } else if (ctx->tb_flags & TB_FLAG_SR_SAME) {
        tcg_gen_mov_i64(dest, cpu_srH);
    } else {
        tcg_gen_ld_i64(dest, tcg_env, offsetof(CPUHPPAState, sr[reg]));
    }
#endif
}

/* 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();

        /* If we're using PSW[N], copy it to a temp because... */
        if (ctx->null_cond.a0 == cpu_psw_n) {
            ctx->null_cond.a0 = tcg_temp_new_i64();
            tcg_gen_mov_i64(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_i64(cpu_psw_n, 0);
        }

        tcg_gen_brcond_i64(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_i64(cpu_psw_n, 0);
        }
        return;
    }
    if (ctx->null_cond.a0 != cpu_psw_n) {
        tcg_gen_setcond_i64(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_i64(cpu_psw_n, x);
    }
}

/* Mark the end of an instruction that may have been nullified.
   This is the pair to nullify_over.  Always returns true so that
   it may be tail-called from a translate function.  */
static bool nullify_end(DisasContext *ctx)
{
    TCGLabel *null_lab = ctx->null_lab;
    DisasJumpType status = ctx->base.is_jmp;

    /* For NEXT, NORETURN, STALE, we can easily continue (or exit).
       For UPDATED, we cannot update on the nullified path.  */
    assert(status != DISAS_IAQ_N_UPDATED);

    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 true;
    }
    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();
    }
    if (status == DISAS_NORETURN) {
        ctx->base.is_jmp = DISAS_NEXT;
    }
    return true;
}

static void copy_iaoq_entry(DisasContext *ctx, TCGv_i64 dest,
                            uint64_t ival, TCGv_i64 vval)
{
    uint64_t mask = gva_offset_mask(ctx->tb_flags);

    if (ival != -1) {
        tcg_gen_movi_i64(dest, ival & mask);
        return;
    }
    tcg_debug_assert(vval != NULL);

    /*
     * We know that the IAOQ is already properly masked.
     * This optimization is primarily for "iaoq_f = iaoq_b".
     */
    if (vval == cpu_iaoq_f || vval == cpu_iaoq_b) {
        tcg_gen_mov_i64(dest, vval);
    } else {
        tcg_gen_andi_i64(dest, vval, mask);
    }
}

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

static void gen_excp_1(int exception)
{
    gen_helper_excp(tcg_env, tcg_constant_i32(exception));
}

static void gen_excp(DisasContext *ctx, int exception)
{
    copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
    copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
    nullify_save(ctx);
    gen_excp_1(exception);
    ctx->base.is_jmp = DISAS_NORETURN;
}

static bool gen_excp_iir(DisasContext *ctx, int exc)
{
    nullify_over(ctx);
    tcg_gen_st_i64(tcg_constant_i64(ctx->insn),
                   tcg_env, offsetof(CPUHPPAState, cr[CR_IIR]));
    gen_excp(ctx, exc);
    return nullify_end(ctx);
}

static bool gen_illegal(DisasContext *ctx)
{
    return gen_excp_iir(ctx, EXCP_ILL);
}

#ifdef CONFIG_USER_ONLY
#define CHECK_MOST_PRIVILEGED(EXCP) \
    return gen_excp_iir(ctx, EXCP)
#else
#define CHECK_MOST_PRIVILEGED(EXCP) \
    do {                                     \
        if (ctx->privilege != 0) {           \
            return gen_excp_iir(ctx, EXCP);  \
        }                                    \
    } while (0)
#endif

static bool use_goto_tb(DisasContext *ctx, uint64_t dest)
{
    return translator_use_goto_tb(&ctx->base, dest);
}

/* 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,
                        uint64_t f, uint64_t b)
{
    if (f != -1 && b != -1 && use_goto_tb(ctx, f)) {
        tcg_gen_goto_tb(which);
        copy_iaoq_entry(ctx, cpu_iaoq_f, f, NULL);
        copy_iaoq_entry(ctx, cpu_iaoq_b, b, NULL);
        tcg_gen_exit_tb(ctx->base.tb, which);
    } else {
        copy_iaoq_entry(ctx, cpu_iaoq_f, f, cpu_iaoq_b);
        copy_iaoq_entry(ctx, cpu_iaoq_b, b, ctx->iaoq_n_var);
        tcg_gen_lookup_and_goto_ptr();
    }
}

static bool cond_need_sv(int c)
{
    return c == 2 || c == 3 || c == 6;
}

static bool cond_need_cb(int c)
{
    return c == 4 || c == 5;
}

/*
 * Compute conditional for arithmetic.  See Page 5-3, Table 5-1, of
 * the Parisc 1.1 Architecture Reference Manual for details.
 */

static DisasCond do_cond(DisasContext *ctx, unsigned cf, bool d,
                         TCGv_i64 res, TCGv_i64 uv, TCGv_i64 sv)
{
    DisasCond cond;
    TCGv_i64 tmp;

    switch (cf >> 1) {
    case 0: /* Never / TR    (0 / 1) */
        cond = cond_make_f();
        break;
    case 1: /* = / <>        (Z / !Z) */
        if (!d) {
            tmp = tcg_temp_new_i64();
            tcg_gen_ext32u_i64(tmp, res);
            res = tmp;
        }
        cond = cond_make_0(TCG_COND_EQ, res);
        break;
    case 2: /* < / >=        (N ^ V / !(N ^ V) */
        tmp = tcg_temp_new_i64();
        tcg_gen_xor_i64(tmp, res, sv);
        if (!d) {
            tcg_gen_ext32s_i64(tmp, tmp);
        }
        cond = cond_make_0_tmp(TCG_COND_LT, tmp);
        break;
    case 3: /* <= / >        (N ^ V) | Z / !((N ^ V) | Z) */
        /*
         * Simplify:
         *   (N ^ V) | Z
         *   ((res < 0) ^ (sv < 0)) | !res
         *   ((res ^ sv) < 0) | !res
         *   (~(res ^ sv) >= 0) | !res
         *   !(~(res ^ sv) >> 31) | !res
         *   !(~(res ^ sv) >> 31 & res)
         */
        tmp = tcg_temp_new_i64();
        tcg_gen_eqv_i64(tmp, res, sv);
        if (!d) {
            tcg_gen_sextract_i64(tmp, tmp, 31, 1);
            tcg_gen_and_i64(tmp, tmp, res);
            tcg_gen_ext32u_i64(tmp, tmp);
        } else {
            tcg_gen_sari_i64(tmp, tmp, 63);
            tcg_gen_and_i64(tmp, tmp, res);
        }
        cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
        break;
    case 4: /* NUV / UV      (!UV / UV) */
        cond = cond_make_0(TCG_COND_EQ, uv);
        break;
    case 5: /* ZNV / VNZ     (!UV | Z / UV & !Z) */
        tmp = tcg_temp_new_i64();
        tcg_gen_movcond_i64(TCG_COND_EQ, tmp, uv, ctx->zero, ctx->zero, res);
        if (!d) {
            tcg_gen_ext32u_i64(tmp, tmp);
        }
        cond = cond_make_0_tmp(TCG_COND_EQ, tmp);
        break;
    case 6: /* SV / NSV      (V / !V) */
        if (!d) {
            tmp = tcg_temp_new_i64();
            tcg_gen_ext32s_i64(tmp, sv);
            sv = tmp;
        }
        cond = cond_make_0(TCG_COND_LT, sv);
        break;
    case 7: /* OD / EV */
        tmp = tcg_temp_new_i64();
        tcg_gen_andi_i64(tmp, res, 1);
        cond = cond_make_0_tmp(TCG_COND_NE, 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(DisasContext *ctx, unsigned cf, bool d,
                             TCGv_i64 res, TCGv_i64 in1,
                             TCGv_i64 in2, TCGv_i64 sv)
{
    TCGCond tc;
    bool ext_uns;

    switch (cf >> 1) {
    case 1: /* = / <> */
        tc = TCG_COND_EQ;
        ext_uns = true;
        break;
    case 2: /* < / >= */
        tc = TCG_COND_LT;
        ext_uns = false;
        break;
    case 3: /* <= / > */
        tc = TCG_COND_LE;
        ext_uns = false;
        break;
    case 4: /* << / >>= */
        tc = TCG_COND_LTU;
        ext_uns = true;
        break;
    case 5: /* <<= / >> */
        tc = TCG_COND_LEU;
        ext_uns = true;
        break;
    default:
        return do_cond(ctx, cf, d, res, NULL, sv);
    }

    if (cf & 1) {
        tc = tcg_invert_cond(tc);
    }
    if (!d) {
        TCGv_i64 t1 = tcg_temp_new_i64();
        TCGv_i64 t2 = tcg_temp_new_i64();

        if (ext_uns) {
            tcg_gen_ext32u_i64(t1, in1);
            tcg_gen_ext32u_i64(t2, in2);
        } else {
            tcg_gen_ext32s_i64(t1, in1);
            tcg_gen_ext32s_i64(t2, in2);
        }
        return cond_make_tmp(tc, t1, t2);
    }
    return cond_make(tc, in1, in2);
}

/*
 * Similar, but for logicals, where the carry and overflow bits are not
 * computed, and use of them is undefined.
 *
 * Undefined or not, hardware does not trap.  It seems reasonable to
 * assume hardware treats cases c={4,5,6} as if C=0 & V=0, since that's
 * how cases c={2,3} are treated.
 */

static DisasCond do_log_cond(DisasContext *ctx, unsigned cf, bool d,
                             TCGv_i64 res)
{
    TCGCond tc;
    bool ext_uns;

    switch (cf) {
    case 0:  /* never */
    case 9:  /* undef, C */
    case 11: /* undef, C & !Z */
    case 12: /* undef, V */
        return cond_make_f();

    case 1:  /* true */
    case 8:  /* undef, !C */
    case 10: /* undef, !C | Z */
    case 13: /* undef, !V */
        return cond_make_t();

    case 2:  /* == */
        tc = TCG_COND_EQ;
        ext_uns = true;
        break;
    case 3:  /* <> */
        tc = TCG_COND_NE;
        ext_uns = true;
        break;
    case 4:  /* < */
        tc = TCG_COND_LT;
        ext_uns = false;
        break;
    case 5:  /* >= */
        tc = TCG_COND_GE;
        ext_uns = false;
        break;
    case 6:  /* <= */
        tc = TCG_COND_LE;
        ext_uns = false;
        break;
    case 7:  /* > */
        tc = TCG_COND_GT;
        ext_uns = false;
        break;

    case 14: /* OD */
    case 15: /* EV */
        return do_cond(ctx, cf, d, res, NULL, NULL);

    default:
        g_assert_not_reached();
    }

    if (!d) {
        TCGv_i64 tmp = tcg_temp_new_i64();

        if (ext_uns) {
            tcg_gen_ext32u_i64(tmp, res);
        } else {
            tcg_gen_ext32s_i64(tmp, res);
        }
        return cond_make_0_tmp(tc, tmp);
    }
    return cond_make_0(tc, res);
}

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

static DisasCond do_sed_cond(DisasContext *ctx, unsigned orig, bool d,
                             TCGv_i64 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(ctx, c * 2 + f, d, res);
}

/* Similar, but for unit zero conditions.  */
static DisasCond do_unit_zero_cond(unsigned cf, bool d, TCGv_i64 res)
{
    TCGv_i64 tmp;
    uint64_t d_repl = d ? 0x0000000100000001ull : 1;
    uint64_t ones = 0, sgns = 0;

    switch (cf >> 1) {
    case 1: /* SBW / NBW */
        if (d) {
            ones = d_repl;
            sgns = d_repl << 31;
        }
        break;
    case 2: /* SBZ / NBZ */
        ones = d_repl * 0x01010101u;
        sgns = ones << 7;
        break;
    case 3: /* SHZ / NHZ */
        ones = d_repl * 0x00010001u;
        sgns = ones << 15;
        break;
    }
    if (ones == 0) {
        /* Undefined, or 0/1 (never/always). */
        return cf & 1 ? cond_make_t() : cond_make_f();
    }

    /*
     * See hasless(v,1) from
     * https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
     */
    tmp = tcg_temp_new_i64();
    tcg_gen_subi_i64(tmp, res, ones);
    tcg_gen_andc_i64(tmp, tmp, res);
    tcg_gen_andi_i64(tmp, tmp, sgns);

    return cond_make_0_tmp(cf & 1 ? TCG_COND_EQ : TCG_COND_NE, tmp);
}

static TCGv_i64 get_carry(DisasContext *ctx, bool d,
                          TCGv_i64 cb, TCGv_i64 cb_msb)
{
    if (!d) {
        TCGv_i64 t = tcg_temp_new_i64();
        tcg_gen_extract_i64(t, cb, 32, 1);
        return t;
    }
    return cb_msb;
}

static TCGv_i64 get_psw_carry(DisasContext *ctx, bool d)
{
    return get_carry(ctx, d, cpu_psw_cb, cpu_psw_cb_msb);
}

/* Compute signed overflow for addition.  */
static TCGv_i64 do_add_sv(DisasContext *ctx, TCGv_i64 res,
                          TCGv_i64 in1, TCGv_i64 in2,
                          TCGv_i64 orig_in1, int shift, bool d)
{
    TCGv_i64 sv = tcg_temp_new_i64();
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_xor_i64(sv, res, in1);
    tcg_gen_xor_i64(tmp, in1, in2);
    tcg_gen_andc_i64(sv, sv, tmp);

    switch (shift) {
    case 0:
        break;
    case 1:
        /* Shift left by one and compare the sign. */
        tcg_gen_add_i64(tmp, orig_in1, orig_in1);
        tcg_gen_xor_i64(tmp, tmp, orig_in1);
        /* Incorporate into the overflow. */
        tcg_gen_or_i64(sv, sv, tmp);
        break;
    default:
        {
            int sign_bit = d ? 63 : 31;

            /* Compare the sign against all lower bits. */
            tcg_gen_sextract_i64(tmp, orig_in1, sign_bit, 1);
            tcg_gen_xor_i64(tmp, tmp, orig_in1);
            /*
             * If one of the bits shifting into or through the sign
             * differs, then we have overflow.
             */
            tcg_gen_extract_i64(tmp, tmp, sign_bit - shift, shift);
            tcg_gen_movcond_i64(TCG_COND_NE, sv, tmp, ctx->zero,
                                tcg_constant_i64(-1), sv);
        }
    }
    return sv;
}

/* Compute unsigned overflow for addition.  */
static TCGv_i64 do_add_uv(DisasContext *ctx, TCGv_i64 cb, TCGv_i64 cb_msb,
                          TCGv_i64 in1, int shift, bool d)
{
    if (shift == 0) {
        return get_carry(ctx, d, cb, cb_msb);
    } else {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_extract_i64(tmp, in1, (d ? 63 : 31) - shift, shift);
        tcg_gen_or_i64(tmp, tmp, get_carry(ctx, d, cb, cb_msb));
        return tmp;
    }
}

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

    tcg_gen_xor_i64(sv, res, in1);
    tcg_gen_xor_i64(tmp, in1, in2);
    tcg_gen_and_i64(sv, sv, tmp);

    return sv;
}

static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
                   TCGv_i64 in2, unsigned shift, bool is_l,
                   bool is_tsv, bool is_tc, bool is_c, unsigned cf, bool d)
{
    TCGv_i64 dest, cb, cb_msb, in1, uv, sv, tmp;
    unsigned c = cf >> 1;
    DisasCond cond;

    dest = tcg_temp_new_i64();
    cb = NULL;
    cb_msb = NULL;

    in1 = orig_in1;
    if (shift) {
        tmp = tcg_temp_new_i64();
        tcg_gen_shli_i64(tmp, in1, shift);
        in1 = tmp;
    }

    if (!is_l || cond_need_cb(c)) {
        cb_msb = tcg_temp_new_i64();
        cb = tcg_temp_new_i64();

        tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
        if (is_c) {
            tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb,
                             get_psw_carry(ctx, d), ctx->zero);
        }
        tcg_gen_xor_i64(cb, in1, in2);
        tcg_gen_xor_i64(cb, cb, dest);
    } else {
        tcg_gen_add_i64(dest, in1, in2);
        if (is_c) {
            tcg_gen_add_i64(dest, dest, get_psw_carry(ctx, d));
        }
    }

    /* Compute signed overflow if required.  */
    sv = NULL;
    if (is_tsv || cond_need_sv(c)) {
        sv = do_add_sv(ctx, dest, in1, in2, orig_in1, shift, d);
        if (is_tsv) {
            if (!d) {
                tcg_gen_ext32s_i64(sv, sv);
            }
            gen_helper_tsv(tcg_env, sv);
        }
    }

    /* Compute unsigned overflow if required.  */
    uv = NULL;
    if (cond_need_cb(c)) {
        uv = do_add_uv(ctx, cb, cb_msb, orig_in1, shift, d);
    }

    /* Emit any conditional trap before any writeback.  */
    cond = do_cond(ctx, cf, d, dest, uv, sv);
    if (is_tc) {
        tmp = tcg_temp_new_i64();
        tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
        gen_helper_tcond(tcg_env, 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);

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

static bool do_add_reg(DisasContext *ctx, arg_rrr_cf_d_sh *a,
                       bool is_l, bool is_tsv, bool is_tc, bool is_c)
{
    TCGv_i64 tcg_r1, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    do_add(ctx, a->t, tcg_r1, tcg_r2, a->sh, is_l,
           is_tsv, is_tc, is_c, a->cf, a->d);
    return nullify_end(ctx);
}

static bool do_add_imm(DisasContext *ctx, arg_rri_cf *a,
                       bool is_tsv, bool is_tc)
{
    TCGv_i64 tcg_im, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_im = tcg_constant_i64(a->i);
    tcg_r2 = load_gpr(ctx, a->r);
    /* All ADDI conditions are 32-bit. */
    do_add(ctx, a->t, tcg_im, tcg_r2, 0, 0, is_tsv, is_tc, 0, a->cf, false);
    return nullify_end(ctx);
}

static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
                   TCGv_i64 in2, bool is_tsv, bool is_b,
                   bool is_tc, unsigned cf, bool d)
{
    TCGv_i64 dest, sv, cb, cb_msb, tmp;
    unsigned c = cf >> 1;
    DisasCond cond;

    dest = tcg_temp_new_i64();
    cb = tcg_temp_new_i64();
    cb_msb = tcg_temp_new_i64();

    if (is_b) {
        /* DEST,C = IN1 + ~IN2 + C.  */
        tcg_gen_not_i64(cb, in2);
        tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero,
                         get_psw_carry(ctx, d), ctx->zero);
        tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, ctx->zero);
        tcg_gen_xor_i64(cb, cb, in1);
        tcg_gen_xor_i64(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.
         */
        TCGv_i64 one = tcg_constant_i64(1);
        tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, ctx->zero);
        tcg_gen_eqv_i64(cb, in1, in2);
        tcg_gen_xor_i64(cb, cb, dest);
    }

    /* Compute signed overflow if required.  */
    sv = NULL;
    if (is_tsv || cond_need_sv(c)) {
        sv = do_sub_sv(ctx, dest, in1, in2);
        if (is_tsv) {
            if (!d) {
                tcg_gen_ext32s_i64(sv, sv);
            }
            gen_helper_tsv(tcg_env, sv);
        }
    }

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

    /* Emit any conditional trap before any writeback.  */
    if (is_tc) {
        tmp = tcg_temp_new_i64();
        tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
        gen_helper_tcond(tcg_env, 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);

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

static bool do_sub_reg(DisasContext *ctx, arg_rrr_cf_d *a,
                       bool is_tsv, bool is_b, bool is_tc)
{
    TCGv_i64 tcg_r1, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    do_sub(ctx, a->t, tcg_r1, tcg_r2, is_tsv, is_b, is_tc, a->cf, a->d);
    return nullify_end(ctx);
}

static bool do_sub_imm(DisasContext *ctx, arg_rri_cf *a, bool is_tsv)
{
    TCGv_i64 tcg_im, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_im = tcg_constant_i64(a->i);
    tcg_r2 = load_gpr(ctx, a->r);
    /* All SUBI conditions are 32-bit. */
    do_sub(ctx, a->t, tcg_im, tcg_r2, is_tsv, 0, 0, a->cf, false);
    return nullify_end(ctx);
}

static void do_cmpclr(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
                      TCGv_i64 in2, unsigned cf, bool d)
{
    TCGv_i64 dest, sv;
    DisasCond cond;

    dest = tcg_temp_new_i64();
    tcg_gen_sub_i64(dest, in1, in2);

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

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

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

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

static void do_log(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
                   TCGv_i64 in2, unsigned cf, bool d,
                   void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
{
    TCGv_i64 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(ctx, cf, d, dest);
    }
}

static bool do_log_reg(DisasContext *ctx, arg_rrr_cf_d *a,
                       void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
{
    TCGv_i64 tcg_r1, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    do_log(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d, fn);
    return nullify_end(ctx);
}

static void do_unit_addsub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
                           TCGv_i64 in2, unsigned cf, bool d,
                           bool is_tc, bool is_add)
{
    TCGv_i64 dest = tcg_temp_new_i64();
    uint64_t test_cb = 0;
    DisasCond cond;

    /* Select which carry-out bits to test. */
    switch (cf >> 1) {
    case 4: /* NDC / SDC -- 4-bit carries */
        test_cb = dup_const(MO_8, 0x88);
        break;
    case 5: /* NWC / SWC -- 32-bit carries */
        if (d) {
            test_cb = dup_const(MO_32, INT32_MIN);
        } else {
            cf &= 1; /* undefined -- map to never/always */
        }
        break;
    case 6: /* NBC / SBC -- 8-bit carries */
        test_cb = dup_const(MO_8, INT8_MIN);
        break;
    case 7: /* NHC / SHC -- 16-bit carries */
        test_cb = dup_const(MO_16, INT16_MIN);
        break;
    }
    if (!d) {
        test_cb = (uint32_t)test_cb;
    }

    if (!test_cb) {
        /* No need to compute carries if we don't need to test them. */
        if (is_add) {
            tcg_gen_add_i64(dest, in1, in2);
        } else {
            tcg_gen_sub_i64(dest, in1, in2);
        }
        cond = do_unit_zero_cond(cf, d, dest);
    } else {
        TCGv_i64 cb = tcg_temp_new_i64();

        if (d) {
            TCGv_i64 cb_msb = tcg_temp_new_i64();
            if (is_add) {
                tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
                tcg_gen_xor_i64(cb, in1, in2);
            } else {
                /* See do_sub, !is_b. */
                TCGv_i64 one = tcg_constant_i64(1);
                tcg_gen_sub2_i64(dest, cb_msb, in1, one, in2, ctx->zero);
                tcg_gen_eqv_i64(cb, in1, in2);
            }
            tcg_gen_xor_i64(cb, cb, dest);
            tcg_gen_extract2_i64(cb, cb, cb_msb, 1);
        } else {
            if (is_add) {
                tcg_gen_add_i64(dest, in1, in2);
                tcg_gen_xor_i64(cb, in1, in2);
            } else {
                tcg_gen_sub_i64(dest, in1, in2);
                tcg_gen_eqv_i64(cb, in1, in2);
            }
            tcg_gen_xor_i64(cb, cb, dest);
            tcg_gen_shri_i64(cb, cb, 1);
        }

        tcg_gen_andi_i64(cb, cb, test_cb);
        cond = cond_make_0_tmp(cf & 1 ? TCG_COND_EQ : TCG_COND_NE, cb);
    }

    if (is_tc) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_setcond_i64(cond.c, tmp, cond.a0, cond.a1);
        gen_helper_tcond(tcg_env, tmp);
    }
    save_gpr(ctx, rt, dest);

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

#ifndef CONFIG_USER_ONLY
/* The "normal" usage is SP >= 0, wherein SP == 0 selects the space
   from the top 2 bits of the base register.  There are a few system
   instructions that have a 3-bit space specifier, for which SR0 is
   not special.  To handle this, pass ~SP.  */
static TCGv_i64 space_select(DisasContext *ctx, int sp, TCGv_i64 base)
{
    TCGv_ptr ptr;
    TCGv_i64 tmp;
    TCGv_i64 spc;

    if (sp != 0) {
        if (sp < 0) {
            sp = ~sp;
        }
        spc = tcg_temp_new_i64();
        load_spr(ctx, spc, sp);
        return spc;
    }
    if (ctx->tb_flags & TB_FLAG_SR_SAME) {
        return cpu_srH;
    }

    ptr = tcg_temp_new_ptr();
    tmp = tcg_temp_new_i64();
    spc = tcg_temp_new_i64();

    /* Extract top 2 bits of the address, shift left 3 for uint64_t index. */
    tcg_gen_shri_i64(tmp, base, (ctx->tb_flags & PSW_W ? 64 : 32) - 5);
    tcg_gen_andi_i64(tmp, tmp, 030);
    tcg_gen_trunc_i64_ptr(ptr, tmp);

    tcg_gen_add_ptr(ptr, ptr, tcg_env);
    tcg_gen_ld_i64(spc, ptr, offsetof(CPUHPPAState, sr[4]));

    return spc;
}
#endif

static void form_gva(DisasContext *ctx, TCGv_i64 *pgva, TCGv_i64 *pofs,
                     unsigned rb, unsigned rx, int scale, int64_t disp,
                     unsigned sp, int modify, bool is_phys)
{
    TCGv_i64 base = load_gpr(ctx, rb);
    TCGv_i64 ofs;
    TCGv_i64 addr;

    set_insn_breg(ctx, rb);

    /* Note that RX is mutually exclusive with DISP.  */
    if (rx) {
        ofs = tcg_temp_new_i64();
        tcg_gen_shli_i64(ofs, cpu_gr[rx], scale);
        tcg_gen_add_i64(ofs, ofs, base);
    } else if (disp || modify) {
        ofs = tcg_temp_new_i64();
        tcg_gen_addi_i64(ofs, base, disp);
    } else {
        ofs = base;
    }

    *pofs = ofs;
    *pgva = addr = tcg_temp_new_i64();
    tcg_gen_andi_i64(addr, modify <= 0 ? ofs : base,
                     gva_offset_mask(ctx->tb_flags));
#ifndef CONFIG_USER_ONLY
    if (!is_phys) {
        tcg_gen_or_i64(addr, addr, space_select(ctx, sp, base));
    }
#endif
}

/* 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, int64_t disp,
                       unsigned sp, int modify, MemOp mop)
{
    TCGv_i64 ofs;
    TCGv_i64 addr;

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

    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
             MMU_DISABLED(ctx));
    tcg_gen_qemu_ld_i32(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
    if (modify) {
        save_gpr(ctx, rb, ofs);
    }
}

static void do_load_64(DisasContext *ctx, TCGv_i64 dest, unsigned rb,
                       unsigned rx, int scale, int64_t disp,
                       unsigned sp, int modify, MemOp mop)
{
    TCGv_i64 ofs;
    TCGv_i64 addr;

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

    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
             MMU_DISABLED(ctx));
    tcg_gen_qemu_ld_i64(dest, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
    if (modify) {
        save_gpr(ctx, rb, ofs);
    }
}

static void do_store_32(DisasContext *ctx, TCGv_i32 src, unsigned rb,
                        unsigned rx, int scale, int64_t disp,
                        unsigned sp, int modify, MemOp mop)
{
    TCGv_i64 ofs;
    TCGv_i64 addr;

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

    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
             MMU_DISABLED(ctx));
    tcg_gen_qemu_st_i32(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
    if (modify) {
        save_gpr(ctx, rb, ofs);
    }
}

static void do_store_64(DisasContext *ctx, TCGv_i64 src, unsigned rb,
                        unsigned rx, int scale, int64_t disp,
                        unsigned sp, int modify, MemOp mop)
{
    TCGv_i64 ofs;
    TCGv_i64 addr;

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

    form_gva(ctx, &addr, &ofs, rb, rx, scale, disp, sp, modify,
             MMU_DISABLED(ctx));
    tcg_gen_qemu_st_i64(src, addr, ctx->mmu_idx, mop | UNALIGN(ctx));
    if (modify) {
        save_gpr(ctx, rb, ofs);
    }
}

static bool do_load(DisasContext *ctx, unsigned rt, unsigned rb,
                    unsigned rx, int scale, int64_t disp,
                    unsigned sp, int modify, MemOp mop)
{
    TCGv_i64 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 = tcg_temp_new_i64();
    }
    do_load_64(ctx, dest, rb, rx, scale, disp, sp, modify, mop);
    save_gpr(ctx, rt, dest);

    return nullify_end(ctx);
}

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

    nullify_over(ctx);

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

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

    return nullify_end(ctx);
}

static bool trans_fldw(DisasContext *ctx, arg_ldst *a)
{
    return do_floadw(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
                     a->disp, a->sp, a->m);
}

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

    nullify_over(ctx);

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

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

    return nullify_end(ctx);
}

static bool trans_fldd(DisasContext *ctx, arg_ldst *a)
{
    return do_floadd(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
                     a->disp, a->sp, a->m);
}

static bool do_store(DisasContext *ctx, unsigned rt, unsigned rb,
                     int64_t disp, unsigned sp,
                     int modify, MemOp mop)
{
    nullify_over(ctx);
    do_store_64(ctx, load_gpr(ctx, rt), rb, 0, 0, disp, sp, modify, mop);
    return nullify_end(ctx);
}

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

    nullify_over(ctx);

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

    return nullify_end(ctx);
}

static bool trans_fstw(DisasContext *ctx, arg_ldst *a)
{
    return do_fstorew(ctx, a->t, a->b, a->x, a->scale ? 2 : 0,
                      a->disp, a->sp, a->m);
}

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

    nullify_over(ctx);

    tmp = load_frd(rt);
    do_store_64(ctx, tmp, rb, rx, scale, disp, sp, modify, MO_TEUQ);

    return nullify_end(ctx);
}

static bool trans_fstd(DisasContext *ctx, arg_ldst *a)
{
    return do_fstored(ctx, a->t, a->b, a->x, a->scale ? 3 : 0,
                      a->disp, a->sp, a->m);
}

static bool 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, tcg_env, tmp);

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

static bool 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, tcg_env, src);

    save_frw_i32(rt, dst);
    return nullify_end(ctx);
}

static bool 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, tcg_env, tmp);

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

static bool 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, tcg_env, src);

    save_frd(rt, dst);
    return nullify_end(ctx);
}

static bool 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, tcg_env, a, b);

    save_frw_i32(rt, a);
    return nullify_end(ctx);
}

static bool 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, tcg_env, a, b);

    save_frd(rt, a);
    return nullify_end(ctx);
}

/* Emit an unconditional branch to a direct target, which may or may not
   have already had nullification handled.  */
static bool do_dbranch(DisasContext *ctx, uint64_t dest,
                       unsigned link, bool is_n)
{
    if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
        if (link != 0) {
            copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }
        ctx->iaoq_n = dest;
        if (is_n) {
            ctx->null_cond.c = TCG_COND_ALWAYS;
        }
    } else {
        nullify_over(ctx);

        if (link != 0) {
            copy_iaoq_entry(ctx, 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);

        nullify_set(ctx, 0);
        gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
        ctx->base.is_jmp = DISAS_NORETURN;
    }
    return true;
}

/* Emit a conditional branch to a direct target.  If the branch itself
   is nullified, we should have already used nullify_over.  */
static bool do_cbranch(DisasContext *ctx, int64_t disp, bool is_n,
                       DisasCond *cond)
{
    uint64_t dest = iaoq_dest(ctx, disp);
    TCGLabel *taken = NULL;
    TCGCond c = cond->c;
    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();
    tcg_gen_brcond_i64(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, 0, 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);
        if (ctx->iaoq_n == -1) {
            /* The temporary iaoq_n_var died at the branch above.
               Regenerate it here instead of saving it.  */
            tcg_gen_addi_i64(ctx->iaoq_n_var, cpu_iaoq_b, 4);
        }
        gen_goto_tb(ctx, 0, 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, 1, dest, dest + 4);
    } else {
        nullify_set(ctx, n);
        gen_goto_tb(ctx, 1, 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;
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    } else {
        ctx->base.is_jmp = DISAS_NORETURN;
    }
    return true;
}

/* Emit an unconditional branch to an indirect target.  This handles
   nullification of the branch itself.  */
static bool do_ibranch(DisasContext *ctx, TCGv_i64 dest,
                       unsigned link, bool is_n)
{
    TCGv_i64 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(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }
        next = tcg_temp_new_i64();
        tcg_gen_mov_i64(next, dest);
        if (is_n) {
            if (use_nullify_skip(ctx)) {
                copy_iaoq_entry(ctx, cpu_iaoq_f, -1, next);
                tcg_gen_addi_i64(next, next, 4);
                copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);
                nullify_set(ctx, 0);
                ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
                return true;
            }
            ctx->null_cond.c = TCG_COND_ALWAYS;
        }
        ctx->iaoq_n = -1;
        ctx->iaoq_n_var = next;
    } 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 goto_ptr 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.  */
        copy_iaoq_entry(ctx, cpu_iaoq_f, -1, dest);
        next = tcg_temp_new_i64();
        tcg_gen_addi_i64(next, dest, 4);
        copy_iaoq_entry(ctx, cpu_iaoq_b, -1, next);

        nullify_over(ctx);
        if (link != 0) {
            copy_iaoq_entry(ctx, cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
        }
        tcg_gen_lookup_and_goto_ptr();
        return nullify_end(ctx);
    } else {
        c = ctx->null_cond.c;
        a0 = ctx->null_cond.a0;
        a1 = ctx->null_cond.a1;

        tmp = tcg_temp_new_i64();
        next = tcg_temp_new_i64();

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

        if (link != 0) {
            tcg_gen_movcond_i64(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_i64(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 true;
}

/* Implement
 *    if (IAOQ_Front{30..31} < GR[b]{30..31})
 *      IAOQ_Next{30..31} ← GR[b]{30..31};
 *    else
 *      IAOQ_Next{30..31} ← IAOQ_Front{30..31};
 * which keeps the privilege level from being increased.
 */
static TCGv_i64 do_ibranch_priv(DisasContext *ctx, TCGv_i64 offset)
{
    TCGv_i64 dest;
    switch (ctx->privilege) {
    case 0:
        /* Privilege 0 is maximum and is allowed to decrease.  */
        return offset;
    case 3:
        /* Privilege 3 is minimum and is never allowed to increase.  */
        dest = tcg_temp_new_i64();
        tcg_gen_ori_i64(dest, offset, 3);
        break;
    default:
        dest = tcg_temp_new_i64();
        tcg_gen_andi_i64(dest, offset, -4);
        tcg_gen_ori_i64(dest, dest, ctx->privilege);
        tcg_gen_movcond_i64(TCG_COND_GTU, dest, dest, offset, dest, offset);
        break;
    }
    return dest;
}

#ifdef CONFIG_USER_ONLY
/* 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 void do_page_zero(DisasContext *ctx)
{
    TCGv_i64 tmp;

    /* 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 privileged page.  */
    switch (ctx->null_cond.c) {
    case TCG_COND_NEVER:
        break;
    case TCG_COND_ALWAYS:
        tcg_gen_movi_i64(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 & -4) {
    case 0x00: /* Null pointer call */
        gen_excp_1(EXCP_IMP);
        ctx->base.is_jmp = DISAS_NORETURN;
        break;

    case 0xb0: /* LWS */
        gen_excp_1(EXCP_SYSCALL_LWS);
        ctx->base.is_jmp = DISAS_NORETURN;
        break;

    case 0xe0: /* SET_THREAD_POINTER */
        tcg_gen_st_i64(cpu_gr[26], tcg_env, offsetof(CPUHPPAState, cr[27]));
        tmp = tcg_temp_new_i64();
        tcg_gen_ori_i64(tmp, cpu_gr[31], 3);
        copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
        tcg_gen_addi_i64(tmp, tmp, 4);
        copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
        ctx->base.is_jmp = DISAS_IAQ_N_UPDATED;
        break;

    case 0x100: /* SYSCALL */
        gen_excp_1(EXCP_SYSCALL);
        ctx->base.is_jmp = DISAS_NORETURN;
        break;

    default:
    do_sigill:
        gen_excp_1(EXCP_ILL);
        ctx->base.is_jmp = DISAS_NORETURN;
        break;
    }
}
#endif

static bool trans_nop(DisasContext *ctx, arg_nop *a)
{
    cond_free(&ctx->null_cond);
    return true;
}

static bool trans_break(DisasContext *ctx, arg_break *a)
{
    return gen_excp_iir(ctx, EXCP_BREAK);
}

static bool trans_sync(DisasContext *ctx, arg_sync *a)
{
    /* No point in nullifying the memory barrier.  */
    tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);

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

static bool trans_mfia(DisasContext *ctx, arg_mfia *a)
{
    unsigned rt = a->t;
    TCGv_i64 tmp = dest_gpr(ctx, rt);
    tcg_gen_movi_i64(tmp, ctx->iaoq_f & ~3ULL);
    save_gpr(ctx, rt, tmp);

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

static bool trans_mfsp(DisasContext *ctx, arg_mfsp *a)
{
    unsigned rt = a->t;
    unsigned rs = a->sp;
    TCGv_i64 t0 = tcg_temp_new_i64();

    load_spr(ctx, t0, rs);
    tcg_gen_shri_i64(t0, t0, 32);

    save_gpr(ctx, rt, t0);

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

static bool trans_mfctl(DisasContext *ctx, arg_mfctl *a)
{
    unsigned rt = a->t;
    unsigned ctl = a->r;
    TCGv_i64 tmp;

    switch (ctl) {
    case CR_SAR:
        if (a->e == 0) {
            /* MFSAR without ,W masks low 5 bits.  */
            tmp = dest_gpr(ctx, rt);
            tcg_gen_andi_i64(tmp, cpu_sar, 31);
            save_gpr(ctx, rt, tmp);
            goto done;
        }
        save_gpr(ctx, rt, cpu_sar);
        goto done;
    case CR_IT: /* Interval Timer */
        /* FIXME: Respect PSW_S bit.  */
        nullify_over(ctx);
        tmp = dest_gpr(ctx, rt);
        if (translator_io_start(&ctx->base)) {
            ctx->base.is_jmp = DISAS_IAQ_N_STALE;
        }
        gen_helper_read_interval_timer(tmp);
        save_gpr(ctx, rt, tmp);
        return nullify_end(ctx);
    case 26:
    case 27:
        break;
    default:
        /* All other control registers are privileged.  */
        CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
        break;
    }

    tmp = tcg_temp_new_i64();
    tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUHPPAState, cr[ctl]));
    save_gpr(ctx, rt, tmp);

 done:
    cond_free(&ctx->null_cond);
    return true;
}

static bool trans_mtsp(DisasContext *ctx, arg_mtsp *a)
{
    unsigned rr = a->r;
    unsigned rs = a->sp;
    TCGv_i64 tmp;

    if (rs >= 5) {
        CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);
    }
    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_gen_shli_i64(tmp, load_gpr(ctx, rr), 32);

    if (rs >= 4) {
        tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUHPPAState, sr[rs]));
        ctx->tb_flags &= ~TB_FLAG_SR_SAME;
    } else {
        tcg_gen_mov_i64(cpu_sr[rs], tmp);
    }

    return nullify_end(ctx);
}

static bool trans_mtctl(DisasContext *ctx, arg_mtctl *a)
{
    unsigned ctl = a->t;
    TCGv_i64 reg;
    TCGv_i64 tmp;

    if (ctl == CR_SAR) {
        reg = load_gpr(ctx, a->r);
        tmp = tcg_temp_new_i64();
        tcg_gen_andi_i64(tmp, reg, ctx->is_pa20 ? 63 : 31);
        save_or_nullify(ctx, cpu_sar, tmp);

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

    /* All other control registers are privileged or read-only.  */
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_REG);

#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);

    if (ctx->is_pa20) {
        reg = load_gpr(ctx, a->r);
    } else {
        reg = tcg_temp_new_i64();
        tcg_gen_ext32u_i64(reg, load_gpr(ctx, a->r));
    }

    switch (ctl) {
    case CR_IT:
        if (translator_io_start(&ctx->base)) {
            ctx->base.is_jmp = DISAS_IAQ_N_STALE;
        }
        gen_helper_write_interval_timer(tcg_env, reg);
        break;
    case CR_EIRR:
        /* Helper modifies interrupt lines and is therefore IO. */
        translator_io_start(&ctx->base);
        gen_helper_write_eirr(tcg_env, reg);
        /* Exit to re-evaluate interrupts in the main loop. */
        ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
        break;

    case CR_IIASQ:
    case CR_IIAOQ:
        /* FIXME: Respect PSW_Q bit */
        /* The write advances the queue and stores to the back element.  */
        tmp = tcg_temp_new_i64();
        tcg_gen_ld_i64(tmp, tcg_env,
                       offsetof(CPUHPPAState, cr_back[ctl - CR_IIASQ]));
        tcg_gen_st_i64(tmp, tcg_env, offsetof(CPUHPPAState, cr[ctl]));
        tcg_gen_st_i64(reg, tcg_env,
                       offsetof(CPUHPPAState, cr_back[ctl - CR_IIASQ]));
        break;

    case CR_PID1:
    case CR_PID2:
    case CR_PID3:
    case CR_PID4:
        tcg_gen_st_i64(reg, tcg_env, offsetof(CPUHPPAState, cr[ctl]));
#ifndef CONFIG_USER_ONLY
        gen_helper_change_prot_id(tcg_env);
#endif
        break;

    case CR_EIEM:
        /* Exit to re-evaluate interrupts in the main loop. */
        ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
        /* FALLTHRU */
    default:
        tcg_gen_st_i64(reg, tcg_env, offsetof(CPUHPPAState, cr[ctl]));
        break;
    }
    return nullify_end(ctx);
#endif
}

static bool trans_mtsarcm(DisasContext *ctx, arg_mtsarcm *a)
{
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_not_i64(tmp, load_gpr(ctx, a->r));
    tcg_gen_andi_i64(tmp, tmp, ctx->is_pa20 ? 63 : 31);
    save_or_nullify(ctx, cpu_sar, tmp);

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

static bool trans_ldsid(DisasContext *ctx, arg_ldsid *a)
{
    TCGv_i64 dest = dest_gpr(ctx, a->t);

#ifdef CONFIG_USER_ONLY
    /* We don't implement space registers in user mode. */
    tcg_gen_movi_i64(dest, 0);
#else
    tcg_gen_mov_i64(dest, space_select(ctx, a->sp, load_gpr(ctx, a->b)));
    tcg_gen_shri_i64(dest, dest, 32);
#endif
    save_gpr(ctx, a->t, dest);

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

static bool trans_rsm(DisasContext *ctx, arg_rsm *a)
{
#ifdef CONFIG_USER_ONLY
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#else
    TCGv_i64 tmp;

    /* HP-UX 11i and HP ODE use rsm for read-access to PSW */
    if (a->i) {
        CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    }

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUHPPAState, psw));
    tcg_gen_andi_i64(tmp, tmp, ~a->i);
    gen_helper_swap_system_mask(tmp, tcg_env, tmp);
    save_gpr(ctx, a->t, tmp);

    /* Exit the TB to recognize new interrupts, e.g. PSW_M.  */
    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
    return nullify_end(ctx);
#endif
}

static bool trans_ssm(DisasContext *ctx, arg_ssm *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 tmp;

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_gen_ld_i64(tmp, tcg_env, offsetof(CPUHPPAState, psw));
    tcg_gen_ori_i64(tmp, tmp, a->i);
    gen_helper_swap_system_mask(tmp, tcg_env, tmp);
    save_gpr(ctx, a->t, tmp);

    /* Exit the TB to recognize new interrupts, e.g. PSW_I.  */
    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
    return nullify_end(ctx);
#endif
}

static bool trans_mtsm(DisasContext *ctx, arg_mtsm *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 tmp, reg;
    nullify_over(ctx);

    reg = load_gpr(ctx, a->r);
    tmp = tcg_temp_new_i64();
    gen_helper_swap_system_mask(tmp, tcg_env, reg);

    /* Exit the TB to recognize new interrupts.  */
    ctx->base.is_jmp = DISAS_IAQ_N_STALE_EXIT;
    return nullify_end(ctx);
#endif
}

static bool do_rfi(DisasContext *ctx, bool rfi_r)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);

    if (rfi_r) {
        gen_helper_rfi_r(tcg_env);
    } else {
        gen_helper_rfi(tcg_env);
    }
    /* Exit the TB to recognize new interrupts.  */
    tcg_gen_exit_tb(NULL, 0);
    ctx->base.is_jmp = DISAS_NORETURN;

    return nullify_end(ctx);
#endif
}

static bool trans_rfi(DisasContext *ctx, arg_rfi *a)
{
    return do_rfi(ctx, false);
}

static bool trans_rfi_r(DisasContext *ctx, arg_rfi_r *a)
{
    return do_rfi(ctx, true);
}

static bool trans_halt(DisasContext *ctx, arg_halt *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);
    gen_helper_halt(tcg_env);
    ctx->base.is_jmp = DISAS_NORETURN;
    return nullify_end(ctx);
#endif
}

static bool trans_reset(DisasContext *ctx, arg_reset *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);
    gen_helper_reset(tcg_env);
    ctx->base.is_jmp = DISAS_NORETURN;
    return nullify_end(ctx);
#endif
}

static bool do_getshadowregs(DisasContext *ctx)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    nullify_over(ctx);
    tcg_gen_ld_i64(cpu_gr[1], tcg_env, offsetof(CPUHPPAState, shadow[0]));
    tcg_gen_ld_i64(cpu_gr[8], tcg_env, offsetof(CPUHPPAState, shadow[1]));
    tcg_gen_ld_i64(cpu_gr[9], tcg_env, offsetof(CPUHPPAState, shadow[2]));
    tcg_gen_ld_i64(cpu_gr[16], tcg_env, offsetof(CPUHPPAState, shadow[3]));
    tcg_gen_ld_i64(cpu_gr[17], tcg_env, offsetof(CPUHPPAState, shadow[4]));
    tcg_gen_ld_i64(cpu_gr[24], tcg_env, offsetof(CPUHPPAState, shadow[5]));
    tcg_gen_ld_i64(cpu_gr[25], tcg_env, offsetof(CPUHPPAState, shadow[6]));
    return nullify_end(ctx);
}

static bool do_putshadowregs(DisasContext *ctx)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    nullify_over(ctx);
    tcg_gen_st_i64(cpu_gr[1], tcg_env, offsetof(CPUHPPAState, shadow[0]));
    tcg_gen_st_i64(cpu_gr[8], tcg_env, offsetof(CPUHPPAState, shadow[1]));
    tcg_gen_st_i64(cpu_gr[9], tcg_env, offsetof(CPUHPPAState, shadow[2]));
    tcg_gen_st_i64(cpu_gr[16], tcg_env, offsetof(CPUHPPAState, shadow[3]));
    tcg_gen_st_i64(cpu_gr[17], tcg_env, offsetof(CPUHPPAState, shadow[4]));
    tcg_gen_st_i64(cpu_gr[24], tcg_env, offsetof(CPUHPPAState, shadow[5]));
    tcg_gen_st_i64(cpu_gr[25], tcg_env, offsetof(CPUHPPAState, shadow[6]));
    return nullify_end(ctx);
}

static bool trans_getshadowregs(DisasContext *ctx, arg_getshadowregs *a)
{
    return do_getshadowregs(ctx);
}

static bool trans_nop_addrx(DisasContext *ctx, arg_ldst *a)
{
    if (a->m) {
        TCGv_i64 dest = dest_gpr(ctx, a->b);
        TCGv_i64 src1 = load_gpr(ctx, a->b);
        TCGv_i64 src2 = load_gpr(ctx, a->x);

        /* The only thing we need to do is the base register modification.  */
        tcg_gen_add_i64(dest, src1, src2);
        save_gpr(ctx, a->b, dest);
    }
    cond_free(&ctx->null_cond);
    return true;
}

static bool trans_fic(DisasContext *ctx, arg_ldst *a)
{
    /* End TB for flush instruction cache, so we pick up new insns. */
    ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    return trans_nop_addrx(ctx, a);
}

static bool trans_probe(DisasContext *ctx, arg_probe *a)
{
    TCGv_i64 dest, ofs;
    TCGv_i32 level, want;
    TCGv_i64 addr;

    nullify_over(ctx);

    dest = dest_gpr(ctx, a->t);
    form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);

    if (a->imm) {
        level = tcg_constant_i32(a->ri & 3);
    } else {
        level = tcg_temp_new_i32();
        tcg_gen_extrl_i64_i32(level, load_gpr(ctx, a->ri));
        tcg_gen_andi_i32(level, level, 3);
    }
    want = tcg_constant_i32(a->write ? PAGE_WRITE : PAGE_READ);

    gen_helper_probe(dest, tcg_env, addr, level, want);

    save_gpr(ctx, a->t, dest);
    return nullify_end(ctx);
}

static bool trans_ixtlbx(DisasContext *ctx, arg_ixtlbx *a)
{
    if (ctx->is_pa20) {
        return false;
    }
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 addr;
    TCGv_i64 ofs, reg;

    nullify_over(ctx);

    form_gva(ctx, &addr, &ofs, a->b, 0, 0, 0, a->sp, 0, false);
    reg = load_gpr(ctx, a->r);
    if (a->addr) {
        gen_helper_itlba_pa11(tcg_env, addr, reg);
    } else {
        gen_helper_itlbp_pa11(tcg_env, addr, reg);
    }

    /* Exit TB for TLB change if mmu is enabled.  */
    if (ctx->tb_flags & PSW_C) {
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    }
    return nullify_end(ctx);
#endif
}

static bool do_pxtlb(DisasContext *ctx, arg_ldst *a, bool local)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 addr;
    TCGv_i64 ofs;

    nullify_over(ctx);

    form_gva(ctx, &addr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);

    /*
     * Page align now, rather than later, so that we can add in the
     * page_size field from pa2.0 from the low 4 bits of GR[b].
     */
    tcg_gen_andi_i64(addr, addr, TARGET_PAGE_MASK);
    if (ctx->is_pa20) {
        tcg_gen_deposit_i64(addr, addr, load_gpr(ctx, a->b), 0, 4);
    }

    if (local) {
        gen_helper_ptlb_l(tcg_env, addr);
    } else {
        gen_helper_ptlb(tcg_env, addr);
    }

    if (a->m) {
        save_gpr(ctx, a->b, ofs);
    }

    /* Exit TB for TLB change if mmu is enabled.  */
    if (ctx->tb_flags & PSW_C) {
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    }
    return nullify_end(ctx);
#endif
}

static bool trans_pxtlb(DisasContext *ctx, arg_ldst *a)
{
    return do_pxtlb(ctx, a, false);
}

static bool trans_pxtlb_l(DisasContext *ctx, arg_ldst *a)
{
    return ctx->is_pa20 && do_pxtlb(ctx, a, true);
}

static bool trans_pxtlbe(DisasContext *ctx, arg_ldst *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);

    trans_nop_addrx(ctx, a);
    gen_helper_ptlbe(tcg_env);

    /* Exit TB for TLB change if mmu is enabled.  */
    if (ctx->tb_flags & PSW_C) {
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    }
    return nullify_end(ctx);
#endif
}

/*
 * Implement the pcxl and pcxl2 Fast TLB Insert instructions.
 * See
 *     https://parisc.wiki.kernel.org/images-parisc/a/a9/Pcxl2_ers.pdf
 *     page 13-9 (195/206)
 */
static bool trans_ixtlbxf(DisasContext *ctx, arg_ixtlbxf *a)
{
    if (ctx->is_pa20) {
        return false;
    }
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 addr, atl, stl;
    TCGv_i64 reg;

    nullify_over(ctx);

    /*
     * FIXME:
     *  if (not (pcxl or pcxl2))
     *    return gen_illegal(ctx);
     */

    atl = tcg_temp_new_i64();
    stl = tcg_temp_new_i64();
    addr = tcg_temp_new_i64();

    tcg_gen_ld32u_i64(stl, tcg_env,
                      a->data ? offsetof(CPUHPPAState, cr[CR_ISR])
                      : offsetof(CPUHPPAState, cr[CR_IIASQ]));
    tcg_gen_ld32u_i64(atl, tcg_env,
                      a->data ? offsetof(CPUHPPAState, cr[CR_IOR])
                      : offsetof(CPUHPPAState, cr[CR_IIAOQ]));
    tcg_gen_shli_i64(stl, stl, 32);
    tcg_gen_or_i64(addr, atl, stl);

    reg = load_gpr(ctx, a->r);
    if (a->addr) {
        gen_helper_itlba_pa11(tcg_env, addr, reg);
    } else {
        gen_helper_itlbp_pa11(tcg_env, addr, reg);
    }

    /* Exit TB for TLB change if mmu is enabled.  */
    if (ctx->tb_flags & PSW_C) {
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    }
    return nullify_end(ctx);
#endif
}

static bool trans_ixtlbt(DisasContext *ctx, arg_ixtlbt *a)
{
    if (!ctx->is_pa20) {
        return false;
    }
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);
    {
        TCGv_i64 src1 = load_gpr(ctx, a->r1);
        TCGv_i64 src2 = load_gpr(ctx, a->r2);

        if (a->data) {
            gen_helper_idtlbt_pa20(tcg_env, src1, src2);
        } else {
            gen_helper_iitlbt_pa20(tcg_env, src1, src2);
        }
    }
    /* Exit TB for TLB change if mmu is enabled.  */
    if (ctx->tb_flags & PSW_C) {
        ctx->base.is_jmp = DISAS_IAQ_N_STALE;
    }
    return nullify_end(ctx);
#endif
}

static bool trans_lpa(DisasContext *ctx, arg_ldst *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    TCGv_i64 vaddr;
    TCGv_i64 ofs, paddr;

    nullify_over(ctx);

    form_gva(ctx, &vaddr, &ofs, a->b, a->x, 0, 0, a->sp, a->m, false);

    paddr = tcg_temp_new_i64();
    gen_helper_lpa(paddr, tcg_env, vaddr);

    /* Note that physical address result overrides base modification.  */
    if (a->m) {
        save_gpr(ctx, a->b, ofs);
    }
    save_gpr(ctx, a->t, paddr);

    return nullify_end(ctx);
#endif
}

static bool trans_lci(DisasContext *ctx, arg_lci *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);

    /* The Coherence Index is an implementation-defined function of the
       physical address.  Two addresses with the same CI have a coherent
       view of the cache.  Our implementation is to return 0 for all,
       since the entire address space is coherent.  */
    save_gpr(ctx, a->t, ctx->zero);

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

static bool trans_add(DisasContext *ctx, arg_rrr_cf_d_sh *a)
{
    return do_add_reg(ctx, a, false, false, false, false);
}

static bool trans_add_l(DisasContext *ctx, arg_rrr_cf_d_sh *a)
{
    return do_add_reg(ctx, a, true, false, false, false);
}

static bool trans_add_tsv(DisasContext *ctx, arg_rrr_cf_d_sh *a)
{
    return do_add_reg(ctx, a, false, true, false, false);
}

static bool trans_add_c(DisasContext *ctx, arg_rrr_cf_d_sh *a)
{
    return do_add_reg(ctx, a, false, false, false, true);
}

static bool trans_add_c_tsv(DisasContext *ctx, arg_rrr_cf_d_sh *a)
{
    return do_add_reg(ctx, a, false, true, false, true);
}

static bool trans_sub(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, false, false, false);
}

static bool trans_sub_tsv(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, true, false, false);
}

static bool trans_sub_tc(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, false, false, true);
}

static bool trans_sub_tsv_tc(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, true, false, true);
}

static bool trans_sub_b(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, false, true, false);
}

static bool trans_sub_b_tsv(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_sub_reg(ctx, a, true, true, false);
}

static bool trans_andcm(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_log_reg(ctx, a, tcg_gen_andc_i64);
}

static bool trans_and(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_log_reg(ctx, a, tcg_gen_and_i64);
}

static bool trans_or(DisasContext *ctx, arg_rrr_cf_d *a)
{
    if (a->cf == 0) {
        unsigned r2 = a->r2;
        unsigned r1 = a->r1;
        unsigned rt = a->t;

        if (rt == 0) { /* NOP */
            cond_free(&ctx->null_cond);
            return true;
        }
        if (r2 == 0) { /* COPY */
            if (r1 == 0) {
                TCGv_i64 dest = dest_gpr(ctx, rt);
                tcg_gen_movi_i64(dest, 0);
                save_gpr(ctx, rt, dest);
            } else {
                save_gpr(ctx, rt, cpu_gr[r1]);
            }
            cond_free(&ctx->null_cond);
            return true;
        }
#ifndef CONFIG_USER_ONLY
        /* These are QEMU extensions and are nops in the real architecture:
         *
         * or %r10,%r10,%r10 -- idle loop; wait for interrupt
         * or %r31,%r31,%r31 -- death loop; offline cpu
         *                      currently implemented as idle.
         */
        if ((rt == 10 || rt == 31) && r1 == rt && r2 == rt) { /* PAUSE */
            /* No need to check for supervisor, as userland can only pause
               until the next timer interrupt.  */
            nullify_over(ctx);

            /* Advance the instruction queue.  */
            copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
            copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
            nullify_set(ctx, 0);

            /* Tell the qemu main loop to halt until this cpu has work.  */
            tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
                           offsetof(CPUState, halted) - offsetof(HPPACPU, env));
            gen_excp_1(EXCP_HALTED);
            ctx->base.is_jmp = DISAS_NORETURN;

            return nullify_end(ctx);
        }
#endif
    }
    return do_log_reg(ctx, a, tcg_gen_or_i64);
}

static bool trans_xor(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_log_reg(ctx, a, tcg_gen_xor_i64);
}

static bool trans_cmpclr(DisasContext *ctx, arg_rrr_cf_d *a)
{
    TCGv_i64 tcg_r1, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }
    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    do_cmpclr(ctx, a->t, tcg_r1, tcg_r2, a->cf, a->d);
    return nullify_end(ctx);
}

static bool trans_uxor(DisasContext *ctx, arg_rrr_cf_d *a)
{
    TCGv_i64 tcg_r1, tcg_r2, dest;

    if (a->cf) {
        nullify_over(ctx);
    }

    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    dest = dest_gpr(ctx, a->t);

    tcg_gen_xor_i64(dest, tcg_r1, tcg_r2);
    save_gpr(ctx, a->t, dest);

    cond_free(&ctx->null_cond);
    if (a->cf) {
        ctx->null_cond = do_unit_zero_cond(a->cf, a->d, dest);
    }

    return nullify_end(ctx);
}

static bool do_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a, bool is_tc)
{
    TCGv_i64 tcg_r1, tcg_r2, tmp;

    if (a->cf == 0) {
        tcg_r2 = load_gpr(ctx, a->r2);
        tmp = dest_gpr(ctx, a->t);

        if (a->r1 == 0) {
            /* UADDCM r0,src,dst is the common idiom for dst = ~src. */
            tcg_gen_not_i64(tmp, tcg_r2);
        } else {
            /*
             * Recall that r1 - r2 == r1 + ~r2 + 1.
             * Thus r1 + ~r2 == r1 - r2 - 1,
             * which does not require an extra temporary.
             */
            tcg_r1 = load_gpr(ctx, a->r1);
            tcg_gen_sub_i64(tmp, tcg_r1, tcg_r2);
            tcg_gen_subi_i64(tmp, tmp, 1);
        }
        save_gpr(ctx, a->t, tmp);
        cond_free(&ctx->null_cond);
        return true;
    }

    nullify_over(ctx);
    tcg_r1 = load_gpr(ctx, a->r1);
    tcg_r2 = load_gpr(ctx, a->r2);
    tmp = tcg_temp_new_i64();
    tcg_gen_not_i64(tmp, tcg_r2);
    do_unit_addsub(ctx, a->t, tcg_r1, tmp, a->cf, a->d, is_tc, true);
    return nullify_end(ctx);
}

static bool trans_uaddcm(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_uaddcm(ctx, a, false);
}

static bool trans_uaddcm_tc(DisasContext *ctx, arg_rrr_cf_d *a)
{
    return do_uaddcm(ctx, a, true);
}

static bool do_dcor(DisasContext *ctx, arg_rr_cf_d *a, bool is_i)
{
    TCGv_i64 tmp;

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_gen_extract2_i64(tmp, cpu_psw_cb, cpu_psw_cb_msb, 4);
    if (!is_i) {
        tcg_gen_not_i64(tmp, tmp);
    }
    tcg_gen_andi_i64(tmp, tmp, (uint64_t)0x1111111111111111ull);
    tcg_gen_muli_i64(tmp, tmp, 6);
    do_unit_addsub(ctx, a->t, load_gpr(ctx, a->r), tmp,
                   a->cf, a->d, false, is_i);
    return nullify_end(ctx);
}

static bool trans_dcor(DisasContext *ctx, arg_rr_cf_d *a)
{
    return do_dcor(ctx, a, false);
}

static bool trans_dcor_i(DisasContext *ctx, arg_rr_cf_d *a)
{
    return do_dcor(ctx, a, true);
}

static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
{
    TCGv_i64 dest, add1, add2, addc, in1, in2;

    nullify_over(ctx);

    in1 = load_gpr(ctx, a->r1);
    in2 = load_gpr(ctx, a->r2);

    add1 = tcg_temp_new_i64();
    add2 = tcg_temp_new_i64();
    addc = tcg_temp_new_i64();
    dest = tcg_temp_new_i64();

    /* Form R1 << 1 | PSW[CB]{8}.  */
    tcg_gen_add_i64(add1, in1, in1);
    tcg_gen_add_i64(add1, add1, get_psw_carry(ctx, false));

    /*
     * Add or subtract R2, depending on PSW[V].  Proper computation of
     * carry 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_sextract_i64(addc, cpu_psw_v, 31, 1);
    tcg_gen_xor_i64(add2, in2, addc);
    tcg_gen_andi_i64(addc, addc, 1);

    tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, ctx->zero, add2, ctx->zero);
    tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb,
                     addc, ctx->zero);

    /* Write back the result register.  */
    save_gpr(ctx, a->t, dest);

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

    /*
     * Write back PSW[V] for the division step.
     * Shift cb{8} from where it lives in bit 32 to bit 31,
     * so that it overlaps r2{32} in bit 31.
     */
    tcg_gen_shri_i64(cpu_psw_v, cpu_psw_cb, 1);
    tcg_gen_xor_i64(cpu_psw_v, cpu_psw_v, in2);

    /* Install the new nullification.  */
    if (a->cf) {
        TCGv_i64 sv = NULL, uv = NULL;
        if (cond_need_sv(a->cf >> 1)) {
            sv = do_add_sv(ctx, dest, add1, add2, in1, 1, false);
        } else if (cond_need_cb(a->cf >> 1)) {
            uv = do_add_uv(ctx, cpu_psw_cb, NULL, in1, 1, false);
        }
        ctx->null_cond = do_cond(ctx, a->cf, false, dest, uv, sv);
    }

    return nullify_end(ctx);
}

static bool trans_addi(DisasContext *ctx, arg_rri_cf *a)
{
    return do_add_imm(ctx, a, false, false);
}

static bool trans_addi_tsv(DisasContext *ctx, arg_rri_cf *a)
{
    return do_add_imm(ctx, a, true, false);
}

static bool trans_addi_tc(DisasContext *ctx, arg_rri_cf *a)
{
    return do_add_imm(ctx, a, false, true);
}

static bool trans_addi_tc_tsv(DisasContext *ctx, arg_rri_cf *a)
{
    return do_add_imm(ctx, a, true, true);
}

static bool trans_subi(DisasContext *ctx, arg_rri_cf *a)
{
    return do_sub_imm(ctx, a, false);
}

static bool trans_subi_tsv(DisasContext *ctx, arg_rri_cf *a)
{
    return do_sub_imm(ctx, a, true);
}

static bool trans_cmpiclr(DisasContext *ctx, arg_rri_cf_d *a)
{
    TCGv_i64 tcg_im, tcg_r2;

    if (a->cf) {
        nullify_over(ctx);
    }

    tcg_im = tcg_constant_i64(a->i);
    tcg_r2 = load_gpr(ctx, a->r);
    do_cmpclr(ctx, a->t, tcg_im, tcg_r2, a->cf, a->d);

    return nullify_end(ctx);
}

static bool do_multimedia(DisasContext *ctx, arg_rrr *a,
                          void (*fn)(TCGv_i64, TCGv_i64, TCGv_i64))
{
    TCGv_i64 r1, r2, dest;

    if (!ctx->is_pa20) {
        return false;
    }

    nullify_over(ctx);

    r1 = load_gpr(ctx, a->r1);
    r2 = load_gpr(ctx, a->r2);
    dest = dest_gpr(ctx, a->t);

    fn(dest, r1, r2);
    save_gpr(ctx, a->t, dest);

    return nullify_end(ctx);
}

static bool do_multimedia_sh(DisasContext *ctx, arg_rri *a,
                             void (*fn)(TCGv_i64, TCGv_i64, int64_t))
{
    TCGv_i64 r, dest;

    if (!ctx->is_pa20) {
        return false;
    }

    nullify_over(ctx);

    r = load_gpr(ctx, a->r);
    dest = dest_gpr(ctx, a->t);

    fn(dest, r, a->i);
    save_gpr(ctx, a->t, dest);

    return nullify_end(ctx);
}

static bool do_multimedia_shadd(DisasContext *ctx, arg_rrr_sh *a,
                                void (*fn)(TCGv_i64, TCGv_i64,
                                           TCGv_i64, TCGv_i32))
{
    TCGv_i64 r1, r2, dest;

    if (!ctx->is_pa20) {
        return false;
    }

    nullify_over(ctx);

    r1 = load_gpr(ctx, a->r1);
    r2 = load_gpr(ctx, a->r2);
    dest = dest_gpr(ctx, a->t);

    fn(dest, r1, r2, tcg_constant_i32(a->sh));
    save_gpr(ctx, a->t, dest);

    return nullify_end(ctx);
}

static bool trans_hadd(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, tcg_gen_vec_add16_i64);
}

static bool trans_hadd_ss(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_helper_hadd_ss);
}

static bool trans_hadd_us(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_helper_hadd_us);
}

static bool trans_havg(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_helper_havg);
}

static bool trans_hshl(DisasContext *ctx, arg_rri *a)
{
    return do_multimedia_sh(ctx, a, tcg_gen_vec_shl16i_i64);
}

static bool trans_hshr_s(DisasContext *ctx, arg_rri *a)
{
    return do_multimedia_sh(ctx, a, tcg_gen_vec_sar16i_i64);
}

static bool trans_hshr_u(DisasContext *ctx, arg_rri *a)
{
    return do_multimedia_sh(ctx, a, tcg_gen_vec_shr16i_i64);
}

static bool trans_hshladd(DisasContext *ctx, arg_rrr_sh *a)
{
    return do_multimedia_shadd(ctx, a, gen_helper_hshladd);
}

static bool trans_hshradd(DisasContext *ctx, arg_rrr_sh *a)
{
    return do_multimedia_shadd(ctx, a, gen_helper_hshradd);
}

static bool trans_hsub(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, tcg_gen_vec_sub16_i64);
}

static bool trans_hsub_ss(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_helper_hsub_ss);
}

static bool trans_hsub_us(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_helper_hsub_us);
}

static void gen_mixh_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
{
    uint64_t mask = 0xffff0000ffff0000ull;
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_andi_i64(tmp, r2, mask);
    tcg_gen_andi_i64(dst, r1, mask);
    tcg_gen_shri_i64(tmp, tmp, 16);
    tcg_gen_or_i64(dst, dst, tmp);
}

static bool trans_mixh_l(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_mixh_l);
}

static void gen_mixh_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
{
    uint64_t mask = 0x0000ffff0000ffffull;
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_andi_i64(tmp, r1, mask);
    tcg_gen_andi_i64(dst, r2, mask);
    tcg_gen_shli_i64(tmp, tmp, 16);
    tcg_gen_or_i64(dst, dst, tmp);
}

static bool trans_mixh_r(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_mixh_r);
}

static void gen_mixw_l(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
{
    TCGv_i64 tmp = tcg_temp_new_i64();

    tcg_gen_shri_i64(tmp, r2, 32);
    tcg_gen_deposit_i64(dst, r1, tmp, 0, 32);
}

static bool trans_mixw_l(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_mixw_l);
}

static void gen_mixw_r(TCGv_i64 dst, TCGv_i64 r1, TCGv_i64 r2)
{
    tcg_gen_deposit_i64(dst, r2, r1, 32, 32);
}

static bool trans_mixw_r(DisasContext *ctx, arg_rrr *a)
{
    return do_multimedia(ctx, a, gen_mixw_r);
}

static bool trans_permh(DisasContext *ctx, arg_permh *a)
{
    TCGv_i64 r, t0, t1, t2, t3;

    if (!ctx->is_pa20) {
        return false;
    }

    nullify_over(ctx);

    r = load_gpr(ctx, a->r1);
    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();
    t2 = tcg_temp_new_i64();
    t3 = tcg_temp_new_i64();

    tcg_gen_extract_i64(t0, r, (3 - a->c0) * 16, 16);
    tcg_gen_extract_i64(t1, r, (3 - a->c1) * 16, 16);
    tcg_gen_extract_i64(t2, r, (3 - a->c2) * 16, 16);
    tcg_gen_extract_i64(t3, r, (3 - a->c3) * 16, 16);

    tcg_gen_deposit_i64(t0, t1, t0, 16, 48);
    tcg_gen_deposit_i64(t2, t3, t2, 16, 48);
    tcg_gen_deposit_i64(t0, t2, t0, 32, 32);

    save_gpr(ctx, a->t, t0);
    return nullify_end(ctx);
}

static bool trans_ld(DisasContext *ctx, arg_ldst *a)
{
    if (ctx->is_pa20) {
       /*
        * With pa20, LDB, LDH, LDW, LDD to %g0 are prefetches.
        * Any base modification still occurs.
        */
        if (a->t == 0) {
            return trans_nop_addrx(ctx, a);
        }
    } else if (a->size > MO_32) {
        return gen_illegal(ctx);
    }
    return do_load(ctx, a->t, a->b, a->x, a->scale ? a->size : 0,
                   a->disp, a->sp, a->m, a->size | MO_TE);
}

static bool trans_st(DisasContext *ctx, arg_ldst *a)
{
    assert(a->x == 0 && a->scale == 0);
    if (!ctx->is_pa20 && a->size > MO_32) {
        return gen_illegal(ctx);
    }
    return do_store(ctx, a->t, a->b, a->disp, a->sp, a->m, a->size | MO_TE);
}

static bool trans_ldc(DisasContext *ctx, arg_ldst *a)
{
    MemOp mop = MO_TE | MO_ALIGN | a->size;
    TCGv_i64 dest, ofs;
    TCGv_i64 addr;

    if (!ctx->is_pa20 && a->size > MO_32) {
        return gen_illegal(ctx);
    }

    nullify_over(ctx);

    if (a->m) {
        /* Base register modification.  Make sure if RT == RB,
           we see the result of the load.  */
        dest = tcg_temp_new_i64();
    } else {
        dest = dest_gpr(ctx, a->t);
    }

    form_gva(ctx, &addr, &ofs, a->b, a->x, a->scale ? 3 : 0,
             a->disp, a->sp, a->m, MMU_DISABLED(ctx));

    /*
     * For hppa1.1, LDCW is undefined unless aligned mod 16.
     * However actual hardware succeeds with aligned mod 4.
     * Detect this case and log a GUEST_ERROR.
     *
     * TODO: HPPA64 relaxes the over-alignment requirement
     * with the ,co completer.
     */
    gen_helper_ldc_check(addr);

    tcg_gen_atomic_xchg_i64(dest, addr, ctx->zero, ctx->mmu_idx, mop);

    if (a->m) {
        save_gpr(ctx, a->b, ofs);
    }
    save_gpr(ctx, a->t, dest);

    return nullify_end(ctx);
}

static bool trans_stby(DisasContext *ctx, arg_stby *a)
{
    TCGv_i64 ofs, val;
    TCGv_i64 addr;

    nullify_over(ctx);

    form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m,
             MMU_DISABLED(ctx));
    val = load_gpr(ctx, a->r);
    if (a->a) {
        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
            gen_helper_stby_e_parallel(tcg_env, addr, val);
        } else {
            gen_helper_stby_e(tcg_env, addr, val);
        }
    } else {
        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
            gen_helper_stby_b_parallel(tcg_env, addr, val);
        } else {
            gen_helper_stby_b(tcg_env, addr, val);
        }
    }
    if (a->m) {
        tcg_gen_andi_i64(ofs, ofs, ~3);
        save_gpr(ctx, a->b, ofs);
    }

    return nullify_end(ctx);
}

static bool trans_stdby(DisasContext *ctx, arg_stby *a)
{
    TCGv_i64 ofs, val;
    TCGv_i64 addr;

    if (!ctx->is_pa20) {
        return false;
    }
    nullify_over(ctx);

    form_gva(ctx, &addr, &ofs, a->b, 0, 0, a->disp, a->sp, a->m,
             MMU_DISABLED(ctx));
    val = load_gpr(ctx, a->r);
    if (a->a) {
        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
            gen_helper_stdby_e_parallel(tcg_env, addr, val);
        } else {
            gen_helper_stdby_e(tcg_env, addr, val);
        }
    } else {
        if (tb_cflags(ctx->base.tb) & CF_PARALLEL) {
            gen_helper_stdby_b_parallel(tcg_env, addr, val);
        } else {
            gen_helper_stdby_b(tcg_env, addr, val);
        }
    }
    if (a->m) {
        tcg_gen_andi_i64(ofs, ofs, ~7);
        save_gpr(ctx, a->b, ofs);
    }

    return nullify_end(ctx);
}

static bool trans_lda(DisasContext *ctx, arg_ldst *a)
{
    int hold_mmu_idx = ctx->mmu_idx;

    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
    trans_ld(ctx, a);
    ctx->mmu_idx = hold_mmu_idx;
    return true;
}

static bool trans_sta(DisasContext *ctx, arg_ldst *a)
{
    int hold_mmu_idx = ctx->mmu_idx;

    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    ctx->mmu_idx = ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX;
    trans_st(ctx, a);
    ctx->mmu_idx = hold_mmu_idx;
    return true;
}

static bool trans_ldil(DisasContext *ctx, arg_ldil *a)
{
    TCGv_i64 tcg_rt = dest_gpr(ctx, a->t);

    tcg_gen_movi_i64(tcg_rt, a->i);
    save_gpr(ctx, a->t, tcg_rt);
    cond_free(&ctx->null_cond);
    return true;
}

static bool trans_addil(DisasContext *ctx, arg_addil *a)
{
    TCGv_i64 tcg_rt = load_gpr(ctx, a->r);
    TCGv_i64 tcg_r1 = dest_gpr(ctx, 1);

    tcg_gen_addi_i64(tcg_r1, tcg_rt, a->i);
    save_gpr(ctx, 1, tcg_r1);
    cond_free(&ctx->null_cond);
    return true;
}

static bool trans_ldo(DisasContext *ctx, arg_ldo *a)
{
    TCGv_i64 tcg_rt = dest_gpr(ctx, a->t);

    /* Special case rb == 0, for the LDI pseudo-op.
       The COPY pseudo-op is handled for free within tcg_gen_addi_i64.  */
    if (a->b == 0) {
        tcg_gen_movi_i64(tcg_rt, a->i);
    } else {
        tcg_gen_addi_i64(tcg_rt, cpu_gr[a->b], a->i);
    }
    save_gpr(ctx, a->t, tcg_rt);
    cond_free(&ctx->null_cond);
    return true;
}

static bool do_cmpb(DisasContext *ctx, unsigned r, TCGv_i64 in1,
                    unsigned c, unsigned f, bool d, unsigned n, int disp)
{
    TCGv_i64 dest, in2, sv;
    DisasCond cond;

    in2 = load_gpr(ctx, r);
    dest = tcg_temp_new_i64();

    tcg_gen_sub_i64(dest, in1, in2);

    sv = NULL;
    if (cond_need_sv(c)) {
        sv = do_sub_sv(ctx, dest, in1, in2);
    }

    cond = do_sub_cond(ctx, c * 2 + f, d, dest, in1, in2, sv);
    return do_cbranch(ctx, disp, n, &cond);
}

static bool trans_cmpb(DisasContext *ctx, arg_cmpb *a)
{
    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    nullify_over(ctx);
    return do_cmpb(ctx, a->r2, load_gpr(ctx, a->r1),
                   a->c, a->f, a->d, a->n, a->disp);
}

static bool trans_cmpbi(DisasContext *ctx, arg_cmpbi *a)
{
    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    nullify_over(ctx);
    return do_cmpb(ctx, a->r, tcg_constant_i64(a->i),
                   a->c, a->f, a->d, a->n, a->disp);
}

static bool do_addb(DisasContext *ctx, unsigned r, TCGv_i64 in1,
                    unsigned c, unsigned f, unsigned n, int disp)
{
    TCGv_i64 dest, in2, sv, cb_cond;
    DisasCond cond;
    bool d = false;

    /*
     * For hppa64, the ADDB conditions change with PSW.W,
     * dropping ZNV, SV, OD in favor of double-word EQ, LT, LE.
     */
    if (ctx->tb_flags & PSW_W) {
        d = c >= 5;
        if (d) {
            c &= 3;
        }
    }

    in2 = load_gpr(ctx, r);
    dest = tcg_temp_new_i64();
    sv = NULL;
    cb_cond = NULL;

    if (cond_need_cb(c)) {
        TCGv_i64 cb = tcg_temp_new_i64();
        TCGv_i64 cb_msb = tcg_temp_new_i64();

        tcg_gen_movi_i64(cb_msb, 0);
        tcg_gen_add2_i64(dest, cb_msb, in1, cb_msb, in2, cb_msb);
        tcg_gen_xor_i64(cb, in1, in2);
        tcg_gen_xor_i64(cb, cb, dest);
        cb_cond = get_carry(ctx, d, cb, cb_msb);
    } else {
        tcg_gen_add_i64(dest, in1, in2);
    }
    if (cond_need_sv(c)) {
        sv = do_add_sv(ctx, dest, in1, in2, in1, 0, d);
    }

    cond = do_cond(ctx, c * 2 + f, d, dest, cb_cond, sv);
    save_gpr(ctx, r, dest);
    return do_cbranch(ctx, disp, n, &cond);
}

static bool trans_addb(DisasContext *ctx, arg_addb *a)
{
    nullify_over(ctx);
    return do_addb(ctx, a->r2, load_gpr(ctx, a->r1), a->c, a->f, a->n, a->disp);
}

static bool trans_addbi(DisasContext *ctx, arg_addbi *a)
{
    nullify_over(ctx);
    return do_addb(ctx, a->r, tcg_constant_i64(a->i), a->c, a->f, a->n, a->disp);
}

static bool trans_bb_sar(DisasContext *ctx, arg_bb_sar *a)
{
    TCGv_i64 tmp, tcg_r;
    DisasCond cond;

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_r = load_gpr(ctx, a->r);
    if (a->d) {
        tcg_gen_shl_i64(tmp, tcg_r, cpu_sar);
    } else {
        /* Force shift into [32,63] */
        tcg_gen_ori_i64(tmp, cpu_sar, 32);
        tcg_gen_shl_i64(tmp, tcg_r, tmp);
    }

    cond = cond_make_0_tmp(a->c ? TCG_COND_GE : TCG_COND_LT, tmp);
    return do_cbranch(ctx, a->disp, a->n, &cond);
}

static bool trans_bb_imm(DisasContext *ctx, arg_bb_imm *a)
{
    TCGv_i64 tmp, tcg_r;
    DisasCond cond;
    int p;

    nullify_over(ctx);

    tmp = tcg_temp_new_i64();
    tcg_r = load_gpr(ctx, a->r);
    p = a->p | (a->d ? 0 : 32);
    tcg_gen_shli_i64(tmp, tcg_r, p);

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

static bool trans_movb(DisasContext *ctx, arg_movb *a)
{
    TCGv_i64 dest;
    DisasCond cond;

    nullify_over(ctx);

    dest = dest_gpr(ctx, a->r2);
    if (a->r1 == 0) {
        tcg_gen_movi_i64(dest, 0);
    } else {
        tcg_gen_mov_i64(dest, cpu_gr[a->r1]);
    }

    /* All MOVB conditions are 32-bit. */
    cond = do_sed_cond(ctx, a->c, false, dest);
    return do_cbranch(ctx, a->disp, a->n, &cond);
}

static bool trans_movbi(DisasContext *ctx, arg_movbi *a)
{
    TCGv_i64 dest;
    DisasCond cond;

    nullify_over(ctx);

    dest = dest_gpr(ctx, a->r);
    tcg_gen_movi_i64(dest, a->i);

    /* All MOVBI conditions are 32-bit. */
    cond = do_sed_cond(ctx, a->c, false, dest);
    return do_cbranch(ctx, a->disp, a->n, &cond);
}

static bool trans_shrp_sar(DisasContext *ctx, arg_shrp_sar *a)
{
    TCGv_i64 dest, src2;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, a->t);
    src2 = load_gpr(ctx, a->r2);
    if (a->r1 == 0) {
        if (a->d) {
            tcg_gen_shr_i64(dest, src2, cpu_sar);
        } else {
            TCGv_i64 tmp = tcg_temp_new_i64();

            tcg_gen_ext32u_i64(dest, src2);
            tcg_gen_andi_i64(tmp, cpu_sar, 31);
            tcg_gen_shr_i64(dest, dest, tmp);
        }
    } else if (a->r1 == a->r2) {
        if (a->d) {
            tcg_gen_rotr_i64(dest, src2, cpu_sar);
        } else {
            TCGv_i32 t32 = tcg_temp_new_i32();
            TCGv_i32 s32 = tcg_temp_new_i32();

            tcg_gen_extrl_i64_i32(t32, src2);
            tcg_gen_extrl_i64_i32(s32, cpu_sar);
            tcg_gen_andi_i32(s32, s32, 31);
            tcg_gen_rotr_i32(t32, t32, s32);
            tcg_gen_extu_i32_i64(dest, t32);
        }
    } else {
        TCGv_i64 src1 = load_gpr(ctx, a->r1);

        if (a->d) {
            TCGv_i64 t = tcg_temp_new_i64();
            TCGv_i64 n = tcg_temp_new_i64();

            tcg_gen_xori_i64(n, cpu_sar, 63);
            tcg_gen_shl_i64(t, src1, n);
            tcg_gen_shli_i64(t, t, 1);
            tcg_gen_shr_i64(dest, src2, cpu_sar);
            tcg_gen_or_i64(dest, dest, t);
        } else {
            TCGv_i64 t = tcg_temp_new_i64();
            TCGv_i64 s = tcg_temp_new_i64();

            tcg_gen_concat32_i64(t, src2, src1);
            tcg_gen_andi_i64(s, cpu_sar, 31);
            tcg_gen_shr_i64(dest, t, s);
        }
    }
    save_gpr(ctx, a->t, dest);

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

static bool trans_shrp_imm(DisasContext *ctx, arg_shrp_imm *a)
{
    unsigned width, sa;
    TCGv_i64 dest, t2;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    width = a->d ? 64 : 32;
    sa = width - 1 - a->cpos;

    dest = dest_gpr(ctx, a->t);
    t2 = load_gpr(ctx, a->r2);
    if (a->r1 == 0) {
        tcg_gen_extract_i64(dest, t2, sa, width - sa);
    } else if (width == TARGET_LONG_BITS) {
        tcg_gen_extract2_i64(dest, t2, cpu_gr[a->r1], sa);
    } else {
        assert(!a->d);
        if (a->r1 == a->r2) {
            TCGv_i32 t32 = tcg_temp_new_i32();
            tcg_gen_extrl_i64_i32(t32, t2);
            tcg_gen_rotri_i32(t32, t32, sa);
            tcg_gen_extu_i32_i64(dest, t32);
        } else {
            tcg_gen_concat32_i64(dest, t2, cpu_gr[a->r1]);
            tcg_gen_extract_i64(dest, dest, sa, 32);
        }
    }
    save_gpr(ctx, a->t, dest);

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

static bool trans_extr_sar(DisasContext *ctx, arg_extr_sar *a)
{
    unsigned widthm1 = a->d ? 63 : 31;
    TCGv_i64 dest, src, tmp;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    dest = dest_gpr(ctx, a->t);
    src = load_gpr(ctx, a->r);
    tmp = tcg_temp_new_i64();

    /* Recall that SAR is using big-endian bit numbering.  */
    tcg_gen_andi_i64(tmp, cpu_sar, widthm1);
    tcg_gen_xori_i64(tmp, tmp, widthm1);

    if (a->se) {
        if (!a->d) {
            tcg_gen_ext32s_i64(dest, src);
            src = dest;
        }
        tcg_gen_sar_i64(dest, src, tmp);
        tcg_gen_sextract_i64(dest, dest, 0, a->len);
    } else {
        if (!a->d) {
            tcg_gen_ext32u_i64(dest, src);
            src = dest;
        }
        tcg_gen_shr_i64(dest, src, tmp);
        tcg_gen_extract_i64(dest, dest, 0, a->len);
    }
    save_gpr(ctx, a->t, dest);

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

static bool trans_extr_imm(DisasContext *ctx, arg_extr_imm *a)
{
    unsigned len, cpos, width;
    TCGv_i64 dest, src;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    len = a->len;
    width = a->d ? 64 : 32;
    cpos = width - 1 - a->pos;
    if (cpos + len > width) {
        len = width - cpos;
    }

    dest = dest_gpr(ctx, a->t);
    src = load_gpr(ctx, a->r);
    if (a->se) {
        tcg_gen_sextract_i64(dest, src, cpos, len);
    } else {
        tcg_gen_extract_i64(dest, src, cpos, len);
    }
    save_gpr(ctx, a->t, dest);

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

static bool trans_depi_imm(DisasContext *ctx, arg_depi_imm *a)
{
    unsigned len, width;
    uint64_t mask0, mask1;
    TCGv_i64 dest;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    len = a->len;
    width = a->d ? 64 : 32;
    if (a->cpos + len > width) {
        len = width - a->cpos;
    }

    dest = dest_gpr(ctx, a->t);
    mask0 = deposit64(0, a->cpos, len, a->i);
    mask1 = deposit64(-1, a->cpos, len, a->i);

    if (a->nz) {
        TCGv_i64 src = load_gpr(ctx, a->t);
        tcg_gen_andi_i64(dest, src, mask1);
        tcg_gen_ori_i64(dest, dest, mask0);
    } else {
        tcg_gen_movi_i64(dest, mask0);
    }
    save_gpr(ctx, a->t, dest);

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

static bool trans_dep_imm(DisasContext *ctx, arg_dep_imm *a)
{
    unsigned rs = a->nz ? a->t : 0;
    unsigned len, width;
    TCGv_i64 dest, val;

    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }

    len = a->len;
    width = a->d ? 64 : 32;
    if (a->cpos + len > width) {
        len = width - a->cpos;
    }

    dest = dest_gpr(ctx, a->t);
    val = load_gpr(ctx, a->r);
    if (rs == 0) {
        tcg_gen_deposit_z_i64(dest, val, a->cpos, len);
    } else {
        tcg_gen_deposit_i64(dest, cpu_gr[rs], val, a->cpos, len);
    }
    save_gpr(ctx, a->t, dest);

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

static bool do_dep_sar(DisasContext *ctx, unsigned rt, unsigned c,
                       bool d, bool nz, unsigned len, TCGv_i64 val)
{
    unsigned rs = nz ? rt : 0;
    unsigned widthm1 = d ? 63 : 31;
    TCGv_i64 mask, tmp, shift, dest;
    uint64_t msb = 1ULL << (len - 1);

    dest = dest_gpr(ctx, rt);
    shift = tcg_temp_new_i64();
    tmp = tcg_temp_new_i64();

    /* Convert big-endian bit numbering in SAR to left-shift.  */
    tcg_gen_andi_i64(shift, cpu_sar, widthm1);
    tcg_gen_xori_i64(shift, shift, widthm1);

    mask = tcg_temp_new_i64();
    tcg_gen_movi_i64(mask, msb + (msb - 1));
    tcg_gen_and_i64(tmp, val, mask);
    if (rs) {
        tcg_gen_shl_i64(mask, mask, shift);
        tcg_gen_shl_i64(tmp, tmp, shift);
        tcg_gen_andc_i64(dest, cpu_gr[rs], mask);
        tcg_gen_or_i64(dest, dest, tmp);
    } else {
        tcg_gen_shl_i64(dest, tmp, shift);
    }
    save_gpr(ctx, rt, dest);

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

static bool trans_dep_sar(DisasContext *ctx, arg_dep_sar *a)
{
    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }
    return do_dep_sar(ctx, a->t, a->c, a->d, a->nz, a->len,
                      load_gpr(ctx, a->r));
}

static bool trans_depi_sar(DisasContext *ctx, arg_depi_sar *a)
{
    if (!ctx->is_pa20 && a->d) {
        return false;
    }
    if (a->c) {
        nullify_over(ctx);
    }
    return do_dep_sar(ctx, a->t, a->c, a->d, a->nz, a->len,
                      tcg_constant_i64(a->i));
}

static bool trans_be(DisasContext *ctx, arg_be *a)
{
    TCGv_i64 tmp;

#ifdef CONFIG_USER_ONLY
    /* ??? 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 (a->b == 0) {
        return do_dbranch(ctx, a->disp, a->l, a->n);
    }
#else
    nullify_over(ctx);
#endif

    tmp = tcg_temp_new_i64();
    tcg_gen_addi_i64(tmp, load_gpr(ctx, a->b), a->disp);
    tmp = do_ibranch_priv(ctx, tmp);

#ifdef CONFIG_USER_ONLY
    return do_ibranch(ctx, tmp, a->l, a->n);
#else
    TCGv_i64 new_spc = tcg_temp_new_i64();

    load_spr(ctx, new_spc, a->sp);
    if (a->l) {
        copy_iaoq_entry(ctx, cpu_gr[31], ctx->iaoq_n, ctx->iaoq_n_var);
        tcg_gen_mov_i64(cpu_sr[0], cpu_iasq_b);
    }
    if (a->n && use_nullify_skip(ctx)) {
        copy_iaoq_entry(ctx, cpu_iaoq_f, -1, tmp);
        tcg_gen_addi_i64(tmp, tmp, 4);
        copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
        tcg_gen_mov_i64(cpu_iasq_f, new_spc);
        tcg_gen_mov_i64(cpu_iasq_b, cpu_iasq_f);
        nullify_set(ctx, 0);
    } else {
        copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
        if (ctx->iaoq_b == -1) {
            tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
        }
        copy_iaoq_entry(ctx, cpu_iaoq_b, -1, tmp);
        tcg_gen_mov_i64(cpu_iasq_b, new_spc);
        nullify_set(ctx, a->n);
    }
    tcg_gen_lookup_and_goto_ptr();
    ctx->base.is_jmp = DISAS_NORETURN;
    return nullify_end(ctx);
#endif
}

static bool trans_bl(DisasContext *ctx, arg_bl *a)
{
    return do_dbranch(ctx, iaoq_dest(ctx, a->disp), a->l, a->n);
}

static bool trans_b_gate(DisasContext *ctx, arg_b_gate *a)
{
    uint64_t dest = iaoq_dest(ctx, a->disp);

    nullify_over(ctx);

    /* Make sure the caller hasn't done something weird with the queue.
     * ??? This is not quite the same as the PSW[B] bit, which would be
     * expensive to track.  Real hardware will trap for
     *    b  gateway
     *    b  gateway+4  (in delay slot of first branch)
     * However, checking for a non-sequential instruction queue *will*
     * diagnose the security hole
     *    b  gateway
     *    b  evil
     * in which instructions at evil would run with increased privs.
     */
    if (ctx->iaoq_b == -1 || ctx->iaoq_b != ctx->iaoq_f + 4) {
        return gen_illegal(ctx);
    }

#ifndef CONFIG_USER_ONLY
    if (ctx->tb_flags & PSW_C) {
        int type = hppa_artype_for_page(cpu_env(ctx->cs), ctx->base.pc_next);
        /* If we could not find a TLB entry, then we need to generate an
           ITLB miss exception so the kernel will provide it.
           The resulting TLB fill operation will invalidate this TB and
           we will re-translate, at which point we *will* be able to find
           the TLB entry and determine if this is in fact a gateway page.  */
        if (type < 0) {
            gen_excp(ctx, EXCP_ITLB_MISS);
            return true;
        }
        /* No change for non-gateway pages or for priv decrease.  */
        if (type >= 4 && type - 4 < ctx->privilege) {
            dest = deposit64(dest, 0, 2, type - 4);
        }
    } else {
        dest &= -4;  /* priv = 0 */
    }
#endif

    if (a->l) {
        TCGv_i64 tmp = dest_gpr(ctx, a->l);
        if (ctx->privilege < 3) {
            tcg_gen_andi_i64(tmp, tmp, -4);
        }
        tcg_gen_ori_i64(tmp, tmp, ctx->privilege);
        save_gpr(ctx, a->l, tmp);
    }

    return do_dbranch(ctx, dest, 0, a->n);
}

static bool trans_blr(DisasContext *ctx, arg_blr *a)
{
    if (a->x) {
        TCGv_i64 tmp = tcg_temp_new_i64();
        tcg_gen_shli_i64(tmp, load_gpr(ctx, a->x), 3);
        tcg_gen_addi_i64(tmp, tmp, ctx->iaoq_f + 8);
        /* The computation here never changes privilege level.  */
        return do_ibranch(ctx, tmp, a->l, a->n);
    } else {
        /* BLR R0,RX is a good way to load PC+8 into RX.  */
        return do_dbranch(ctx, ctx->iaoq_f + 8, a->l, a->n);
    }
}

static bool trans_bv(DisasContext *ctx, arg_bv *a)
{
    TCGv_i64 dest;

    if (a->x == 0) {
        dest = load_gpr(ctx, a->b);
    } else {
        dest = tcg_temp_new_i64();
        tcg_gen_shli_i64(dest, load_gpr(ctx, a->x), 3);
        tcg_gen_add_i64(dest, dest, load_gpr(ctx, a->b));
    }
    dest = do_ibranch_priv(ctx, dest);
    return do_ibranch(ctx, dest, 0, a->n);
}

static bool trans_bve(DisasContext *ctx, arg_bve *a)
{
    TCGv_i64 dest;

#ifdef CONFIG_USER_ONLY
    dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));
    return do_ibranch(ctx, dest, a->l, a->n);
#else
    nullify_over(ctx);
    dest = do_ibranch_priv(ctx, load_gpr(ctx, a->b));

    copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_b, cpu_iaoq_b);
    if (ctx->iaoq_b == -1) {
        tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
    }
    copy_iaoq_entry(ctx, cpu_iaoq_b, -1, dest);
    tcg_gen_mov_i64(cpu_iasq_b, space_select(ctx, 0, dest));
    if (a->l) {
        copy_iaoq_entry(ctx, cpu_gr[a->l], ctx->iaoq_n, ctx->iaoq_n_var);
    }
    nullify_set(ctx, a->n);
    tcg_gen_lookup_and_goto_ptr();
    ctx->base.is_jmp = DISAS_NORETURN;
    return nullify_end(ctx);
#endif
}

static bool trans_nopbts(DisasContext *ctx, arg_nopbts *a)
{
    /* All branch target stack instructions implement as nop. */
    return ctx->is_pa20;
}

/*
 * Float class 0
 */

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

static bool trans_fid_f(DisasContext *ctx, arg_fid_f *a)
{
    uint64_t ret;

    if (ctx->is_pa20) {
        ret = 0x13080000000000ULL; /* PA8700 (PCX-W2) */
    } else {
        ret = 0x0f080000000000ULL; /* PA7300LC (PCX-L2) */
    }

    nullify_over(ctx);
    save_frd(0, tcg_constant_i64(ret));
    return nullify_end(ctx);
}

static bool trans_fcpy_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_fcpy_f);
}

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

static bool trans_fcpy_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_fcpy_d);
}

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

static bool trans_fabs_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_fabs_f);
}

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

static bool trans_fabs_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_fabs_d);
}

static bool trans_fsqrt_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fsqrt_s);
}

static bool trans_fsqrt_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fsqrt_d);
}

static bool trans_frnd_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_frnd_s);
}

static bool trans_frnd_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_frnd_d);
}

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

static bool trans_fneg_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_fneg_f);
}

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

static bool trans_fneg_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_fneg_d);
}

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

static bool trans_fnegabs_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_fnegabs_f);
}

static void gen_fnegabs_d(TCGv_i64 dst, TCGv_env unused, TCGv_i64 src)
{
    tcg_gen_ori_i64(dst, src, INT64_MIN);
}

static bool trans_fnegabs_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_fnegabs_d);
}

/*
 * Float class 1
 */

static bool trans_fcnv_d_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_s);
}

static bool trans_fcnv_f_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_d);
}

static bool trans_fcnv_w_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_w_s);
}

static bool trans_fcnv_q_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_dw_s);
}

static bool trans_fcnv_w_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_w_d);
}

static bool trans_fcnv_q_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_dw_d);
}

static bool trans_fcnv_f_w(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_w);
}

static bool trans_fcnv_d_w(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_w);
}

static bool trans_fcnv_f_q(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_dw);
}

static bool trans_fcnv_d_q(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_dw);
}

static bool trans_fcnv_t_f_w(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_w);
}

static bool trans_fcnv_t_d_w(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_w);
}

static bool trans_fcnv_t_f_q(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_dw);
}

static bool trans_fcnv_t_d_q(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_dw);
}

static bool trans_fcnv_uw_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_uw_s);
}

static bool trans_fcnv_uq_f(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_udw_s);
}

static bool trans_fcnv_uw_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_uw_d);
}

static bool trans_fcnv_uq_d(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_udw_d);
}

static bool trans_fcnv_f_uw(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_s_uw);
}

static bool trans_fcnv_d_uw(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_d_uw);
}

static bool trans_fcnv_f_uq(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_s_udw);
}

static bool trans_fcnv_d_uq(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_d_udw);
}

static bool trans_fcnv_t_f_uw(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wew(ctx, a->t, a->r, gen_helper_fcnv_t_s_uw);
}

static bool trans_fcnv_t_d_uw(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_wed(ctx, a->t, a->r, gen_helper_fcnv_t_d_uw);
}

static bool trans_fcnv_t_f_uq(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_dew(ctx, a->t, a->r, gen_helper_fcnv_t_s_udw);
}

static bool trans_fcnv_t_d_uq(DisasContext *ctx, arg_fclass01 *a)
{
    return do_fop_ded(ctx, a->t, a->r, gen_helper_fcnv_t_d_udw);
}

/*
 * Float class 2
 */

static bool trans_fcmp_f(DisasContext *ctx, arg_fclass2 *a)
{
    TCGv_i32 ta, tb, tc, ty;

    nullify_over(ctx);

    ta = load_frw0_i32(a->r1);
    tb = load_frw0_i32(a->r2);
    ty = tcg_constant_i32(a->y);
    tc = tcg_constant_i32(a->c);

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

    return nullify_end(ctx);
}

static bool trans_fcmp_d(DisasContext *ctx, arg_fclass2 *a)
{
    TCGv_i64 ta, tb;
    TCGv_i32 tc, ty;

    nullify_over(ctx);

    ta = load_frd0(a->r1);
    tb = load_frd0(a->r2);
    ty = tcg_constant_i32(a->y);
    tc = tcg_constant_i32(a->c);

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

    return nullify_end(ctx);
}

static bool trans_ftest(DisasContext *ctx, arg_ftest *a)
{
    TCGv_i64 t;

    nullify_over(ctx);

    t = tcg_temp_new_i64();
    tcg_gen_ld32u_i64(t, tcg_env, offsetof(CPUHPPAState, fr0_shadow));

    if (a->y == 1) {
        int mask;
        bool inv = false;

        switch (a->c) {
        case 0: /* simple */
            tcg_gen_andi_i64(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:
            gen_illegal(ctx);
            return true;
        }
        if (inv) {
            TCGv_i64 c = tcg_constant_i64(mask);
            tcg_gen_or_i64(t, t, c);
            ctx->null_cond = cond_make(TCG_COND_EQ, t, c);
        } else {
            tcg_gen_andi_i64(t, t, mask);
            ctx->null_cond = cond_make_0(TCG_COND_EQ, t);
        }
    } else {
        unsigned cbit = (a->y ^ 1) - 1;

        tcg_gen_extract_i64(t, t, 21 - cbit, 1);
        ctx->null_cond = cond_make_0(TCG_COND_NE, t);
    }

 done:
    return nullify_end(ctx);
}

/*
 * Float class 2
 */

static bool trans_fadd_f(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fadd_s);
}

static bool trans_fadd_d(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fadd_d);
}

static bool trans_fsub_f(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fsub_s);
}

static bool trans_fsub_d(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fsub_d);
}

static bool trans_fmpy_f(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_s);
}

static bool trans_fmpy_d(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fmpy_d);
}

static bool trans_fdiv_f(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_weww(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_s);
}

static bool trans_fdiv_d(DisasContext *ctx, arg_fclass3 *a)
{
    return do_fop_dedd(ctx, a->t, a->r1, a->r2, gen_helper_fdiv_d);
}

static bool trans_xmpyu(DisasContext *ctx, arg_xmpyu *a)
{
    TCGv_i64 x, y;

    nullify_over(ctx);

    x = load_frw0_i64(a->r1);
    y = load_frw0_i64(a->r2);
    tcg_gen_mul_i64(x, x, y);
    save_frd(a->t, x);

    return nullify_end(ctx);
}

/* 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 bool do_fmpyadd_s(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
{
    int tm = fmpyadd_s_reg(a->tm);
    int ra = fmpyadd_s_reg(a->ra);
    int ta = fmpyadd_s_reg(a->ta);
    int rm2 = fmpyadd_s_reg(a->rm2);
    int rm1 = fmpyadd_s_reg(a->rm1);

    nullify_over(ctx);

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

    return nullify_end(ctx);
}

static bool trans_fmpyadd_f(DisasContext *ctx, arg_mpyadd *a)
{
    return do_fmpyadd_s(ctx, a, false);
}

static bool trans_fmpysub_f(DisasContext *ctx, arg_mpyadd *a)
{
    return do_fmpyadd_s(ctx, a, true);
}

static bool do_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a, bool is_sub)
{
    nullify_over(ctx);

    do_fop_dedd(ctx, a->tm, a->rm1, a->rm2, gen_helper_fmpy_d);
    do_fop_dedd(ctx, a->ta, a->ta, a->ra,
                is_sub ? gen_helper_fsub_d : gen_helper_fadd_d);

    return nullify_end(ctx);
}

static bool trans_fmpyadd_d(DisasContext *ctx, arg_mpyadd *a)
{
    return do_fmpyadd_d(ctx, a, false);
}

static bool trans_fmpysub_d(DisasContext *ctx, arg_mpyadd *a)
{
    return do_fmpyadd_d(ctx, a, true);
}

static bool trans_fmpyfadd_f(DisasContext *ctx, arg_fmpyfadd_f *a)
{
    TCGv_i32 x, y, z;

    nullify_over(ctx);
    x = load_frw0_i32(a->rm1);
    y = load_frw0_i32(a->rm2);
    z = load_frw0_i32(a->ra3);

    if (a->neg) {
        gen_helper_fmpynfadd_s(x, tcg_env, x, y, z);
    } else {
        gen_helper_fmpyfadd_s(x, tcg_env, x, y, z);
    }

    save_frw_i32(a->t, x);
    return nullify_end(ctx);
}

static bool trans_fmpyfadd_d(DisasContext *ctx, arg_fmpyfadd_d *a)
{
    TCGv_i64 x, y, z;

    nullify_over(ctx);
    x = load_frd0(a->rm1);
    y = load_frd0(a->rm2);
    z = load_frd0(a->ra3);

    if (a->neg) {
        gen_helper_fmpynfadd_d(x, tcg_env, x, y, z);
    } else {
        gen_helper_fmpyfadd_d(x, tcg_env, x, y, z);
    }

    save_frd(a->t, x);
    return nullify_end(ctx);
}

/* Emulate PDC BTLB, called by SeaBIOS-hppa */
static bool trans_diag_btlb(DisasContext *ctx, arg_diag_btlb *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);
    gen_helper_diag_btlb(tcg_env);
    return nullify_end(ctx);
#endif
}

/* Print char in %r26 to first serial console, used by SeaBIOS-hppa */
static bool trans_diag_cout(DisasContext *ctx, arg_diag_cout *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
#ifndef CONFIG_USER_ONLY
    nullify_over(ctx);
    gen_helper_diag_console_output(tcg_env);
    return nullify_end(ctx);
#endif
}

static bool trans_diag_getshadowregs_pa1(DisasContext *ctx, arg_empty *a)
{
    return !ctx->is_pa20 && do_getshadowregs(ctx);
}

static bool trans_diag_getshadowregs_pa2(DisasContext *ctx, arg_empty *a)
{
    return ctx->is_pa20 && do_getshadowregs(ctx);
}

static bool trans_diag_putshadowregs_pa1(DisasContext *ctx, arg_empty *a)
{
    return !ctx->is_pa20 && do_putshadowregs(ctx);
}

static bool trans_diag_putshadowregs_pa2(DisasContext *ctx, arg_empty *a)
{
    return ctx->is_pa20 && do_putshadowregs(ctx);
}

static bool trans_diag_unimp(DisasContext *ctx, arg_diag_unimp *a)
{
    CHECK_MOST_PRIVILEGED(EXCP_PRIV_OPR);
    qemu_log_mask(LOG_UNIMP, "DIAG opcode 0x%04x ignored\n", a->i);
    return true;
}

static void hppa_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *ctx = container_of(dcbase, DisasContext, base);
    int bound;

    ctx->cs = cs;
    ctx->tb_flags = ctx->base.tb->flags;
    ctx->is_pa20 = hppa_is_pa20(cpu_env(cs));

#ifdef CONFIG_USER_ONLY
    ctx->privilege = MMU_IDX_TO_PRIV(MMU_USER_IDX);
    ctx->mmu_idx = MMU_USER_IDX;
    ctx->iaoq_f = ctx->base.pc_first | ctx->privilege;
    ctx->iaoq_b = ctx->base.tb->cs_base | ctx->privilege;
    ctx->unalign = (ctx->tb_flags & TB_FLAG_UNALIGN ? MO_UNALN : MO_ALIGN);
#else
    ctx->privilege = (ctx->tb_flags >> TB_FLAG_PRIV_SHIFT) & 3;
    ctx->mmu_idx = (ctx->tb_flags & PSW_D
                    ? PRIV_P_TO_MMU_IDX(ctx->privilege, ctx->tb_flags & PSW_P)
                    : ctx->tb_flags & PSW_W ? MMU_ABS_W_IDX : MMU_ABS_IDX);

    /* Recover the IAOQ values from the GVA + PRIV.  */
    uint64_t cs_base = ctx->base.tb->cs_base;
    uint64_t iasq_f = cs_base & ~0xffffffffull;
    int32_t diff = cs_base;

    ctx->iaoq_f = (ctx->base.pc_first & ~iasq_f) + ctx->privilege;
    ctx->iaoq_b = (diff ? ctx->iaoq_f + diff : -1);
#endif
    ctx->iaoq_n = -1;
    ctx->iaoq_n_var = NULL;

    ctx->zero = tcg_constant_i64(0);

    /* Bound the number of instructions by those left on the page.  */
    bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4;
    ctx->base.max_insns = MIN(ctx->base.max_insns, bound);
}

static void hppa_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *ctx = container_of(dcbase, DisasContext, base);

    /* Seed the nullification status from PSW[N], as saved in TB->FLAGS.  */
    ctx->null_cond = cond_make_f();
    ctx->psw_n_nonzero = false;
    if (ctx->tb_flags & PSW_N) {
        ctx->null_cond.c = TCG_COND_ALWAYS;
        ctx->psw_n_nonzero = true;
    }
    ctx->null_lab = NULL;
}

static void hppa_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *ctx = container_of(dcbase, DisasContext, base);

    tcg_gen_insn_start(ctx->iaoq_f, ctx->iaoq_b, 0);
    ctx->insn_start = tcg_last_op();
}

static void hppa_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *ctx = container_of(dcbase, DisasContext, base);
    CPUHPPAState *env = cpu_env(cs);
    DisasJumpType ret;

    /* Execute one insn.  */
#ifdef CONFIG_USER_ONLY
    if (ctx->base.pc_next < TARGET_PAGE_SIZE) {
        do_page_zero(ctx);
        ret = ctx->base.is_jmp;
        assert(ret != DISAS_NEXT);
    } else
#endif
    {
        /* Always fetch the insn, even if nullified, so that we check
           the page permissions for execute.  */
        uint32_t insn = translator_ldl(env, &ctx->base, ctx->base.pc_next);

        /* 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 = tcg_temp_new_i64();
            tcg_gen_addi_i64(ctx->iaoq_n_var, cpu_iaoq_b, 4);
        } else {
            ctx->iaoq_n = ctx->iaoq_b + 4;
            ctx->iaoq_n_var = NULL;
        }

        if (unlikely(ctx->null_cond.c == TCG_COND_ALWAYS)) {
            ctx->null_cond.c = TCG_COND_NEVER;
            ret = DISAS_NEXT;
        } else {
            ctx->insn = insn;
            if (!decode(ctx, insn)) {
                gen_illegal(ctx);
            }
            ret = ctx->base.is_jmp;
            assert(ctx->null_lab == NULL);
        }
    }

    /* Advance the insn queue.  Note that this check also detects
       a priority change within the instruction queue.  */
    if (ret == DISAS_NEXT && ctx->iaoq_b != ctx->iaoq_f + 4) {
        if (ctx->iaoq_b != -1 && ctx->iaoq_n != -1
            && use_goto_tb(ctx, ctx->iaoq_b)
            && (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);
            ctx->base.is_jmp = ret = DISAS_NORETURN;
        } else {
            ctx->base.is_jmp = ret = DISAS_IAQ_N_STALE;
        }
    }
    ctx->iaoq_f = ctx->iaoq_b;
    ctx->iaoq_b = ctx->iaoq_n;
    ctx->base.pc_next += 4;

    switch (ret) {
    case DISAS_NORETURN:
    case DISAS_IAQ_N_UPDATED:
        break;

    case DISAS_NEXT:
    case DISAS_IAQ_N_STALE:
    case DISAS_IAQ_N_STALE_EXIT:
        if (ctx->iaoq_f == -1) {
            copy_iaoq_entry(ctx, cpu_iaoq_f, -1, cpu_iaoq_b);
            copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_n, ctx->iaoq_n_var);
#ifndef CONFIG_USER_ONLY
            tcg_gen_mov_i64(cpu_iasq_f, cpu_iasq_b);
#endif
            nullify_save(ctx);
            ctx->base.is_jmp = (ret == DISAS_IAQ_N_STALE_EXIT
                                ? DISAS_EXIT
                                : DISAS_IAQ_N_UPDATED);
        } else if (ctx->iaoq_b == -1) {
            copy_iaoq_entry(ctx, cpu_iaoq_b, -1, ctx->iaoq_n_var);
        }
        break;

    default:
        g_assert_not_reached();
    }
}

static void hppa_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *ctx = container_of(dcbase, DisasContext, base);
    DisasJumpType is_jmp = ctx->base.is_jmp;

    switch (is_jmp) {
    case DISAS_NORETURN:
        break;
    case DISAS_TOO_MANY:
    case DISAS_IAQ_N_STALE:
    case DISAS_IAQ_N_STALE_EXIT:
        copy_iaoq_entry(ctx, cpu_iaoq_f, ctx->iaoq_f, cpu_iaoq_f);
        copy_iaoq_entry(ctx, cpu_iaoq_b, ctx->iaoq_b, cpu_iaoq_b);
        nullify_save(ctx);
        /* FALLTHRU */
    case DISAS_IAQ_N_UPDATED:
        if (is_jmp != DISAS_IAQ_N_STALE_EXIT) {
            tcg_gen_lookup_and_goto_ptr();
            break;
        }
        /* FALLTHRU */
    case DISAS_EXIT:
        tcg_gen_exit_tb(NULL, 0);
        break;
    default:
        g_assert_not_reached();
    }
}

static void hppa_tr_disas_log(const DisasContextBase *dcbase,
                              CPUState *cs, FILE *logfile)
{
    target_ulong pc = dcbase->pc_first;

#ifdef CONFIG_USER_ONLY
    switch (pc) {
    case 0x00:
        fprintf(logfile, "IN:\n0x00000000:  (null)\n");
        return;
    case 0xb0:
        fprintf(logfile, "IN:\n0x000000b0:  light-weight-syscall\n");
        return;
    case 0xe0:
        fprintf(logfile, "IN:\n0x000000e0:  set-thread-pointer-syscall\n");
        return;
    case 0x100:
        fprintf(logfile, "IN:\n0x00000100:  syscall\n");
        return;
    }
#endif

    fprintf(logfile, "IN: %s\n", lookup_symbol(pc));
    target_disas(logfile, cs, pc, dcbase->tb->size);
}

static const TranslatorOps hppa_tr_ops = {
    .init_disas_context = hppa_tr_init_disas_context,
    .tb_start           = hppa_tr_tb_start,
    .insn_start         = hppa_tr_insn_start,
    .translate_insn     = hppa_tr_translate_insn,
    .tb_stop            = hppa_tr_tb_stop,
    .disas_log          = hppa_tr_disas_log,
};

void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int *max_insns,
                           vaddr pc, void *host_pc)
{
    DisasContext ctx;
    translator_loop(cs, tb, max_insns, pc, host_pc, &hppa_tr_ops, &ctx.base);
}
