/*
 *  UniCore32 translation
 *
 * Copyright (C) 2010-2012 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation, or (at your option) any
 * later version. See the COPYING file in the top-level directory.
 */
#include "qemu/osdep.h"

#include "cpu.h"
#include "disas/disas.h"
#include "exec/exec-all.h"
#include "tcg/tcg-op.h"
#include "qemu/log.h"
#include "exec/cpu_ldst.h"
#include "exec/translator.h"
#include "qemu/qemu-print.h"

#include "exec/helper-proto.h"
#include "exec/helper-gen.h"

#include "trace-tcg.h"
#include "exec/log.h"


/* internal defines */
typedef struct DisasContext {
    target_ulong pc;
    int is_jmp;
    /* Nonzero if this instruction has been conditionally skipped.  */
    int condjmp;
    /* The label that will be jumped to when the instruction is skipped.  */
    TCGLabel *condlabel;
    struct TranslationBlock *tb;
    int singlestep_enabled;
#ifndef CONFIG_USER_ONLY
    int user;
#endif
} DisasContext;

#ifndef CONFIG_USER_ONLY
#define IS_USER(s)      (s->user)
#else
#define IS_USER(s)      1
#endif

/* is_jmp field values */
#define DISAS_JUMP    DISAS_TARGET_0 /* only pc was modified dynamically */
#define DISAS_UPDATE  DISAS_TARGET_1 /* cpu state was modified dynamically */
#define DISAS_TB_JUMP DISAS_TARGET_2 /* only pc was modified statically */
/* These instructions trap after executing, so defer them until after the
   conditional executions state has been updated.  */
#define DISAS_SYSCALL DISAS_TARGET_3

static TCGv_i32 cpu_R[32];

/* FIXME:  These should be removed.  */
static TCGv cpu_F0s, cpu_F1s;
static TCGv_i64 cpu_F0d, cpu_F1d;

#include "exec/gen-icount.h"

static const char *regnames[] = {
      "r00", "r01", "r02", "r03", "r04", "r05", "r06", "r07",
      "r08", "r09", "r10", "r11", "r12", "r13", "r14", "r15",
      "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
      "r24", "r25", "r26", "r27", "r28", "r29", "r30", "pc" };

/* initialize TCG globals.  */
void uc32_translate_init(void)
{
    int i;

    for (i = 0; i < 32; i++) {
        cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
                                offsetof(CPUUniCore32State, regs[i]), regnames[i]);
    }
}

static int num_temps;

/* Allocate a temporary variable.  */
static TCGv_i32 new_tmp(void)
{
    num_temps++;
    return tcg_temp_new_i32();
}

/* Release a temporary variable.  */
static void dead_tmp(TCGv tmp)
{
    tcg_temp_free(tmp);
    num_temps--;
}

static inline TCGv load_cpu_offset(int offset)
{
    TCGv tmp = new_tmp();
    tcg_gen_ld_i32(tmp, cpu_env, offset);
    return tmp;
}

#define load_cpu_field(name) load_cpu_offset(offsetof(CPUUniCore32State, name))

static inline void store_cpu_offset(TCGv var, int offset)
{
    tcg_gen_st_i32(var, cpu_env, offset);
    dead_tmp(var);
}

#define store_cpu_field(var, name) \
    store_cpu_offset(var, offsetof(CPUUniCore32State, name))

/* Set a variable to the value of a CPU register.  */
static void load_reg_var(DisasContext *s, TCGv var, int reg)
{
    if (reg == 31) {
        uint32_t addr;
        /* normaly, since we updated PC */
        addr = (long)s->pc;
        tcg_gen_movi_i32(var, addr);
    } else {
        tcg_gen_mov_i32(var, cpu_R[reg]);
    }
}

/* Create a new temporary and set it to the value of a CPU register.  */
static inline TCGv load_reg(DisasContext *s, int reg)
{
    TCGv tmp = new_tmp();
    load_reg_var(s, tmp, reg);
    return tmp;
}

/* Set a CPU register.  The source must be a temporary and will be
   marked as dead.  */
static void store_reg(DisasContext *s, int reg, TCGv var)
{
    if (reg == 31) {
        tcg_gen_andi_i32(var, var, ~3);
        s->is_jmp = DISAS_JUMP;
    }
    tcg_gen_mov_i32(cpu_R[reg], var);
    dead_tmp(var);
}

/* Value extensions.  */
#define gen_uxtb(var)           tcg_gen_ext8u_i32(var, var)
#define gen_uxth(var)           tcg_gen_ext16u_i32(var, var)
#define gen_sxtb(var)           tcg_gen_ext8s_i32(var, var)
#define gen_sxth(var)           tcg_gen_ext16s_i32(var, var)

#define UCOP_REG_M              (((insn) >>  0) & 0x1f)
#define UCOP_REG_N              (((insn) >> 19) & 0x1f)
#define UCOP_REG_D              (((insn) >> 14) & 0x1f)
#define UCOP_REG_S              (((insn) >>  9) & 0x1f)
#define UCOP_REG_LO             (((insn) >> 14) & 0x1f)
#define UCOP_REG_HI             (((insn) >>  9) & 0x1f)
#define UCOP_SH_OP              (((insn) >>  6) & 0x03)
#define UCOP_SH_IM              (((insn) >>  9) & 0x1f)
#define UCOP_OPCODES            (((insn) >> 25) & 0x0f)
#define UCOP_IMM_9              (((insn) >>  0) & 0x1ff)
#define UCOP_IMM10              (((insn) >>  0) & 0x3ff)
#define UCOP_IMM14              (((insn) >>  0) & 0x3fff)
#define UCOP_COND               (((insn) >> 25) & 0x0f)
#define UCOP_CMOV_COND          (((insn) >> 19) & 0x0f)
#define UCOP_CPNUM              (((insn) >> 10) & 0x0f)
#define UCOP_UCF64_FMT          (((insn) >> 24) & 0x03)
#define UCOP_UCF64_FUNC         (((insn) >>  6) & 0x0f)
#define UCOP_UCF64_COND         (((insn) >>  6) & 0x0f)

#define UCOP_SET(i)             ((insn) & (1 << (i)))
#define UCOP_SET_P              UCOP_SET(28)
#define UCOP_SET_U              UCOP_SET(27)
#define UCOP_SET_B              UCOP_SET(26)
#define UCOP_SET_W              UCOP_SET(25)
#define UCOP_SET_L              UCOP_SET(24)
#define UCOP_SET_S              UCOP_SET(24)

#define ILLEGAL         cpu_abort(env_cpu(env),                         \
                        "Illegal UniCore32 instruction %x at line %d!", \
                        insn, __LINE__)

#ifndef CONFIG_USER_ONLY
static void disas_cp0_insn(CPUUniCore32State *env, DisasContext *s,
        uint32_t insn)
{
    TCGv tmp, tmp2, tmp3;
    if ((insn & 0xfe000000) == 0xe0000000) {
        tmp2 = new_tmp();
        tmp3 = new_tmp();
        tcg_gen_movi_i32(tmp2, UCOP_REG_N);
        tcg_gen_movi_i32(tmp3, UCOP_IMM10);
        if (UCOP_SET_L) {
            tmp = new_tmp();
            gen_helper_cp0_get(tmp, cpu_env, tmp2, tmp3);
            store_reg(s, UCOP_REG_D, tmp);
        } else {
            tmp = load_reg(s, UCOP_REG_D);
            gen_helper_cp0_set(cpu_env, tmp, tmp2, tmp3);
            dead_tmp(tmp);
        }
        dead_tmp(tmp2);
        dead_tmp(tmp3);
        return;
    }
    ILLEGAL;
}

static void disas_ocd_insn(CPUUniCore32State *env, DisasContext *s,
        uint32_t insn)
{
    TCGv tmp;

    if ((insn & 0xff003fff) == 0xe1000400) {
        /*
         * movc rd, pp.nn, #imm9
         *      rd: UCOP_REG_D
         *      nn: UCOP_REG_N (must be 0)
         *      imm9: 0
         */
        if (UCOP_REG_N == 0) {
            tmp = new_tmp();
            tcg_gen_movi_i32(tmp, 0);
            store_reg(s, UCOP_REG_D, tmp);
            return;
        } else {
            ILLEGAL;
        }
    }
    if ((insn & 0xff003fff) == 0xe0000401) {
        /*
         * movc pp.nn, rn, #imm9
         *      rn: UCOP_REG_D
         *      nn: UCOP_REG_N (must be 1)
         *      imm9: 1
         */
        if (UCOP_REG_N == 1) {
            tmp = load_reg(s, UCOP_REG_D);
            gen_helper_cp1_putc(tmp);
            dead_tmp(tmp);
            return;
        } else {
            ILLEGAL;
        }
    }
    ILLEGAL;
}
#endif

static inline void gen_set_asr(TCGv var, uint32_t mask)
{
    TCGv tmp_mask = tcg_const_i32(mask);
    gen_helper_asr_write(cpu_env, var, tmp_mask);
    tcg_temp_free_i32(tmp_mask);
}
/* Set NZCV flags from the high 4 bits of var.  */
#define gen_set_nzcv(var) gen_set_asr(var, ASR_NZCV)

static void gen_exception(int excp)
{
    TCGv tmp = new_tmp();
    tcg_gen_movi_i32(tmp, excp);
    gen_helper_exception(cpu_env, tmp);
    dead_tmp(tmp);
}

#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, CF))

/* Set CF to the top bit of var.  */
static void gen_set_CF_bit31(TCGv var)
{
    TCGv tmp = new_tmp();
    tcg_gen_shri_i32(tmp, var, 31);
    gen_set_CF(tmp);
    dead_tmp(tmp);
}

/* Set N and Z flags from var.  */
static inline void gen_logic_CC(TCGv var)
{
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, NF));
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, ZF));
}

/* dest = T0 + T1 + CF. */
static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
{
    TCGv tmp;
    tcg_gen_add_i32(dest, t0, t1);
    tmp = load_cpu_field(CF);
    tcg_gen_add_i32(dest, dest, tmp);
    dead_tmp(tmp);
}

/* dest = T0 - T1 + CF - 1.  */
static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
{
    TCGv tmp;
    tcg_gen_sub_i32(dest, t0, t1);
    tmp = load_cpu_field(CF);
    tcg_gen_add_i32(dest, dest, tmp);
    tcg_gen_subi_i32(dest, dest, 1);
    dead_tmp(tmp);
}

static void shifter_out_im(TCGv var, int shift)
{
    TCGv tmp = new_tmp();
    if (shift == 0) {
        tcg_gen_andi_i32(tmp, var, 1);
    } else {
        tcg_gen_shri_i32(tmp, var, shift);
        if (shift != 31) {
            tcg_gen_andi_i32(tmp, tmp, 1);
        }
    }
    gen_set_CF(tmp);
    dead_tmp(tmp);
}

/* Shift by immediate.  Includes special handling for shift == 0.  */
static inline void gen_uc32_shift_im(TCGv var, int shiftop, int shift,
        int flags)
{
    switch (shiftop) {
    case 0: /* LSL */
        if (shift != 0) {
            if (flags) {
                shifter_out_im(var, 32 - shift);
            }
            tcg_gen_shli_i32(var, var, shift);
        }
        break;
    case 1: /* LSR */
        if (shift == 0) {
            if (flags) {
                tcg_gen_shri_i32(var, var, 31);
                gen_set_CF(var);
            }
            tcg_gen_movi_i32(var, 0);
        } else {
            if (flags) {
                shifter_out_im(var, shift - 1);
            }
            tcg_gen_shri_i32(var, var, shift);
        }
        break;
    case 2: /* ASR */
        if (shift == 0) {
            shift = 32;
        }
        if (flags) {
            shifter_out_im(var, shift - 1);
        }
        if (shift == 32) {
            shift = 31;
        }
        tcg_gen_sari_i32(var, var, shift);
        break;
    case 3: /* ROR/RRX */
        if (shift != 0) {
            if (flags) {
                shifter_out_im(var, shift - 1);
            }
            tcg_gen_rotri_i32(var, var, shift); break;
        } else {
            TCGv tmp = load_cpu_field(CF);
            if (flags) {
                shifter_out_im(var, 0);
            }
            tcg_gen_shri_i32(var, var, 1);
            tcg_gen_shli_i32(tmp, tmp, 31);
            tcg_gen_or_i32(var, var, tmp);
            dead_tmp(tmp);
        }
    }
};

static inline void gen_uc32_shift_reg(TCGv var, int shiftop,
                                     TCGv shift, int flags)
{
    if (flags) {
        switch (shiftop) {
        case 0:
            gen_helper_shl_cc(var, cpu_env, var, shift);
            break;
        case 1:
            gen_helper_shr_cc(var, cpu_env, var, shift);
            break;
        case 2:
            gen_helper_sar_cc(var, cpu_env, var, shift);
            break;
        case 3:
            gen_helper_ror_cc(var, cpu_env, var, shift);
            break;
        }
    } else {
        switch (shiftop) {
        case 0:
            gen_helper_shl(var, var, shift);
            break;
        case 1:
            gen_helper_shr(var, var, shift);
            break;
        case 2:
            gen_helper_sar(var, var, shift);
            break;
        case 3:
            tcg_gen_andi_i32(shift, shift, 0x1f);
            tcg_gen_rotr_i32(var, var, shift);
            break;
        }
    }
    dead_tmp(shift);
}

static void gen_test_cc(int cc, TCGLabel *label)
{
    TCGv tmp;
    TCGv tmp2;
    TCGLabel *inv;

    switch (cc) {
    case 0: /* eq: Z */
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
        break;
    case 1: /* ne: !Z */
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
        break;
    case 2: /* cs: C */
        tmp = load_cpu_field(CF);
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
        break;
    case 3: /* cc: !C */
        tmp = load_cpu_field(CF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
        break;
    case 4: /* mi: N */
        tmp = load_cpu_field(NF);
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
        break;
    case 5: /* pl: !N */
        tmp = load_cpu_field(NF);
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
        break;
    case 6: /* vs: V */
        tmp = load_cpu_field(VF);
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
        break;
    case 7: /* vc: !V */
        tmp = load_cpu_field(VF);
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
        break;
    case 8: /* hi: C && !Z */
        inv = gen_new_label();
        tmp = load_cpu_field(CF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
        dead_tmp(tmp);
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
        gen_set_label(inv);
        break;
    case 9: /* ls: !C || Z */
        tmp = load_cpu_field(CF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
        dead_tmp(tmp);
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
        break;
    case 10: /* ge: N == V -> N ^ V == 0 */
        tmp = load_cpu_field(VF);
        tmp2 = load_cpu_field(NF);
        tcg_gen_xor_i32(tmp, tmp, tmp2);
        dead_tmp(tmp2);
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
        break;
    case 11: /* lt: N != V -> N ^ V != 0 */
        tmp = load_cpu_field(VF);
        tmp2 = load_cpu_field(NF);
        tcg_gen_xor_i32(tmp, tmp, tmp2);
        dead_tmp(tmp2);
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
        break;
    case 12: /* gt: !Z && N == V */
        inv = gen_new_label();
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
        dead_tmp(tmp);
        tmp = load_cpu_field(VF);
        tmp2 = load_cpu_field(NF);
        tcg_gen_xor_i32(tmp, tmp, tmp2);
        dead_tmp(tmp2);
        tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
        gen_set_label(inv);
        break;
    case 13: /* le: Z || N != V */
        tmp = load_cpu_field(ZF);
        tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
        dead_tmp(tmp);
        tmp = load_cpu_field(VF);
        tmp2 = load_cpu_field(NF);
        tcg_gen_xor_i32(tmp, tmp, tmp2);
        dead_tmp(tmp2);
        tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
        break;
    default:
        fprintf(stderr, "Bad condition code 0x%x\n", cc);
        abort();
    }
    dead_tmp(tmp);
}

static const uint8_t table_logic_cc[16] = {
    1, /* and */    1, /* xor */    0, /* sub */    0, /* rsb */
    0, /* add */    0, /* adc */    0, /* sbc */    0, /* rsc */
    1, /* andl */   1, /* xorl */   0, /* cmp */    0, /* cmn */
    1, /* orr */    1, /* mov */    1, /* bic */    1, /* mvn */
};

/* Set PC state from an immediate address.  */
static inline void gen_bx_im(DisasContext *s, uint32_t addr)
{
    s->is_jmp = DISAS_UPDATE;
    tcg_gen_movi_i32(cpu_R[31], addr & ~3);
}

/* Set PC state from var.  var is marked as dead.  */
static inline void gen_bx(DisasContext *s, TCGv var)
{
    s->is_jmp = DISAS_UPDATE;
    tcg_gen_andi_i32(cpu_R[31], var, ~3);
    dead_tmp(var);
}

static inline void store_reg_bx(DisasContext *s, int reg, TCGv var)
{
    store_reg(s, reg, var);
}

static inline TCGv gen_ld8s(TCGv addr, int index)
{
    TCGv tmp = new_tmp();
    tcg_gen_qemu_ld8s(tmp, addr, index);
    return tmp;
}

static inline TCGv gen_ld8u(TCGv addr, int index)
{
    TCGv tmp = new_tmp();
    tcg_gen_qemu_ld8u(tmp, addr, index);
    return tmp;
}

static inline TCGv gen_ld16s(TCGv addr, int index)
{
    TCGv tmp = new_tmp();
    tcg_gen_qemu_ld16s(tmp, addr, index);
    return tmp;
}

static inline TCGv gen_ld16u(TCGv addr, int index)
{
    TCGv tmp = new_tmp();
    tcg_gen_qemu_ld16u(tmp, addr, index);
    return tmp;
}

static inline TCGv gen_ld32(TCGv addr, int index)
{
    TCGv tmp = new_tmp();
    tcg_gen_qemu_ld32u(tmp, addr, index);
    return tmp;
}

static inline void gen_st8(TCGv val, TCGv addr, int index)
{
    tcg_gen_qemu_st8(val, addr, index);
    dead_tmp(val);
}

static inline void gen_st16(TCGv val, TCGv addr, int index)
{
    tcg_gen_qemu_st16(val, addr, index);
    dead_tmp(val);
}

static inline void gen_st32(TCGv val, TCGv addr, int index)
{
    tcg_gen_qemu_st32(val, addr, index);
    dead_tmp(val);
}

static inline void gen_set_pc_im(uint32_t val)
{
    tcg_gen_movi_i32(cpu_R[31], val);
}

/* Force a TB lookup after an instruction that changes the CPU state.  */
static inline void gen_lookup_tb(DisasContext *s)
{
    tcg_gen_movi_i32(cpu_R[31], s->pc & ~1);
    s->is_jmp = DISAS_UPDATE;
}

static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
        TCGv var)
{
    int val;
    TCGv offset;

    if (UCOP_SET(29)) {
        /* immediate */
        val = UCOP_IMM14;
        if (!UCOP_SET_U) {
            val = -val;
        }
        if (val != 0) {
            tcg_gen_addi_i32(var, var, val);
        }
    } else {
        /* shift/register */
        offset = load_reg(s, UCOP_REG_M);
        gen_uc32_shift_im(offset, UCOP_SH_OP, UCOP_SH_IM, 0);
        if (!UCOP_SET_U) {
            tcg_gen_sub_i32(var, var, offset);
        } else {
            tcg_gen_add_i32(var, var, offset);
        }
        dead_tmp(offset);
    }
}

static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
        TCGv var)
{
    int val;
    TCGv offset;

    if (UCOP_SET(26)) {
        /* immediate */
        val = (insn & 0x1f) | ((insn >> 4) & 0x3e0);
        if (!UCOP_SET_U) {
            val = -val;
        }
        if (val != 0) {
            tcg_gen_addi_i32(var, var, val);
        }
    } else {
        /* register */
        offset = load_reg(s, UCOP_REG_M);
        if (!UCOP_SET_U) {
            tcg_gen_sub_i32(var, var, offset);
        } else {
            tcg_gen_add_i32(var, var, offset);
        }
        dead_tmp(offset);
    }
}

static inline long ucf64_reg_offset(int reg)
{
    if (reg & 1) {
        return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
          + offsetof(CPU_DoubleU, l.upper);
    } else {
        return offsetof(CPUUniCore32State, ucf64.regs[reg >> 1])
          + offsetof(CPU_DoubleU, l.lower);
    }
}

#define ucf64_gen_ld32(reg)      load_cpu_offset(ucf64_reg_offset(reg))
#define ucf64_gen_st32(var, reg) store_cpu_offset(var, ucf64_reg_offset(reg))

/* UniCore-F64 single load/store I_offset */
static void do_ucf64_ldst_i(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    int offset;
    TCGv tmp;
    TCGv addr;

    addr = load_reg(s, UCOP_REG_N);
    if (!UCOP_SET_P && !UCOP_SET_W) {
        ILLEGAL;
    }

    if (UCOP_SET_P) {
        offset = UCOP_IMM10 << 2;
        if (!UCOP_SET_U) {
            offset = -offset;
        }
        if (offset != 0) {
            tcg_gen_addi_i32(addr, addr, offset);
        }
    }

    if (UCOP_SET_L) { /* load */
        tmp = gen_ld32(addr, IS_USER(s));
        ucf64_gen_st32(tmp, UCOP_REG_D);
    } else { /* store */
        tmp = ucf64_gen_ld32(UCOP_REG_D);
        gen_st32(tmp, addr, IS_USER(s));
    }

    if (!UCOP_SET_P) {
        offset = UCOP_IMM10 << 2;
        if (!UCOP_SET_U) {
            offset = -offset;
        }
        if (offset != 0) {
            tcg_gen_addi_i32(addr, addr, offset);
        }
    }
    if (UCOP_SET_W) {
        store_reg(s, UCOP_REG_N, addr);
    } else {
        dead_tmp(addr);
    }
}

/* UniCore-F64 load/store multiple words */
static void do_ucf64_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    unsigned int i;
    int j, n, freg;
    TCGv tmp;
    TCGv addr;

    if (UCOP_REG_D != 0) {
        ILLEGAL;
    }
    if (UCOP_REG_N == 31) {
        ILLEGAL;
    }
    if ((insn << 24) == 0) {
        ILLEGAL;
    }

    addr = load_reg(s, UCOP_REG_N);

    n = 0;
    for (i = 0; i < 8; i++) {
        if (UCOP_SET(i)) {
            n++;
        }
    }

    if (UCOP_SET_U) {
        if (UCOP_SET_P) { /* pre increment */
            tcg_gen_addi_i32(addr, addr, 4);
        } /* unnecessary to do anything when post increment */
    } else {
        if (UCOP_SET_P) { /* pre decrement */
            tcg_gen_addi_i32(addr, addr, -(n * 4));
        } else { /* post decrement */
            if (n != 1) {
                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
            }
        }
    }

    freg = ((insn >> 8) & 3) << 3; /* freg should be 0, 8, 16, 24 */

    for (i = 0, j = 0; i < 8; i++, freg++) {
        if (!UCOP_SET(i)) {
            continue;
        }

        if (UCOP_SET_L) { /* load */
            tmp = gen_ld32(addr, IS_USER(s));
            ucf64_gen_st32(tmp, freg);
        } else { /* store */
            tmp = ucf64_gen_ld32(freg);
            gen_st32(tmp, addr, IS_USER(s));
        }

        j++;
        /* unnecessary to add after the last transfer */
        if (j != n) {
            tcg_gen_addi_i32(addr, addr, 4);
        }
    }

    if (UCOP_SET_W) { /* write back */
        if (UCOP_SET_U) {
            if (!UCOP_SET_P) { /* post increment */
                tcg_gen_addi_i32(addr, addr, 4);
            } /* unnecessary to do anything when pre increment */
        } else {
            if (UCOP_SET_P) {
                /* pre decrement */
                if (n != 1) {
                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
                }
            } else {
                /* post decrement */
                tcg_gen_addi_i32(addr, addr, -(n * 4));
            }
        }
        store_reg(s, UCOP_REG_N, addr);
    } else {
        dead_tmp(addr);
    }
}

/* UniCore-F64 mrc/mcr */
static void do_ucf64_trans(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    TCGv tmp;

    if ((insn & 0xfe0003ff) == 0xe2000000) {
        /* control register */
        if ((UCOP_REG_N != UC32_UCF64_FPSCR) || (UCOP_REG_D == 31)) {
            ILLEGAL;
        }
        if (UCOP_SET(24)) {
            /* CFF */
            tmp = new_tmp();
            gen_helper_ucf64_get_fpscr(tmp, cpu_env);
            store_reg(s, UCOP_REG_D, tmp);
        } else {
            /* CTF */
            tmp = load_reg(s, UCOP_REG_D);
            gen_helper_ucf64_set_fpscr(cpu_env, tmp);
            dead_tmp(tmp);
            gen_lookup_tb(s);
        }
        return;
    }
    if ((insn & 0xfe0003ff) == 0xe0000000) {
        /* general register */
        if (UCOP_REG_D == 31) {
            ILLEGAL;
        }
        if (UCOP_SET(24)) { /* MFF */
            tmp = ucf64_gen_ld32(UCOP_REG_N);
            store_reg(s, UCOP_REG_D, tmp);
        } else { /* MTF */
            tmp = load_reg(s, UCOP_REG_D);
            ucf64_gen_st32(tmp, UCOP_REG_N);
        }
        return;
    }
    if ((insn & 0xfb000000) == 0xe9000000) {
        /* MFFC */
        if (UCOP_REG_D != 31) {
            ILLEGAL;
        }
        if (UCOP_UCF64_COND & 0x8) {
            ILLEGAL;
        }

        tmp = new_tmp();
        tcg_gen_movi_i32(tmp, UCOP_UCF64_COND);
        if (UCOP_SET(26)) {
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
            tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, tmp, cpu_env);
        } else {
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
            tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, tmp, cpu_env);
        }
        dead_tmp(tmp);
        return;
    }
    ILLEGAL;
}

/* UniCore-F64 convert instructions */
static void do_ucf64_fcvt(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    if (UCOP_UCF64_FMT == 3) {
        ILLEGAL;
    }
    if (UCOP_REG_N != 0) {
        ILLEGAL;
    }
    switch (UCOP_UCF64_FUNC) {
    case 0: /* cvt.s */
        switch (UCOP_UCF64_FMT) {
        case 1 /* d */:
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_df2sf(cpu_F0s, cpu_F0d, cpu_env);
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
        case 2 /* w */:
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_si2sf(cpu_F0s, cpu_F0s, cpu_env);
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
        default /* s */:
            ILLEGAL;
            break;
        }
        break;
    case 1: /* cvt.d */
        switch (UCOP_UCF64_FMT) {
        case 0 /* s */:
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_sf2df(cpu_F0d, cpu_F0s, cpu_env);
            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
        case 2 /* w */:
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_si2df(cpu_F0d, cpu_F0s, cpu_env);
            tcg_gen_st_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
        default /* d */:
            ILLEGAL;
            break;
        }
        break;
    case 4: /* cvt.w */
        switch (UCOP_UCF64_FMT) {
        case 0 /* s */:
            tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_sf2si(cpu_F0s, cpu_F0s, cpu_env);
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
        case 1 /* d */:
            tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
            gen_helper_ucf64_df2si(cpu_F0s, cpu_F0d, cpu_env);
            tcg_gen_st_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_D));
            break;
    default /* w */:
            ILLEGAL;
            break;
        }
        break;
    default:
        ILLEGAL;
    }
}

/* UniCore-F64 compare instructions */
static void do_ucf64_fcmp(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    if (UCOP_SET(25)) {
        ILLEGAL;
    }
    if (UCOP_REG_D != 0) {
        ILLEGAL;
    }

    ILLEGAL; /* TODO */
    if (UCOP_SET(24)) {
        tcg_gen_ld_i64(cpu_F0d, cpu_env, ucf64_reg_offset(UCOP_REG_N));
        tcg_gen_ld_i64(cpu_F1d, cpu_env, ucf64_reg_offset(UCOP_REG_M));
        /* gen_helper_ucf64_cmpd(cpu_F0d, cpu_F1d, cpu_env); */
    } else {
        tcg_gen_ld_i32(cpu_F0s, cpu_env, ucf64_reg_offset(UCOP_REG_N));
        tcg_gen_ld_i32(cpu_F1s, cpu_env, ucf64_reg_offset(UCOP_REG_M));
        /* gen_helper_ucf64_cmps(cpu_F0s, cpu_F1s, cpu_env); */
    }
}

#define gen_helper_ucf64_movs(x, y)      do { } while (0)
#define gen_helper_ucf64_movd(x, y)      do { } while (0)

#define UCF64_OP1(name)    do {                           \
        if (UCOP_REG_N != 0) {                            \
            ILLEGAL;                                      \
        }                                                 \
        switch (UCOP_UCF64_FMT) {                         \
        case 0 /* s */:                                   \
            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_M)); \
            gen_helper_ucf64_##name##s(cpu_F0s, cpu_F0s); \
            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_D)); \
            break;                                        \
        case 1 /* d */:                                   \
            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_M)); \
            gen_helper_ucf64_##name##d(cpu_F0d, cpu_F0d); \
            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_D)); \
            break;                                        \
        case 2 /* w */:                                   \
            ILLEGAL;                                      \
            break;                                        \
        }                                                 \
    } while (0)

#define UCF64_OP2(name)    do {                           \
        switch (UCOP_UCF64_FMT) {                         \
        case 0 /* s */:                                   \
            tcg_gen_ld_i32(cpu_F0s, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_N)); \
            tcg_gen_ld_i32(cpu_F1s, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_M)); \
            gen_helper_ucf64_##name##s(cpu_F0s,           \
                           cpu_F0s, cpu_F1s, cpu_env);    \
            tcg_gen_st_i32(cpu_F0s, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_D)); \
            break;                                        \
        case 1 /* d */:                                   \
            tcg_gen_ld_i64(cpu_F0d, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_N)); \
            tcg_gen_ld_i64(cpu_F1d, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_M)); \
            gen_helper_ucf64_##name##d(cpu_F0d,           \
                           cpu_F0d, cpu_F1d, cpu_env);    \
            tcg_gen_st_i64(cpu_F0d, cpu_env,              \
                           ucf64_reg_offset(UCOP_REG_D)); \
            break;                                        \
        case 2 /* w */:                                   \
            ILLEGAL;                                      \
            break;                                        \
        }                                                 \
    } while (0)

/* UniCore-F64 data processing */
static void do_ucf64_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    if (UCOP_UCF64_FMT == 3) {
        ILLEGAL;
    }
    switch (UCOP_UCF64_FUNC) {
    case 0: /* add */
        UCF64_OP2(add);
        break;
    case 1: /* sub */
        UCF64_OP2(sub);
        break;
    case 2: /* mul */
        UCF64_OP2(mul);
        break;
    case 4: /* div */
        UCF64_OP2(div);
        break;
    case 5: /* abs */
        UCF64_OP1(abs);
        break;
    case 6: /* mov */
        UCF64_OP1(mov);
        break;
    case 7: /* neg */
        UCF64_OP1(neg);
        break;
    default:
        ILLEGAL;
    }
}

/* Disassemble an F64 instruction */
static void disas_ucf64_insn(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    if (!UCOP_SET(29)) {
        if (UCOP_SET(26)) {
            do_ucf64_ldst_m(env, s, insn);
        } else {
            do_ucf64_ldst_i(env, s, insn);
        }
    } else {
        if (UCOP_SET(5)) {
            switch ((insn >> 26) & 0x3) {
            case 0:
                do_ucf64_datap(env, s, insn);
                break;
            case 1:
                ILLEGAL;
                break;
            case 2:
                do_ucf64_fcvt(env, s, insn);
                break;
            case 3:
                do_ucf64_fcmp(env, s, insn);
                break;
            }
        } else {
            do_ucf64_trans(env, s, insn);
        }
    }
}

static inline bool use_goto_tb(DisasContext *s, uint32_t dest)
{
#ifndef CONFIG_USER_ONLY
    return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
#else
    return true;
#endif
}

static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
{
    if (use_goto_tb(s, dest)) {
        tcg_gen_goto_tb(n);
        gen_set_pc_im(dest);
        tcg_gen_exit_tb(s->tb, n);
    } else {
        gen_set_pc_im(dest);
        tcg_gen_exit_tb(NULL, 0);
    }
}

static inline void gen_jmp(DisasContext *s, uint32_t dest)
{
    if (unlikely(s->singlestep_enabled)) {
        /* An indirect jump so that we still trigger the debug exception.  */
        gen_bx_im(s, dest);
    } else {
        gen_goto_tb(s, 0, dest);
        s->is_jmp = DISAS_TB_JUMP;
    }
}

/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
static int gen_set_psr(DisasContext *s, uint32_t mask, int bsr, TCGv t0)
{
    TCGv tmp;
    if (bsr) {
        /* ??? This is also undefined in system mode.  */
        if (IS_USER(s)) {
            return 1;
        }

        tmp = load_cpu_field(bsr);
        tcg_gen_andi_i32(tmp, tmp, ~mask);
        tcg_gen_andi_i32(t0, t0, mask);
        tcg_gen_or_i32(tmp, tmp, t0);
        store_cpu_field(tmp, bsr);
    } else {
        gen_set_asr(t0, mask);
    }
    dead_tmp(t0);
    gen_lookup_tb(s);
    return 0;
}

/* Generate an old-style exception return. Marks pc as dead. */
static void gen_exception_return(DisasContext *s, TCGv pc)
{
    TCGv tmp;
    store_reg(s, 31, pc);
    tmp = load_cpu_field(bsr);
    gen_set_asr(tmp, 0xffffffff);
    dead_tmp(tmp);
    s->is_jmp = DISAS_UPDATE;
}

static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s,
        uint32_t insn)
{
    switch (UCOP_CPNUM) {
#ifndef CONFIG_USER_ONLY
    case 0:
        disas_cp0_insn(env, s, insn);
        break;
    case 1:
        disas_ocd_insn(env, s, insn);
        break;
#endif
    case 2:
        disas_ucf64_insn(env, s, insn);
        break;
    default:
        /* Unknown coprocessor. */
        cpu_abort(env_cpu(env), "Unknown coprocessor!");
    }
}

/* data processing instructions */
static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    TCGv tmp;
    TCGv tmp2;
    int logic_cc;

    if (UCOP_OPCODES == 0x0f || UCOP_OPCODES == 0x0d) {
        if (UCOP_SET(23)) { /* CMOV instructions */
            if ((UCOP_CMOV_COND == 0xe) || (UCOP_CMOV_COND == 0xf)) {
                ILLEGAL;
            }
            /* if not always execute, we generate a conditional jump to
               next instruction */
            s->condlabel = gen_new_label();
            gen_test_cc(UCOP_CMOV_COND ^ 1, s->condlabel);
            s->condjmp = 1;
        }
    }

    logic_cc = table_logic_cc[UCOP_OPCODES] & (UCOP_SET_S >> 24);

    if (UCOP_SET(29)) {
        unsigned int val;
        /* immediate operand */
        val = UCOP_IMM_9;
        if (UCOP_SH_IM) {
            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
        }
        tmp2 = new_tmp();
        tcg_gen_movi_i32(tmp2, val);
        if (logic_cc && UCOP_SH_IM) {
            gen_set_CF_bit31(tmp2);
        }
   } else {
        /* register */
        tmp2 = load_reg(s, UCOP_REG_M);
        if (UCOP_SET(5)) {
            tmp = load_reg(s, UCOP_REG_S);
            gen_uc32_shift_reg(tmp2, UCOP_SH_OP, tmp, logic_cc);
        } else {
            gen_uc32_shift_im(tmp2, UCOP_SH_OP, UCOP_SH_IM, logic_cc);
        }
    }

    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
        tmp = load_reg(s, UCOP_REG_N);
    } else {
        tmp = NULL;
    }

    switch (UCOP_OPCODES) {
    case 0x00:
        tcg_gen_and_i32(tmp, tmp, tmp2);
        if (logic_cc) {
            gen_logic_CC(tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x01:
        tcg_gen_xor_i32(tmp, tmp, tmp2);
        if (logic_cc) {
            gen_logic_CC(tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x02:
        if (UCOP_SET_S && UCOP_REG_D == 31) {
            /* SUBS r31, ... is used for exception return.  */
            if (IS_USER(s)) {
                ILLEGAL;
            }
            gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
            gen_exception_return(s, tmp);
        } else {
            if (UCOP_SET_S) {
                gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
            } else {
                tcg_gen_sub_i32(tmp, tmp, tmp2);
            }
            store_reg_bx(s, UCOP_REG_D, tmp);
        }
        break;
    case 0x03:
        if (UCOP_SET_S) {
            gen_helper_sub_cc(tmp, cpu_env, tmp2, tmp);
        } else {
            tcg_gen_sub_i32(tmp, tmp2, tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x04:
        if (UCOP_SET_S) {
            gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
        } else {
            tcg_gen_add_i32(tmp, tmp, tmp2);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x05:
        if (UCOP_SET_S) {
            gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
        } else {
            gen_add_carry(tmp, tmp, tmp2);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x06:
        if (UCOP_SET_S) {
            gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
        } else {
            gen_sub_carry(tmp, tmp, tmp2);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x07:
        if (UCOP_SET_S) {
            gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
        } else {
            gen_sub_carry(tmp, tmp2, tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x08:
        if (UCOP_SET_S) {
            tcg_gen_and_i32(tmp, tmp, tmp2);
            gen_logic_CC(tmp);
        }
        dead_tmp(tmp);
        break;
    case 0x09:
        if (UCOP_SET_S) {
            tcg_gen_xor_i32(tmp, tmp, tmp2);
            gen_logic_CC(tmp);
        }
        dead_tmp(tmp);
        break;
    case 0x0a:
        if (UCOP_SET_S) {
            gen_helper_sub_cc(tmp, cpu_env, tmp, tmp2);
        }
        dead_tmp(tmp);
        break;
    case 0x0b:
        if (UCOP_SET_S) {
            gen_helper_add_cc(tmp, cpu_env, tmp, tmp2);
        }
        dead_tmp(tmp);
        break;
    case 0x0c:
        tcg_gen_or_i32(tmp, tmp, tmp2);
        if (logic_cc) {
            gen_logic_CC(tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    case 0x0d:
        if (logic_cc && UCOP_REG_D == 31) {
            /* MOVS r31, ... is used for exception return.  */
            if (IS_USER(s)) {
                ILLEGAL;
            }
            gen_exception_return(s, tmp2);
        } else {
            if (logic_cc) {
                gen_logic_CC(tmp2);
            }
            store_reg_bx(s, UCOP_REG_D, tmp2);
        }
        break;
    case 0x0e:
        tcg_gen_andc_i32(tmp, tmp, tmp2);
        if (logic_cc) {
            gen_logic_CC(tmp);
        }
        store_reg_bx(s, UCOP_REG_D, tmp);
        break;
    default:
    case 0x0f:
        tcg_gen_not_i32(tmp2, tmp2);
        if (logic_cc) {
            gen_logic_CC(tmp2);
        }
        store_reg_bx(s, UCOP_REG_D, tmp2);
        break;
    }
    if (UCOP_OPCODES != 0x0f && UCOP_OPCODES != 0x0d) {
        dead_tmp(tmp2);
    }
}

/* multiply */
static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    TCGv tmp, tmp2, tmp3, tmp4;

    if (UCOP_SET(27)) {
        /* 64 bit mul */
        tmp = load_reg(s, UCOP_REG_M);
        tmp2 = load_reg(s, UCOP_REG_N);
        if (UCOP_SET(26)) {
            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
        } else {
            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
        }
        if (UCOP_SET(25)) { /* mult accumulate */
            tmp3 = load_reg(s, UCOP_REG_LO);
            tmp4 = load_reg(s, UCOP_REG_HI);
            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4);
            dead_tmp(tmp3);
            dead_tmp(tmp4);
        }
        store_reg(s, UCOP_REG_LO, tmp);
        store_reg(s, UCOP_REG_HI, tmp2);
    } else {
        /* 32 bit mul */
        tmp = load_reg(s, UCOP_REG_M);
        tmp2 = load_reg(s, UCOP_REG_N);
        tcg_gen_mul_i32(tmp, tmp, tmp2);
        dead_tmp(tmp2);
        if (UCOP_SET(25)) {
            /* Add */
            tmp2 = load_reg(s, UCOP_REG_S);
            tcg_gen_add_i32(tmp, tmp, tmp2);
            dead_tmp(tmp2);
        }
        if (UCOP_SET_S) {
            gen_logic_CC(tmp);
        }
        store_reg(s, UCOP_REG_D, tmp);
    }
}

/* miscellaneous instructions */
static void do_misc(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    unsigned int val;
    TCGv tmp;

    if ((insn & 0xffffffe0) == 0x10ffc120) {
        /* Trivial implementation equivalent to bx.  */
        tmp = load_reg(s, UCOP_REG_M);
        gen_bx(s, tmp);
        return;
    }

    if ((insn & 0xfbffc000) == 0x30ffc000) {
        /* PSR = immediate */
        val = UCOP_IMM_9;
        if (UCOP_SH_IM) {
            val = (val >> UCOP_SH_IM) | (val << (32 - UCOP_SH_IM));
        }
        tmp = new_tmp();
        tcg_gen_movi_i32(tmp, val);
        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
            ILLEGAL;
        }
        return;
    }

    if ((insn & 0xfbffffe0) == 0x12ffc020) {
        /* PSR.flag = reg */
        tmp = load_reg(s, UCOP_REG_M);
        if (gen_set_psr(s, ASR_NZCV, UCOP_SET_B, tmp)) {
            ILLEGAL;
        }
        return;
    }

    if ((insn & 0xfbffffe0) == 0x10ffc020) {
        /* PSR = reg */
        tmp = load_reg(s, UCOP_REG_M);
        if (gen_set_psr(s, ~ASR_RESERVED, UCOP_SET_B, tmp)) {
            ILLEGAL;
        }
        return;
    }

    if ((insn & 0xfbf83fff) == 0x10f80000) {
        /* reg = PSR */
        if (UCOP_SET_B) {
            if (IS_USER(s)) {
                ILLEGAL;
            }
            tmp = load_cpu_field(bsr);
        } else {
            tmp = new_tmp();
            gen_helper_asr_read(tmp, cpu_env);
        }
        store_reg(s, UCOP_REG_D, tmp);
        return;
    }

    if ((insn & 0xfbf83fe0) == 0x12f80120) {
        /* clz */
        tmp = load_reg(s, UCOP_REG_M);
        if (UCOP_SET(26)) {
            /* clo */
            tcg_gen_not_i32(tmp, tmp);
        }
        tcg_gen_clzi_i32(tmp, tmp, 32);
        store_reg(s, UCOP_REG_D, tmp);
        return;
    }

    /* otherwise */
    ILLEGAL;
}

/* load/store I_offset and R_offset */
static void do_ldst_ir(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    unsigned int mmu_idx;
    TCGv tmp;
    TCGv tmp2;

    tmp2 = load_reg(s, UCOP_REG_N);
    mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));

    /* immediate */
    if (UCOP_SET_P) {
        gen_add_data_offset(s, insn, tmp2);
    }

    if (UCOP_SET_L) {
        /* load */
        if (UCOP_SET_B) {
            tmp = gen_ld8u(tmp2, mmu_idx);
        } else {
            tmp = gen_ld32(tmp2, mmu_idx);
        }
    } else {
        /* store */
        tmp = load_reg(s, UCOP_REG_D);
        if (UCOP_SET_B) {
            gen_st8(tmp, tmp2, mmu_idx);
        } else {
            gen_st32(tmp, tmp2, mmu_idx);
        }
    }
    if (!UCOP_SET_P) {
        gen_add_data_offset(s, insn, tmp2);
        store_reg(s, UCOP_REG_N, tmp2);
    } else if (UCOP_SET_W) {
        store_reg(s, UCOP_REG_N, tmp2);
    } else {
        dead_tmp(tmp2);
    }
    if (UCOP_SET_L) {
        /* Complete the load.  */
        if (UCOP_REG_D == 31) {
            gen_bx(s, tmp);
        } else {
            store_reg(s, UCOP_REG_D, tmp);
        }
    }
}

/* SWP instruction */
static void do_swap(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    TCGv addr;
    TCGv tmp;
    TCGv tmp2;

    if ((insn & 0xff003fe0) != 0x40000120) {
        ILLEGAL;
    }

    /* ??? This is not really atomic.  However we know
       we never have multiple CPUs running in parallel,
       so it is good enough.  */
    addr = load_reg(s, UCOP_REG_N);
    tmp = load_reg(s, UCOP_REG_M);
    if (UCOP_SET_B) {
        tmp2 = gen_ld8u(addr, IS_USER(s));
        gen_st8(tmp, addr, IS_USER(s));
    } else {
        tmp2 = gen_ld32(addr, IS_USER(s));
        gen_st32(tmp, addr, IS_USER(s));
    }
    dead_tmp(addr);
    store_reg(s, UCOP_REG_D, tmp2);
}

/* load/store hw/sb */
static void do_ldst_hwsb(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    TCGv addr;
    TCGv tmp;

    if (UCOP_SH_OP == 0) {
        do_swap(env, s, insn);
        return;
    }

    addr = load_reg(s, UCOP_REG_N);
    if (UCOP_SET_P) {
        gen_add_datah_offset(s, insn, addr);
    }

    if (UCOP_SET_L) { /* load */
        switch (UCOP_SH_OP) {
        case 1:
            tmp = gen_ld16u(addr, IS_USER(s));
            break;
        case 2:
            tmp = gen_ld8s(addr, IS_USER(s));
            break;
        default: /* see do_swap */
        case 3:
            tmp = gen_ld16s(addr, IS_USER(s));
            break;
        }
    } else { /* store */
        if (UCOP_SH_OP != 1) {
            ILLEGAL;
        }
        tmp = load_reg(s, UCOP_REG_D);
        gen_st16(tmp, addr, IS_USER(s));
    }
    /* Perform base writeback before the loaded value to
       ensure correct behavior with overlapping index registers. */
    if (!UCOP_SET_P) {
        gen_add_datah_offset(s, insn, addr);
        store_reg(s, UCOP_REG_N, addr);
    } else if (UCOP_SET_W) {
        store_reg(s, UCOP_REG_N, addr);
    } else {
        dead_tmp(addr);
    }
    if (UCOP_SET_L) {
        /* Complete the load.  */
        store_reg(s, UCOP_REG_D, tmp);
    }
}

/* load/store multiple words */
static void do_ldst_m(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    unsigned int val, i, mmu_idx;
    int j, n, reg, user, loaded_base;
    TCGv tmp;
    TCGv tmp2;
    TCGv addr;
    TCGv loaded_var;

    if (UCOP_SET(7)) {
        ILLEGAL;
    }
    /* XXX: store correct base if write back */
    user = 0;
    if (UCOP_SET_B) { /* S bit in instruction table */
        if (IS_USER(s)) {
            ILLEGAL; /* only usable in supervisor mode */
        }
        if (UCOP_SET(18) == 0) { /* pc reg */
            user = 1;
        }
    }

    mmu_idx = (IS_USER(s) || (!UCOP_SET_P && UCOP_SET_W));
    addr = load_reg(s, UCOP_REG_N);

    /* compute total size */
    loaded_base = 0;
    loaded_var = NULL;
    n = 0;
    for (i = 0; i < 6; i++) {
        if (UCOP_SET(i)) {
            n++;
        }
    }
    for (i = 9; i < 19; i++) {
        if (UCOP_SET(i)) {
            n++;
        }
    }
    /* XXX: test invalid n == 0 case ? */
    if (UCOP_SET_U) {
        if (UCOP_SET_P) {
            /* pre increment */
            tcg_gen_addi_i32(addr, addr, 4);
        } else {
            /* post increment */
        }
    } else {
        if (UCOP_SET_P) {
            /* pre decrement */
            tcg_gen_addi_i32(addr, addr, -(n * 4));
        } else {
            /* post decrement */
            if (n != 1) {
                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
            }
        }
    }

    j = 0;
    reg = UCOP_SET(6) ? 16 : 0;
    for (i = 0; i < 19; i++, reg++) {
        if (i == 6) {
            i = i + 3;
        }
        if (UCOP_SET(i)) {
            if (UCOP_SET_L) { /* load */
                tmp = gen_ld32(addr, mmu_idx);
                if (reg == 31) {
                    gen_bx(s, tmp);
                } else if (user) {
                    tmp2 = tcg_const_i32(reg);
                    gen_helper_set_user_reg(cpu_env, tmp2, tmp);
                    tcg_temp_free_i32(tmp2);
                    dead_tmp(tmp);
                } else if (reg == UCOP_REG_N) {
                    loaded_var = tmp;
                    loaded_base = 1;
                } else {
                    store_reg(s, reg, tmp);
                }
            } else { /* store */
                if (reg == 31) {
                    /* special case: r31 = PC + 4 */
                    val = (long)s->pc;
                    tmp = new_tmp();
                    tcg_gen_movi_i32(tmp, val);
                } else if (user) {
                    tmp = new_tmp();
                    tmp2 = tcg_const_i32(reg);
                    gen_helper_get_user_reg(tmp, cpu_env, tmp2);
                    tcg_temp_free_i32(tmp2);
                } else {
                    tmp = load_reg(s, reg);
                }
                gen_st32(tmp, addr, mmu_idx);
            }
            j++;
            /* no need to add after the last transfer */
            if (j != n) {
                tcg_gen_addi_i32(addr, addr, 4);
            }
        }
    }
    if (UCOP_SET_W) { /* write back */
        if (UCOP_SET_U) {
            if (UCOP_SET_P) {
                /* pre increment */
            } else {
                /* post increment */
                tcg_gen_addi_i32(addr, addr, 4);
            }
        } else {
            if (UCOP_SET_P) {
                /* pre decrement */
                if (n != 1) {
                    tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
                }
            } else {
                /* post decrement */
                tcg_gen_addi_i32(addr, addr, -(n * 4));
            }
        }
        store_reg(s, UCOP_REG_N, addr);
    } else {
        dead_tmp(addr);
    }
    if (loaded_base) {
        store_reg(s, UCOP_REG_N, loaded_var);
    }
    if (UCOP_SET_B && !user) {
        /* Restore ASR from BSR.  */
        tmp = load_cpu_field(bsr);
        gen_set_asr(tmp, 0xffffffff);
        dead_tmp(tmp);
        s->is_jmp = DISAS_UPDATE;
    }
}

/* branch (and link) */
static void do_branch(CPUUniCore32State *env, DisasContext *s, uint32_t insn)
{
    unsigned int val;
    int32_t offset;
    TCGv tmp;

    if (UCOP_COND == 0xf) {
        ILLEGAL;
    }

    if (UCOP_COND != 0xe) {
        /* if not always execute, we generate a conditional jump to
           next instruction */
        s->condlabel = gen_new_label();
        gen_test_cc(UCOP_COND ^ 1, s->condlabel);
        s->condjmp = 1;
    }

    val = (int32_t)s->pc;
    if (UCOP_SET_L) {
        tmp = new_tmp();
        tcg_gen_movi_i32(tmp, val);
        store_reg(s, 30, tmp);
    }
    offset = (((int32_t)insn << 8) >> 8);
    val += (offset << 2); /* unicore is pc+4 */
    gen_jmp(s, val);
}

static void disas_uc32_insn(CPUUniCore32State *env, DisasContext *s)
{
    unsigned int insn;

    insn = cpu_ldl_code(env, s->pc);
    s->pc += 4;

    /* UniCore instructions class:
     * AAAB BBBC xxxx xxxx xxxx xxxD xxEx xxxx
     * AAA  : see switch case
     * BBBB : opcodes or cond or PUBW
     * C    : S OR L
     * D    : 8
     * E    : 5
     */
    switch (insn >> 29) {
    case 0x0:
        if (UCOP_SET(5) && UCOP_SET(8) && !UCOP_SET(28)) {
            do_mult(env, s, insn);
            break;
        }

        if (UCOP_SET(8)) {
            do_misc(env, s, insn);
            break;
        }
        /* fallthrough */
    case 0x1:
        if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
            do_misc(env, s, insn);
            break;
        }
        do_datap(env, s, insn);
        break;

    case 0x2:
        if (UCOP_SET(8) && UCOP_SET(5)) {
            do_ldst_hwsb(env, s, insn);
            break;
        }
        if (UCOP_SET(8) || UCOP_SET(5)) {
            ILLEGAL;
        }
        /* fallthrough */
    case 0x3:
        do_ldst_ir(env, s, insn);
        break;

    case 0x4:
        if (UCOP_SET(8)) {
            ILLEGAL; /* extended instructions */
        }
        do_ldst_m(env, s, insn);
        break;
    case 0x5:
        do_branch(env, s, insn);
        break;
    case 0x6:
        /* Coprocessor.  */
        disas_coproc_insn(env, s, insn);
        break;
    case 0x7:
        if (!UCOP_SET(28)) {
            disas_coproc_insn(env, s, insn);
            break;
        }
        if ((insn & 0xff000000) == 0xff000000) { /* syscall */
            gen_set_pc_im(s->pc);
            s->is_jmp = DISAS_SYSCALL;
            break;
        }
        ILLEGAL;
    }
}

/* generate intermediate code for basic block 'tb'.  */
void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
{
    CPUUniCore32State *env = cs->env_ptr;
    DisasContext dc1, *dc = &dc1;
    target_ulong pc_start;
    uint32_t page_start;
    int num_insns;

    /* generate intermediate code */
    num_temps = 0;

    pc_start = tb->pc;

    dc->tb = tb;

    dc->is_jmp = DISAS_NEXT;
    dc->pc = pc_start;
    dc->singlestep_enabled = cs->singlestep_enabled;
    dc->condjmp = 0;
    cpu_F0s = tcg_temp_new_i32();
    cpu_F1s = tcg_temp_new_i32();
    cpu_F0d = tcg_temp_new_i64();
    cpu_F1d = tcg_temp_new_i64();
    page_start = pc_start & TARGET_PAGE_MASK;
    num_insns = 0;

#ifndef CONFIG_USER_ONLY
    if ((env->uncached_asr & ASR_M) == ASR_MODE_USER) {
        dc->user = 1;
    } else {
        dc->user = 0;
    }
#endif

    gen_tb_start(tb);
    do {
        tcg_gen_insn_start(dc->pc);
        num_insns++;

        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
            gen_set_pc_im(dc->pc);
            gen_exception(EXCP_DEBUG);
            dc->is_jmp = DISAS_JUMP;
            /* The address covered by the breakpoint must be included in
               [tb->pc, tb->pc + tb->size) in order to for it to be
               properly cleared -- thus we increment the PC here so that
               the logic setting tb->size below does the right thing.  */
            dc->pc += 4;
            goto done_generating;
        }

        if (num_insns == max_insns && (tb_cflags(tb) & CF_LAST_IO)) {
            gen_io_start();
        }

        disas_uc32_insn(env, dc);

        if (num_temps) {
            fprintf(stderr, "Internal resource leak before %08x\n", dc->pc);
            num_temps = 0;
        }

        if (dc->condjmp && !dc->is_jmp) {
            gen_set_label(dc->condlabel);
            dc->condjmp = 0;
        }
        /* Translation stops when a conditional branch is encountered.
         * Otherwise the subsequent code could get translated several times.
         * Also stop translation when a page boundary is reached.  This
         * ensures prefetch aborts occur at the right place.  */
    } while (!dc->is_jmp && !tcg_op_buf_full() &&
             !cs->singlestep_enabled &&
             !singlestep &&
             dc->pc - page_start < TARGET_PAGE_SIZE &&
             num_insns < max_insns);

    if (tb_cflags(tb) & CF_LAST_IO) {
        if (dc->condjmp) {
            /* FIXME:  This can theoretically happen with self-modifying
               code.  */
            cpu_abort(cs, "IO on conditional branch instruction");
        }
    }

    /* At this stage dc->condjmp will only be set when the skipped
       instruction was a conditional branch or trap, and the PC has
       already been written.  */
    if (unlikely(cs->singlestep_enabled)) {
        /* Make sure the pc is updated, and raise a debug exception.  */
        if (dc->condjmp) {
            if (dc->is_jmp == DISAS_SYSCALL) {
                gen_exception(UC32_EXCP_PRIV);
            } else {
                gen_exception(EXCP_DEBUG);
            }
            gen_set_label(dc->condlabel);
        }
        if (dc->condjmp || !dc->is_jmp) {
            gen_set_pc_im(dc->pc);
            dc->condjmp = 0;
        }
        if (dc->is_jmp == DISAS_SYSCALL && !dc->condjmp) {
            gen_exception(UC32_EXCP_PRIV);
        } else {
            gen_exception(EXCP_DEBUG);
        }
    } else {
        /* While branches must always occur at the end of an IT block,
           there are a few other things that can cause us to terminate
           the TB in the middel of an IT block:
            - Exception generating instructions (bkpt, swi, undefined).
            - Page boundaries.
            - Hardware watchpoints.
           Hardware breakpoints have already been handled and skip this code.
         */
        switch (dc->is_jmp) {
        case DISAS_NEXT:
            gen_goto_tb(dc, 1, dc->pc);
            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(NULL, 0);
            break;
        case DISAS_TB_JUMP:
            /* nothing more to generate */
            break;
        case DISAS_SYSCALL:
            gen_exception(UC32_EXCP_PRIV);
            break;
        }
        if (dc->condjmp) {
            gen_set_label(dc->condlabel);
            gen_goto_tb(dc, 1, dc->pc);
            dc->condjmp = 0;
        }
    }

done_generating:
    gen_tb_end(tb, num_insns);

#ifdef DEBUG_DISAS
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
        && qemu_log_in_addr_range(pc_start)) {
        FILE *logfile = qemu_log_lock();
        qemu_log("----------------\n");
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
        log_target_disas(cs, pc_start, dc->pc - pc_start);
        qemu_log("\n");
        qemu_log_unlock(logfile);
    }
#endif
    tb->size = dc->pc - pc_start;
    tb->icount = num_insns;
}

static const char *cpu_mode_names[16] = {
    "USER", "REAL", "INTR", "PRIV", "UM14", "UM15", "UM16", "TRAP",
    "UM18", "UM19", "UM1A", "EXTN", "UM1C", "UM1D", "UM1E", "SUSR"
};

#undef UCF64_DUMP_STATE
#ifdef UCF64_DUMP_STATE
static void cpu_dump_state_ucf64(CPUUniCore32State *env, int flags)
{
    int i;
    union {
        uint32_t i;
        float s;
    } s0, s1;
    CPU_DoubleU d;
    /* ??? This assumes float64 and double have the same layout.
       Oh well, it's only debug dumps.  */
    union {
        float64 f64;
        double d;
    } d0;

    for (i = 0; i < 16; i++) {
        d.d = env->ucf64.regs[i];
        s0.i = d.l.lower;
        s1.i = d.l.upper;
        d0.f64 = d.d;
        qemu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g)",
                     i * 2, (int)s0.i, s0.s,
                     i * 2 + 1, (int)s1.i, s1.s);
        qemu_fprintf(f, " d%02d=%" PRIx64 "(%8g)\n",
                     i, (uint64_t)d0.f64, d0.d);
    }
    qemu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
}
#else
#define cpu_dump_state_ucf64(env, file, pr, flags)      do { } while (0)
#endif

void uc32_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
    UniCore32CPU *cpu = UNICORE32_CPU(cs);
    CPUUniCore32State *env = &cpu->env;
    int i;
    uint32_t psr;

    for (i = 0; i < 32; i++) {
        qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
        if ((i % 4) == 3) {
            qemu_fprintf(f, "\n");
        } else {
            qemu_fprintf(f, " ");
        }
    }
    psr = cpu_asr_read(env);
    qemu_fprintf(f, "PSR=%08x %c%c%c%c %s\n",
                 psr,
                 psr & (1 << 31) ? 'N' : '-',
                 psr & (1 << 30) ? 'Z' : '-',
                 psr & (1 << 29) ? 'C' : '-',
                 psr & (1 << 28) ? 'V' : '-',
                 cpu_mode_names[psr & 0xf]);

    if (flags & CPU_DUMP_FPU) {
        cpu_dump_state_ucf64(env, f, cpu_fprintf, flags);
    }
}

void restore_state_to_opc(CPUUniCore32State *env, TranslationBlock *tb,
                          target_ulong *data)
{
    env->regs[31] = data[0];
}
