/*
 *  Xilinx MicroBlaze emulation for qemu: main translation routines.
 *
 *  Copyright (c) 2009 Edgar E. Iglesias.
 *  Copyright (c) 2009-2012 PetaLogix Qld Pty Ltd.
 *
 * 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 "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "tcg/tcg-op.h"
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "qemu/qemu-print.h"

#include "exec/log.h"

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

#define EXTRACT_FIELD(src, start, end) \
            (((src) >> start) & ((1 << (end - start + 1)) - 1))

/* is_jmp field values */
#define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_EXIT    DISAS_TARGET_1 /* all cpu state modified dynamically */

/* cpu state besides pc was modified dynamically; update pc to next */
#define DISAS_EXIT_NEXT DISAS_TARGET_2
/* cpu state besides pc was modified dynamically; update pc to btarget */
#define DISAS_EXIT_JUMP DISAS_TARGET_3

static TCGv_i32 cpu_R[32];
static TCGv_i32 cpu_pc;
static TCGv_i32 cpu_msr;
static TCGv_i32 cpu_msr_c;
static TCGv_i32 cpu_imm;
static TCGv_i32 cpu_bvalue;
static TCGv_i32 cpu_btarget;
static TCGv_i32 cpu_iflags;
static TCGv cpu_res_addr;
static TCGv_i32 cpu_res_val;

/* This is the state at translation time.  */
typedef struct DisasContext {
    DisasContextBase base;
    const MicroBlazeCPUConfig *cfg;

    TCGv_i32 r0;
    bool r0_set;

    /* Decoder.  */
    uint32_t ext_imm;
    unsigned int tb_flags;
    unsigned int tb_flags_to_set;
    int mem_index;

    /* Condition under which to jump, including NEVER and ALWAYS. */
    TCGCond jmp_cond;

    /* Immediate branch-taken destination, or -1 for indirect. */
    uint32_t jmp_dest;
} DisasContext;

static int typeb_imm(DisasContext *dc, int x)
{
    if (dc->tb_flags & IMM_FLAG) {
        return deposit32(dc->ext_imm, 0, 16, x);
    }
    return x;
}

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

static void t_sync_flags(DisasContext *dc)
{
    /* Synch the tb dependent flags between translator and runtime.  */
    if ((dc->tb_flags ^ dc->base.tb->flags) & IFLAGS_TB_MASK) {
        tcg_gen_movi_i32(cpu_iflags, dc->tb_flags & IFLAGS_TB_MASK);
    }
}

static void gen_raise_exception(DisasContext *dc, uint32_t index)
{
    gen_helper_raise_exception(tcg_env, tcg_constant_i32(index));
    dc->base.is_jmp = DISAS_NORETURN;
}

static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
{
    t_sync_flags(dc);
    tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
    gen_raise_exception(dc, index);
}

static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
{
    TCGv_i32 tmp = tcg_constant_i32(esr_ec);
    tcg_gen_st_i32(tmp, tcg_env, offsetof(CPUMBState, esr));

    gen_raise_exception_sync(dc, EXCP_HW_EXCP);
}

static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
{
    if (translator_use_goto_tb(&dc->base, dest)) {
        tcg_gen_goto_tb(n);
        tcg_gen_movi_i32(cpu_pc, dest);
        tcg_gen_exit_tb(dc->base.tb, n);
    } else {
        tcg_gen_movi_i32(cpu_pc, dest);
        tcg_gen_lookup_and_goto_ptr();
    }
    dc->base.is_jmp = DISAS_NORETURN;
}

/*
 * Returns true if the insn an illegal operation.
 * If exceptions are enabled, an exception is raised.
 */
static bool trap_illegal(DisasContext *dc, bool cond)
{
    if (cond && (dc->tb_flags & MSR_EE)
        && dc->cfg->illegal_opcode_exception) {
        gen_raise_hw_excp(dc, ESR_EC_ILLEGAL_OP);
    }
    return cond;
}

/*
 * Returns true if the insn is illegal in userspace.
 * If exceptions are enabled, an exception is raised.
 */
static bool trap_userspace(DisasContext *dc, bool cond)
{
    bool cond_user = cond && dc->mem_index == MMU_USER_IDX;

    if (cond_user && (dc->tb_flags & MSR_EE)) {
        gen_raise_hw_excp(dc, ESR_EC_PRIVINSN);
    }
    return cond_user;
}

/*
 * Return true, and log an error, if the current insn is
 * within a delay slot.
 */
static bool invalid_delay_slot(DisasContext *dc, const char *insn_type)
{
    if (dc->tb_flags & D_FLAG) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "Invalid insn in delay slot: %s at %08x\n",
                      insn_type, (uint32_t)dc->base.pc_next);
        return true;
    }
    return false;
}

static TCGv_i32 reg_for_read(DisasContext *dc, int reg)
{
    if (likely(reg != 0)) {
        return cpu_R[reg];
    }
    if (!dc->r0_set) {
        if (dc->r0 == NULL) {
            dc->r0 = tcg_temp_new_i32();
        }
        tcg_gen_movi_i32(dc->r0, 0);
        dc->r0_set = true;
    }
    return dc->r0;
}

static TCGv_i32 reg_for_write(DisasContext *dc, int reg)
{
    if (likely(reg != 0)) {
        return cpu_R[reg];
    }
    if (dc->r0 == NULL) {
        dc->r0 = tcg_temp_new_i32();
    }
    return dc->r0;
}

static bool do_typea(DisasContext *dc, arg_typea *arg, bool side_effects,
                     void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
{
    TCGv_i32 rd, ra, rb;

    if (arg->rd == 0 && !side_effects) {
        return true;
    }

    rd = reg_for_write(dc, arg->rd);
    ra = reg_for_read(dc, arg->ra);
    rb = reg_for_read(dc, arg->rb);
    fn(rd, ra, rb);
    return true;
}

static bool do_typea0(DisasContext *dc, arg_typea0 *arg, bool side_effects,
                      void (*fn)(TCGv_i32, TCGv_i32))
{
    TCGv_i32 rd, ra;

    if (arg->rd == 0 && !side_effects) {
        return true;
    }

    rd = reg_for_write(dc, arg->rd);
    ra = reg_for_read(dc, arg->ra);
    fn(rd, ra);
    return true;
}

static bool do_typeb_imm(DisasContext *dc, arg_typeb *arg, bool side_effects,
                         void (*fni)(TCGv_i32, TCGv_i32, int32_t))
{
    TCGv_i32 rd, ra;

    if (arg->rd == 0 && !side_effects) {
        return true;
    }

    rd = reg_for_write(dc, arg->rd);
    ra = reg_for_read(dc, arg->ra);
    fni(rd, ra, arg->imm);
    return true;
}

static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
                         void (*fn)(TCGv_i32, TCGv_i32, TCGv_i32))
{
    TCGv_i32 rd, ra, imm;

    if (arg->rd == 0 && !side_effects) {
        return true;
    }

    rd = reg_for_write(dc, arg->rd);
    ra = reg_for_read(dc, arg->ra);
    imm = tcg_constant_i32(arg->imm);

    fn(rd, ra, imm);
    return true;
}

#define DO_TYPEA(NAME, SE, FN) \
    static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
    { return do_typea(dc, a, SE, FN); }

#define DO_TYPEA_CFG(NAME, CFG, SE, FN) \
    static bool trans_##NAME(DisasContext *dc, arg_typea *a) \
    { return dc->cfg->CFG && do_typea(dc, a, SE, FN); }

#define DO_TYPEA0(NAME, SE, FN) \
    static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
    { return do_typea0(dc, a, SE, FN); }

#define DO_TYPEA0_CFG(NAME, CFG, SE, FN) \
    static bool trans_##NAME(DisasContext *dc, arg_typea0 *a) \
    { return dc->cfg->CFG && do_typea0(dc, a, SE, FN); }

#define DO_TYPEBI(NAME, SE, FNI) \
    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
    { return do_typeb_imm(dc, a, SE, FNI); }

#define DO_TYPEBI_CFG(NAME, CFG, SE, FNI) \
    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
    { return dc->cfg->CFG && do_typeb_imm(dc, a, SE, FNI); }

#define DO_TYPEBV(NAME, SE, FN) \
    static bool trans_##NAME(DisasContext *dc, arg_typeb *a) \
    { return do_typeb_val(dc, a, SE, FN); }

#define ENV_WRAPPER2(NAME, HELPER) \
    static void NAME(TCGv_i32 out, TCGv_i32 ina) \
    { HELPER(out, tcg_env, ina); }

#define ENV_WRAPPER3(NAME, HELPER) \
    static void NAME(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb) \
    { HELPER(out, tcg_env, ina, inb); }

/* No input carry, but output carry. */
static void gen_add(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 zero = tcg_constant_i32(0);

    tcg_gen_add2_i32(out, cpu_msr_c, ina, zero, inb, zero);
}

/* Input and output carry. */
static void gen_addc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 zero = tcg_constant_i32(0);
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_add2_i32(tmp, cpu_msr_c, ina, zero, cpu_msr_c, zero);
    tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
}

/* Input carry, but no output carry. */
static void gen_addkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    tcg_gen_add_i32(out, ina, inb);
    tcg_gen_add_i32(out, out, cpu_msr_c);
}

DO_TYPEA(add, true, gen_add)
DO_TYPEA(addc, true, gen_addc)
DO_TYPEA(addk, false, tcg_gen_add_i32)
DO_TYPEA(addkc, true, gen_addkc)

DO_TYPEBV(addi, true, gen_add)
DO_TYPEBV(addic, true, gen_addc)
DO_TYPEBI(addik, false, tcg_gen_addi_i32)
DO_TYPEBV(addikc, true, gen_addkc)

static void gen_andni(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
{
    tcg_gen_andi_i32(out, ina, ~imm);
}

DO_TYPEA(and, false, tcg_gen_and_i32)
DO_TYPEBI(andi, false, tcg_gen_andi_i32)
DO_TYPEA(andn, false, tcg_gen_andc_i32)
DO_TYPEBI(andni, false, gen_andni)

static void gen_bsra(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_andi_i32(tmp, inb, 31);
    tcg_gen_sar_i32(out, ina, tmp);
}

static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_andi_i32(tmp, inb, 31);
    tcg_gen_shr_i32(out, ina, tmp);
}

static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_andi_i32(tmp, inb, 31);
    tcg_gen_shl_i32(out, ina, tmp);
}

static void gen_bsefi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
{
    /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
    int imm_w = extract32(imm, 5, 5);
    int imm_s = extract32(imm, 0, 5);

    if (imm_w + imm_s > 32 || imm_w == 0) {
        /* These inputs have an undefined behavior.  */
        qemu_log_mask(LOG_GUEST_ERROR, "bsefi: Bad input w=%d s=%d\n",
                      imm_w, imm_s);
    } else {
        tcg_gen_extract_i32(out, ina, imm_s, imm_w);
    }
}

static void gen_bsifi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
{
    /* Note that decodetree has extracted and reassembled imm_w/imm_s. */
    int imm_w = extract32(imm, 5, 5);
    int imm_s = extract32(imm, 0, 5);
    int width = imm_w - imm_s + 1;

    if (imm_w < imm_s) {
        /* These inputs have an undefined behavior.  */
        qemu_log_mask(LOG_GUEST_ERROR, "bsifi: Bad input w=%d s=%d\n",
                      imm_w, imm_s);
    } else {
        tcg_gen_deposit_i32(out, out, ina, imm_s, width);
    }
}

DO_TYPEA_CFG(bsra, use_barrel, false, gen_bsra)
DO_TYPEA_CFG(bsrl, use_barrel, false, gen_bsrl)
DO_TYPEA_CFG(bsll, use_barrel, false, gen_bsll)

DO_TYPEBI_CFG(bsrai, use_barrel, false, tcg_gen_sari_i32)
DO_TYPEBI_CFG(bsrli, use_barrel, false, tcg_gen_shri_i32)
DO_TYPEBI_CFG(bslli, use_barrel, false, tcg_gen_shli_i32)

DO_TYPEBI_CFG(bsefi, use_barrel, false, gen_bsefi)
DO_TYPEBI_CFG(bsifi, use_barrel, false, gen_bsifi)

static void gen_clz(TCGv_i32 out, TCGv_i32 ina)
{
    tcg_gen_clzi_i32(out, ina, 32);
}

DO_TYPEA0_CFG(clz, use_pcmp_instr, false, gen_clz)

static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 lt = tcg_temp_new_i32();

    tcg_gen_setcond_i32(TCG_COND_LT, lt, inb, ina);
    tcg_gen_sub_i32(out, inb, ina);
    tcg_gen_deposit_i32(out, out, lt, 31, 1);
}

static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 lt = tcg_temp_new_i32();

    tcg_gen_setcond_i32(TCG_COND_LTU, lt, inb, ina);
    tcg_gen_sub_i32(out, inb, ina);
    tcg_gen_deposit_i32(out, out, lt, 31, 1);
}

DO_TYPEA(cmp, false, gen_cmp)
DO_TYPEA(cmpu, false, gen_cmpu)

ENV_WRAPPER3(gen_fadd, gen_helper_fadd)
ENV_WRAPPER3(gen_frsub, gen_helper_frsub)
ENV_WRAPPER3(gen_fmul, gen_helper_fmul)
ENV_WRAPPER3(gen_fdiv, gen_helper_fdiv)
ENV_WRAPPER3(gen_fcmp_un, gen_helper_fcmp_un)
ENV_WRAPPER3(gen_fcmp_lt, gen_helper_fcmp_lt)
ENV_WRAPPER3(gen_fcmp_eq, gen_helper_fcmp_eq)
ENV_WRAPPER3(gen_fcmp_le, gen_helper_fcmp_le)
ENV_WRAPPER3(gen_fcmp_gt, gen_helper_fcmp_gt)
ENV_WRAPPER3(gen_fcmp_ne, gen_helper_fcmp_ne)
ENV_WRAPPER3(gen_fcmp_ge, gen_helper_fcmp_ge)

DO_TYPEA_CFG(fadd, use_fpu, true, gen_fadd)
DO_TYPEA_CFG(frsub, use_fpu, true, gen_frsub)
DO_TYPEA_CFG(fmul, use_fpu, true, gen_fmul)
DO_TYPEA_CFG(fdiv, use_fpu, true, gen_fdiv)
DO_TYPEA_CFG(fcmp_un, use_fpu, true, gen_fcmp_un)
DO_TYPEA_CFG(fcmp_lt, use_fpu, true, gen_fcmp_lt)
DO_TYPEA_CFG(fcmp_eq, use_fpu, true, gen_fcmp_eq)
DO_TYPEA_CFG(fcmp_le, use_fpu, true, gen_fcmp_le)
DO_TYPEA_CFG(fcmp_gt, use_fpu, true, gen_fcmp_gt)
DO_TYPEA_CFG(fcmp_ne, use_fpu, true, gen_fcmp_ne)
DO_TYPEA_CFG(fcmp_ge, use_fpu, true, gen_fcmp_ge)

ENV_WRAPPER2(gen_flt, gen_helper_flt)
ENV_WRAPPER2(gen_fint, gen_helper_fint)
ENV_WRAPPER2(gen_fsqrt, gen_helper_fsqrt)

DO_TYPEA0_CFG(flt, use_fpu >= 2, true, gen_flt)
DO_TYPEA0_CFG(fint, use_fpu >= 2, true, gen_fint)
DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)

/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    gen_helper_divs(out, tcg_env, inb, ina);
}

static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    gen_helper_divu(out, tcg_env, inb, ina);
}

DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
DO_TYPEA_CFG(idivu, use_div, true, gen_idivu)

static bool trans_imm(DisasContext *dc, arg_imm *arg)
{
    if (invalid_delay_slot(dc, "imm")) {
        return true;
    }
    dc->ext_imm = arg->imm << 16;
    tcg_gen_movi_i32(cpu_imm, dc->ext_imm);
    dc->tb_flags_to_set = IMM_FLAG;
    return true;
}

static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_muls2_i32(tmp, out, ina, inb);
}

static void gen_mulhu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_mulu2_i32(tmp, out, ina, inb);
}

static void gen_mulhsu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 tmp = tcg_temp_new_i32();
    tcg_gen_mulsu2_i32(tmp, out, ina, inb);
}

DO_TYPEA_CFG(mul, use_hw_mul, false, tcg_gen_mul_i32)
DO_TYPEA_CFG(mulh, use_hw_mul >= 2, false, gen_mulh)
DO_TYPEA_CFG(mulhu, use_hw_mul >= 2, false, gen_mulhu)
DO_TYPEA_CFG(mulhsu, use_hw_mul >= 2, false, gen_mulhsu)
DO_TYPEBI_CFG(muli, use_hw_mul, false, tcg_gen_muli_i32)

DO_TYPEA(or, false, tcg_gen_or_i32)
DO_TYPEBI(ori, false, tcg_gen_ori_i32)

static void gen_pcmpeq(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    tcg_gen_setcond_i32(TCG_COND_EQ, out, ina, inb);
}

static void gen_pcmpne(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    tcg_gen_setcond_i32(TCG_COND_NE, out, ina, inb);
}

DO_TYPEA_CFG(pcmpbf, use_pcmp_instr, false, gen_helper_pcmpbf)
DO_TYPEA_CFG(pcmpeq, use_pcmp_instr, false, gen_pcmpeq)
DO_TYPEA_CFG(pcmpne, use_pcmp_instr, false, gen_pcmpne)

/* No input carry, but output carry. */
static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_msr_c, inb, ina);
    tcg_gen_sub_i32(out, inb, ina);
}

/* Input and output carry. */
static void gen_rsubc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 zero = tcg_constant_i32(0);
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_not_i32(tmp, ina);
    tcg_gen_add2_i32(tmp, cpu_msr_c, tmp, zero, cpu_msr_c, zero);
    tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
}

/* No input or output carry. */
static void gen_rsubk(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    tcg_gen_sub_i32(out, inb, ina);
}

/* Input carry, no output carry. */
static void gen_rsubkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
    TCGv_i32 nota = tcg_temp_new_i32();

    tcg_gen_not_i32(nota, ina);
    tcg_gen_add_i32(out, inb, nota);
    tcg_gen_add_i32(out, out, cpu_msr_c);
}

DO_TYPEA(rsub, true, gen_rsub)
DO_TYPEA(rsubc, true, gen_rsubc)
DO_TYPEA(rsubk, false, gen_rsubk)
DO_TYPEA(rsubkc, true, gen_rsubkc)

DO_TYPEBV(rsubi, true, gen_rsub)
DO_TYPEBV(rsubic, true, gen_rsubc)
DO_TYPEBV(rsubik, false, gen_rsubk)
DO_TYPEBV(rsubikc, true, gen_rsubkc)

DO_TYPEA0(sext8, false, tcg_gen_ext8s_i32)
DO_TYPEA0(sext16, false, tcg_gen_ext16s_i32)

static void gen_sra(TCGv_i32 out, TCGv_i32 ina)
{
    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
    tcg_gen_sari_i32(out, ina, 1);
}

static void gen_src(TCGv_i32 out, TCGv_i32 ina)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_mov_i32(tmp, cpu_msr_c);
    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
    tcg_gen_extract2_i32(out, ina, tmp, 1);
}

static void gen_srl(TCGv_i32 out, TCGv_i32 ina)
{
    tcg_gen_andi_i32(cpu_msr_c, ina, 1);
    tcg_gen_shri_i32(out, ina, 1);
}

DO_TYPEA0(sra, false, gen_sra)
DO_TYPEA0(src, false, gen_src)
DO_TYPEA0(srl, false, gen_srl)

static void gen_swaph(TCGv_i32 out, TCGv_i32 ina)
{
    tcg_gen_rotri_i32(out, ina, 16);
}

DO_TYPEA0(swapb, false, tcg_gen_bswap32_i32)
DO_TYPEA0(swaph, false, gen_swaph)

static bool trans_wdic(DisasContext *dc, arg_wdic *a)
{
    /* Cache operations are nops: only check for supervisor mode.  */
    trap_userspace(dc, true);
    return true;
}

DO_TYPEA(xor, false, tcg_gen_xor_i32)
DO_TYPEBI(xori, false, tcg_gen_xori_i32)

static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
{
    TCGv ret = tcg_temp_new();

    /* If any of the regs is r0, set t to the value of the other reg.  */
    if (ra && rb) {
        TCGv_i32 tmp = tcg_temp_new_i32();
        tcg_gen_add_i32(tmp, cpu_R[ra], cpu_R[rb]);
        tcg_gen_extu_i32_tl(ret, tmp);
    } else if (ra) {
        tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
    } else if (rb) {
        tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
    } else {
        tcg_gen_movi_tl(ret, 0);
    }

    if ((ra == 1 || rb == 1) && dc->cfg->stackprot) {
        gen_helper_stackprot(tcg_env, ret);
    }
    return ret;
}

static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
{
    TCGv ret = tcg_temp_new();

    /* If any of the regs is r0, set t to the value of the other reg.  */
    if (ra) {
        TCGv_i32 tmp = tcg_temp_new_i32();
        tcg_gen_addi_i32(tmp, cpu_R[ra], imm);
        tcg_gen_extu_i32_tl(ret, tmp);
    } else {
        tcg_gen_movi_tl(ret, (uint32_t)imm);
    }

    if (ra == 1 && dc->cfg->stackprot) {
        gen_helper_stackprot(tcg_env, ret);
    }
    return ret;
}

#ifndef CONFIG_USER_ONLY
static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
{
    int addr_size = dc->cfg->addr_size;
    TCGv ret = tcg_temp_new();

    if (addr_size == 32 || ra == 0) {
        if (rb) {
            tcg_gen_extu_i32_tl(ret, cpu_R[rb]);
        } else {
            tcg_gen_movi_tl(ret, 0);
        }
    } else {
        if (rb) {
            tcg_gen_concat_i32_i64(ret, cpu_R[rb], cpu_R[ra]);
        } else {
            tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
            tcg_gen_shli_tl(ret, ret, 32);
        }
        if (addr_size < 64) {
            /* Mask off out of range bits.  */
            tcg_gen_andi_i64(ret, ret, MAKE_64BIT_MASK(0, addr_size));
        }
    }
    return ret;
}
#endif

#ifndef CONFIG_USER_ONLY
static void record_unaligned_ess(DisasContext *dc, int rd,
                                 MemOp size, bool store)
{
    uint32_t iflags = tcg_get_insn_start_param(dc->base.insn_start, 1);

    iflags |= ESR_ESS_FLAG;
    iflags |= rd << 5;
    iflags |= store * ESR_S;
    iflags |= (size == MO_32) * ESR_W;

    tcg_set_insn_start_param(dc->base.insn_start, 1, iflags);
}
#endif

static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
                    int mem_index, bool rev)
{
    MemOp size = mop & MO_SIZE;

    /*
     * When doing reverse accesses we need to do two things.
     *
     * 1. Reverse the address wrt endianness.
     * 2. Byteswap the data lanes on the way back into the CPU core.
     */
    if (rev) {
        if (size > MO_8) {
            mop ^= MO_BSWAP;
        }
        if (size < MO_32) {
            tcg_gen_xori_tl(addr, addr, 3 - size);
        }
    }

    /*
     * For system mode, enforce alignment if the cpu configuration
     * requires it.  For user-mode, the Linux kernel will have fixed up
     * any unaligned access, so emulate that by *not* setting MO_ALIGN.
     */
#ifndef CONFIG_USER_ONLY
    if (size > MO_8 &&
        (dc->tb_flags & MSR_EE) &&
        dc->cfg->unaligned_exceptions) {
        record_unaligned_ess(dc, rd, size, false);
        mop |= MO_ALIGN;
    }
#endif

    tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
    return true;
}

static bool trans_lbu(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
}

static bool trans_lbur(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
}

static bool trans_lbuea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_lbui(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_load(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
}

static bool trans_lhu(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
}

static bool trans_lhur(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
}

static bool trans_lhuea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_lhui(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_load(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
}

static bool trans_lw(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
}

static bool trans_lwr(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
}

static bool trans_lwea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_load(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_lwi(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_load(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
}

static bool trans_lwx(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);

    /* lwx does not throw unaligned access errors, so force alignment */
    tcg_gen_andi_tl(addr, addr, ~3);

    tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
    tcg_gen_mov_tl(cpu_res_addr, addr);

    if (arg->rd) {
        tcg_gen_mov_i32(cpu_R[arg->rd], cpu_res_val);
    }

    /* No support for AXI exclusive so always clear C */
    tcg_gen_movi_i32(cpu_msr_c, 0);
    return true;
}

static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
                     int mem_index, bool rev)
{
    MemOp size = mop & MO_SIZE;

    /*
     * When doing reverse accesses we need to do two things.
     *
     * 1. Reverse the address wrt endianness.
     * 2. Byteswap the data lanes on the way back into the CPU core.
     */
    if (rev) {
        if (size > MO_8) {
            mop ^= MO_BSWAP;
        }
        if (size < MO_32) {
            tcg_gen_xori_tl(addr, addr, 3 - size);
        }
    }

    /*
     * For system mode, enforce alignment if the cpu configuration
     * requires it.  For user-mode, the Linux kernel will have fixed up
     * any unaligned access, so emulate that by *not* setting MO_ALIGN.
     */
#ifndef CONFIG_USER_ONLY
    if (size > MO_8 &&
        (dc->tb_flags & MSR_EE) &&
        dc->cfg->unaligned_exceptions) {
        record_unaligned_ess(dc, rd, size, true);
        mop |= MO_ALIGN;
    }
#endif

    tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
    return true;
}

static bool trans_sb(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
}

static bool trans_sbr(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, true);
}

static bool trans_sbea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_UB, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_sbi(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_store(dc, arg->rd, addr, MO_UB, dc->mem_index, false);
}

static bool trans_sh(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
}

static bool trans_shr(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, true);
}

static bool trans_shea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUW, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_shi(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_store(dc, arg->rd, addr, MO_TEUW, dc->mem_index, false);
}

static bool trans_sw(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
}

static bool trans_swr(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, true);
}

static bool trans_swea(DisasContext *dc, arg_typea *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
#ifdef CONFIG_USER_ONLY
    return true;
#else
    TCGv addr = compute_ldst_addr_ea(dc, arg->ra, arg->rb);
    return do_store(dc, arg->rd, addr, MO_TEUL, MMU_NOMMU_IDX, false);
#endif
}

static bool trans_swi(DisasContext *dc, arg_typeb *arg)
{
    TCGv addr = compute_ldst_addr_typeb(dc, arg->ra, arg->imm);
    return do_store(dc, arg->rd, addr, MO_TEUL, dc->mem_index, false);
}

static bool trans_swx(DisasContext *dc, arg_typea *arg)
{
    TCGv addr = compute_ldst_addr_typea(dc, arg->ra, arg->rb);
    TCGLabel *swx_done = gen_new_label();
    TCGLabel *swx_fail = gen_new_label();
    TCGv_i32 tval;

    /* swx does not throw unaligned access errors, so force alignment */
    tcg_gen_andi_tl(addr, addr, ~3);

    /*
     * Compare the address vs the one we used during lwx.
     * On mismatch, the operation fails.  On match, addr dies at the
     * branch, but we know we can use the equal version in the global.
     * In either case, addr is no longer needed.
     */
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_fail);

    /*
     * Compare the value loaded during lwx with current contents of
     * the reserved location.
     */
    tval = tcg_temp_new_i32();

    tcg_gen_atomic_cmpxchg_i32(tval, cpu_res_addr, cpu_res_val,
                               reg_for_write(dc, arg->rd),
                               dc->mem_index, MO_TEUL);

    tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail);

    /* Success */
    tcg_gen_movi_i32(cpu_msr_c, 0);
    tcg_gen_br(swx_done);

    /* Failure */
    gen_set_label(swx_fail);
    tcg_gen_movi_i32(cpu_msr_c, 1);

    gen_set_label(swx_done);

    /*
     * Prevent the saved address from working again without another ldx.
     * Akin to the pseudocode setting reservation = 0.
     */
    tcg_gen_movi_tl(cpu_res_addr, -1);
    return true;
}

static void setup_dslot(DisasContext *dc, bool type_b)
{
    dc->tb_flags_to_set |= D_FLAG;
    if (type_b && (dc->tb_flags & IMM_FLAG)) {
        dc->tb_flags_to_set |= BIMM_FLAG;
    }
}

static bool do_branch(DisasContext *dc, int dest_rb, int dest_imm,
                      bool delay, bool abs, int link)
{
    uint32_t add_pc;

    if (invalid_delay_slot(dc, "branch")) {
        return true;
    }
    if (delay) {
        setup_dslot(dc, dest_rb < 0);
    }

    if (link) {
        tcg_gen_movi_i32(cpu_R[link], dc->base.pc_next);
    }

    /* Store the branch taken destination into btarget.  */
    add_pc = abs ? 0 : dc->base.pc_next;
    if (dest_rb > 0) {
        dc->jmp_dest = -1;
        tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], add_pc);
    } else {
        dc->jmp_dest = add_pc + dest_imm;
        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
    }
    dc->jmp_cond = TCG_COND_ALWAYS;
    return true;
}

#define DO_BR(NAME, NAMEI, DELAY, ABS, LINK)                               \
    static bool trans_##NAME(DisasContext *dc, arg_typea_br *arg)          \
    { return do_branch(dc, arg->rb, 0, DELAY, ABS, LINK ? arg->rd : 0); }  \
    static bool trans_##NAMEI(DisasContext *dc, arg_typeb_br *arg)         \
    { return do_branch(dc, -1, arg->imm, DELAY, ABS, LINK ? arg->rd : 0); }

DO_BR(br, bri, false, false, false)
DO_BR(bra, brai, false, true, false)
DO_BR(brd, brid, true, false, false)
DO_BR(brad, braid, true, true, false)
DO_BR(brld, brlid, true, false, true)
DO_BR(brald, bralid, true, true, true)

static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
                   TCGCond cond, int ra, bool delay)
{
    TCGv_i32 zero, next;

    if (invalid_delay_slot(dc, "bcc")) {
        return true;
    }
    if (delay) {
        setup_dslot(dc, dest_rb < 0);
    }

    dc->jmp_cond = cond;

    /* Cache the condition register in cpu_bvalue across any delay slot.  */
    tcg_gen_mov_i32(cpu_bvalue, reg_for_read(dc, ra));

    /* Store the branch taken destination into btarget.  */
    if (dest_rb > 0) {
        dc->jmp_dest = -1;
        tcg_gen_addi_i32(cpu_btarget, cpu_R[dest_rb], dc->base.pc_next);
    } else {
        dc->jmp_dest = dc->base.pc_next + dest_imm;
        tcg_gen_movi_i32(cpu_btarget, dc->jmp_dest);
    }

    /* Compute the final destination into btarget.  */
    zero = tcg_constant_i32(0);
    next = tcg_constant_i32(dc->base.pc_next + (delay + 1) * 4);
    tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
                        reg_for_read(dc, ra), zero,
                        cpu_btarget, next);

    return true;
}

#define DO_BCC(NAME, COND)                                              \
    static bool trans_##NAME(DisasContext *dc, arg_typea_bc *arg)       \
    { return do_bcc(dc, arg->rb, 0, COND, arg->ra, false); }            \
    static bool trans_##NAME##d(DisasContext *dc, arg_typea_bc *arg)    \
    { return do_bcc(dc, arg->rb, 0, COND, arg->ra, true); }             \
    static bool trans_##NAME##i(DisasContext *dc, arg_typeb_bc *arg)    \
    { return do_bcc(dc, -1, arg->imm, COND, arg->ra, false); }          \
    static bool trans_##NAME##id(DisasContext *dc, arg_typeb_bc *arg)   \
    { return do_bcc(dc, -1, arg->imm, COND, arg->ra, true); }

DO_BCC(beq, TCG_COND_EQ)
DO_BCC(bge, TCG_COND_GE)
DO_BCC(bgt, TCG_COND_GT)
DO_BCC(ble, TCG_COND_LE)
DO_BCC(blt, TCG_COND_LT)
DO_BCC(bne, TCG_COND_NE)

static bool trans_brk(DisasContext *dc, arg_typea_br *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }
    if (invalid_delay_slot(dc, "brk")) {
        return true;
    }

    tcg_gen_mov_i32(cpu_pc, reg_for_read(dc, arg->rb));
    if (arg->rd) {
        tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
    }
    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_BIP);
    tcg_gen_movi_tl(cpu_res_addr, -1);

    dc->base.is_jmp = DISAS_EXIT;
    return true;
}

static bool trans_brki(DisasContext *dc, arg_typeb_br *arg)
{
    uint32_t imm = arg->imm;

    if (trap_userspace(dc, imm != 0x8 && imm != 0x18)) {
        return true;
    }
    if (invalid_delay_slot(dc, "brki")) {
        return true;
    }

    tcg_gen_movi_i32(cpu_pc, imm);
    if (arg->rd) {
        tcg_gen_movi_i32(cpu_R[arg->rd], dc->base.pc_next);
    }
    tcg_gen_movi_tl(cpu_res_addr, -1);

#ifdef CONFIG_USER_ONLY
    switch (imm) {
    case 0x8:  /* syscall trap */
        gen_raise_exception_sync(dc, EXCP_SYSCALL);
        break;
    case 0x18: /* debug trap */
        gen_raise_exception_sync(dc, EXCP_DEBUG);
        break;
    default:   /* eliminated with trap_userspace check */
        g_assert_not_reached();
    }
#else
    uint32_t msr_to_set = 0;

    if (imm != 0x18) {
        msr_to_set |= MSR_BIP;
    }
    if (imm == 0x8 || imm == 0x18) {
        /* MSR_UM and MSR_VM are in tb_flags, so we know their value. */
        msr_to_set |= (dc->tb_flags & (MSR_UM | MSR_VM)) << 1;
        tcg_gen_andi_i32(cpu_msr, cpu_msr,
                         ~(MSR_VMS | MSR_UMS | MSR_VM | MSR_UM));
    }
    tcg_gen_ori_i32(cpu_msr, cpu_msr, msr_to_set);
    dc->base.is_jmp = DISAS_EXIT;
#endif

    return true;
}

static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
{
    int mbar_imm = arg->imm;

    /* Note that mbar is a specialized branch instruction. */
    if (invalid_delay_slot(dc, "mbar")) {
        return true;
    }

    /* Data access memory barrier.  */
    if ((mbar_imm & 2) == 0) {
        tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
    }

    /* Sleep. */
    if (mbar_imm & 16) {
        if (trap_userspace(dc, true)) {
            /* Sleep is a privileged instruction.  */
            return true;
        }

        t_sync_flags(dc);

        tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
                       -offsetof(MicroBlazeCPU, env)
                       +offsetof(CPUState, halted));

        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);

        gen_raise_exception(dc, EXCP_HLT);
    }

    /*
     * If !(mbar_imm & 1), this is an instruction access memory barrier
     * and we need to end the TB so that we recognize self-modified
     * code immediately.
     *
     * However, there are some data mbars that need the TB break
     * (and return to main loop) to recognize interrupts right away.
     * E.g. recognizing a change to an interrupt controller register.
     *
     * Therefore, choose to end the TB always.
     */
    dc->base.is_jmp = DISAS_EXIT_NEXT;
    return true;
}

static bool do_rts(DisasContext *dc, arg_typeb_bc *arg, int to_set)
{
    if (trap_userspace(dc, to_set)) {
        return true;
    }
    if (invalid_delay_slot(dc, "rts")) {
        return true;
    }

    dc->tb_flags_to_set |= to_set;
    setup_dslot(dc, true);

    dc->jmp_cond = TCG_COND_ALWAYS;
    dc->jmp_dest = -1;
    tcg_gen_addi_i32(cpu_btarget, reg_for_read(dc, arg->ra), arg->imm);
    return true;
}

#define DO_RTS(NAME, IFLAG) \
    static bool trans_##NAME(DisasContext *dc, arg_typeb_bc *arg) \
    { return do_rts(dc, arg, IFLAG); }

DO_RTS(rtbd, DRTB_FLAG)
DO_RTS(rtid, DRTI_FLAG)
DO_RTS(rted, DRTE_FLAG)
DO_RTS(rtsd, 0)

static bool trans_zero(DisasContext *dc, arg_zero *arg)
{
    /* If opcode_0_illegal, trap.  */
    if (dc->cfg->opcode_0_illegal) {
        trap_illegal(dc, true);
        return true;
    }
    /*
     * Otherwise, this is "add r0, r0, r0".
     * Continue to trans_add so that MSR[C] gets cleared.
     */
    return false;
}

static void msr_read(DisasContext *dc, TCGv_i32 d)
{
    TCGv_i32 t;

    /* Replicate the cpu_msr_c boolean into the proper bit and the copy. */
    t = tcg_temp_new_i32();
    tcg_gen_muli_i32(t, cpu_msr_c, MSR_C | MSR_CC);
    tcg_gen_or_i32(d, cpu_msr, t);
}

static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
{
    uint32_t imm = arg->imm;

    if (trap_userspace(dc, imm != MSR_C)) {
        return true;
    }

    if (arg->rd) {
        msr_read(dc, cpu_R[arg->rd]);
    }

    /*
     * Handle the carry bit separately.
     * This is the only bit that userspace can modify.
     */
    if (imm & MSR_C) {
        tcg_gen_movi_i32(cpu_msr_c, set);
    }

    /*
     * MSR_C and MSR_CC set above.
     * MSR_PVR is not writable, and is always clear.
     */
    imm &= ~(MSR_C | MSR_CC | MSR_PVR);

    if (imm != 0) {
        if (set) {
            tcg_gen_ori_i32(cpu_msr, cpu_msr, imm);
        } else {
            tcg_gen_andi_i32(cpu_msr, cpu_msr, ~imm);
        }
        dc->base.is_jmp = DISAS_EXIT_NEXT;
    }
    return true;
}

static bool trans_msrclr(DisasContext *dc, arg_type_msr *arg)
{
    return do_msrclrset(dc, arg, false);
}

static bool trans_msrset(DisasContext *dc, arg_type_msr *arg)
{
    return do_msrclrset(dc, arg, true);
}

static bool trans_mts(DisasContext *dc, arg_mts *arg)
{
    if (trap_userspace(dc, true)) {
        return true;
    }

#ifdef CONFIG_USER_ONLY
    g_assert_not_reached();
#else
    if (arg->e && arg->rs != 0x1003) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "Invalid extended mts reg 0x%x\n", arg->rs);
        return true;
    }

    TCGv_i32 src = reg_for_read(dc, arg->ra);
    switch (arg->rs) {
    case SR_MSR:
        /* Install MSR_C.  */
        tcg_gen_extract_i32(cpu_msr_c, src, 2, 1);
        /*
         * Clear MSR_C and MSR_CC;
         * MSR_PVR is not writable, and is always clear.
         */
        tcg_gen_andi_i32(cpu_msr, src, ~(MSR_C | MSR_CC | MSR_PVR));
        break;
    case SR_FSR:
        tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, fsr));
        break;
    case 0x800:
        tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, slr));
        break;
    case 0x802:
        tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, shr));
        break;

    case 0x1000: /* PID */
    case 0x1001: /* ZPR */
    case 0x1002: /* TLBX */
    case 0x1003: /* TLBLO */
    case 0x1004: /* TLBHI */
    case 0x1005: /* TLBSX */
        {
            TCGv_i32 tmp_ext = tcg_constant_i32(arg->e);
            TCGv_i32 tmp_reg = tcg_constant_i32(arg->rs & 7);

            gen_helper_mmu_write(tcg_env, tmp_ext, tmp_reg, src);
        }
        break;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "Invalid mts reg 0x%x\n", arg->rs);
        return true;
    }
    dc->base.is_jmp = DISAS_EXIT_NEXT;
    return true;
#endif
}

static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
{
    TCGv_i32 dest = reg_for_write(dc, arg->rd);

    if (arg->e) {
        switch (arg->rs) {
        case SR_EAR:
            {
                TCGv_i64 t64 = tcg_temp_new_i64();
                tcg_gen_ld_i64(t64, tcg_env, offsetof(CPUMBState, ear));
                tcg_gen_extrh_i64_i32(dest, t64);
            }
            return true;
#ifndef CONFIG_USER_ONLY
        case 0x1003: /* TLBLO */
            /* Handled below. */
            break;
#endif
        case 0x2006 ... 0x2009:
            /* High bits of PVR6-9 not implemented. */
            tcg_gen_movi_i32(dest, 0);
            return true;
        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "Invalid extended mfs reg 0x%x\n", arg->rs);
            return true;
        }
    }

    switch (arg->rs) {
    case SR_PC:
        tcg_gen_movi_i32(dest, dc->base.pc_next);
        break;
    case SR_MSR:
        msr_read(dc, dest);
        break;
    case SR_EAR:
        {
            TCGv_i64 t64 = tcg_temp_new_i64();
            tcg_gen_ld_i64(t64, tcg_env, offsetof(CPUMBState, ear));
            tcg_gen_extrl_i64_i32(dest, t64);
        }
        break;
    case SR_ESR:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, esr));
        break;
    case SR_FSR:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, fsr));
        break;
    case SR_BTR:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, btr));
        break;
    case SR_EDR:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, edr));
        break;
    case 0x800:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, slr));
        break;
    case 0x802:
        tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, shr));
        break;

#ifndef CONFIG_USER_ONLY
    case 0x1000: /* PID */
    case 0x1001: /* ZPR */
    case 0x1002: /* TLBX */
    case 0x1003: /* TLBLO */
    case 0x1004: /* TLBHI */
    case 0x1005: /* TLBSX */
        {
            TCGv_i32 tmp_ext = tcg_constant_i32(arg->e);
            TCGv_i32 tmp_reg = tcg_constant_i32(arg->rs & 7);

            gen_helper_mmu_read(dest, tcg_env, tmp_ext, tmp_reg);
        }
        break;
#endif

    case 0x2000 ... 0x200c:
        tcg_gen_ld_i32(dest, tcg_env,
                       offsetof(MicroBlazeCPU, cfg.pvr_regs[arg->rs - 0x2000])
                       - offsetof(MicroBlazeCPU, env));
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "Invalid mfs reg 0x%x\n", arg->rs);
        break;
    }
    return true;
}

static void do_rti(DisasContext *dc)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_shri_i32(tmp, cpu_msr, 1);
    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_IE);
    tcg_gen_andi_i32(tmp, tmp, MSR_VM | MSR_UM);
    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM));
    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
}

static void do_rtb(DisasContext *dc)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_shri_i32(tmp, cpu_msr, 1);
    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_BIP));
    tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
}

static void do_rte(DisasContext *dc)
{
    TCGv_i32 tmp = tcg_temp_new_i32();

    tcg_gen_shri_i32(tmp, cpu_msr, 1);
    tcg_gen_ori_i32(cpu_msr, cpu_msr, MSR_EE);
    tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
    tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_EIP));
    tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
}

/* Insns connected to FSL or AXI stream attached devices.  */
static bool do_get(DisasContext *dc, int rd, int rb, int imm, int ctrl)
{
    TCGv_i32 t_id, t_ctrl;

    if (trap_userspace(dc, true)) {
        return true;
    }

    t_id = tcg_temp_new_i32();
    if (rb) {
        tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
    } else {
        tcg_gen_movi_i32(t_id, imm);
    }

    t_ctrl = tcg_constant_i32(ctrl);
    gen_helper_get(reg_for_write(dc, rd), t_id, t_ctrl);
    return true;
}

static bool trans_get(DisasContext *dc, arg_get *arg)
{
    return do_get(dc, arg->rd, 0, arg->imm, arg->ctrl);
}

static bool trans_getd(DisasContext *dc, arg_getd *arg)
{
    return do_get(dc, arg->rd, arg->rb, 0, arg->ctrl);
}

static bool do_put(DisasContext *dc, int ra, int rb, int imm, int ctrl)
{
    TCGv_i32 t_id, t_ctrl;

    if (trap_userspace(dc, true)) {
        return true;
    }

    t_id = tcg_temp_new_i32();
    if (rb) {
        tcg_gen_andi_i32(t_id, cpu_R[rb], 0xf);
    } else {
        tcg_gen_movi_i32(t_id, imm);
    }

    t_ctrl = tcg_constant_i32(ctrl);
    gen_helper_put(t_id, t_ctrl, reg_for_read(dc, ra));
    return true;
}

static bool trans_put(DisasContext *dc, arg_put *arg)
{
    return do_put(dc, arg->ra, 0, arg->imm, arg->ctrl);
}

static bool trans_putd(DisasContext *dc, arg_putd *arg)
{
    return do_put(dc, arg->ra, arg->rb, 0, arg->ctrl);
}

static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
{
    DisasContext *dc = container_of(dcb, DisasContext, base);
    MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
    int bound;

    dc->cfg = &cpu->cfg;
    dc->tb_flags = dc->base.tb->flags;
    dc->ext_imm = dc->base.tb->cs_base;
    dc->r0 = NULL;
    dc->r0_set = false;
    dc->mem_index = cpu_mmu_index(cs, false);
    dc->jmp_cond = dc->tb_flags & D_FLAG ? TCG_COND_ALWAYS : TCG_COND_NEVER;
    dc->jmp_dest = -1;

    bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
    dc->base.max_insns = MIN(dc->base.max_insns, bound);
}

static void mb_tr_tb_start(DisasContextBase *dcb, CPUState *cs)
{
}

static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
{
    DisasContext *dc = container_of(dcb, DisasContext, base);

    tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
}

static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
{
    DisasContext *dc = container_of(dcb, DisasContext, base);
    uint32_t ir;

    /* TODO: This should raise an exception, not terminate qemu. */
    if (dc->base.pc_next & 3) {
        cpu_abort(cs, "Microblaze: unaligned PC=%x\n",
                  (uint32_t)dc->base.pc_next);
    }

    dc->tb_flags_to_set = 0;

    ir = translator_ldl(cpu_env(cs), &dc->base, dc->base.pc_next);
    if (!decode(dc, ir)) {
        trap_illegal(dc, true);
    }

    if (dc->r0) {
        dc->r0 = NULL;
        dc->r0_set = false;
    }

    /* Discard the imm global when its contents cannot be used. */
    if ((dc->tb_flags & ~dc->tb_flags_to_set) & IMM_FLAG) {
        tcg_gen_discard_i32(cpu_imm);
    }

    dc->tb_flags &= ~(IMM_FLAG | BIMM_FLAG | D_FLAG);
    dc->tb_flags |= dc->tb_flags_to_set;
    dc->base.pc_next += 4;

    if (dc->jmp_cond != TCG_COND_NEVER && !(dc->tb_flags & D_FLAG)) {
        /*
         * Finish any return-from branch.
         */
        uint32_t rt_ibe = dc->tb_flags & (DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
        if (unlikely(rt_ibe != 0)) {
            dc->tb_flags &= ~(DRTI_FLAG | DRTB_FLAG | DRTE_FLAG);
            if (rt_ibe & DRTI_FLAG) {
                do_rti(dc);
            } else if (rt_ibe & DRTB_FLAG) {
                do_rtb(dc);
            } else {
                do_rte(dc);
            }
        }

        /* Complete the branch, ending the TB. */
        switch (dc->base.is_jmp) {
        case DISAS_NORETURN:
            /*
             * E.g. illegal insn in a delay slot.  We've already exited
             * and will handle D_FLAG in mb_cpu_do_interrupt.
             */
            break;
        case DISAS_NEXT:
            /*
             * Normal insn a delay slot.
             * However, the return-from-exception type insns should
             * return to the main loop, as they have adjusted MSR.
             */
            dc->base.is_jmp = (rt_ibe ? DISAS_EXIT_JUMP : DISAS_JUMP);
            break;
        case DISAS_EXIT_NEXT:
            /*
             * E.g. mts insn in a delay slot.  Continue with btarget,
             * but still return to the main loop.
             */
            dc->base.is_jmp = DISAS_EXIT_JUMP;
            break;
        default:
            g_assert_not_reached();
        }
    }
}

static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
{
    DisasContext *dc = container_of(dcb, DisasContext, base);

    if (dc->base.is_jmp == DISAS_NORETURN) {
        /* We have already exited the TB. */
        return;
    }

    t_sync_flags(dc);

    switch (dc->base.is_jmp) {
    case DISAS_TOO_MANY:
        gen_goto_tb(dc, 0, dc->base.pc_next);
        return;

    case DISAS_EXIT:
        break;
    case DISAS_EXIT_NEXT:
        tcg_gen_movi_i32(cpu_pc, dc->base.pc_next);
        break;
    case DISAS_EXIT_JUMP:
        tcg_gen_mov_i32(cpu_pc, cpu_btarget);
        tcg_gen_discard_i32(cpu_btarget);
        break;

    case DISAS_JUMP:
        if (dc->jmp_dest != -1 && !(tb_cflags(dc->base.tb) & CF_NO_GOTO_TB)) {
            /* Direct jump. */
            tcg_gen_discard_i32(cpu_btarget);

            if (dc->jmp_cond != TCG_COND_ALWAYS) {
                /* Conditional direct jump. */
                TCGLabel *taken = gen_new_label();
                TCGv_i32 tmp = tcg_temp_new_i32();

                /*
                 * Copy bvalue to a temp now, so we can discard bvalue.
                 * This can avoid writing bvalue to memory when the
                 * delay slot cannot raise an exception.
                 */
                tcg_gen_mov_i32(tmp, cpu_bvalue);
                tcg_gen_discard_i32(cpu_bvalue);

                tcg_gen_brcondi_i32(dc->jmp_cond, tmp, 0, taken);
                gen_goto_tb(dc, 1, dc->base.pc_next);
                gen_set_label(taken);
            }
            gen_goto_tb(dc, 0, dc->jmp_dest);
            return;
        }

        /* Indirect jump (or direct jump w/ goto_tb disabled) */
        tcg_gen_mov_i32(cpu_pc, cpu_btarget);
        tcg_gen_discard_i32(cpu_btarget);
        tcg_gen_lookup_and_goto_ptr();
        return;

    default:
        g_assert_not_reached();
    }

    /* Finish DISAS_EXIT_* */
    if (unlikely(cs->singlestep_enabled)) {
        gen_raise_exception(dc, EXCP_DEBUG);
    } else {
        tcg_gen_exit_tb(NULL, 0);
    }
}

static const TranslatorOps mb_tr_ops = {
    .init_disas_context = mb_tr_init_disas_context,
    .tb_start           = mb_tr_tb_start,
    .insn_start         = mb_tr_insn_start,
    .translate_insn     = mb_tr_translate_insn,
    .tb_stop            = mb_tr_tb_stop,
};

void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
                           vaddr pc, void *host_pc)
{
    DisasContext dc;
    translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
}

void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
    CPUMBState *env = cpu_env(cs);
    uint32_t iflags;
    int i;

    qemu_fprintf(f, "pc=0x%08x msr=0x%05x mode=%s(saved=%s) eip=%d ie=%d\n",
                 env->pc, env->msr,
                 (env->msr & MSR_UM) ? "user" : "kernel",
                 (env->msr & MSR_UMS) ? "user" : "kernel",
                 (bool)(env->msr & MSR_EIP),
                 (bool)(env->msr & MSR_IE));

    iflags = env->iflags;
    qemu_fprintf(f, "iflags: 0x%08x", iflags);
    if (iflags & IMM_FLAG) {
        qemu_fprintf(f, " IMM(0x%08x)", env->imm);
    }
    if (iflags & BIMM_FLAG) {
        qemu_fprintf(f, " BIMM");
    }
    if (iflags & D_FLAG) {
        qemu_fprintf(f, " D(btarget=0x%08x)", env->btarget);
    }
    if (iflags & DRTI_FLAG) {
        qemu_fprintf(f, " DRTI");
    }
    if (iflags & DRTE_FLAG) {
        qemu_fprintf(f, " DRTE");
    }
    if (iflags & DRTB_FLAG) {
        qemu_fprintf(f, " DRTB");
    }
    if (iflags & ESR_ESS_FLAG) {
        qemu_fprintf(f, " ESR_ESS(0x%04x)", iflags & ESR_ESS_MASK);
    }

    qemu_fprintf(f, "\nesr=0x%04x fsr=0x%02x btr=0x%08x edr=0x%x\n"
                 "ear=0x" TARGET_FMT_lx " slr=0x%x shr=0x%x\n",
                 env->esr, env->fsr, env->btr, env->edr,
                 env->ear, env->slr, env->shr);

    for (i = 0; i < 32; i++) {
        qemu_fprintf(f, "r%2.2d=%08x%c",
                     i, env->regs[i], i % 4 == 3 ? '\n' : ' ');
    }
    qemu_fprintf(f, "\n");
}

void mb_tcg_init(void)
{
#define R(X)  { &cpu_R[X], offsetof(CPUMBState, regs[X]), "r" #X }
#define SP(X) { &cpu_##X, offsetof(CPUMBState, X), #X }

    static const struct {
        TCGv_i32 *var; int ofs; char name[8];
    } i32s[] = {
        /*
         * Note that r0 is handled specially in reg_for_read
         * and reg_for_write.  Nothing should touch cpu_R[0].
         * Leave that element NULL, which will assert quickly
         * inside the tcg generator functions.
         */
               R(1),  R(2),  R(3),  R(4),  R(5),  R(6),  R(7),
        R(8),  R(9),  R(10), R(11), R(12), R(13), R(14), R(15),
        R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
        R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),

        SP(pc),
        SP(msr),
        SP(msr_c),
        SP(imm),
        SP(iflags),
        SP(bvalue),
        SP(btarget),
        SP(res_val),
    };

#undef R
#undef SP

    for (int i = 0; i < ARRAY_SIZE(i32s); ++i) {
        *i32s[i].var =
          tcg_global_mem_new_i32(tcg_env, i32s[i].ofs, i32s[i].name);
    }

    cpu_res_addr =
        tcg_global_mem_new(tcg_env, offsetof(CPUMBState, res_addr), "res_addr");
}
