/*
 *  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 "disas/disas.h"
#include "exec/exec-all.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;

    /* TCG op of the current insn_start.  */
    TCGOp *insn_start;

    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->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->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);
    dc->insn_start = tcg_last_op();
}

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 = cpu_ldl_code(cpu_env(cs), 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 void mb_tr_disas_log(const DisasContextBase *dcb,
                            CPUState *cs, FILE *logfile)
{
    fprintf(logfile, "IN: %s\n", lookup_symbol(dcb->pc_first));
    target_disas(logfile, cs, dcb->pc_first, dcb->tb->size);
}

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,
    .disas_log          = mb_tr_disas_log,
};

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