/*
 *  CRISv10 emulation for qemu: main translation routines.
 *
 *  Copyright (c) 2010 AXIS Communications AB
 *  Written by 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 "crisv10-decode.h"

static const char *regnames_v10[] =
{
    "$r0", "$r1", "$r2", "$r3",
    "$r4", "$r5", "$r6", "$r7",
    "$r8", "$r9", "$r10", "$r11",
    "$r12", "$r13", "$sp", "$pc",
};

static const char *pregnames_v10[] =
{
    "$bz", "$vr", "$p2", "$p3",
    "$wz", "$ccr", "$p6-prefix", "$mof",
    "$dz", "$ibr", "$irp", "$srp",
    "$bar", "$dccr", "$brp", "$usp",
};

/* We need this table to handle preg-moves with implicit width.  */
static int preg_sizes_v10[] = {
    1, /* bz.  */
    1, /* vr.  */
    1, /* pid. */
    1, /* srs. */
    2, /* wz.  */
    2, 2, 4,
    4, 4, 4, 4,
    4, 4, 4, 4,
};

static inline int dec10_size(unsigned int size)
{
    size++;
    if (size == 3)
        size++;
    return size;
}

static inline void cris_illegal_insn(DisasContext *dc)
{
    qemu_log("illegal insn at pc=%x\n", dc->pc);
    t_gen_raise_exception(EXCP_BREAK);
}

static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
                       unsigned int size, int mem_index)
{
    int l1 = gen_new_label();
    TCGv taddr = tcg_temp_local_new();
    TCGv tval = tcg_temp_local_new();
    TCGv t1 = tcg_temp_local_new();
    dc->postinc = 0;
    cris_evaluate_flags(dc);

    tcg_gen_mov_tl(taddr, addr);
    tcg_gen_mov_tl(tval, val);

    /* Store only if F flag isn't set */
    tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
    tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
    if (size == 1) {
        tcg_gen_qemu_st8(tval, taddr, mem_index);
    } else if (size == 2) {
        tcg_gen_qemu_st16(tval, taddr, mem_index);
    } else {
        tcg_gen_qemu_st32(tval, taddr, mem_index);
    }
    gen_set_label(l1);
    tcg_gen_shri_tl(t1, t1, 1);  /* shift F to P position */
    tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
    tcg_temp_free(t1);
    tcg_temp_free(tval);
    tcg_temp_free(taddr);
}

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

    /* If we get a fault on a delayslot we must keep the jmp state in
       the cpu-state to be able to re-execute the jmp.  */
    if (dc->delayed_branch == 1) {
        cris_store_direct_jmp(dc);
    }

    /* Conditional writes. We only support the kind were X is known
       at translation time.  */
    if (dc->flagx_known && dc->flags_x) {
        gen_store_v10_conditional(dc, addr, val, size, mem_index);
        return;
    }

    if (size == 1) {
        tcg_gen_qemu_st8(val, addr, mem_index);
    } else if (size == 2) {
        tcg_gen_qemu_st16(val, addr, mem_index);
    } else {
        tcg_gen_qemu_st32(val, addr, mem_index);
    }
}


/* Prefix flag and register are used to handle the more complex
   addressing modes.  */
static void cris_set_prefix(DisasContext *dc)
{
    dc->clear_prefix = 0;
    dc->tb_flags |= PFIX_FLAG;
    tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], PFIX_FLAG);

    /* prefix insns dont clear the x flag.  */
    dc->clear_x = 0;
    cris_lock_irq(dc);
}

static void crisv10_prepare_memaddr(DisasContext *dc,
                                    TCGv addr, unsigned int size)
{
    if (dc->tb_flags & PFIX_FLAG) {
        tcg_gen_mov_tl(addr, cpu_PR[PR_PREFIX]);
    } else {
        tcg_gen_mov_tl(addr, cpu_R[dc->src]);
    }
}

static unsigned int crisv10_post_memaddr(DisasContext *dc, unsigned int size)
{
    unsigned int insn_len = 0;

    if (dc->tb_flags & PFIX_FLAG) {
        if (dc->mode == CRISV10_MODE_AUTOINC) {
            tcg_gen_mov_tl(cpu_R[dc->src], cpu_PR[PR_PREFIX]);
        }
    } else {
        if (dc->mode == CRISV10_MODE_AUTOINC) {
            if (dc->src == 15) {
                insn_len += size & ~1;
            } else {
                tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], size);
            }
        }
    }
    return insn_len;
}

static int dec10_prep_move_m(DisasContext *dc, int s_ext, int memsize,
                           TCGv dst)
{
    unsigned int rs;
    uint32_t imm;
    int is_imm;
    int insn_len = 0;

    rs = dc->src;
    is_imm = rs == 15 && !(dc->tb_flags & PFIX_FLAG);
    LOG_DIS("rs=%d rd=%d is_imm=%d mode=%d pfix=%d\n",
             rs, dc->dst, is_imm, dc->mode, dc->tb_flags & PFIX_FLAG);

    /* Load [$rs] onto T1.  */
    if (is_imm) {
        if (memsize != 4) {
            if (s_ext) {
                if (memsize == 1)
                    imm = ldsb_code(dc->pc + 2);
                else
                    imm = ldsw_code(dc->pc + 2);
            } else {
                if (memsize == 1)
                    imm = ldub_code(dc->pc + 2);
                else
                    imm = lduw_code(dc->pc + 2);
            }
        } else
            imm = ldl_code(dc->pc + 2);

        tcg_gen_movi_tl(dst, imm);

        if (dc->mode == CRISV10_MODE_AUTOINC) {
            insn_len += memsize;
            if (memsize == 1)
                insn_len++;
            tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len);
        }
    } else {
        TCGv addr;

        addr = tcg_temp_new();
        cris_flush_cc_state(dc);
        crisv10_prepare_memaddr(dc, addr, memsize);
        gen_load(dc, dst, addr, memsize, 0);
        if (s_ext)
            t_gen_sext(dst, dst, memsize);
        else
            t_gen_zext(dst, dst, memsize);
        insn_len += crisv10_post_memaddr(dc, memsize);
        tcg_temp_free(addr);
    }

    if (dc->mode == CRISV10_MODE_INDIRECT && (dc->tb_flags & PFIX_FLAG)) {
        dc->dst = dc->src;
    }
    return insn_len;
}

static unsigned int dec10_quick_imm(DisasContext *dc)
{
    int32_t imm, simm;
    int op;

    /* sign extend.  */
    imm = dc->ir & ((1 << 6) - 1);
    simm = (int8_t) (imm << 2);
    simm >>= 2;
    switch (dc->opcode) {
        case CRISV10_QIMM_BDAP_R0:
        case CRISV10_QIMM_BDAP_R1:
        case CRISV10_QIMM_BDAP_R2:
        case CRISV10_QIMM_BDAP_R3:
            simm = (int8_t)dc->ir;
            LOG_DIS("bdap %d $r%d\n", simm, dc->dst);
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
            cris_set_prefix(dc);
            if (dc->dst == 15) {
                tcg_gen_movi_tl(cpu_PR[PR_PREFIX], dc->pc + 2 + simm);
            } else {
                tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);
            }
            break;

        case CRISV10_QIMM_MOVEQ:
            LOG_DIS("moveq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_CMPQ:
            LOG_DIS("cmpq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_ADDQ:
            LOG_DIS("addq %d, $r%d\n", imm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_ADD, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_ANDQ:
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_AND, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;
        case CRISV10_QIMM_ASHQ:
            LOG_DIS("ashq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            op = imm & (1 << 5);
            imm &= 0x1f;
            if (op) {
                cris_alu(dc, CC_OP_ASR, cpu_R[dc->dst],
                          cpu_R[dc->dst], tcg_const_tl(imm), 4);
            } else {
                /* BTST */
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
                           tcg_const_tl(imm), cpu_PR[PR_CCS]);
            }
            break;
        case CRISV10_QIMM_LSHQ:
            LOG_DIS("lshq %d, $r%d\n", simm, dc->dst);

            op = CC_OP_LSL;
            if (imm & (1 << 5)) {
                op = CC_OP_LSR; 
            }
            imm &= 0x1f;
            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, op, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_SUBQ:
            LOG_DIS("subq %d, $r%d\n", imm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_SUB, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(imm), 4);
            break;
        case CRISV10_QIMM_ORQ:
            LOG_DIS("andq %d, $r%d\n", simm, dc->dst);

            cris_cc_mask(dc, CC_MASK_NZVC);
            cris_alu(dc, CC_OP_OR, cpu_R[dc->dst],
                     cpu_R[dc->dst], tcg_const_tl(simm), 4);
            break;

        case CRISV10_QIMM_BCC_R0:
        case CRISV10_QIMM_BCC_R1:
        case CRISV10_QIMM_BCC_R2:
        case CRISV10_QIMM_BCC_R3:
            imm = dc->ir & 0xff;
            /* bit 0 is a sign bit.  */
            if (imm & 1) {
                imm |= 0xffffff00;   /* sign extend.  */
                imm &= ~1;           /* get rid of the sign bit.  */
            }
            imm += 2;
            LOG_DIS("b%s %d\n", cc_name(dc->cond), imm);

            cris_cc_mask(dc, 0);
            cris_prepare_cc_branch(dc, imm, dc->cond); 
            break;

        default:
            LOG_DIS("pc=%x mode=%x quickimm %d r%d r%d\n",
                     dc->pc, dc->mode, dc->opcode, dc->src, dc->dst);
            cpu_abort(dc->env, "Unhandled quickimm\n");
            break;
    }
    return 2;
}

static unsigned int dec10_setclrf(DisasContext *dc)
{
    uint32_t flags;
    unsigned int set = ~dc->opcode & 1;

    flags = EXTRACT_FIELD(dc->ir, 0, 3)
            | (EXTRACT_FIELD(dc->ir, 12, 15) << 4);
    LOG_DIS("%s set=%d flags=%x\n", __func__, set, flags);


    if (flags & X_FLAG) {
        dc->flagx_known = 1;
        if (set)
            dc->flags_x = X_FLAG;
        else
            dc->flags_x = 0;
    }

    cris_evaluate_flags (dc);
    cris_update_cc_op(dc, CC_OP_FLAGS, 4);
    cris_update_cc_x(dc);
    tcg_gen_movi_tl(cc_op, dc->cc_op);

    if (set) {
        tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
    } else {
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
                        ~(flags|F_FLAG_V10|P_FLAG_V10));
    }

    dc->flags_uptodate = 1;
    dc->clear_x = 0;
    cris_lock_irq(dc);
    return 2;
}

static inline void dec10_reg_prep_sext(DisasContext *dc, int size, int sext,
				       TCGv dd, TCGv ds, TCGv sd, TCGv ss)
{
    if (sext) {
        t_gen_sext(dd, sd, size);
        t_gen_sext(ds, ss, size);
    } else {
        t_gen_zext(dd, sd, size);
        t_gen_zext(ds, ss, size);
    }
}

static void dec10_reg_alu(DisasContext *dc, int op, int size, int sext)
{
    TCGv t[2];

    t[0] = tcg_temp_new();
    t[1] = tcg_temp_new();
    dec10_reg_prep_sext(dc, size, sext,
                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);

    if (op == CC_OP_LSL || op == CC_OP_LSR || op == CC_OP_ASR) {
        tcg_gen_andi_tl(t[1], t[1], 63);
    }

    assert(dc->dst != 15);
    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], size);
    tcg_temp_free(t[0]);
    tcg_temp_free(t[1]);
}

static void dec10_reg_bound(DisasContext *dc, int size)
{
    TCGv t;

    t = tcg_temp_local_new();
    t_gen_zext(t, cpu_R[dc->src], size);
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    tcg_temp_free(t);
}

static void dec10_reg_mul(DisasContext *dc, int size, int sext)
{
    int op = sext ? CC_OP_MULS : CC_OP_MULU;
    TCGv t[2];

    t[0] = tcg_temp_new();
    t[1] = tcg_temp_new();
    dec10_reg_prep_sext(dc, size, sext,
                        t[0], t[1], cpu_R[dc->dst], cpu_R[dc->src]);

    cris_alu(dc, op, cpu_R[dc->dst], t[0], t[1], 4);

    tcg_temp_free(t[0]);
    tcg_temp_free(t[1]);
}


static void dec10_reg_movs(DisasContext *dc)
{
    int size = (dc->size & 1) + 1;
    TCGv t;

    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
    cris_cc_mask(dc, CC_MASK_NZVC);

    t = tcg_temp_new();
    if (dc->ir & 32)
        t_gen_sext(t, cpu_R[dc->src], size);
    else
        t_gen_zext(t, cpu_R[dc->src], size);

    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    tcg_temp_free(t);
}

static void dec10_reg_alux(DisasContext *dc, int op)
{
    int size = (dc->size & 1) + 1;
    TCGv t;

    LOG_DIS("movx.%d $r%d, $r%d\n", size, dc->src, dc->dst);
    cris_cc_mask(dc, CC_MASK_NZVC);

    t = tcg_temp_new();
    if (dc->ir & 32)
        t_gen_sext(t, cpu_R[dc->src], size);
    else
        t_gen_zext(t, cpu_R[dc->src], size);

    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[dc->dst], t, 4);
    tcg_temp_free(t);
}

static void dec10_reg_mov_pr(DisasContext *dc)
{
    LOG_DIS("move p%d r%d sz=%d\n", dc->dst, dc->src, preg_sizes_v10[dc->dst]);
    cris_lock_irq(dc);
    if (dc->src == 15) {
        tcg_gen_mov_tl(env_btarget, cpu_PR[dc->dst]);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        return;
    }
    if (dc->dst == PR_CCS) {
        cris_evaluate_flags(dc); 
    }
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src],
                 cpu_R[dc->src], cpu_PR[dc->dst], preg_sizes_v10[dc->dst]);
}

static void dec10_reg_abs(DisasContext *dc)
{
    TCGv t0;

    LOG_DIS("abs $r%u, $r%u\n", dc->src, dc->dst);

    assert(dc->dst != 15);
    t0 = tcg_temp_new();
    tcg_gen_sari_tl(t0, cpu_R[dc->src], 31);
    tcg_gen_xor_tl(cpu_R[dc->dst], cpu_R[dc->src], t0);
    tcg_gen_sub_tl(t0, cpu_R[dc->dst], t0);

    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t0, 4);
    tcg_temp_free(t0);
}

static void dec10_reg_swap(DisasContext *dc)
{
    TCGv t0;

    LOG_DIS("not $r%d, $r%d\n", dc->src, dc->dst);

    cris_cc_mask(dc, CC_MASK_NZVC);
    t0 = tcg_temp_new();
    t_gen_mov_TN_reg(t0, dc->src);
    if (dc->dst & 8)
        tcg_gen_not_tl(t0, t0);
    if (dc->dst & 4)
        t_gen_swapw(t0, t0);
    if (dc->dst & 2)
        t_gen_swapb(t0, t0);
    if (dc->dst & 1)
        t_gen_swapr(t0, t0);
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->src], cpu_R[dc->src], t0, 4);
    tcg_temp_free(t0);
}

static void dec10_reg_scc(DisasContext *dc)
{
    int cond = dc->dst;

    LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src);

    if (cond != CC_A)
    {
        int l1;

        gen_tst_cc (dc, cpu_R[dc->src], cond);
        l1 = gen_new_label();
        tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1);
        tcg_gen_movi_tl(cpu_R[dc->src], 1);
        gen_set_label(l1);
    } else {
        tcg_gen_movi_tl(cpu_R[dc->src], 1);
    }

    cris_cc_mask(dc, 0);
}

static unsigned int dec10_reg(DisasContext *dc)
{
    TCGv t;
    unsigned int insn_len = 2;
    unsigned int size = dec10_size(dc->size);
    unsigned int tmp;

    if (dc->size != 3) {
        switch (dc->opcode) {
            case CRISV10_REG_MOVE_R:
                LOG_DIS("move.%d $r%d, $r%d\n", dc->size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_MOVE, size, 0);
                if (dc->dst == 15) {
                    tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
                    cris_prepare_jmp(dc, JMP_INDIRECT);
                    dc->delayed_branch = 1;
                }
                break;
            case CRISV10_REG_MOVX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_movs(dc);
                break;
            case CRISV10_REG_ADDX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alux(dc, CC_OP_ADD);
                break;
            case CRISV10_REG_SUBX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alux(dc, CC_OP_SUB);
                break;
            case CRISV10_REG_ADD:
                LOG_DIS("add $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_ADD, size, 0);
                break;
            case CRISV10_REG_SUB:
                LOG_DIS("sub $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_SUB, size, 0);
                break;
            case CRISV10_REG_CMP:
                LOG_DIS("cmp $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_CMP, size, 0);
                break;
            case CRISV10_REG_BOUND:
                LOG_DIS("bound $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_bound(dc, size);
                break;
            case CRISV10_REG_AND:
                LOG_DIS("and $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_AND, size, 0);
                break;
            case CRISV10_REG_ADDI:
                if (dc->src == 15) {
                    /* nop.  */
                    return 2;
                }
                t = tcg_temp_new();
                LOG_DIS("addi r%d r%d size=%d\n", dc->src, dc->dst, dc->size);
                tcg_gen_shli_tl(t, cpu_R[dc->dst], dc->size & 3);
                tcg_gen_add_tl(cpu_R[dc->src], cpu_R[dc->src], t);
                tcg_temp_free(t);
                break;
            case CRISV10_REG_LSL:
                LOG_DIS("lsl $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_LSL, size, 0);
                break;
            case CRISV10_REG_LSR:
                LOG_DIS("lsr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_LSR, size, 0);
                break;
            case CRISV10_REG_ASR:
                LOG_DIS("asr $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_ASR, size, 1);
                break;
            case CRISV10_REG_OR:
                LOG_DIS("or $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_OR, size, 0);
                break;
            case CRISV10_REG_NEG:
                LOG_DIS("neg $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_NEG, size, 0);
                break;
            case CRISV10_REG_BIAP:
                LOG_DIS("BIAP pc=%x reg %d r%d r%d size=%d\n", dc->pc,
                         dc->opcode, dc->src, dc->dst, size);
                switch (size) {
                    case 4: tmp = 2; break;
                    case 2: tmp = 1; break;
                    case 1: tmp = 0; break;
                    default:
                        cpu_abort(dc->env, "Unhandled BIAP");
                        break;
                }

                t = tcg_temp_new();
                tcg_gen_shli_tl(t, cpu_R[dc->dst], tmp);
                if (dc->src == 15) {
                    tcg_gen_addi_tl(cpu_PR[PR_PREFIX], t, ((dc->pc +2)| 1) + 1);
                } else {
                    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_R[dc->src], t);
                }
                tcg_temp_free(t);
                cris_set_prefix(dc);
                break;

            default:
                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
                         dc->opcode, dc->src, dc->dst);
                cpu_abort(dc->env, "Unhandled opcode");
                break;
        }
    } else {
        switch (dc->opcode) {
            case CRISV10_REG_MOVX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_movs(dc);
                break;
            case CRISV10_REG_ADDX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alux(dc, CC_OP_ADD);
                break;
            case CRISV10_REG_SUBX:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alux(dc, CC_OP_SUB);
                break;
            case CRISV10_REG_MOVE_SPR_R:
                cris_evaluate_flags(dc);
                cris_cc_mask(dc, 0);
                dec10_reg_mov_pr(dc);
                break;
            case CRISV10_REG_MOVE_R_SPR:
                LOG_DIS("move r%d p%d\n", dc->src, dc->dst);
                cris_evaluate_flags(dc);
                if (dc->src != 11) /* fast for srp.  */
                    dc->cpustate_changed = 1;
                t_gen_mov_preg_TN(dc, dc->dst, cpu_R[dc->src]);
                break;
            case CRISV10_REG_SETF:
            case CRISV10_REG_CLEARF:
                dec10_setclrf(dc);
                break;
            case CRISV10_REG_SWAP:
                dec10_reg_swap(dc);
                break;
            case CRISV10_REG_ABS:
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_abs(dc);
                break;
            case CRISV10_REG_LZ:
                LOG_DIS("lz $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_LZ, 4, 0);
                break;
            case CRISV10_REG_XOR:
                LOG_DIS("xor $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_alu(dc, CC_OP_XOR, 4, 0);
                break;
            case CRISV10_REG_BTST:
                LOG_DIS("btst $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                cris_update_cc_op(dc, CC_OP_FLAGS, 4);
                gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->dst],
                           cpu_R[dc->src], cpu_PR[PR_CCS]);
                break;
            case CRISV10_REG_DSTEP:
                LOG_DIS("dstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_cc_mask(dc, CC_MASK_NZVC);
                cris_alu(dc, CC_OP_DSTEP, cpu_R[dc->dst],
                            cpu_R[dc->dst], cpu_R[dc->src], 4);
                break;
            case CRISV10_REG_MSTEP:
                LOG_DIS("mstep $r%d, $r%d sz=%d\n", dc->src, dc->dst, size);
                cris_evaluate_flags(dc);
                cris_cc_mask(dc, CC_MASK_NZVC);
                cris_alu(dc, CC_OP_MSTEP, cpu_R[dc->dst],
                            cpu_R[dc->dst], cpu_R[dc->src], 4);
                break;
            case CRISV10_REG_SCC:
                dec10_reg_scc(dc);
                break;
            default:
                LOG_DIS("pc=%x reg %d r%d r%d\n", dc->pc,
                         dc->opcode, dc->src, dc->dst);
                cpu_abort(dc->env, "Unhandled opcode");
                break;
        }
    }
    return insn_len;
}

static unsigned int dec10_ind_move_m_r(DisasContext *dc, unsigned int size)
{
    unsigned int insn_len = 2;
    TCGv t;

    LOG_DIS("%s: move.%d [$r%d], $r%d\n", __func__,
             size, dc->src, dc->dst);

    cris_cc_mask(dc, CC_MASK_NZVC);
    t = tcg_temp_new();
    insn_len += dec10_prep_move_m(dc, 0, size, t);
    cris_alu(dc, CC_OP_MOVE, cpu_R[dc->dst], cpu_R[dc->dst], t, size);
    if (dc->dst == 15) {
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        dc->delayed_branch = 1;
        return insn_len;
    }

    tcg_temp_free(t);
    return insn_len;
}

static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
{
    unsigned int insn_len = 2;
    TCGv addr;

    LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
    addr = tcg_temp_new();
    crisv10_prepare_memaddr(dc, addr, size);
    gen_store_v10(dc, addr, cpu_R[dc->dst], size);
    insn_len += crisv10_post_memaddr(dc, size);

    return insn_len;
}

static unsigned int dec10_ind_move_m_pr(DisasContext *dc)
{
    unsigned int insn_len = 2, rd = dc->dst;
    TCGv t, addr;

    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);
    cris_lock_irq(dc);

    addr = tcg_temp_new();
    t = tcg_temp_new();
    insn_len += dec10_prep_move_m(dc, 0, 4, t);
    if (rd == 15) {
        tcg_gen_mov_tl(env_btarget, t);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        dc->delayed_branch = 1;
        return insn_len;
    }

    tcg_gen_mov_tl(cpu_PR[rd], t);
    dc->cpustate_changed = 1;
    tcg_temp_free(addr);
    tcg_temp_free(t);
    return insn_len;
}

static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
{
    unsigned int insn_len = 2, size = preg_sizes_v10[dc->dst];
    TCGv addr, t0;

    LOG_DIS("move.%d $p%d, [$r%d]\n", dc->size, dc->dst, dc->src);

    addr = tcg_temp_new();
    crisv10_prepare_memaddr(dc, addr, size);
    if (dc->dst == PR_CCS) {
        t0 = tcg_temp_new();
        cris_evaluate_flags(dc);
        tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
        gen_store_v10(dc, addr, t0, size);
        tcg_temp_free(t0);
    } else {
        gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
    }
    t0 = tcg_temp_new();
    insn_len += crisv10_post_memaddr(dc, size);
    cris_lock_irq(dc);

    return insn_len;
}

static void dec10_movem_r_m(DisasContext *dc)
{
    int i, pfix = dc->tb_flags & PFIX_FLAG;
    TCGv addr, t0;

    LOG_DIS("%s r%d, [r%d] pi=%d ir=%x\n", __func__,
              dc->dst, dc->src, dc->postinc, dc->ir);

    addr = tcg_temp_new();
    t0 = tcg_temp_new();
    crisv10_prepare_memaddr(dc, addr, 4);
    tcg_gen_mov_tl(t0, addr);
    for (i = dc->dst; i >= 0; i--) {
        if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
            gen_store_v10(dc, addr, t0, 4);
        } else {
            gen_store_v10(dc, addr, cpu_R[i], 4);
        }
        tcg_gen_addi_tl(addr, addr, 4);
    }

    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
        tcg_gen_mov_tl(cpu_R[dc->src], t0);
    }

    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
        tcg_gen_mov_tl(cpu_R[dc->src], addr);
    }
    tcg_temp_free(addr);
    tcg_temp_free(t0);
}

static void dec10_movem_m_r(DisasContext *dc)
{
    int i, pfix = dc->tb_flags & PFIX_FLAG;
    TCGv addr, t0;

    LOG_DIS("%s [r%d], r%d pi=%d ir=%x\n", __func__,
              dc->src, dc->dst, dc->postinc, dc->ir);

    addr = tcg_temp_new();
    t0 = tcg_temp_new();
    crisv10_prepare_memaddr(dc, addr, 4);
    tcg_gen_mov_tl(t0, addr);
    for (i = dc->dst; i >= 0; i--) {
        gen_load(dc, cpu_R[i], addr, 4, 0);
        tcg_gen_addi_tl(addr, addr, 4);
    }

    if (pfix && dc->mode == CRISV10_MODE_AUTOINC) {
        tcg_gen_mov_tl(cpu_R[dc->src], t0);
    }

    if (!pfix && dc->mode == CRISV10_MODE_AUTOINC) {
        tcg_gen_mov_tl(cpu_R[dc->src], addr);
    }
    tcg_temp_free(addr);
    tcg_temp_free(t0);
}

static int dec10_ind_alu(DisasContext *dc, int op, unsigned int size)
{
    int insn_len = 0;
    int rd = dc->dst;
    TCGv t[2];

    cris_alu_m_alloc_temps(t);
    insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t[0], size);
    if (dc->dst == 15) {
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        dc->delayed_branch = 1;
        return insn_len;
    }

    cris_alu_m_free_temps(t);

    return insn_len;
}

static int dec10_ind_bound(DisasContext *dc, unsigned int size)
{
    int insn_len = 0;
    int rd = dc->dst;
    TCGv t;

    t = tcg_temp_local_new();
    insn_len += dec10_prep_move_m(dc, 0, size, t);
    cris_alu(dc, CC_OP_BOUND, cpu_R[dc->dst], cpu_R[rd], t, 4);
    if (dc->dst == 15) {
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        dc->delayed_branch = 1;
        return insn_len;
    }

    tcg_temp_free(t);
    return insn_len;
}

static int dec10_alux_m(DisasContext *dc, int op)
{
    unsigned int size = (dc->size & 1) ? 2 : 1;
    unsigned int sx = !!(dc->size & 2);
    int insn_len = 2;
    int rd = dc->dst;
    TCGv t;

    LOG_DIS("addx size=%d sx=%d op=%d %d\n", size, sx, dc->src, dc->dst);

    t = tcg_temp_new();

    cris_cc_mask(dc, CC_MASK_NZVC);
    insn_len += dec10_prep_move_m(dc, sx, size, t);
    cris_alu(dc, op, cpu_R[dc->dst], cpu_R[rd], t, 4);
    if (dc->dst == 15) {
        tcg_gen_mov_tl(env_btarget, cpu_R[dc->dst]);
        cris_prepare_jmp(dc, JMP_INDIRECT);
        dc->delayed_branch = 1;
        return insn_len;
    }

    tcg_temp_free(t);
    return insn_len;
}

static int dec10_dip(DisasContext *dc)
{
    int insn_len = 2;
    uint32_t imm;

    LOG_DIS("dip pc=%x opcode=%d r%d r%d\n",
              dc->pc, dc->opcode, dc->src, dc->dst);
    if (dc->src == 15) {
        imm = ldl_code(dc->pc + 2);
        tcg_gen_movi_tl(cpu_PR[PR_PREFIX], imm);
        if (dc->postinc)
            insn_len += 4;
        tcg_gen_addi_tl(cpu_R[15], cpu_R[15], insn_len - 2);
    } else {
        gen_load(dc, cpu_PR[PR_PREFIX], cpu_R[dc->src], 4, 0);
        if (dc->postinc)
            tcg_gen_addi_tl(cpu_R[dc->src], cpu_R[dc->src], 4);
    }

    cris_set_prefix(dc);
    return insn_len;
}

static int dec10_bdap_m(DisasContext *dc, int size)
{
    int insn_len = 2;
    int rd = dc->dst;

    LOG_DIS("bdap_m pc=%x opcode=%d r%d r%d sz=%d\n",
              dc->pc, dc->opcode, dc->src, dc->dst, size);

    assert(dc->dst != 15);
#if 0
    /* 8bit embedded offset?  */
    if (!dc->postinc && (dc->ir & (1 << 11))) {
        int simm = dc->ir & 0xff;

        /* cpu_abort(dc->env, "Unhandled opcode"); */
        /* sign extended.  */
        simm = (int8_t)simm;

        tcg_gen_addi_tl(cpu_PR[PR_PREFIX], cpu_R[dc->dst], simm);

        cris_set_prefix(dc);
        return insn_len;
    }
#endif
    /* Now the rest of the modes are truly indirect.  */
    insn_len += dec10_prep_move_m(dc, 1, size, cpu_PR[PR_PREFIX]);
    tcg_gen_add_tl(cpu_PR[PR_PREFIX], cpu_PR[PR_PREFIX], cpu_R[rd]);
    cris_set_prefix(dc);
    return insn_len;
}

static unsigned int dec10_ind(DisasContext *dc)
{
    unsigned int insn_len = 2;
    unsigned int size = dec10_size(dc->size);
    uint32_t imm;
    int32_t simm;
    TCGv t[2];

    if (dc->size != 3) {
        switch (dc->opcode) {
            case CRISV10_IND_MOVE_M_R:
                return dec10_ind_move_m_r(dc, size);
                break;
            case CRISV10_IND_MOVE_R_M:
                return dec10_ind_move_r_m(dc, size);
                break;
            case CRISV10_IND_CMP:
                LOG_DIS("cmp size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_CMP, size);
                break;
            case CRISV10_IND_TEST:
                LOG_DIS("test size=%d op=%d %d\n",  size, dc->src, dc->dst);

                cris_evaluate_flags(dc);
                cris_cc_mask(dc, CC_MASK_NZVC);
                cris_alu_m_alloc_temps(t);
                insn_len += dec10_prep_move_m(dc, 0, size, t[0]);
                tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);
                cris_alu(dc, CC_OP_CMP, cpu_R[dc->dst],
                         t[0], tcg_const_tl(0), size);
                cris_alu_m_free_temps(t);
                break;
            case CRISV10_IND_ADD:
                LOG_DIS("add size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_ADD, size);
                break;
            case CRISV10_IND_SUB:
                LOG_DIS("sub size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_SUB, size);
                break;
            case CRISV10_IND_BOUND:
                LOG_DIS("bound size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_bound(dc, size);
                break;
            case CRISV10_IND_AND:
                LOG_DIS("and size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_AND, size);
                break;
            case CRISV10_IND_OR:
                LOG_DIS("or size=%d op=%d %d\n",  size, dc->src, dc->dst);
                cris_cc_mask(dc, CC_MASK_NZVC);
                insn_len += dec10_ind_alu(dc, CC_OP_OR, size);
                break;
            case CRISV10_IND_MOVX:
                insn_len = dec10_alux_m(dc, CC_OP_MOVE);
                break;
            case CRISV10_IND_ADDX:
                insn_len = dec10_alux_m(dc, CC_OP_ADD);
                break;
            case CRISV10_IND_SUBX:
                insn_len = dec10_alux_m(dc, CC_OP_SUB);
                break;
            case CRISV10_IND_CMPX:
                insn_len = dec10_alux_m(dc, CC_OP_CMP);
                break;
            case CRISV10_IND_MUL:
                /* This is a reg insn coded in the mem indir space.  */
                LOG_DIS("mul pc=%x opcode=%d\n", dc->pc, dc->opcode);
                cris_cc_mask(dc, CC_MASK_NZVC);
                dec10_reg_mul(dc, size, dc->ir & (1 << 10));
                break;
            case CRISV10_IND_BDAP_M:
                insn_len = dec10_bdap_m(dc, size);
                break;
            default:
                LOG_DIS("pc=%x var-ind.%d %d r%d r%d\n",
                          dc->pc, size, dc->opcode, dc->src, dc->dst);
                cpu_abort(dc->env, "Unhandled opcode");
                break;
        }
        return insn_len;
    }

    switch (dc->opcode) {
        case CRISV10_IND_MOVE_M_SPR:
            insn_len = dec10_ind_move_m_pr(dc);
            break;
        case CRISV10_IND_MOVE_SPR_M:
            insn_len = dec10_ind_move_pr_m(dc);
            break;
        case CRISV10_IND_JUMP_M:
            if (dc->src == 15) {
                LOG_DIS("jump.%d %d r%d r%d direct\n", size,
                         dc->opcode, dc->src, dc->dst);
                imm = ldl_code(dc->pc + 2);
                if (dc->mode == CRISV10_MODE_AUTOINC)
                    insn_len += size;

                t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
                dc->jmp_pc = imm;
                cris_prepare_jmp(dc, JMP_DIRECT);
                dc->delayed_branch--; /* v10 has no dslot here.  */
            } else {
                if (dc->dst == 14) {
                    LOG_DIS("break %d\n", dc->src);
                    cris_evaluate_flags(dc);
                    tcg_gen_movi_tl(env_pc, dc->pc + 2);
                    t_gen_raise_exception(EXCP_BREAK);
                    dc->is_jmp = DISAS_UPDATE;
                    return insn_len;
                }
                LOG_DIS("%d: jump.%d %d r%d r%d\n", __LINE__, size,
                         dc->opcode, dc->src, dc->dst);
                t[0] = tcg_temp_new();
                t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
                crisv10_prepare_memaddr(dc, t[0], size);
                gen_load(dc, env_btarget, t[0], 4, 0);
                insn_len += crisv10_post_memaddr(dc, size);
                cris_prepare_jmp(dc, JMP_INDIRECT);
                dc->delayed_branch--; /* v10 has no dslot here.  */
                tcg_temp_free(t[0]);
            }
            break;

        case CRISV10_IND_MOVEM_R_M:
            LOG_DIS("movem_r_m pc=%x opcode=%d r%d r%d\n",
                        dc->pc, dc->opcode, dc->dst, dc->src);
            dec10_movem_r_m(dc);
            break;
        case CRISV10_IND_MOVEM_M_R:
            LOG_DIS("movem_m_r pc=%x opcode=%d\n", dc->pc, dc->opcode);
            dec10_movem_m_r(dc);
            break;
        case CRISV10_IND_JUMP_R:
            LOG_DIS("jmp pc=%x opcode=%d r%d r%d\n",
                        dc->pc, dc->opcode, dc->dst, dc->src);
            tcg_gen_mov_tl(env_btarget, cpu_R[dc->src]);
            t_gen_mov_preg_TN(dc, dc->dst, tcg_const_tl(dc->pc + insn_len));
            cris_prepare_jmp(dc, JMP_INDIRECT);
            dc->delayed_branch--; /* v10 has no dslot here.  */
            break;
        case CRISV10_IND_MOVX:
            insn_len = dec10_alux_m(dc, CC_OP_MOVE);
            break;
        case CRISV10_IND_ADDX:
            insn_len = dec10_alux_m(dc, CC_OP_ADD);
            break;
        case CRISV10_IND_SUBX:
            insn_len = dec10_alux_m(dc, CC_OP_SUB);
            break;
        case CRISV10_IND_CMPX:
            insn_len = dec10_alux_m(dc, CC_OP_CMP);
            break;
        case CRISV10_IND_DIP:
            insn_len = dec10_dip(dc);
            break;
        case CRISV10_IND_BCC_M:

            cris_cc_mask(dc, 0);
            imm = ldsw_code(dc->pc + 2);
            simm = (int16_t)imm;
            simm += 4;

            LOG_DIS("bcc_m: b%s %x\n", cc_name(dc->cond), dc->pc + simm);
            cris_prepare_cc_branch(dc, simm, dc->cond);
            insn_len = 4;
            break;
        default:
            LOG_DIS("ERROR pc=%x opcode=%d\n", dc->pc, dc->opcode);
            cpu_abort(dc->env, "Unhandled opcode");
            break;
    }

    return insn_len;
}

static unsigned int crisv10_decoder(DisasContext *dc)
{
    unsigned int insn_len = 2;

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

    /* Load a halfword onto the instruction register.  */
    dc->ir = lduw_code(dc->pc);

    /* Now decode it.  */
    dc->opcode   = EXTRACT_FIELD(dc->ir, 6, 9);
    dc->mode     = EXTRACT_FIELD(dc->ir, 10, 11);
    dc->src      = EXTRACT_FIELD(dc->ir, 0, 3);
    dc->size     = EXTRACT_FIELD(dc->ir, 4, 5);
    dc->cond = dc->dst = EXTRACT_FIELD(dc->ir, 12, 15);
    dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);

    dc->clear_prefix = 1;

    /* FIXME: What if this insn insn't 2 in length??  */
    if (dc->src == 15 || dc->dst == 15)
        tcg_gen_movi_tl(cpu_R[15], dc->pc + 2);

    switch (dc->mode) {
        case CRISV10_MODE_QIMMEDIATE:
            insn_len = dec10_quick_imm(dc);
            break;
        case CRISV10_MODE_REG:
            insn_len = dec10_reg(dc);
            break;
        case CRISV10_MODE_AUTOINC:
        case CRISV10_MODE_INDIRECT:
            insn_len = dec10_ind(dc);
            break;
    }

    if (dc->clear_prefix && dc->tb_flags & PFIX_FLAG) {
        dc->tb_flags &= ~PFIX_FLAG;
        tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~PFIX_FLAG);
        if (dc->tb_flags != dc->tb->flags) {
            dc->cpustate_changed = 1;
        }
    }

    /* CRISv10 locks out interrupts on dslots.  */
    if (dc->delayed_branch == 2) {
        cris_lock_irq(dc);
    }
    return insn_len;
}

static CPUCRISState *cpu_crisv10_init (CPUCRISState *env)
{
	int i;

	cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
	cc_x = tcg_global_mem_new(TCG_AREG0,
				  offsetof(CPUCRISState, cc_x), "cc_x");
	cc_src = tcg_global_mem_new(TCG_AREG0,
				    offsetof(CPUCRISState, cc_src), "cc_src");
	cc_dest = tcg_global_mem_new(TCG_AREG0,
				     offsetof(CPUCRISState, cc_dest),
				     "cc_dest");
	cc_result = tcg_global_mem_new(TCG_AREG0,
				       offsetof(CPUCRISState, cc_result),
				       "cc_result");
	cc_op = tcg_global_mem_new(TCG_AREG0,
				   offsetof(CPUCRISState, cc_op), "cc_op");
	cc_size = tcg_global_mem_new(TCG_AREG0,
				     offsetof(CPUCRISState, cc_size),
				     "cc_size");
	cc_mask = tcg_global_mem_new(TCG_AREG0,
				     offsetof(CPUCRISState, cc_mask),
				     "cc_mask");

	env_pc = tcg_global_mem_new(TCG_AREG0, 
				    offsetof(CPUCRISState, pc),
				    "pc");
	env_btarget = tcg_global_mem_new(TCG_AREG0,
					 offsetof(CPUCRISState, btarget),
					 "btarget");
	env_btaken = tcg_global_mem_new(TCG_AREG0,
					 offsetof(CPUCRISState, btaken),
					 "btaken");
	for (i = 0; i < 16; i++) {
		cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
					      offsetof(CPUCRISState, regs[i]),
					      regnames_v10[i]);
	}
	for (i = 0; i < 16; i++) {
		cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
					       offsetof(CPUCRISState, pregs[i]),
					       pregnames_v10[i]);
	}

	return env;
}

