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

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <assert.h>

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
#include "microblaze-decode.h"
#include "qemu-common.h"

#define GEN_HELPER 1
#include "helper.h"

#define SIM_COMPAT 0
#define DISAS_GNU 1
#define DISAS_MB 1
#if DISAS_MB && !SIM_COMPAT
#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
#else
#  define LOG_DIS(...) do { } while (0)
#endif

#define D(x)

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

static TCGv env_debug;
static TCGv_ptr cpu_env;
static TCGv cpu_R[32];
static TCGv cpu_SR[18];
static TCGv env_imm;
static TCGv env_btaken;
static TCGv env_btarget;
static TCGv env_iflags;

#include "gen-icount.h"

/* This is the state at translation time.  */
typedef struct DisasContext {
    CPUState *env;
    target_ulong pc, ppc;
    target_ulong cache_pc;

    /* Decoder.  */
    int type_b;
    uint32_t ir;
    uint8_t opcode;
    uint8_t rd, ra, rb;
    uint16_t imm;

    unsigned int cpustate_changed;
    unsigned int delayed_branch;
    unsigned int tb_flags, synced_flags; /* tb dependent flags.  */
    unsigned int clear_imm;
    int is_jmp;

#define JMP_NOJMP    0
#define JMP_DIRECT   1
#define JMP_INDIRECT 2
    unsigned int jmp;
    uint32_t jmp_pc;

    int abort_at_next_insn;
    int nr_nops;
    struct TranslationBlock *tb;
    int singlestep_enabled;
} DisasContext;

const static char *regnames[] =
{
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
};

const static char *special_regnames[] =
{
    "rpc", "rmsr", "sr2", "sr3", "sr4", "sr5", "sr6", "sr7",
    "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
    "sr16", "sr17", "sr18"
};

/* Sign extend at translation time.  */
static inline int sign_extend(unsigned int val, unsigned int width)
{
        int sval;

        /* LSL.  */
        val <<= 31 - width;
        sval = val;
        /* ASR.  */
        sval >>= 31 - width;
        return sval;
}

static inline void t_sync_flags(DisasContext *dc)
{
    /* Synch the tb dependant flags between translator and runtime.  */
    if (dc->tb_flags != dc->synced_flags) {
        tcg_gen_movi_tl(env_iflags, dc->tb_flags);
        dc->synced_flags = dc->tb_flags;
    }
}

static inline void t_gen_raise_exception(DisasContext *dc, uint32_t index)
{
    TCGv_i32 tmp = tcg_const_i32(index);

    t_sync_flags(dc);
    tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
    gen_helper_raise_exception(tmp);
    tcg_temp_free_i32(tmp);
    dc->is_jmp = DISAS_UPDATE;
}

static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
{
    TranslationBlock *tb;
    tb = dc->tb;
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
        tcg_gen_goto_tb(n);
        tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
        tcg_gen_exit_tb((long)tb + n);
    } else {
        tcg_gen_movi_tl(cpu_SR[SR_PC], dest);
        tcg_gen_exit_tb(0);
    }
}

static inline TCGv *dec_alu_op_b(DisasContext *dc)
{
    if (dc->type_b) {
        if (dc->tb_flags & IMM_FLAG)
            tcg_gen_ori_tl(env_imm, env_imm, dc->imm);
        else
            tcg_gen_movi_tl(env_imm, (int32_t)((int16_t)dc->imm));
        return &env_imm;
    } else
        return &cpu_R[dc->rb];
}

static void dec_add(DisasContext *dc)
{
    unsigned int k, c;

    k = dc->opcode & 4;
    c = dc->opcode & 2;

    LOG_DIS("add%s%s%s r%d r%d r%d\n",
            dc->type_b ? "i" : "", k ? "k" : "", c ? "c" : "",
            dc->rd, dc->ra, dc->rb);

    if (k && !c && dc->rd)
        tcg_gen_add_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
    else if (dc->rd)
        gen_helper_addkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                         tcg_const_tl(k), tcg_const_tl(c));
    else {
        TCGv d = tcg_temp_new();
        gen_helper_addkc(d, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                         tcg_const_tl(k), tcg_const_tl(c));
        tcg_temp_free(d);
    }
}

static void dec_sub(DisasContext *dc)
{
    unsigned int u, cmp, k, c;

    u = dc->imm & 2;
    k = dc->opcode & 4;
    c = dc->opcode & 2;
    cmp = (dc->imm & 1) && (!dc->type_b) && k;

    if (cmp) {
        LOG_DIS("cmp%s r%d, r%d ir=%x\n", u ? "u" : "", dc->rd, dc->ra, dc->ir);
        if (dc->rd) {
            if (u)
                gen_helper_cmpu(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
            else
                gen_helper_cmp(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
        }
    } else {
        LOG_DIS("sub%s%s r%d, r%d r%d\n",
                 k ? "k" : "",  c ? "c" : "", dc->rd, dc->ra, dc->rb);

        if (!k || c) {
            TCGv t;
            t = tcg_temp_new();
            if (dc->rd)
                gen_helper_subkc(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                                 tcg_const_tl(k), tcg_const_tl(c));
            else
                gen_helper_subkc(t, cpu_R[dc->ra], *(dec_alu_op_b(dc)),
                                 tcg_const_tl(k), tcg_const_tl(c));
            tcg_temp_free(t);
        }
        else if (dc->rd)
            tcg_gen_sub_tl(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
    }
}

static void dec_pattern(DisasContext *dc)
{
    unsigned int mode;
    int l1;

    if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
          && !((dc->env->pvr.regs[2] & PVR2_USE_PCMP_INSTR))) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
    }

    mode = dc->opcode & 3;
    switch (mode) {
        case 0:
            /* pcmpbf.  */
            LOG_DIS("pcmpbf r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            if (dc->rd)
                gen_helper_pcmpbf(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
            break;
        case 2:
            LOG_DIS("pcmpeq r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            if (dc->rd) {
                TCGv t0 = tcg_temp_local_new();
                l1 = gen_new_label();
                tcg_gen_movi_tl(t0, 1);
                tcg_gen_brcond_tl(TCG_COND_EQ,
                                  cpu_R[dc->ra], cpu_R[dc->rb], l1);
                tcg_gen_movi_tl(t0, 0);
                gen_set_label(l1);
                tcg_gen_mov_tl(cpu_R[dc->rd], t0);
                tcg_temp_free(t0);
            }
            break;
        case 3:
            LOG_DIS("pcmpne r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            l1 = gen_new_label();
            if (dc->rd) {
                TCGv t0 = tcg_temp_local_new();
                tcg_gen_movi_tl(t0, 1);
                tcg_gen_brcond_tl(TCG_COND_NE,
                                  cpu_R[dc->ra], cpu_R[dc->rb], l1);
                tcg_gen_movi_tl(t0, 0);
                gen_set_label(l1);
                tcg_gen_mov_tl(cpu_R[dc->rd], t0);
                tcg_temp_free(t0);
            }
            break;
        default:
            cpu_abort(dc->env,
                      "unsupported pattern insn opcode=%x\n", dc->opcode);
            break;
    }
}

static void dec_and(DisasContext *dc)
{
    unsigned int not;

    if (!dc->type_b && (dc->imm & (1 << 10))) {
        dec_pattern(dc);
        return;
    }

    not = dc->opcode & (1 << 1);
    LOG_DIS("and%s\n", not ? "n" : "");

    if (!dc->rd)
        return;

    if (not) {
        TCGv t = tcg_temp_new();
        tcg_gen_not_tl(t, *(dec_alu_op_b(dc)));
        tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], t);
        tcg_temp_free(t);
    } else
        tcg_gen_and_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
}

static void dec_or(DisasContext *dc)
{
    if (!dc->type_b && (dc->imm & (1 << 10))) {
        dec_pattern(dc);
        return;
    }

    LOG_DIS("or r%d r%d r%d imm=%x\n", dc->rd, dc->ra, dc->rb, dc->imm);
    if (dc->rd)
        tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
}

static void dec_xor(DisasContext *dc)
{
    if (!dc->type_b && (dc->imm & (1 << 10))) {
        dec_pattern(dc);
        return;
    }

    LOG_DIS("xor r%d\n", dc->rd);
    if (dc->rd)
        tcg_gen_xor_tl(cpu_R[dc->rd], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
}

static void read_carry(DisasContext *dc, TCGv d)
{
    tcg_gen_shri_tl(d, cpu_SR[SR_MSR], 31);
}

static void write_carry(DisasContext *dc, TCGv v)
{
    TCGv t0 = tcg_temp_new();
    tcg_gen_shli_tl(t0, v, 31);
    tcg_gen_sari_tl(t0, t0, 31);
    tcg_gen_mov_tl(env_debug, t0);
    tcg_gen_andi_tl(t0, t0, (MSR_C | MSR_CC));
    tcg_gen_andi_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR],
                    ~(MSR_C | MSR_CC));
    tcg_gen_or_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], t0);
    tcg_temp_free(t0);
}


static inline void msr_read(DisasContext *dc, TCGv d)
{
    tcg_gen_mov_tl(d, cpu_SR[SR_MSR]);
}

static inline void msr_write(DisasContext *dc, TCGv v)
{
    dc->cpustate_changed = 1;
    tcg_gen_mov_tl(cpu_SR[SR_MSR], v);
    /* PVR, we have a processor version register.  */
    tcg_gen_ori_tl(cpu_SR[SR_MSR], cpu_SR[SR_MSR], (1 << 10));
}

static void dec_msr(DisasContext *dc)
{
    TCGv t0, t1;
    unsigned int sr, to, rn;
    int mem_index = cpu_mmu_index(dc->env);

    sr = dc->imm & ((1 << 14) - 1);
    to = dc->imm & (1 << 14);
    dc->type_b = 1;
    if (to)
        dc->cpustate_changed = 1;

    /* msrclr and msrset.  */
    if (!(dc->imm & (1 << 15))) {
        unsigned int clr = dc->ir & (1 << 16);

        LOG_DIS("msr%s r%d imm=%x\n", clr ? "clr" : "set",
                dc->rd, dc->imm);

        if (!(dc->env->pvr.regs[2] & PVR2_USE_MSR_INSTR)) {
            /* nop??? */
            return;
        }

        if ((dc->tb_flags & MSR_EE_FLAG)
            && mem_index == MMU_USER_IDX && (dc->imm != 4 && dc->imm != 0)) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
            return;
        }

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

        t0 = tcg_temp_new();
        t1 = tcg_temp_new();
        msr_read(dc, t0);
        tcg_gen_mov_tl(t1, *(dec_alu_op_b(dc)));

        if (clr) {
            tcg_gen_not_tl(t1, t1);
            tcg_gen_and_tl(t0, t0, t1);
        } else
            tcg_gen_or_tl(t0, t0, t1);
        msr_write(dc, t0);
        tcg_temp_free(t0);
        tcg_temp_free(t1);
	tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
        dc->is_jmp = DISAS_UPDATE;
        return;
    }

    if (to) {
        if ((dc->tb_flags & MSR_EE_FLAG)
             && mem_index == MMU_USER_IDX) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
            return;
        }
    }

#if !defined(CONFIG_USER_ONLY)
    /* Catch read/writes to the mmu block.  */
    if ((sr & ~0xff) == 0x1000) {
        sr &= 7;
        LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
        if (to)
            gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]);
        else
            gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr));
        return;
    }
#endif

    if (to) {
        LOG_DIS("m%ss sr%x r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
        switch (sr) {
            case 0:
                break;
            case 1:
                msr_write(dc, cpu_R[dc->ra]);
                break;
            case 0x3:
                tcg_gen_mov_tl(cpu_SR[SR_EAR], cpu_R[dc->ra]);
                break;
            case 0x5:
                tcg_gen_mov_tl(cpu_SR[SR_ESR], cpu_R[dc->ra]);
                break;
            case 0x7:
                /* Ignored at the moment.  */
                break;
            default:
                cpu_abort(dc->env, "unknown mts reg %x\n", sr);
                break;
        }
    } else {
        LOG_DIS("m%ss r%d sr%x imm=%x\n", to ? "t" : "f", dc->rd, sr, dc->imm);

        switch (sr) {
            case 0:
                tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);
                break;
            case 1:
                msr_read(dc, cpu_R[dc->rd]);
                break;
            case 0x3:
                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_EAR]);
                break;
            case 0x5:
                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_ESR]);
                break;
             case 0x7:
                tcg_gen_movi_tl(cpu_R[dc->rd], 0);
                break;
            case 0xb:
                tcg_gen_mov_tl(cpu_R[dc->rd], cpu_SR[SR_BTR]);
                break;
            case 0x2000:
            case 0x2001:
            case 0x2002:
            case 0x2003:
            case 0x2004:
            case 0x2005:
            case 0x2006:
            case 0x2007:
            case 0x2008:
            case 0x2009:
            case 0x200a:
            case 0x200b:
            case 0x200c:
                rn = sr & 0xf;
                tcg_gen_ld_tl(cpu_R[dc->rd],
                              cpu_env, offsetof(CPUState, pvr.regs[rn]));
                break;
            default:
                cpu_abort(dc->env, "unknown mfs reg %x\n", sr);
                break;
        }
    }

    if (dc->rd == 0) {
        tcg_gen_movi_tl(cpu_R[0], 0);
    }
}

/* 64-bit signed mul, lower result in d and upper in d2.  */
static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b)
{
    TCGv_i64 t0, t1;

    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();

    tcg_gen_ext_i32_i64(t0, a);
    tcg_gen_ext_i32_i64(t1, b);
    tcg_gen_mul_i64(t0, t0, t1);

    tcg_gen_trunc_i64_i32(d, t0);
    tcg_gen_shri_i64(t0, t0, 32);
    tcg_gen_trunc_i64_i32(d2, t0);

    tcg_temp_free_i64(t0);
    tcg_temp_free_i64(t1);
}

/* 64-bit unsigned muls, lower result in d and upper in d2.  */
static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b)
{
    TCGv_i64 t0, t1;

    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();

    tcg_gen_extu_i32_i64(t0, a);
    tcg_gen_extu_i32_i64(t1, b);
    tcg_gen_mul_i64(t0, t0, t1);

    tcg_gen_trunc_i64_i32(d, t0);
    tcg_gen_shri_i64(t0, t0, 32);
    tcg_gen_trunc_i64_i32(d2, t0);

    tcg_temp_free_i64(t0);
    tcg_temp_free_i64(t1);
}

/* Multiplier unit.  */
static void dec_mul(DisasContext *dc)
{
    TCGv d[2];
    unsigned int subcode;

    if ((dc->tb_flags & MSR_EE_FLAG)
         && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
         && !(dc->env->pvr.regs[0] & PVR0_USE_HW_MUL_MASK)) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }

    subcode = dc->imm & 3;
    d[0] = tcg_temp_new();
    d[1] = tcg_temp_new();

    if (dc->type_b) {
        LOG_DIS("muli r%d r%d %x\n", dc->rd, dc->ra, dc->imm);
        t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], *(dec_alu_op_b(dc)));
        goto done;
    }

    /* mulh, mulhsu and mulhu are not available if C_USE_HW_MUL is < 2.  */
    if (subcode >= 1 && subcode <= 3
        && !((dc->env->pvr.regs[2] & PVR2_USE_MUL64_MASK))) {
        /* nop??? */
    }

    switch (subcode) {
        case 0:
            LOG_DIS("mul r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            t_gen_mulu(cpu_R[dc->rd], d[1], cpu_R[dc->ra], cpu_R[dc->rb]);
            break;
        case 1:
            LOG_DIS("mulh r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
            break;
        case 2:
            LOG_DIS("mulhsu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            t_gen_muls(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
            break;
        case 3:
            LOG_DIS("mulhu r%d r%d r%d\n", dc->rd, dc->ra, dc->rb);
            t_gen_mulu(d[0], cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
            break;
        default:
            cpu_abort(dc->env, "unknown MUL insn %x\n", subcode);
            break;
    }
done:
    tcg_temp_free(d[0]);
    tcg_temp_free(d[1]);
}

/* Div unit.  */
static void dec_div(DisasContext *dc)
{
    unsigned int u;

    u = dc->imm & 2; 
    LOG_DIS("div\n");

    if ((dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
          && !((dc->env->pvr.regs[0] & PVR0_USE_DIV_MASK))) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
    }

    if (u)
        gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
    else
        gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
    if (!dc->rd)
        tcg_gen_movi_tl(cpu_R[dc->rd], 0);
}

static void dec_barrel(DisasContext *dc)
{
    TCGv t0;
    unsigned int s, t;

    if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
          && !(dc->env->pvr.regs[0] & PVR0_USE_BARREL_MASK)) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }

    s = dc->imm & (1 << 10);
    t = dc->imm & (1 << 9);

    LOG_DIS("bs%s%s r%d r%d r%d\n",
            s ? "l" : "r", t ? "a" : "l", dc->rd, dc->ra, dc->rb);

    t0 = tcg_temp_new();

    tcg_gen_mov_tl(t0, *(dec_alu_op_b(dc)));
    tcg_gen_andi_tl(t0, t0, 31);

    if (s)
        tcg_gen_shl_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
    else {
        if (t)
            tcg_gen_sar_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
        else
            tcg_gen_shr_tl(cpu_R[dc->rd], cpu_R[dc->ra], t0);
    }
}

static void dec_bit(DisasContext *dc)
{
    TCGv t0, t1;
    unsigned int op;
    int mem_index = cpu_mmu_index(dc->env);

    op = dc->ir & ((1 << 8) - 1);
    switch (op) {
        case 0x21:
            /* src.  */
            t0 = tcg_temp_new();

            LOG_DIS("src r%d r%d\n", dc->rd, dc->ra);
            tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
            if (dc->rd) {
                t1 = tcg_temp_new();
                read_carry(dc, t1);
                tcg_gen_shli_tl(t1, t1, 31);

                tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                tcg_gen_or_tl(cpu_R[dc->rd], cpu_R[dc->rd], t1);
                tcg_temp_free(t1);
            }

            /* Update carry.  */
            write_carry(dc, t0);
            tcg_temp_free(t0);
            break;

        case 0x1:
        case 0x41:
            /* srl.  */
            t0 = tcg_temp_new();
            LOG_DIS("srl r%d r%d\n", dc->rd, dc->ra);

            /* Update carry.  */
            tcg_gen_andi_tl(t0, cpu_R[dc->ra], 1);
            write_carry(dc, t0);
            tcg_temp_free(t0);
            if (dc->rd) {
                if (op == 0x41)
                    tcg_gen_shri_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
                else
                    tcg_gen_sari_tl(cpu_R[dc->rd], cpu_R[dc->ra], 1);
            }
            break;
        case 0x60:
            LOG_DIS("ext8s r%d r%d\n", dc->rd, dc->ra);
            tcg_gen_ext8s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
            break;
        case 0x61:
            LOG_DIS("ext16s r%d r%d\n", dc->rd, dc->ra);
            tcg_gen_ext16s_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
            break;
        case 0x64:
            /* wdc.  */
            LOG_DIS("wdc r%d\n", dc->ra);
            if ((dc->tb_flags & MSR_EE_FLAG)
                 && mem_index == MMU_USER_IDX) {
                tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
                t_gen_raise_exception(dc, EXCP_HW_EXCP);
                return;
            }
            break;
        case 0x68:
            /* wic.  */
            LOG_DIS("wic r%d\n", dc->ra);
            if ((dc->tb_flags & MSR_EE_FLAG)
                 && mem_index == MMU_USER_IDX) {
                tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
                t_gen_raise_exception(dc, EXCP_HW_EXCP);
                return;
            }
            break;
        default:
            cpu_abort(dc->env, "unknown bit oc=%x op=%x rd=%d ra=%d rb=%d\n",
                     dc->pc, op, dc->rd, dc->ra, dc->rb);
            break;
    }
}

static inline void sync_jmpstate(DisasContext *dc)
{
    if (dc->jmp == JMP_DIRECT) {
            dc->jmp = JMP_INDIRECT;
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
    }
}

static void dec_imm(DisasContext *dc)
{
    LOG_DIS("imm %x\n", dc->imm << 16);
    tcg_gen_movi_tl(env_imm, (dc->imm << 16));
    dc->tb_flags |= IMM_FLAG;
    dc->clear_imm = 0;
}

static inline void gen_load(DisasContext *dc, TCGv dst, TCGv addr,
                            unsigned int size)
{
    int mem_index = cpu_mmu_index(dc->env);

    if (size == 1) {
        tcg_gen_qemu_ld8u(dst, addr, mem_index);
    } else if (size == 2) {
        tcg_gen_qemu_ld16u(dst, addr, mem_index);
    } else if (size == 4) {
        tcg_gen_qemu_ld32u(dst, addr, mem_index);
    } else
        cpu_abort(dc->env, "Incorrect load size %d\n", size);
}

static inline TCGv *compute_ldst_addr(DisasContext *dc, TCGv *t)
{
    unsigned int extimm = dc->tb_flags & IMM_FLAG;

    /* Treat the fast cases first.  */
    if (!dc->type_b) {
        *t = tcg_temp_new();
        tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
        return t;
    }
    /* Immediate.  */
    if (!extimm) {
        if (dc->imm == 0) {
            return &cpu_R[dc->ra];
        }
        *t = tcg_temp_new();
        tcg_gen_movi_tl(*t, (int32_t)((int16_t)dc->imm));
        tcg_gen_add_tl(*t, cpu_R[dc->ra], *t);
    } else {
        *t = tcg_temp_new();
        tcg_gen_add_tl(*t, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
    }

    return t;
}

static void dec_load(DisasContext *dc)
{
    TCGv t, *addr;
    unsigned int size;

    size = 1 << (dc->opcode & 3);
    if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }

    LOG_DIS("l %x %d\n", dc->opcode, size);
    t_sync_flags(dc);
    addr = compute_ldst_addr(dc, &t);

    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
    sync_jmpstate(dc);

    /* Verify alignment if needed.  */
    if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
        TCGv v = tcg_temp_new();

        /*
         * Microblaze gives MMU faults priority over faults due to
         * unaligned addresses. That's why we speculatively do the load
         * into v. If the load succeeds, we verify alignment of the
         * address and if that succeeds we write into the destination reg.
         */
        gen_load(dc, v, *addr, size);

        tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
                            tcg_const_tl(0), tcg_const_tl(size - 1));
        if (dc->rd)
            tcg_gen_mov_tl(cpu_R[dc->rd], v);
        tcg_temp_free(v);
    } else {
        if (dc->rd) {
            gen_load(dc, cpu_R[dc->rd], *addr, size);
        } else {
            gen_load(dc, env_imm, *addr, size);
        }
    }

    if (addr == &t)
        tcg_temp_free(t);
}

static void gen_store(DisasContext *dc, TCGv addr, TCGv val,
                      unsigned int size)
{
    int mem_index = cpu_mmu_index(dc->env);

    if (size == 1)
        tcg_gen_qemu_st8(val, addr, mem_index);
    else if (size == 2) {
        tcg_gen_qemu_st16(val, addr, mem_index);
    } else if (size == 4) {
        tcg_gen_qemu_st32(val, addr, mem_index);
    } else
        cpu_abort(dc->env, "Incorrect store size %d\n", size);
}

static void dec_store(DisasContext *dc)
{
    TCGv t, *addr;
    unsigned int size;

    size = 1 << (dc->opcode & 3);

    if (size > 4 && (dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }

    LOG_DIS("s%d%s\n", size, dc->type_b ? "i" : "");
    t_sync_flags(dc);
    /* If we get a fault on a dslot, the jmpstate better be in sync.  */
    sync_jmpstate(dc);
    addr = compute_ldst_addr(dc, &t);

    gen_store(dc, *addr, cpu_R[dc->rd], size);

    /* Verify alignment if needed.  */
    if ((dc->env->pvr.regs[2] & PVR2_UNALIGNED_EXC_MASK) && size > 1) {
        tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
        /* FIXME: if the alignment is wrong, we should restore the value
         *        in memory.
         */
        gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
                            tcg_const_tl(1), tcg_const_tl(size - 1));
    }

    if (addr == &t)
        tcg_temp_free(t);
}

static inline void eval_cc(DisasContext *dc, unsigned int cc,
                           TCGv d, TCGv a, TCGv b)
{
    int l1;

    switch (cc) {
        case CC_EQ:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_EQ, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        case CC_NE:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_NE, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        case CC_LT:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_LT, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        case CC_LE:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_LE, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        case CC_GE:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_GE, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        case CC_GT:
            l1 = gen_new_label();
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_brcond_tl(TCG_COND_GT, a, b, l1);
            tcg_gen_movi_tl(env_btaken, 0);
            gen_set_label(l1);
            break;
        default:
            cpu_abort(dc->env, "Unknown condition code %x.\n", cc);
            break;
    }
}

static void eval_cond_jmp(DisasContext *dc, TCGv pc_true, TCGv pc_false)
{
    int l1;

    l1 = gen_new_label();
    /* Conditional jmp.  */
    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_false);
    tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
    tcg_gen_mov_tl(cpu_SR[SR_PC], pc_true);
    gen_set_label(l1);
}

static void dec_bcc(DisasContext *dc)
{
    unsigned int cc;
    unsigned int dslot;

    cc = EXTRACT_FIELD(dc->ir, 21, 23);
    dslot = dc->ir & (1 << 25);
    LOG_DIS("bcc%s r%d %x\n", dslot ? "d" : "", dc->ra, dc->imm);

    dc->delayed_branch = 1;
    if (dslot) {
        dc->delayed_branch = 2;
        dc->tb_flags |= D_FLAG;
        tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                      cpu_env, offsetof(CPUState, bimm));
    }

    tcg_gen_movi_tl(env_btarget, dc->pc);
    tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
    eval_cc(dc, cc, env_btaken, cpu_R[dc->ra], tcg_const_tl(0));
    dc->jmp = JMP_INDIRECT;
}

static void dec_br(DisasContext *dc)
{
    unsigned int dslot, link, abs;

    dslot = dc->ir & (1 << 20);
    abs = dc->ir & (1 << 19);
    link = dc->ir & (1 << 18);
    LOG_DIS("br%s%s%s%s imm=%x\n",
             abs ? "a" : "", link ? "l" : "",
             dc->type_b ? "i" : "", dslot ? "d" : "",
             dc->imm);

    dc->delayed_branch = 1;
    if (dslot) {
        dc->delayed_branch = 2;
        dc->tb_flags |= D_FLAG;
        tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                      cpu_env, offsetof(CPUState, bimm));
    }
    if (link && dc->rd)
        tcg_gen_movi_tl(cpu_R[dc->rd], dc->pc);

    dc->jmp = JMP_INDIRECT;
    if (abs) {
        tcg_gen_movi_tl(env_btaken, 1);
        tcg_gen_mov_tl(env_btarget, *(dec_alu_op_b(dc)));
        if (link && !(dc->tb_flags & IMM_FLAG)
            && (dc->imm == 8 || dc->imm == 0x18))
            t_gen_raise_exception(dc, EXCP_BREAK);
        if (dc->imm == 0)
            t_gen_raise_exception(dc, EXCP_DEBUG);
    } else {
        if (dc->tb_flags & IMM_FLAG) {
            tcg_gen_movi_tl(env_btaken, 1);
            tcg_gen_movi_tl(env_btarget, dc->pc);
            tcg_gen_add_tl(env_btarget, env_btarget, *(dec_alu_op_b(dc)));
        } else {
            dc->jmp = JMP_DIRECT;
            dc->jmp_pc = dc->pc + (int32_t)((int16_t)dc->imm);
        }
    }
}

static inline void do_rti(DisasContext *dc)
{
    TCGv t0, t1;
    t0 = tcg_temp_new();
    t1 = tcg_temp_new();
    tcg_gen_shri_tl(t0, cpu_SR[SR_MSR], 1);
    tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_IE);
    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));

    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
    tcg_gen_or_tl(t1, t1, t0);
    msr_write(dc, t1);
    tcg_temp_free(t1);
    tcg_temp_free(t0);
    dc->tb_flags &= ~DRTI_FLAG;
}

static inline void do_rtb(DisasContext *dc)
{
    TCGv t0, t1;
    t0 = tcg_temp_new();
    t1 = tcg_temp_new();
    tcg_gen_andi_tl(t1, cpu_SR[SR_MSR], ~MSR_BIP);
    tcg_gen_shri_tl(t0, t1, 1);
    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));

    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
    tcg_gen_or_tl(t1, t1, t0);
    msr_write(dc, t1);
    tcg_temp_free(t1);
    tcg_temp_free(t0);
    dc->tb_flags &= ~DRTB_FLAG;
}

static inline void do_rte(DisasContext *dc)
{
    TCGv t0, t1;
    t0 = tcg_temp_new();
    t1 = tcg_temp_new();

    tcg_gen_ori_tl(t1, cpu_SR[SR_MSR], MSR_EE);
    tcg_gen_andi_tl(t1, t1, ~MSR_EIP);
    tcg_gen_shri_tl(t0, t1, 1);
    tcg_gen_andi_tl(t0, t0, (MSR_VM | MSR_UM));

    tcg_gen_andi_tl(t1, t1, ~(MSR_VM | MSR_UM));
    tcg_gen_or_tl(t1, t1, t0);
    msr_write(dc, t1);
    tcg_temp_free(t1);
    tcg_temp_free(t0);
    dc->tb_flags &= ~DRTE_FLAG;
}

static void dec_rts(DisasContext *dc)
{
    unsigned int b_bit, i_bit, e_bit;
    int mem_index = cpu_mmu_index(dc->env);

    i_bit = dc->ir & (1 << 21);
    b_bit = dc->ir & (1 << 22);
    e_bit = dc->ir & (1 << 23);

    dc->delayed_branch = 2;
    dc->tb_flags |= D_FLAG;
    tcg_gen_st_tl(tcg_const_tl(dc->type_b && (dc->tb_flags & IMM_FLAG)),
                  cpu_env, offsetof(CPUState, bimm));

    if (i_bit) {
        LOG_DIS("rtid ir=%x\n", dc->ir);
        if ((dc->tb_flags & MSR_EE_FLAG)
             && mem_index == MMU_USER_IDX) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
        }
        dc->tb_flags |= DRTI_FLAG;
    } else if (b_bit) {
        LOG_DIS("rtbd ir=%x\n", dc->ir);
        if ((dc->tb_flags & MSR_EE_FLAG)
             && mem_index == MMU_USER_IDX) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
        }
        dc->tb_flags |= DRTB_FLAG;
    } else if (e_bit) {
        LOG_DIS("rted ir=%x\n", dc->ir);
        if ((dc->tb_flags & MSR_EE_FLAG)
             && mem_index == MMU_USER_IDX) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_PRIVINSN);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
        }
        dc->tb_flags |= DRTE_FLAG;
    } else
        LOG_DIS("rts ir=%x\n", dc->ir);

    tcg_gen_movi_tl(env_btaken, 1);
    tcg_gen_add_tl(env_btarget, cpu_R[dc->ra], *(dec_alu_op_b(dc)));
}

static void dec_fpu(DisasContext *dc)
{
    if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
          && !((dc->env->pvr.regs[2] & PVR2_USE_FPU_MASK))) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_FPU);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }

    qemu_log ("unimplemented FPU insn pc=%x opc=%x\n", dc->pc, dc->opcode);
    dc->abort_at_next_insn = 1;
}

static void dec_null(DisasContext *dc)
{
    if ((dc->tb_flags & MSR_EE_FLAG)
          && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)) {
        tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
        t_gen_raise_exception(dc, EXCP_HW_EXCP);
        return;
    }
    qemu_log ("unknown insn pc=%x opc=%x\n", dc->pc, dc->opcode);
    dc->abort_at_next_insn = 1;
}

static struct decoder_info {
    struct {
        uint32_t bits;
        uint32_t mask;
    };
    void (*dec)(DisasContext *dc);
} decinfo[] = {
    {DEC_ADD, dec_add},
    {DEC_SUB, dec_sub},
    {DEC_AND, dec_and},
    {DEC_XOR, dec_xor},
    {DEC_OR, dec_or},
    {DEC_BIT, dec_bit},
    {DEC_BARREL, dec_barrel},
    {DEC_LD, dec_load},
    {DEC_ST, dec_store},
    {DEC_IMM, dec_imm},
    {DEC_BR, dec_br},
    {DEC_BCC, dec_bcc},
    {DEC_RTS, dec_rts},
    {DEC_FPU, dec_fpu},
    {DEC_MUL, dec_mul},
    {DEC_DIV, dec_div},
    {DEC_MSR, dec_msr},
    {{0, 0}, dec_null}
};

static inline void decode(DisasContext *dc)
{
    uint32_t ir;
    int i;

    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
        tcg_gen_debug_insn_start(dc->pc);

    dc->ir = ir = ldl_code(dc->pc);
    LOG_DIS("%8.8x\t", dc->ir);

    if (dc->ir)
        dc->nr_nops = 0;
    else {
        if ((dc->tb_flags & MSR_EE_FLAG)
              && (dc->env->pvr.regs[2] & PVR2_ILL_OPCODE_EXC_MASK)
              && (dc->env->pvr.regs[2] & PVR2_OPCODE_0x0_ILL_MASK)) {
            tcg_gen_movi_tl(cpu_SR[SR_ESR], ESR_EC_ILLEGAL_OP);
            t_gen_raise_exception(dc, EXCP_HW_EXCP);
            return;
        }

        LOG_DIS("nr_nops=%d\t", dc->nr_nops);
        dc->nr_nops++;
        if (dc->nr_nops > 4)
            cpu_abort(dc->env, "fetching nop sequence\n");
    }
    /* bit 2 seems to indicate insn type.  */
    dc->type_b = ir & (1 << 29);

    dc->opcode = EXTRACT_FIELD(ir, 26, 31);
    dc->rd = EXTRACT_FIELD(ir, 21, 25);
    dc->ra = EXTRACT_FIELD(ir, 16, 20);
    dc->rb = EXTRACT_FIELD(ir, 11, 15);
    dc->imm = EXTRACT_FIELD(ir, 0, 15);

    /* Large switch for all insns.  */
    for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {
            decinfo[i].dec(dc);
            break;
        }
    }
}

static void check_breakpoint(CPUState *env, DisasContext *dc)
{
    CPUBreakpoint *bp;

    if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
        TAILQ_FOREACH(bp, &env->breakpoints, entry) {
            if (bp->pc == dc->pc) {
                t_gen_raise_exception(dc, EXCP_DEBUG);
                dc->is_jmp = DISAS_UPDATE;
             }
        }
    }
}

/* generate intermediate code for basic block 'tb'.  */
static void
gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                               int search_pc)
{
    uint16_t *gen_opc_end;
    uint32_t pc_start;
    int j, lj;
    struct DisasContext ctx;
    struct DisasContext *dc = &ctx;
    uint32_t next_page_start, org_flags;
    target_ulong npc;
    int num_insns;
    int max_insns;

    qemu_log_try_set_file(stderr);

    pc_start = tb->pc;
    dc->env = env;
    dc->tb = tb;
    org_flags = dc->synced_flags = dc->tb_flags = tb->flags;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    dc->is_jmp = DISAS_NEXT;
    dc->jmp = 0;
    dc->delayed_branch = !!(dc->tb_flags & D_FLAG);
    dc->ppc = pc_start;
    dc->pc = pc_start;
    dc->cache_pc = -1;
    dc->singlestep_enabled = env->singlestep_enabled;
    dc->cpustate_changed = 0;
    dc->abort_at_next_insn = 0;
    dc->nr_nops = 0;

    if (pc_start & 3)
        cpu_abort(env, "Microblaze: unaligned PC=%x\n", pc_start);

    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
#if !SIM_COMPAT
        qemu_log("--------------\n");
        log_cpu_state(env, 0);
#endif
    }

    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
    lj = -1;
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0)
        max_insns = CF_COUNT_MASK;

    gen_icount_start();
    do
    {
#if SIM_COMPAT
        if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
            tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
            gen_helper_debug();
        }
#endif
        check_breakpoint(env, dc);

        if (search_pc) {
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j)
                    gen_opc_instr_start[lj++] = 0;
            }
            gen_opc_pc[lj] = dc->pc;
            gen_opc_instr_start[lj] = 1;
                        gen_opc_icount[lj] = num_insns;
        }

        /* Pretty disas.  */
        LOG_DIS("%8.8x:\t", dc->pc);

        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
            gen_io_start();

        dc->clear_imm = 1;
	decode(dc);
        if (dc->clear_imm)
            dc->tb_flags &= ~IMM_FLAG;
        dc->ppc = dc->pc;
        dc->pc += 4;
        num_insns++;

        if (dc->delayed_branch) {
            dc->delayed_branch--;
            if (!dc->delayed_branch) {
                if (dc->tb_flags & DRTI_FLAG)
                    do_rti(dc);
                 if (dc->tb_flags & DRTB_FLAG)
                    do_rtb(dc);
                if (dc->tb_flags & DRTE_FLAG)
                    do_rte(dc);
                /* Clear the delay slot flag.  */
                dc->tb_flags &= ~D_FLAG;
                /* If it is a direct jump, try direct chaining.  */
                if (dc->jmp != JMP_DIRECT) {
                    eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc));
                    dc->is_jmp = DISAS_JUMP;
                }
                break;
            }
        }
        if (env->singlestep_enabled)
            break;
    } while (!dc->is_jmp && !dc->cpustate_changed
         && gen_opc_ptr < gen_opc_end
                 && !singlestep
         && (dc->pc < next_page_start)
                 && num_insns < max_insns);

    npc = dc->pc;
    if (dc->jmp == JMP_DIRECT) {
        if (dc->tb_flags & D_FLAG) {
            dc->is_jmp = DISAS_UPDATE;
            tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
            sync_jmpstate(dc);
        } else
            npc = dc->jmp_pc;
    }

    if (tb->cflags & CF_LAST_IO)
        gen_io_end();
    /* Force an update if the per-tb cpu state has changed.  */
    if (dc->is_jmp == DISAS_NEXT
        && (dc->cpustate_changed || org_flags != dc->tb_flags)) {
        dc->is_jmp = DISAS_UPDATE;
        tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
    }
    t_sync_flags(dc);

    if (unlikely(env->singlestep_enabled)) {
        t_gen_raise_exception(dc, EXCP_DEBUG);
        if (dc->is_jmp == DISAS_NEXT)
            tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
    } else {
        switch(dc->is_jmp) {
            case DISAS_NEXT:
                gen_goto_tb(dc, 1, npc);
                break;
            default:
            case DISAS_JUMP:
            case DISAS_UPDATE:
                /* indicate that the hash table must be used
                   to find the next TB */
                tcg_gen_exit_tb(0);
                break;
            case DISAS_TB_JUMP:
                /* nothing more to generate */
                break;
        }
    }
    gen_icount_end(tb, num_insns);
    *gen_opc_ptr = INDEX_op_end;
    if (search_pc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
    } else {
        tb->size = dc->pc - pc_start;
                tb->icount = num_insns;
    }

#ifdef DEBUG_DISAS
#if !SIM_COMPAT
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        qemu_log("\n");
#if DISAS_GNU
        log_target_disas(pc_start, dc->pc - pc_start, 0);
#endif
        qemu_log("\nisize=%d osize=%zd\n",
            dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
    }
#endif
#endif
    assert(!dc->abort_at_next_insn);
}

void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
{
    gen_intermediate_code_internal(env, tb, 0);
}

void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
{
    gen_intermediate_code_internal(env, tb, 1);
}

void cpu_dump_state (CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                     int flags)
{
    int i;

    if (!env || !f)
        return;

    cpu_fprintf(f, "IN: PC=%x %s\n",
                env->sregs[SR_PC], lookup_symbol(env->sregs[SR_PC]));
    cpu_fprintf(f, "rmsr=%x resr=%x debug[%x] imm=%x iflags=%x\n",
             env->sregs[SR_MSR], env->sregs[SR_ESR],
             env->debug, env->imm, env->iflags);
    cpu_fprintf(f, "btaken=%d btarget=%x mode=%s(saved=%s)\n",
             env->btaken, env->btarget,
             (env->sregs[SR_MSR] & MSR_UM) ? "user" : "kernel",
             (env->sregs[SR_MSR] & MSR_UMS) ? "user" : "kernel");
    for (i = 0; i < 32; i++) {
        cpu_fprintf(f, "r%2.2d=%8.8x ", i, env->regs[i]);
        if ((i + 1) % 4 == 0)
            cpu_fprintf(f, "\n");
        }
    cpu_fprintf(f, "\n\n");
}

CPUState *cpu_mb_init (const char *cpu_model)
{
    CPUState *env;
    static int tcg_initialized = 0;
    int i;

    env = qemu_mallocz(sizeof(CPUState));

    cpu_exec_init(env);
    cpu_reset(env);

    env->pvr.regs[0] = PVR0_PVR_FULL_MASK \
                       | PVR0_USE_BARREL_MASK \
                       | PVR0_USE_DIV_MASK \
                       | PVR0_USE_HW_MUL_MASK \
                       | PVR0_USE_EXC_MASK \
                       | PVR0_USE_ICACHE_MASK \
                       | PVR0_USE_DCACHE_MASK \
                       | PVR0_USE_MMU \
                       | (0xb << 8);
    env->pvr.regs[2] = PVR2_D_OPB_MASK \
                        | PVR2_D_LMB_MASK \
                        | PVR2_I_OPB_MASK \
                        | PVR2_I_LMB_MASK \
                        | PVR2_USE_MSR_INSTR \
                        | PVR2_USE_PCMP_INSTR \
                        | PVR2_USE_BARREL_MASK \
                        | PVR2_USE_DIV_MASK \
                        | PVR2_USE_HW_MUL_MASK \
                        | PVR2_USE_MUL64_MASK \
                        | 0;
    env->pvr.regs[10] = 0x0c000000; /* Default to spartan 3a dsp family.  */
    env->pvr.regs[11] = PVR11_USE_MMU | (16 << 17);
#if !defined(CONFIG_USER_ONLY)
    env->mmu.c_mmu = 3;
    env->mmu.c_mmu_tlb_access = 3;
    env->mmu.c_mmu_zones = 16;
#endif

    if (tcg_initialized)
        return env;

    tcg_initialized = 1;

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

    env_debug = tcg_global_mem_new(TCG_AREG0, 
                    offsetof(CPUState, debug),
                    "debug0");
    env_iflags = tcg_global_mem_new(TCG_AREG0, 
                    offsetof(CPUState, iflags),
                    "iflags");
    env_imm = tcg_global_mem_new(TCG_AREG0, 
                    offsetof(CPUState, imm),
                    "imm");
    env_btarget = tcg_global_mem_new(TCG_AREG0,
                     offsetof(CPUState, btarget),
                     "btarget");
    env_btaken = tcg_global_mem_new(TCG_AREG0,
                     offsetof(CPUState, btaken),
                     "btaken");
    for (i = 0; i < ARRAY_SIZE(cpu_R); i++) {
        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
                          offsetof(CPUState, regs[i]),
                          regnames[i]);
    }
    for (i = 0; i < ARRAY_SIZE(cpu_SR); i++) {
        cpu_SR[i] = tcg_global_mem_new(TCG_AREG0,
                          offsetof(CPUState, sregs[i]),
                          special_regnames[i]);
    }
#define GEN_HELPER 2
#include "helper.h"

    return env;
}

void cpu_reset (CPUState *env)
{
    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
        log_cpu_state(env, 0);
    }

    memset(env, 0, offsetof(CPUMBState, breakpoints));
    tlb_flush(env, 1);

    env->sregs[SR_MSR] = 0;
#if defined(CONFIG_USER_ONLY)
    /* start in user mode with interrupts enabled.  */
    env->pvr.regs[10] = 0x0c000000; /* Spartan 3a dsp.  */
#else
    mmu_init(&env->mmu);
#endif
}

void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
                 unsigned long searched_pc, int pc_pos, void *puc)
{
    env->sregs[SR_PC] = gen_opc_pc[pc_pos];
}
