/*
 *  UniCore32 translation
 *
 * Copyright (C) 2010-2011 GUAN Xue-tao
 *
 * 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.
 */
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
#include "tcg-op.h"
#include "qemu-log.h"

#include "helper.h"
#define GEN_HELPER 1
#include "helper.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.  */
    int condlabel;
    struct TranslationBlock *tb;
    int singlestep_enabled;
} DisasContext;

#define IS_USER(s) 1

/* These instructions trap after executing, so defer them until after the
   conditional executions state has been updated.  */
#define DISAS_SYSCALL 5

static TCGv_ptr cpu_env;
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 "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;

    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");

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

#define GEN_HELPER 2
#include "helper.h"
}

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(CPUState, 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(CPUState, 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,                                  \
                        "Illegal UniCore32 instruction %x at line %d!", \
                        insn, __LINE__)

static inline void gen_set_asr(TCGv var, uint32_t mask)
{
    TCGv tmp_mask = tcg_const_i32(mask);
    gen_helper_asr_write(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(tmp);
    dead_tmp(tmp);
}

/* FIXME: Most targets have native widening multiplication.
   It would be good to use that instead of a full wide multiply.  */
/* 32x32->64 multiply.  Marks inputs as dead.  */
static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
{
    TCGv_i64 tmp1 = tcg_temp_new_i64();
    TCGv_i64 tmp2 = tcg_temp_new_i64();

    tcg_gen_extu_i32_i64(tmp1, a);
    dead_tmp(a);
    tcg_gen_extu_i32_i64(tmp2, b);
    dead_tmp(b);
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    tcg_temp_free_i64(tmp2);
    return tmp1;
}

static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
{
    TCGv_i64 tmp1 = tcg_temp_new_i64();
    TCGv_i64 tmp2 = tcg_temp_new_i64();

    tcg_gen_ext_i32_i64(tmp1, a);
    dead_tmp(a);
    tcg_gen_ext_i32_i64(tmp2, b);
    dead_tmp(b);
    tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    tcg_temp_free_i64(tmp2);
    return tmp1;
}

#define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, 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(CPUState, NF));
    tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, 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, var, shift);
            break;
        case 1:
            gen_helper_shr_cc(var, var, shift);
            break;
        case 2:
            gen_helper_sar_cc(var, var, shift);
            break;
        case 3:
            gen_helper_ror_cc(var, 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, int label)
{
    TCGv tmp;
    TCGv tmp2;
    int 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 TCGv_i64 gen_ld64(TCGv addr, int index)
{
    TCGv_i64 tmp = tcg_temp_new_i64();
    tcg_gen_qemu_ld64(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_st64(TCGv_i64 val, TCGv addr, int index)
{
    tcg_gen_qemu_st64(val, addr, index);
    tcg_temp_free_i64(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(CPUState, ucf64.regs[reg >> 1])
          + offsetof(CPU_DoubleU, l.upper);
    } else {
        return offsetof(CPUState, 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(CPUState *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(CPUState *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(CPUState *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(CPUState *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(CPUState *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(CPUState *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(CPUState *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 void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
{
    TranslationBlock *tb;

    tb = s->tb;
    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
        tcg_gen_goto_tb(n);
        gen_set_pc_im(dest);
        tcg_gen_exit_tb((long)tb + n);
    } else {
        gen_set_pc_im(dest);
        tcg_gen_exit_tb(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;
    }
}

static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
{
    if (x) {
        tcg_gen_sari_i32(t0, t0, 16);
    } else {
        gen_sxth(t0);
    }
    if (y) {
        tcg_gen_sari_i32(t1, t1, 16);
    } else {
        gen_sxth(t1);
    }
    tcg_gen_mul_i32(t0, t0, t1);
}

/* 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(CPUState *env, DisasContext *s, uint32_t insn)
{
    switch (UCOP_CPNUM) {
    case 2:
        disas_ucf64_insn(env, s, insn);
        break;
    default:
        /* Unknown coprocessor. */
        cpu_abort(env, "Unknown coprocessor!");
    }
}


/* Store a 64-bit value to a register pair.  Clobbers val.  */
static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
{
    TCGv tmp;
    tmp = new_tmp();
    tcg_gen_trunc_i64_i32(tmp, val);
    store_reg(s, rlow, tmp);
    tmp = new_tmp();
    tcg_gen_shri_i64(val, val, 32);
    tcg_gen_trunc_i64_i32(tmp, val);
    store_reg(s, rhigh, tmp);
}

/* load and add a 64-bit value from a register pair.  */
static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
{
    TCGv_i64 tmp;
    TCGv tmpl;
    TCGv tmph;

    /* Load 64-bit value rd:rn.  */
    tmpl = load_reg(s, rlow);
    tmph = load_reg(s, rhigh);
    tmp = tcg_temp_new_i64();
    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
    dead_tmp(tmpl);
    dead_tmp(tmph);
    tcg_gen_add_i64(val, val, tmp);
    tcg_temp_free_i64(tmp);
}

/* data processing instructions */
static void do_datap(CPUState *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 {
        TCGV_UNUSED(tmp);
    }

    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, tmp, tmp2);
            gen_exception_return(s, tmp);
        } else {
            if (UCOP_SET_S) {
                gen_helper_sub_cc(tmp, 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, 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, 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, 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, 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, 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, tmp, tmp2);
        }
        dead_tmp(tmp);
        break;
    case 0x0b:
        if (UCOP_SET_S) {
            gen_helper_add_cc(tmp, 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(CPUState *env, DisasContext *s, uint32_t insn)
{
    TCGv tmp;
    TCGv tmp2;
    TCGv_i64 tmp64;

    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)) {
            tmp64 = gen_muls_i64_i32(tmp, tmp2);
        } else {
            tmp64 = gen_mulu_i64_i32(tmp, tmp2);
        }
        if (UCOP_SET(25)) { /* mult accumulate */
            gen_addq(s, tmp64, UCOP_REG_LO, UCOP_REG_HI);
        }
        gen_storeq_reg(s, UCOP_REG_LO, UCOP_REG_HI, tmp64);
        tcg_temp_free_i64(tmp64);
    } 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(CPUState *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);
        }
        store_reg(s, UCOP_REG_D, tmp);
        return;
    }

    if ((insn & 0xfbf83fe0) == 0x12f80120) {
        /* clz */
        tmp = load_reg(s, UCOP_REG_M);
        if (UCOP_SET(26)) {
            gen_helper_clo(tmp, tmp);
        } else {
            gen_helper_clz(tmp, tmp);
        }
        store_reg(s, UCOP_REG_D, tmp);
        return;
    }

    /* otherwise */
    ILLEGAL;
}

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

    tmp2 = load_reg(s, UCOP_REG_N);
    i = (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, i);
        } else {
            tmp = gen_ld32(tmp2, i);
        }
    } else {
        /* store */
        tmp = load_reg(s, UCOP_REG_D);
        if (UCOP_SET_B) {
            gen_st8(tmp, tmp2, i);
        } else {
            gen_st32(tmp, tmp2, i);
        }
    }
    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(CPUState *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(CPUState *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(CPUState *env, DisasContext *s, uint32_t insn)
{
    unsigned int val, i;
    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;
        }
    }

    addr = load_reg(s, UCOP_REG_N);

    /* compute total size */
    loaded_base = 0;
    TCGV_UNUSED(loaded_var);
    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, IS_USER(s));
                if (reg == 31) {
                    gen_bx(s, tmp);
                } else if (user) {
                    tmp2 = tcg_const_i32(reg);
                    gen_helper_set_user_reg(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, tmp2);
                    tcg_temp_free_i32(tmp2);
                } else {
                    tmp = load_reg(s, reg);
                }
                gen_st32(tmp, addr, IS_USER(s));
            }
            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(CPUState *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(CPUState *env, DisasContext *s)
{
    unsigned int insn;

    insn = ldl_code(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 0b000:
        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;
        }
    case 0b001:
        if (((UCOP_OPCODES >> 2) == 2) && !UCOP_SET_S) {
            do_misc(env, s, insn);
            break;
        }
        do_datap(env, s, insn);
        break;

    case 0b010:
        if (UCOP_SET(8) && UCOP_SET(5)) {
            do_ldst_hwsb(env, s, insn);
            break;
        }
        if (UCOP_SET(8) || UCOP_SET(5)) {
            ILLEGAL;
        }
    case 0b011:
        do_ldst_ir(env, s, insn);
        break;

    case 0b100:
        if (UCOP_SET(8)) {
            ILLEGAL; /* extended instructions */
        }
        do_ldst_m(env, s, insn);
        break;
    case 0b101:
        do_branch(env, s, insn);
        break;
    case 0b110:
        /* Coprocessor.  */
        disas_coproc_insn(env, s, insn);
        break;
    case 0b111:
        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;
    }

    return;
}

/* generate intermediate code in gen_opc_buf and gen_opparam_buf for
   basic block 'tb'. If search_pc is TRUE, also generate PC
   information for each intermediate instruction. */
static inline void gen_intermediate_code_internal(CPUState *env,
        TranslationBlock *tb, int search_pc)
{
    DisasContext dc1, *dc = &dc1;
    CPUBreakpoint *bp;
    uint16_t *gen_opc_end;
    int j, lj;
    target_ulong pc_start;
    uint32_t next_page_start;
    int num_insns;
    int max_insns;

    /* generate intermediate code */
    num_temps = 0;

    pc_start = tb->pc;

    dc->tb = tb;

    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    dc->is_jmp = DISAS_NEXT;
    dc->pc = pc_start;
    dc->singlestep_enabled = env->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();
    next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
    lj = -1;
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0) {
        max_insns = CF_COUNT_MASK;
    }

    gen_icount_start();
    do {
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
                if (bp->pc == dc->pc) {
                    gen_set_pc_im(dc->pc);
                    gen_exception(EXCP_DEBUG);
                    dc->is_jmp = DISAS_JUMP;
                    /* Advance PC so that clearing the breakpoint will
                       invalidate this TB.  */
                    dc->pc += 2; /* FIXME */
                    goto done_generating;
                    break;
                }
            }
        }
        if (search_pc) {
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j) {
                    gen_opc_instr_start[lj++] = 0;
                }
            }
            gen_opc_pc[lj] = dc->pc;
            gen_opc_instr_start[lj] = 1;
            gen_opc_icount[lj] = num_insns;
        }

        if (num_insns + 1 == max_insns && (tb->cflags & 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.  */
        num_insns++;
    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
             !env->singlestep_enabled &&
             !singlestep &&
             dc->pc < next_page_start &&
             num_insns < max_insns);

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

    /* 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(env->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(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_icount_end(tb, num_insns);
    *gen_opc_ptr = INDEX_op_end;

#ifdef DEBUG_DISAS
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        qemu_log("----------------\n");
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
        log_target_disas(pc_start, dc->pc - pc_start, 0);
        qemu_log("\n");
    }
#endif
    if (search_pc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j) {
            gen_opc_instr_start[lj++] = 0;
        }
    } else {
        tb->size = dc->pc - pc_start;
        tb->icount = num_insns;
    }
}

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

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

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

#define UCF64_DUMP_STATE
void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
        int flags)
{
    int i;
#ifdef UCF64_DUMP_STATE
    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;
#endif
    uint32_t psr;

    for (i = 0; i < 32; i++) {
        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
        if ((i % 4) == 3) {
            cpu_fprintf(f, "\n");
        } else {
            cpu_fprintf(f, " ");
        }
    }
    psr = cpu_asr_read(env);
    cpu_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]);

#ifdef UCF64_DUMP_STATE
    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;
        cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%" PRIx64 "(%8g)\n",
                    i * 2, (int)s0.i, s0.s,
                    i * 2 + 1, (int)s1.i, s1.s,
                    i, (uint64_t)d0.f64, d0.d);
    }
    cpu_fprintf(f, "FPSCR: %08x\n", (int)env->ucf64.xregs[UC32_UCF64_FPSCR]);
#endif
}

void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
{
    env->regs[31] = gen_opc_pc[pc_pos];
}
