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

/*
 * FIXME:
 * The condition code translation is in need of attention.
 */

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

#include "cpu.h"
#include "disas.h"
#include "tcg-op.h"
#include "helper.h"
#include "mmu.h"
#include "crisv32-decode.h"
#include "qemu-common.h"

#define GEN_HELPER 1
#include "helper.h"

#define DISAS_CRIS 0
#if DISAS_CRIS
#  define LOG_DIS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
#else
#  define LOG_DIS(...) do { } while (0)
#endif

#define D(x)
#define BUG() (gen_BUG(dc, __FILE__, __LINE__))
#define BUG_ON(x) ({if (x) BUG();})

#define DISAS_SWI 5

/* Used by the decoder.  */
#define EXTRACT_FIELD(src, start, end) \
            (((src) >> start) & ((1 << (end - start + 1)) - 1))

#define CC_MASK_NZ 0xc
#define CC_MASK_NZV 0xe
#define CC_MASK_NZVC 0xf
#define CC_MASK_RNZV 0x10e

static TCGv_ptr cpu_env;
static TCGv cpu_R[16];
static TCGv cpu_PR[16];
static TCGv cc_x;
static TCGv cc_src;
static TCGv cc_dest;
static TCGv cc_result;
static TCGv cc_op;
static TCGv cc_size;
static TCGv cc_mask;

static TCGv env_btaken;
static TCGv env_btarget;
static TCGv env_pc;

#include "gen-icount.h"

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

	/* Decoder.  */
	unsigned int (*decoder)(struct DisasContext *dc);
	uint32_t ir;
	uint32_t opcode;
	unsigned int op1;
	unsigned int op2;
	unsigned int zsize, zzsize;
	unsigned int mode;
	unsigned int postinc;

	unsigned int size;
	unsigned int src;
	unsigned int dst;
	unsigned int cond;

	int update_cc;
	int cc_op;
	int cc_size;
	uint32_t cc_mask;

	int cc_size_uptodate; /* -1 invalid or last written value.  */

	int cc_x_uptodate;  /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate.  */
	int flags_uptodate; /* Wether or not $ccs is uptodate.  */
	int flagx_known; /* Wether or not flags_x has the x flag known at
			    translation time.  */
	int flags_x;

	int clear_x; /* Clear x after this insn?  */
	int clear_prefix; /* Clear prefix after this insn?  */
	int clear_locked_irq; /* Clear the irq lockout.  */
	int cpustate_changed;
	unsigned int tb_flags; /* tb dependent flags.  */
	int is_jmp;

#define JMP_NOJMP     0
#define JMP_DIRECT    1
#define JMP_DIRECT_CC 2
#define JMP_INDIRECT  3
	int jmp; /* 0=nojmp, 1=direct, 2=indirect.  */ 
	uint32_t jmp_pc;

	int delayed_branch;

	struct TranslationBlock *tb;
	int singlestep_enabled;
} DisasContext;

static void gen_BUG(DisasContext *dc, const char *file, int line)
{
	printf ("BUG: pc=%x %s %d\n", dc->pc, file, line);
	qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line);
	cpu_abort(dc->env, "%s:%d\n", file, line);
}

static const char *regnames[] =
{
	"$r0", "$r1", "$r2", "$r3",
	"$r4", "$r5", "$r6", "$r7",
	"$r8", "$r9", "$r10", "$r11",
	"$r12", "$r13", "$sp", "$acr",
};
static const char *pregnames[] =
{
	"$bz", "$vr", "$pid", "$srs",
	"$wz", "$exs", "$eda", "$mof",
	"$dz", "$ebp", "$erp", "$srp",
	"$nrp", "$ccs", "$usp", "$spc",
};

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

#define t_gen_mov_TN_env(tn, member) \
 _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
#define t_gen_mov_env_TN(member, tn) \
 _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))

static inline void t_gen_mov_TN_reg(TCGv tn, int r)
{
	if (r < 0 || r > 15)
		fprintf(stderr, "wrong register read $r%d\n", r);
	tcg_gen_mov_tl(tn, cpu_R[r]);
}
static inline void t_gen_mov_reg_TN(int r, TCGv tn)
{
	if (r < 0 || r > 15)
		fprintf(stderr, "wrong register write $r%d\n", r);
	tcg_gen_mov_tl(cpu_R[r], tn);
}

static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
{
	if (offset > sizeof (CPUState))
		fprintf(stderr, "wrong load from env from off=%d\n", offset);
	tcg_gen_ld_tl(tn, cpu_env, offset);
}
static inline void _t_gen_mov_env_TN(int offset, TCGv tn)
{
	if (offset > sizeof (CPUState))
		fprintf(stderr, "wrong store to env at off=%d\n", offset);
	tcg_gen_st_tl(tn, cpu_env, offset);
}

static inline void t_gen_mov_TN_preg(TCGv tn, int r)
{
	if (r < 0 || r > 15)
		fprintf(stderr, "wrong register read $p%d\n", r);
	if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
		tcg_gen_mov_tl(tn, tcg_const_tl(0));
	else if (r == PR_VR)
		tcg_gen_mov_tl(tn, tcg_const_tl(32));
	else
		tcg_gen_mov_tl(tn, cpu_PR[r]);
}
static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
{
	if (r < 0 || r > 15)
		fprintf(stderr, "wrong register write $p%d\n", r);
	if (r == PR_BZ || r == PR_WZ || r == PR_DZ)
		return;
	else if (r == PR_SRS)
		tcg_gen_andi_tl(cpu_PR[r], tn, 3);
	else {
		if (r == PR_PID) 
			gen_helper_tlb_flush_pid(tn);
		if (dc->tb_flags & S_FLAG && r == PR_SPC) 
			gen_helper_spc_write(tn);
		else if (r == PR_CCS)
			dc->cpustate_changed = 1;
		tcg_gen_mov_tl(cpu_PR[r], tn);
	}
}

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

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

static int cris_fetch(DisasContext *dc, uint32_t addr,
		      unsigned int size, unsigned int sign)
{
	int r;

	switch (size) {
		case 4:
		{
			r = ldl_code(addr);
			break;
		}
		case 2:
		{
			if (sign) {
				r = ldsw_code(addr);
			} else {
				r = lduw_code(addr);
			}
			break;
		}
		case 1:
		{
			if (sign) {
				r = ldsb_code(addr);
			} else {
				r = ldub_code(addr);
			}
			break;
		}
		default:
			cpu_abort(dc->env, "Invalid fetch size %d\n", size);
			break;
	}
	return r;
}

static void cris_lock_irq(DisasContext *dc)
{
	dc->clear_locked_irq = 0;
	t_gen_mov_env_TN(locked_irq, tcg_const_tl(1));
}

static inline void t_gen_raise_exception(uint32_t index)
{
        TCGv_i32 tmp = tcg_const_i32(index);
	gen_helper_raise_exception(tmp);
        tcg_temp_free_i32(tmp);
}

static void t_gen_lsl(TCGv d, TCGv a, TCGv b)
{
	TCGv t0, t_31;

	t0 = tcg_temp_new();
	t_31 = tcg_const_tl(31);
	tcg_gen_shl_tl(d, a, b);

	tcg_gen_sub_tl(t0, t_31, b);
	tcg_gen_sar_tl(t0, t0, t_31);
	tcg_gen_and_tl(t0, t0, d);
	tcg_gen_xor_tl(d, d, t0);
	tcg_temp_free(t0);
	tcg_temp_free(t_31);
}

static void t_gen_lsr(TCGv d, TCGv a, TCGv b)
{
	TCGv t0, t_31;

	t0 = tcg_temp_new();
	t_31 = tcg_temp_new();
	tcg_gen_shr_tl(d, a, b);

	tcg_gen_movi_tl(t_31, 31);
	tcg_gen_sub_tl(t0, t_31, b);
	tcg_gen_sar_tl(t0, t0, t_31);
	tcg_gen_and_tl(t0, t0, d);
	tcg_gen_xor_tl(d, d, t0);
	tcg_temp_free(t0);
	tcg_temp_free(t_31);
}

static void t_gen_asr(TCGv d, TCGv a, TCGv b)
{
	TCGv t0, t_31;

	t0 = tcg_temp_new();
	t_31 = tcg_temp_new();
	tcg_gen_sar_tl(d, a, b);

	tcg_gen_movi_tl(t_31, 31);
	tcg_gen_sub_tl(t0, t_31, b);
	tcg_gen_sar_tl(t0, t0, t_31);
	tcg_gen_or_tl(d, d, t0);
	tcg_temp_free(t0);
	tcg_temp_free(t_31);
}

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

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

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

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

	tcg_temp_free_i64(t0);
	tcg_temp_free_i64(t1);
}

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

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

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

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

	tcg_temp_free_i64(t0);
	tcg_temp_free_i64(t1);
}

static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b)
{
	int l1;

	l1 = gen_new_label();

	/* 
	 * d <<= 1
	 * if (d >= s)
	 *    d -= s;
	 */
	tcg_gen_shli_tl(d, a, 1);
	tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1);
	tcg_gen_sub_tl(d, d, b);
	gen_set_label(l1);
}

static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs)
{
	TCGv t;

	/* 
	 * d <<= 1
	 * if (n)
	 *    d += s;
	 */
	t = tcg_temp_new();
	tcg_gen_shli_tl(d, a, 1);
	tcg_gen_shli_tl(t, ccs, 31 - 3);
	tcg_gen_sari_tl(t, t, 31);
	tcg_gen_and_tl(t, t, b);
	tcg_gen_add_tl(d, d, t);
	tcg_temp_free(t);
}

/* Extended arithmetics on CRIS.  */
static inline void t_gen_add_flag(TCGv d, int flag)
{
	TCGv c;

	c = tcg_temp_new();
	t_gen_mov_TN_preg(c, PR_CCS);
	/* Propagate carry into d.  */
	tcg_gen_andi_tl(c, c, 1 << flag);
	if (flag)
		tcg_gen_shri_tl(c, c, flag);
	tcg_gen_add_tl(d, d, c);
	tcg_temp_free(c);
}

static inline void t_gen_addx_carry(DisasContext *dc, TCGv d)
{
	if (dc->flagx_known) {
		if (dc->flags_x) {
			TCGv c;
            
			c = tcg_temp_new();
			t_gen_mov_TN_preg(c, PR_CCS);
			/* C flag is already at bit 0.  */
			tcg_gen_andi_tl(c, c, C_FLAG);
			tcg_gen_add_tl(d, d, c);
			tcg_temp_free(c);
		}
	} else {
		TCGv x, c;

		x = tcg_temp_new();
		c = tcg_temp_new();
		t_gen_mov_TN_preg(x, PR_CCS);
		tcg_gen_mov_tl(c, x);

		/* Propagate carry into d if X is set. Branch free.  */
		tcg_gen_andi_tl(c, c, C_FLAG);
		tcg_gen_andi_tl(x, x, X_FLAG);
		tcg_gen_shri_tl(x, x, 4);

		tcg_gen_and_tl(x, x, c);
		tcg_gen_add_tl(d, d, x);        
		tcg_temp_free(x);
		tcg_temp_free(c);
	}
}

static inline void t_gen_subx_carry(DisasContext *dc, TCGv d)
{
	if (dc->flagx_known) {
		if (dc->flags_x) {
			TCGv c;
            
			c = tcg_temp_new();
			t_gen_mov_TN_preg(c, PR_CCS);
			/* C flag is already at bit 0.  */
			tcg_gen_andi_tl(c, c, C_FLAG);
			tcg_gen_sub_tl(d, d, c);
			tcg_temp_free(c);
		}
	} else {
		TCGv x, c;

		x = tcg_temp_new();
		c = tcg_temp_new();
		t_gen_mov_TN_preg(x, PR_CCS);
		tcg_gen_mov_tl(c, x);

		/* Propagate carry into d if X is set. Branch free.  */
		tcg_gen_andi_tl(c, c, C_FLAG);
		tcg_gen_andi_tl(x, x, X_FLAG);
		tcg_gen_shri_tl(x, x, 4);

		tcg_gen_and_tl(x, x, c);
		tcg_gen_sub_tl(d, d, x);
		tcg_temp_free(x);
		tcg_temp_free(c);
	}
}

/* Swap the two bytes within each half word of the s operand.
   T0 = ((T0 << 8) & 0xff00ff00) | ((T0 >> 8) & 0x00ff00ff)  */
static inline void t_gen_swapb(TCGv d, TCGv s)
{
	TCGv t, org_s;

	t = tcg_temp_new();
	org_s = tcg_temp_new();

	/* d and s may refer to the same object.  */
	tcg_gen_mov_tl(org_s, s);
	tcg_gen_shli_tl(t, org_s, 8);
	tcg_gen_andi_tl(d, t, 0xff00ff00);
	tcg_gen_shri_tl(t, org_s, 8);
	tcg_gen_andi_tl(t, t, 0x00ff00ff);
	tcg_gen_or_tl(d, d, t);
	tcg_temp_free(t);
	tcg_temp_free(org_s);
}

/* Swap the halfwords of the s operand.  */
static inline void t_gen_swapw(TCGv d, TCGv s)
{
	TCGv t;
	/* d and s refer the same object.  */
	t = tcg_temp_new();
	tcg_gen_mov_tl(t, s);
	tcg_gen_shli_tl(d, t, 16);
	tcg_gen_shri_tl(t, t, 16);
	tcg_gen_or_tl(d, d, t);
	tcg_temp_free(t);
}

/* Reverse the within each byte.
   T0 = (((T0 << 7) & 0x80808080) |
   ((T0 << 5) & 0x40404040) |
   ((T0 << 3) & 0x20202020) |
   ((T0 << 1) & 0x10101010) |
   ((T0 >> 1) & 0x08080808) |
   ((T0 >> 3) & 0x04040404) |
   ((T0 >> 5) & 0x02020202) |
   ((T0 >> 7) & 0x01010101));
 */
static inline void t_gen_swapr(TCGv d, TCGv s)
{
	struct {
		int shift; /* LSL when positive, LSR when negative.  */
		uint32_t mask;
	} bitrev [] = {
		{7, 0x80808080},
		{5, 0x40404040},
		{3, 0x20202020},
		{1, 0x10101010},
		{-1, 0x08080808},
		{-3, 0x04040404},
		{-5, 0x02020202},
		{-7, 0x01010101}
	};
	int i;
	TCGv t, org_s;

	/* d and s refer the same object.  */
	t = tcg_temp_new();
	org_s = tcg_temp_new();
	tcg_gen_mov_tl(org_s, s);

	tcg_gen_shli_tl(t, org_s,  bitrev[0].shift);
	tcg_gen_andi_tl(d, t,  bitrev[0].mask);
	for (i = 1; i < ARRAY_SIZE(bitrev); i++) {
		if (bitrev[i].shift >= 0) {
			tcg_gen_shli_tl(t, org_s,  bitrev[i].shift);
		} else {
			tcg_gen_shri_tl(t, org_s,  -bitrev[i].shift);
		}
		tcg_gen_andi_tl(t, t,  bitrev[i].mask);
		tcg_gen_or_tl(d, d, t);
	}
	tcg_temp_free(t);
	tcg_temp_free(org_s);
}

static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
{
	int l1;

	l1 = gen_new_label();

	/* Conditional jmp.  */
	tcg_gen_mov_tl(env_pc, pc_false);
	tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
	tcg_gen_mov_tl(env_pc, pc_true);
	gen_set_label(l1);
}

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

static inline void cris_clear_x_flag(DisasContext *dc)
{
	if (dc->flagx_known && dc->flags_x)
		dc->flags_uptodate = 0;

	dc->flagx_known = 1;
	dc->flags_x = 0;
}

static void cris_flush_cc_state(DisasContext *dc)
{
	if (dc->cc_size_uptodate != dc->cc_size) {
		tcg_gen_movi_tl(cc_size, dc->cc_size);
		dc->cc_size_uptodate = dc->cc_size;
	}
	tcg_gen_movi_tl(cc_op, dc->cc_op);
	tcg_gen_movi_tl(cc_mask, dc->cc_mask);
}

static void cris_evaluate_flags(DisasContext *dc)
{
	if (dc->flags_uptodate)
		return;

	cris_flush_cc_state(dc);

	switch (dc->cc_op)
	{
	case CC_OP_MCP:
		gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
					cpu_PR[PR_CCS], cc_src,
					cc_dest, cc_result);
		break;
	case CC_OP_MULS:
		gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
					cpu_PR[PR_CCS], cc_result,
					cpu_PR[PR_MOF]);
		break;
	case CC_OP_MULU:
		gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
					cpu_PR[PR_CCS], cc_result,
					cpu_PR[PR_MOF]);
		break;
	case CC_OP_MOVE:
	case CC_OP_AND:
	case CC_OP_OR:
	case CC_OP_XOR:
	case CC_OP_ASR:
	case CC_OP_LSR:
	case CC_OP_LSL:
		switch (dc->cc_size)
		{
		case 4:
			gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
						cpu_PR[PR_CCS], cc_result);
			break;
		case 2:
			gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
						cpu_PR[PR_CCS], cc_result);
			break;
		default:
			gen_helper_evaluate_flags();
			break;
		}
		break;
	case CC_OP_FLAGS:
		/* live.  */
		break;
	case CC_OP_SUB:
	case CC_OP_CMP:
		if (dc->cc_size == 4)
			gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
		else
			gen_helper_evaluate_flags();

		break;
	default:
		switch (dc->cc_size)
		{
			case 4:
			gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
				cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
				break;
			default:
				gen_helper_evaluate_flags();
				break;
		}
		break;
	}

	if (dc->flagx_known) {
		if (dc->flags_x)
			tcg_gen_ori_tl(cpu_PR[PR_CCS], 
				       cpu_PR[PR_CCS], X_FLAG);
		else if (dc->cc_op == CC_OP_FLAGS)
			tcg_gen_andi_tl(cpu_PR[PR_CCS], 
					cpu_PR[PR_CCS], ~X_FLAG);
        }
	dc->flags_uptodate = 1;
}

static void cris_cc_mask(DisasContext *dc, unsigned int mask)
{
	uint32_t ovl;

	if (!mask) {
		dc->update_cc = 0;
		return;
	}	

	/* Check if we need to evaluate the condition codes due to 
	   CC overlaying.  */
	ovl = (dc->cc_mask ^ mask) & ~mask;
	if (ovl) {
		/* TODO: optimize this case. It trigs all the time.  */
		cris_evaluate_flags (dc);
	}
	dc->cc_mask = mask;
	dc->update_cc = 1;
}

static void cris_update_cc_op(DisasContext *dc, int op, int size)
{
	dc->cc_op = op;
	dc->cc_size = size;
	dc->flags_uptodate = 0;
}

static inline void cris_update_cc_x(DisasContext *dc)
{
	/* Save the x flag state at the time of the cc snapshot.  */
	if (dc->flagx_known) {
		if (dc->cc_x_uptodate == (2 | dc->flags_x))
			return;
		tcg_gen_movi_tl(cc_x, dc->flags_x);
		dc->cc_x_uptodate = 2 | dc->flags_x;
	}
	else {
		tcg_gen_andi_tl(cc_x, cpu_PR[PR_CCS], X_FLAG);
		dc->cc_x_uptodate = 1;
	}
}

/* Update cc prior to executing ALU op. Needs source operands untouched.  */
static void cris_pre_alu_update_cc(DisasContext *dc, int op, 
				   TCGv dst, TCGv src, int size)
{
	if (dc->update_cc) {
		cris_update_cc_op(dc, op, size);
		tcg_gen_mov_tl(cc_src, src);

		if (op != CC_OP_MOVE
		    && op != CC_OP_AND
		    && op != CC_OP_OR
		    && op != CC_OP_XOR
		    && op != CC_OP_ASR
		    && op != CC_OP_LSR
		    && op != CC_OP_LSL)
			tcg_gen_mov_tl(cc_dest, dst);

		cris_update_cc_x(dc);
	}
}

/* Update cc after executing ALU op. needs the result.  */
static inline void cris_update_result(DisasContext *dc, TCGv res)
{
	if (dc->update_cc)
		tcg_gen_mov_tl(cc_result, res);
}

/* Returns one if the write back stage should execute.  */
static void cris_alu_op_exec(DisasContext *dc, int op, 
			       TCGv dst, TCGv a, TCGv b, int size)
{
	/* Emit the ALU insns.  */
	switch (op)
	{
		case CC_OP_ADD:
			tcg_gen_add_tl(dst, a, b);
			/* Extended arithmetics.  */
			t_gen_addx_carry(dc, dst);
			break;
		case CC_OP_ADDC:
			tcg_gen_add_tl(dst, a, b);
			t_gen_add_flag(dst, 0); /* C_FLAG.  */
			break;
		case CC_OP_MCP:
			tcg_gen_add_tl(dst, a, b);
			t_gen_add_flag(dst, 8); /* R_FLAG.  */
			break;
		case CC_OP_SUB:
			tcg_gen_sub_tl(dst, a, b);
			/* Extended arithmetics.  */
			t_gen_subx_carry(dc, dst);
			break;
		case CC_OP_MOVE:
			tcg_gen_mov_tl(dst, b);
			break;
		case CC_OP_OR:
			tcg_gen_or_tl(dst, a, b);
			break;
		case CC_OP_AND:
			tcg_gen_and_tl(dst, a, b);
			break;
		case CC_OP_XOR:
			tcg_gen_xor_tl(dst, a, b);
			break;
		case CC_OP_LSL:
			t_gen_lsl(dst, a, b);
			break;
		case CC_OP_LSR:
			t_gen_lsr(dst, a, b);
			break;
		case CC_OP_ASR:
			t_gen_asr(dst, a, b);
			break;
		case CC_OP_NEG:
			tcg_gen_neg_tl(dst, b);
			/* Extended arithmetics.  */
			t_gen_subx_carry(dc, dst);
			break;
		case CC_OP_LZ:
			gen_helper_lz(dst, b);
			break;
		case CC_OP_MULS:
			t_gen_muls(dst, cpu_PR[PR_MOF], a, b);
			break;
		case CC_OP_MULU:
			t_gen_mulu(dst, cpu_PR[PR_MOF], a, b);
			break;
		case CC_OP_DSTEP:
			t_gen_cris_dstep(dst, a, b);
			break;
		case CC_OP_MSTEP:
			t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]);
			break;
		case CC_OP_BOUND:
		{
			int l1;
			l1 = gen_new_label();
			tcg_gen_mov_tl(dst, a);
			tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1);
			tcg_gen_mov_tl(dst, b);
			gen_set_label(l1);
		}
		break;
		case CC_OP_CMP:
			tcg_gen_sub_tl(dst, a, b);
			/* Extended arithmetics.  */
			t_gen_subx_carry(dc, dst);
			break;
		default:
			qemu_log("illegal ALU op.\n");
			BUG();
			break;
	}

	if (size == 1)
		tcg_gen_andi_tl(dst, dst, 0xff);
	else if (size == 2)
		tcg_gen_andi_tl(dst, dst, 0xffff);
}

static void cris_alu(DisasContext *dc, int op,
			       TCGv d, TCGv op_a, TCGv op_b, int size)
{
	TCGv tmp;
	int writeback;

	writeback = 1;

	if (op == CC_OP_CMP) {
		tmp = tcg_temp_new();
		writeback = 0;
	} else if (size == 4) {
		tmp = d;
		writeback = 0;
	} else
		tmp = tcg_temp_new();


	cris_pre_alu_update_cc(dc, op, op_a, op_b, size);
	cris_alu_op_exec(dc, op, tmp, op_a, op_b, size);
	cris_update_result(dc, tmp);

	/* Writeback.  */
	if (writeback) {
		if (size == 1)
			tcg_gen_andi_tl(d, d, ~0xff);
		else
			tcg_gen_andi_tl(d, d, ~0xffff);
		tcg_gen_or_tl(d, d, tmp);
	}
	if (!TCGV_EQUAL(tmp, d))
		tcg_temp_free(tmp);
}

static int arith_cc(DisasContext *dc)
{
	if (dc->update_cc) {
		switch (dc->cc_op) {
			case CC_OP_ADDC: return 1;
			case CC_OP_ADD: return 1;
			case CC_OP_SUB: return 1;
			case CC_OP_DSTEP: return 1;
			case CC_OP_LSL: return 1;
			case CC_OP_LSR: return 1;
			case CC_OP_ASR: return 1;
			case CC_OP_CMP: return 1;
			case CC_OP_NEG: return 1;
			case CC_OP_OR: return 1;
			case CC_OP_AND: return 1;
			case CC_OP_XOR: return 1;
			case CC_OP_MULU: return 1;
			case CC_OP_MULS: return 1;
			default:
				return 0;
		}
	}
	return 0;
}

static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
{
	int arith_opt, move_opt;

	/* TODO: optimize more condition codes.  */

	/*
	 * If the flags are live, we've gotta look into the bits of CCS.
	 * Otherwise, if we just did an arithmetic operation we try to
	 * evaluate the condition code faster.
	 *
	 * When this function is done, T0 should be non-zero if the condition
	 * code is true.
	 */
	arith_opt = arith_cc(dc) && !dc->flags_uptodate;
	move_opt = (dc->cc_op == CC_OP_MOVE);
	switch (cond) {
		case CC_EQ:
			if ((arith_opt || move_opt)
			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
				tcg_gen_setcond_tl(TCG_COND_EQ, cc,
						   cc_result, tcg_const_tl(0));
			}
			else {
				cris_evaluate_flags(dc);
				tcg_gen_andi_tl(cc, 
						cpu_PR[PR_CCS], Z_FLAG);
			}
			break;
		case CC_NE:
			if ((arith_opt || move_opt)
			    && dc->cc_x_uptodate != (2 | X_FLAG)) {
				tcg_gen_mov_tl(cc, cc_result);
	 		} else {
				cris_evaluate_flags(dc);
				tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
						Z_FLAG);
				tcg_gen_andi_tl(cc, cc, Z_FLAG);
			}
			break;
		case CC_CS:
			cris_evaluate_flags(dc);
			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], C_FLAG);
			break;
		case CC_CC:
			cris_evaluate_flags(dc);
			tcg_gen_xori_tl(cc, cpu_PR[PR_CCS], C_FLAG);
			tcg_gen_andi_tl(cc, cc, C_FLAG);
			break;
		case CC_VS:
			cris_evaluate_flags(dc);
			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], V_FLAG);
			break;
		case CC_VC:
			cris_evaluate_flags(dc);
			tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
					V_FLAG);
			tcg_gen_andi_tl(cc, cc, V_FLAG);
			break;
		case CC_PL:
			if (arith_opt || move_opt) {
				int bits = 31;

				if (dc->cc_size == 1)
					bits = 7;
				else if (dc->cc_size == 2)
					bits = 15;	

				tcg_gen_shri_tl(cc, cc_result, bits);
				tcg_gen_xori_tl(cc, cc, 1);
			} else {
				cris_evaluate_flags(dc);
				tcg_gen_xori_tl(cc, cpu_PR[PR_CCS],
						N_FLAG);
				tcg_gen_andi_tl(cc, cc, N_FLAG);
			}
			break;
		case CC_MI:
			if (arith_opt || move_opt) {
				int bits = 31;

				if (dc->cc_size == 1)
					bits = 7;
				else if (dc->cc_size == 2)
					bits = 15;	

				tcg_gen_shri_tl(cc, cc_result, bits);
				tcg_gen_andi_tl(cc, cc, 1);
			}
			else {
				cris_evaluate_flags(dc);
				tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
						N_FLAG);
			}
			break;
		case CC_LS:
			cris_evaluate_flags(dc);
			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS],
					C_FLAG | Z_FLAG);
			break;
		case CC_HI:
			cris_evaluate_flags(dc);
			{
				TCGv tmp;

				tmp = tcg_temp_new();
				tcg_gen_xori_tl(tmp, cpu_PR[PR_CCS],
						C_FLAG | Z_FLAG);
				/* Overlay the C flag on top of the Z.  */
				tcg_gen_shli_tl(cc, tmp, 2);
				tcg_gen_and_tl(cc, tmp, cc);
				tcg_gen_andi_tl(cc, cc, Z_FLAG);

				tcg_temp_free(tmp);
			}
			break;
		case CC_GE:
			cris_evaluate_flags(dc);
			/* Overlay the V flag on top of the N.  */
			tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
			tcg_gen_xor_tl(cc,
				       cpu_PR[PR_CCS], cc);
			tcg_gen_andi_tl(cc, cc, N_FLAG);
			tcg_gen_xori_tl(cc, cc, N_FLAG);
			break;
		case CC_LT:
			cris_evaluate_flags(dc);
			/* Overlay the V flag on top of the N.  */
			tcg_gen_shli_tl(cc, cpu_PR[PR_CCS], 2);
			tcg_gen_xor_tl(cc,
				       cpu_PR[PR_CCS], cc);
			tcg_gen_andi_tl(cc, cc, N_FLAG);
			break;
		case CC_GT:
			cris_evaluate_flags(dc);
			{
				TCGv n, z;

				n = tcg_temp_new();
				z = tcg_temp_new();

				/* To avoid a shift we overlay everything on
				   the V flag.  */
				tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
				tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);
				/* invert Z.  */
				tcg_gen_xori_tl(z, z, 2);

				tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
				tcg_gen_xori_tl(n, n, 2);
				tcg_gen_and_tl(cc, z, n);
				tcg_gen_andi_tl(cc, cc, 2);

				tcg_temp_free(n);
				tcg_temp_free(z);
			}
			break;
		case CC_LE:
			cris_evaluate_flags(dc);
			{
				TCGv n, z;

				n = tcg_temp_new();
				z = tcg_temp_new();

				/* To avoid a shift we overlay everything on
				   the V flag.  */
				tcg_gen_shri_tl(n, cpu_PR[PR_CCS], 2);
				tcg_gen_shri_tl(z, cpu_PR[PR_CCS], 1);

				tcg_gen_xor_tl(n, n, cpu_PR[PR_CCS]);
				tcg_gen_or_tl(cc, z, n);
				tcg_gen_andi_tl(cc, cc, 2);

				tcg_temp_free(n);
				tcg_temp_free(z);
			}
			break;
		case CC_P:
			cris_evaluate_flags(dc);
			tcg_gen_andi_tl(cc, cpu_PR[PR_CCS], P_FLAG);
			break;
		case CC_A:
			tcg_gen_movi_tl(cc, 1);
			break;
		default:
			BUG();
			break;
	};
}

static void cris_store_direct_jmp(DisasContext *dc)
{
	/* Store the direct jmp state into the cpu-state.  */
	if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) {
		if (dc->jmp == JMP_DIRECT) {
			tcg_gen_movi_tl(env_btaken, 1);
		}
		tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
		dc->jmp = JMP_INDIRECT;
	}
}

static void cris_prepare_cc_branch (DisasContext *dc, 
				    int offset, int cond)
{
	/* This helps us re-schedule the micro-code to insns in delay-slots
	   before the actual jump.  */
	dc->delayed_branch = 2;
	dc->jmp = JMP_DIRECT_CC;
	dc->jmp_pc = dc->pc + offset;

	gen_tst_cc (dc, env_btaken, cond);
	tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
}


/* jumps, when the dest is in a live reg for example. Direct should be set
   when the dest addr is constant to allow tb chaining.  */
static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
{
	/* This helps us re-schedule the micro-code to insns in delay-slots
	   before the actual jump.  */
	dc->delayed_branch = 2;
	dc->jmp = type;
	if (type == JMP_INDIRECT) {
		tcg_gen_movi_tl(env_btaken, 1);
	}
}

static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
{
	int mem_index = cpu_mmu_index(dc->env);

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

        tcg_gen_qemu_ld64(dst, addr, mem_index);
}

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

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

	if (size == 1) {
		if (sign)
			tcg_gen_qemu_ld8s(dst, addr, mem_index);
		else
			tcg_gen_qemu_ld8u(dst, addr, mem_index);
	}
	else if (size == 2) {
		if (sign)
			tcg_gen_qemu_ld16s(dst, addr, mem_index);
		else
			tcg_gen_qemu_ld16u(dst, addr, mem_index);
	}
	else if (size == 4) {
		tcg_gen_qemu_ld32u(dst, addr, mem_index);
	}
	else {
		abort();
	}
}

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

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


	/* Conditional writes. We only support the kind were X and P are known
	   at translation time.  */
	if (dc->flagx_known && dc->flags_x && (dc->tb_flags & P_FLAG)) {
		dc->postinc = 0;
		cris_evaluate_flags(dc);
		tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], C_FLAG);
		return;
	}

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

	if (dc->flagx_known && dc->flags_x) {
		cris_evaluate_flags(dc);
		tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~C_FLAG);
	}
}

static inline void t_gen_sext(TCGv d, TCGv s, int size)
{
	if (size == 1)
		tcg_gen_ext8s_i32(d, s);
	else if (size == 2)
		tcg_gen_ext16s_i32(d, s);
	else if(!TCGV_EQUAL(d, s))
		tcg_gen_mov_tl(d, s);
}

static inline void t_gen_zext(TCGv d, TCGv s, int size)
{
	if (size == 1)
		tcg_gen_ext8u_i32(d, s);
	else if (size == 2)
		tcg_gen_ext16u_i32(d, s);
	else if (!TCGV_EQUAL(d, s))
		tcg_gen_mov_tl(d, s);
}

#if DISAS_CRIS
static char memsize_char(int size)
{
	switch (size)
	{
		case 1: return 'b';  break;
		case 2: return 'w';  break;
		case 4: return 'd';  break;
		default:
			return 'x';
			break;
	}
}
#endif

static inline unsigned int memsize_z(DisasContext *dc)
{
	return dc->zsize + 1;
}

static inline unsigned int memsize_zz(DisasContext *dc)
{
	switch (dc->zzsize)
	{
		case 0: return 1;
		case 1: return 2;
		default:
			return 4;
	}
}

static inline void do_postinc (DisasContext *dc, int size)
{
	if (dc->postinc)
		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], size);
}

static inline void dec_prep_move_r(DisasContext *dc, int rs, int rd,
				   int size, int s_ext, TCGv dst)
{
	if (s_ext)
		t_gen_sext(dst, cpu_R[rs], size);
	else
		t_gen_zext(dst, cpu_R[rs], size);
}

/* Prepare T0 and T1 for a register alu operation.
   s_ext decides if the operand1 should be sign-extended or zero-extended when
   needed.  */
static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
			  int size, int s_ext, TCGv dst, TCGv src)
{
	dec_prep_move_r(dc, rs, rd, size, s_ext, src);

	if (s_ext)
		t_gen_sext(dst, cpu_R[rd], size);
	else
		t_gen_zext(dst, cpu_R[rd], size);
}

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

	rs = dc->op1;
	is_imm = rs == 15 && dc->postinc;

	/* Load [$rs] onto T1.  */
	if (is_imm) {
		insn_len = 2 + memsize;
		if (memsize == 1)
			insn_len++;

		imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
		tcg_gen_movi_tl(dst, imm);
		dc->postinc = 0;
	} else {
		cris_flush_cc_state(dc);
		gen_load(dc, dst, cpu_R[rs], memsize, 0);
		if (s_ext)
			t_gen_sext(dst, dst, memsize);
		else
			t_gen_zext(dst, dst, memsize);
	}
	return insn_len;
}

/* Prepare T0 and T1 for a memory + alu operation.
   s_ext decides if the operand1 should be sign-extended or zero-extended when
   needed.  */
static int dec_prep_alu_m(DisasContext *dc, int s_ext, int memsize,
			  TCGv dst, TCGv src)
{
	int insn_len;

	insn_len = dec_prep_move_m(dc, s_ext, memsize, src);
	tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
	return insn_len;
}

#if DISAS_CRIS
static const char *cc_name(int cc)
{
	static const char *cc_names[16] = {
		"cc", "cs", "ne", "eq", "vc", "vs", "pl", "mi",
		"ls", "hi", "ge", "lt", "gt", "le", "a", "p"
	};
	assert(cc < 16);
	return cc_names[cc];
}
#endif

/* Start of insn decoders.  */

static int dec_bccq(DisasContext *dc)
{
	int32_t offset;
	int sign;
	uint32_t cond = dc->op2;

	offset = EXTRACT_FIELD (dc->ir, 1, 7);
	sign = EXTRACT_FIELD(dc->ir, 0, 0);

	offset *= 2;
	offset |= sign << 8;
	offset = sign_extend(offset, 8);

	LOG_DIS("b%s %x\n", cc_name(cond), dc->pc + offset);

	/* op2 holds the condition-code.  */
	cris_cc_mask(dc, 0);
	cris_prepare_cc_branch (dc, offset, cond);
	return 2;
}
static int dec_addoq(DisasContext *dc)
{
	int32_t imm;

	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 7);
	imm = sign_extend(dc->op1, 7);

	LOG_DIS("addoq %d, $r%u\n", imm, dc->op2);
	cris_cc_mask(dc, 0);
	/* Fetch register operand,  */
	tcg_gen_addi_tl(cpu_R[R_ACR], cpu_R[dc->op2], imm);

	return 2;
}
static int dec_addq(DisasContext *dc)
{
	LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);

	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);

	cris_cc_mask(dc, CC_MASK_NZVC);

	cris_alu(dc, CC_OP_ADD,
		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
	return 2;
}
static int dec_moveq(DisasContext *dc)
{
	uint32_t imm;

	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
	imm = sign_extend(dc->op1, 5);
	LOG_DIS("moveq %d, $r%u\n", imm, dc->op2);

	tcg_gen_movi_tl(cpu_R[dc->op2], imm);
	return 2;
}
static int dec_subq(DisasContext *dc)
{
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);

	LOG_DIS("subq %u, $r%u\n", dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_SUB,
		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
	return 2;
}
static int dec_cmpq(DisasContext *dc)
{
	uint32_t imm;
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
	imm = sign_extend(dc->op1, 5);

	LOG_DIS("cmpq %d, $r%d\n", imm, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZVC);

	cris_alu(dc, CC_OP_CMP,
		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
	return 2;
}
static int dec_andq(DisasContext *dc)
{
	uint32_t imm;
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
	imm = sign_extend(dc->op1, 5);

	LOG_DIS("andq %d, $r%d\n", imm, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);

	cris_alu(dc, CC_OP_AND,
		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
	return 2;
}
static int dec_orq(DisasContext *dc)
{
	uint32_t imm;
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
	imm = sign_extend(dc->op1, 5);
	LOG_DIS("orq %d, $r%d\n", imm, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);

	cris_alu(dc, CC_OP_OR,
		    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
	return 2;
}
static int dec_btstq(DisasContext *dc)
{
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
	LOG_DIS("btstq %u, $r%d\n", dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	cris_evaluate_flags(dc);
	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
			tcg_const_tl(dc->op1), cpu_PR[PR_CCS]);
	cris_alu(dc, CC_OP_MOVE,
		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
	dc->flags_uptodate = 1;
	return 2;
}
static int dec_asrq(DisasContext *dc)
{
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
	LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);

	tcg_gen_sari_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2],
		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
	return 2;
}
static int dec_lslq(DisasContext *dc)
{
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
	LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);

	tcg_gen_shli_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);

	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2],
		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
	return 2;
}
static int dec_lsrq(DisasContext *dc)
{
	dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
	LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);

	tcg_gen_shri_tl(cpu_R[dc->op2], cpu_R[dc->op2], dc->op1);
	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2],
		    cpu_R[dc->op2], cpu_R[dc->op2], 4);
	return 2;
}

static int dec_move_r(DisasContext *dc)
{
	int size = memsize_zz(dc);

	LOG_DIS("move.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	if (size == 4) {
		dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, cpu_R[dc->op2]);
		cris_cc_mask(dc, CC_MASK_NZ);
		cris_update_cc_op(dc, CC_OP_MOVE, 4);
		cris_update_cc_x(dc);
		cris_update_result(dc, cpu_R[dc->op2]);
	}
	else {
		TCGv t0;

		t0 = tcg_temp_new();
		dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
		cris_alu(dc, CC_OP_MOVE,
			 cpu_R[dc->op2],
			 cpu_R[dc->op2], t0, size);
		tcg_temp_free(t0);
	}
	return 2;
}

static int dec_scc_r(DisasContext *dc)
{
	int cond = dc->op2;

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

	if (cond != CC_A)
	{
		int l1;

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

	cris_cc_mask(dc, 0);
	return 2;
}

static inline void cris_alu_alloc_temps(DisasContext *dc, int size, TCGv *t)
{
	if (size == 4) {
		t[0] = cpu_R[dc->op2];
		t[1] = cpu_R[dc->op1];
	} else {
		t[0] = tcg_temp_new();
		t[1] = tcg_temp_new();
	}
}

static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
{
	if (size != 4) {
		tcg_temp_free(t[0]);
		tcg_temp_free(t[1]);
	}
}

static int dec_and_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("and.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);

	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
	cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_lz_r(DisasContext *dc)
{
	TCGv t0;
	LOG_DIS("lz $r%u, $r%u\n",
		    dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);
	t0 = tcg_temp_new();
	dec_prep_alu_r(dc, dc->op1, dc->op2, 4, 0, cpu_R[dc->op2], t0);
	cris_alu(dc, CC_OP_LZ, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

static int dec_lsl_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("lsl.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
	tcg_gen_andi_tl(t[1], t[1], 63);
	cris_alu(dc, CC_OP_LSL, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_alloc_temps(dc, size, t);
	return 2;
}

static int dec_lsr_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("lsr.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
	tcg_gen_andi_tl(t[1], t[1], 63);
	cris_alu(dc, CC_OP_LSR, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_asr_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("asr.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);
	tcg_gen_andi_tl(t[1], t[1], 63);
	cris_alu(dc, CC_OP_ASR, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_muls_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("muls.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZV);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 1, t[0], t[1]);

	cris_alu(dc, CC_OP_MULS, cpu_R[dc->op2], t[0], t[1], 4);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_mulu_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);

	LOG_DIS("mulu.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZV);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);

	cris_alu(dc, CC_OP_MULU, cpu_R[dc->op2], t[0], t[1], 4);
	cris_alu_alloc_temps(dc, size, t);
	return 2;
}


static int dec_dstep_r(DisasContext *dc)
{
	LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_DSTEP,
		    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
	return 2;
}

static int dec_xor_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("xor.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	BUG_ON(size != 4); /* xor is dword.  */
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);

	cris_alu(dc, CC_OP_XOR, cpu_R[dc->op2], t[0], t[1], 4);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_bound_r(DisasContext *dc)
{
	TCGv l0;
	int size = memsize_zz(dc);
	LOG_DIS("bound.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);
	l0 = tcg_temp_local_new();
	dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, l0);
	cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], cpu_R[dc->op2], l0, 4);
	tcg_temp_free(l0);
	return 2;
}

static int dec_cmp_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("cmp.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);

	cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_abs_r(DisasContext *dc)
{
	TCGv t0;

	LOG_DIS("abs $r%u, $r%u\n",
		    dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);

	t0 = tcg_temp_new();
	tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
	tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
	tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
	tcg_temp_free(t0);

	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
	return 2;
}

static int dec_add_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("add.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);

	cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_addc_r(DisasContext *dc)
{
	LOG_DIS("addc $r%u, $r%u\n",
		    dc->op1, dc->op2);
	cris_evaluate_flags(dc);
	/* Set for this insn.  */
	dc->flagx_known = 1;
	dc->flags_x = X_FLAG;

	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_ADDC,
		 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
	return 2;
}

static int dec_mcp_r(DisasContext *dc)
{
	LOG_DIS("mcp $p%u, $r%u\n",
		     dc->op2, dc->op1);
	cris_evaluate_flags(dc);
	cris_cc_mask(dc, CC_MASK_RNZV);
	cris_alu(dc, CC_OP_MCP,
		    cpu_R[dc->op1], cpu_R[dc->op1], cpu_PR[dc->op2], 4);
	return 2;
}

#if DISAS_CRIS
static char * swapmode_name(int mode, char *modename) {
	int i = 0;
	if (mode & 8)
		modename[i++] = 'n';
	if (mode & 4)
		modename[i++] = 'w';
	if (mode & 2)
		modename[i++] = 'b';
	if (mode & 1)
		modename[i++] = 'r';
	modename[i++] = 0;
	return modename;
}
#endif

static int dec_swap_r(DisasContext *dc)
{
	TCGv t0;
#if DISAS_CRIS
	char modename[4];
#endif
	LOG_DIS("swap%s $r%u\n",
		     swapmode_name(dc->op2, modename), dc->op1);

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

static int dec_or_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("or.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
	cris_alu(dc, CC_OP_OR, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_addi_r(DisasContext *dc)
{
	TCGv t0;
	LOG_DIS("addi.%c $r%u, $r%u\n",
		    memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
	cris_cc_mask(dc, 0);
	t0 = tcg_temp_new();
	tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
	tcg_gen_add_tl(cpu_R[dc->op1], cpu_R[dc->op1], t0);
	tcg_temp_free(t0);
	return 2;
}

static int dec_addi_acr(DisasContext *dc)
{
	TCGv t0;
	LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
		  memsize_char(memsize_zz(dc)), dc->op2, dc->op1);
	cris_cc_mask(dc, 0);
	t0 = tcg_temp_new();
	tcg_gen_shl_tl(t0, cpu_R[dc->op2], tcg_const_tl(dc->zzsize));
	tcg_gen_add_tl(cpu_R[R_ACR], cpu_R[dc->op1], t0);
	tcg_temp_free(t0);
	return 2;
}

static int dec_neg_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("neg.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);

	cris_alu(dc, CC_OP_NEG, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

static int dec_btst_r(DisasContext *dc)
{
	LOG_DIS("btst $r%u, $r%u\n",
		    dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_evaluate_flags(dc);
	gen_helper_btst(cpu_PR[PR_CCS], cpu_R[dc->op2],
			cpu_R[dc->op1], cpu_PR[PR_CCS]);
	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2],
		 cpu_R[dc->op2], cpu_R[dc->op2], 4);
	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
	dc->flags_uptodate = 1;
	return 2;
}

static int dec_sub_r(DisasContext *dc)
{
	TCGv t[2];
	int size = memsize_zz(dc);
	LOG_DIS("sub.%c $r%u, $r%u\n",
		    memsize_char(size), dc->op1, dc->op2);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu_alloc_temps(dc, size, t);
	dec_prep_alu_r(dc, dc->op1, dc->op2, size, 0, t[0], t[1]);
	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], size);
	cris_alu_free_temps(dc, size, t);
	return 2;
}

/* Zero extension. From size to dword.  */
static int dec_movu_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("movu.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	t0 = tcg_temp_new();
	dec_prep_move_r(dc, dc->op1, dc->op2, size, 0, t0);
	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

/* Sign extension. From size to dword.  */
static int dec_movs_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("movs.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZ);
	t0 = tcg_temp_new();
	/* Size can only be qi or hi.  */
	t_gen_sext(t0, cpu_R[dc->op1], size);
	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2], cpu_R[dc->op1], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

/* zero extension. From size to dword.  */
static int dec_addu_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("addu.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZVC);
	t0 = tcg_temp_new();
	/* Size can only be qi or hi.  */
	t_gen_zext(t0, cpu_R[dc->op1], size);
	cris_alu(dc, CC_OP_ADD,
		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

/* Sign extension. From size to dword.  */
static int dec_adds_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("adds.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZVC);
	t0 = tcg_temp_new();
	/* Size can only be qi or hi.  */
	t_gen_sext(t0, cpu_R[dc->op1], size);
	cris_alu(dc, CC_OP_ADD,
		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

/* Zero extension. From size to dword.  */
static int dec_subu_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("subu.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZVC);
	t0 = tcg_temp_new();
	/* Size can only be qi or hi.  */
	t_gen_zext(t0, cpu_R[dc->op1], size);
	cris_alu(dc, CC_OP_SUB,
		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

/* Sign extension. From size to dword.  */
static int dec_subs_r(DisasContext *dc)
{
	TCGv t0;
	int size = memsize_z(dc);
	LOG_DIS("subs.%c $r%u, $r%u\n",
		    memsize_char(size),
		    dc->op1, dc->op2);

	cris_cc_mask(dc, CC_MASK_NZVC);
	t0 = tcg_temp_new();
	/* Size can only be qi or hi.  */
	t_gen_sext(t0, cpu_R[dc->op1], size);
	cris_alu(dc, CC_OP_SUB,
		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);
	tcg_temp_free(t0);
	return 2;
}

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


	flags = (EXTRACT_FIELD(dc->ir, 12, 15) << 4)
		| EXTRACT_FIELD(dc->ir, 0, 3);
	if (set && flags == 0) {
		LOG_DIS("nop\n");
		return 2;
	} else if (!set && (flags & 0x20)) {
		LOG_DIS("di\n");
	}
	else {
		LOG_DIS("%sf %x\n",
			     set ? "set" : "clr",
			    flags);
	}

	/* User space is not allowed to touch these. Silently ignore.  */
	if (dc->tb_flags & U_FLAG) {
		flags &= ~(S_FLAG | I_FLAG | U_FLAG);
	}

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

	/* Break the TB if any of the SPI flag changes.  */
	if (flags & (P_FLAG | S_FLAG)) {
		tcg_gen_movi_tl(env_pc, dc->pc + 2);
		dc->is_jmp = DISAS_UPDATE;
		dc->cpustate_changed = 1;
	}

	/* For the I flag, only act on posedge.  */
	if ((flags & I_FLAG)) {
		tcg_gen_movi_tl(env_pc, dc->pc + 2);
		dc->is_jmp = DISAS_UPDATE;
		dc->cpustate_changed = 1;
	}


	/* Simply decode the flags.  */
	cris_evaluate_flags (dc);
	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
	cris_update_cc_x(dc);
	tcg_gen_movi_tl(cc_op, dc->cc_op);

	if (set) {
		if (!(dc->tb_flags & U_FLAG) && (flags & U_FLAG)) {
			/* Enter user mode.  */
			t_gen_mov_env_TN(ksp, cpu_R[R_SP]);
			tcg_gen_mov_tl(cpu_R[R_SP], cpu_PR[PR_USP]);
			dc->cpustate_changed = 1;
		}
		tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
	}
	else
		tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);

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

static int dec_move_rs(DisasContext *dc)
{
	LOG_DIS("move $r%u, $s%u\n", dc->op1, dc->op2);
	cris_cc_mask(dc, 0);
	gen_helper_movl_sreg_reg(tcg_const_tl(dc->op2), tcg_const_tl(dc->op1));
	return 2;
}
static int dec_move_sr(DisasContext *dc)
{
	LOG_DIS("move $s%u, $r%u\n", dc->op2, dc->op1);
	cris_cc_mask(dc, 0);
	gen_helper_movl_reg_sreg(tcg_const_tl(dc->op1), tcg_const_tl(dc->op2));
	return 2;
}

static int dec_move_rp(DisasContext *dc)
{
	TCGv t[2];
	LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
	cris_cc_mask(dc, 0);

	t[0] = tcg_temp_new();
	if (dc->op2 == PR_CCS) {
		cris_evaluate_flags(dc);
		t_gen_mov_TN_reg(t[0], dc->op1);
		if (dc->tb_flags & U_FLAG) {
			t[1] = tcg_temp_new();
			/* User space is not allowed to touch all flags.  */
			tcg_gen_andi_tl(t[0], t[0], 0x39f);
			tcg_gen_andi_tl(t[1], cpu_PR[PR_CCS], ~0x39f);
			tcg_gen_or_tl(t[0], t[1], t[0]);
			tcg_temp_free(t[1]);
		}
	}
	else
		t_gen_mov_TN_reg(t[0], dc->op1);

	t_gen_mov_preg_TN(dc, dc->op2, t[0]);
	if (dc->op2 == PR_CCS) {
		cris_update_cc_op(dc, CC_OP_FLAGS, 4);
		dc->flags_uptodate = 1;
	}
	tcg_temp_free(t[0]);
	return 2;
}
static int dec_move_pr(DisasContext *dc)
{
	TCGv t0;
	LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
	cris_cc_mask(dc, 0);

	if (dc->op2 == PR_CCS)
		cris_evaluate_flags(dc);

        if (dc->op2 == PR_DZ) {
		tcg_gen_movi_tl(cpu_R[dc->op1], 0);
        } else {
		t0 = tcg_temp_new();
		t_gen_mov_TN_preg(t0, dc->op2);
		cris_alu(dc, CC_OP_MOVE,
			 cpu_R[dc->op1], cpu_R[dc->op1], t0,
			 preg_sizes[dc->op2]);
		tcg_temp_free(t0);
	}
	return 2;
}

static int dec_move_mr(DisasContext *dc)
{
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("move.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	if (memsize == 4) {
		insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
		cris_cc_mask(dc, CC_MASK_NZ);
		cris_update_cc_op(dc, CC_OP_MOVE, 4);
		cris_update_cc_x(dc);
		cris_update_result(dc, cpu_R[dc->op2]);
	}
	else {
		TCGv t0;

		t0 = tcg_temp_new();
		insn_len = dec_prep_move_m(dc, 0, memsize, t0);
		cris_cc_mask(dc, CC_MASK_NZ);
		cris_alu(dc, CC_OP_MOVE,
			    cpu_R[dc->op2], cpu_R[dc->op2], t0, memsize);
		tcg_temp_free(t0);
	}
	do_postinc(dc, memsize);
	return insn_len;
}

static inline void cris_alu_m_alloc_temps(TCGv *t)
{
	t[0] = tcg_temp_new();
	t[1] = tcg_temp_new();
}

static inline void cris_alu_m_free_temps(TCGv *t)
{
	tcg_temp_free(t[0]);
	tcg_temp_free(t[1]);
}

static int dec_movs_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("movs.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	/* sign extend.  */
	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_MOVE,
		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_addu_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("addu.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	/* sign extend.  */
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_ADD,
		    cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_adds_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("adds.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	/* sign extend.  */
	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_ADD, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_subu_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("subu.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	/* sign extend.  */
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_subs_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("subs.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	/* sign extend.  */
	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_movu_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;

	LOG_DIS("movu.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_MOVE, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_cmpu_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("cmpu.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_CMP, cpu_R[dc->op2], cpu_R[dc->op2], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_cmps_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_z(dc);
	int insn_len;
	LOG_DIS("cmps.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_CMP,
		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
		    memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_cmp_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("cmp.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_CMP,
		    cpu_R[dc->op2], cpu_R[dc->op2], t[1],
		    memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_test_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("test.%c [$r%u%s] op2=%x\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_evaluate_flags(dc);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~3);

	cris_alu(dc, CC_OP_CMP,
		 cpu_R[dc->op2], t[1], tcg_const_tl(0), memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_and_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("and.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_AND, cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_add_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("add.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_ADD,
		 cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_addo_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("add.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
	cris_cc_mask(dc, 0);
	cris_alu(dc, CC_OP_ADD, cpu_R[R_ACR], t[0], t[1], 4);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_bound_m(DisasContext *dc)
{
	TCGv l[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("bound.%c [$r%u%s, $r%u\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	l[0] = tcg_temp_local_new();
	l[1] = tcg_temp_local_new();
	insn_len = dec_prep_alu_m(dc, 0, memsize, l[0], l[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_BOUND, cpu_R[dc->op2], l[0], l[1], 4);
	do_postinc(dc, memsize);
	tcg_temp_free(l[0]);
	tcg_temp_free(l[1]);
	return insn_len;
}

static int dec_addc_mr(DisasContext *dc)
{
	TCGv t[2];
	int insn_len = 2;
	LOG_DIS("addc [$r%u%s, $r%u\n",
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_evaluate_flags(dc);

	/* Set for this insn.  */
	dc->flagx_known = 1;
	dc->flags_x = X_FLAG;

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_ADDC, cpu_R[dc->op2], t[0], t[1], 4);
	do_postinc(dc, 4);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_sub_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("sub.%c [$r%u%s, $r%u ir=%x zz=%x\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2, dc->ir, dc->zzsize);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZVC);
	cris_alu(dc, CC_OP_SUB, cpu_R[dc->op2], t[0], t[1], memsize);
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_or_m(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len;
	LOG_DIS("or.%c [$r%u%s, $r%u pc=%x\n",
		    memsize_char(memsize),
		    dc->op1, dc->postinc ? "+]" : "]",
		    dc->op2, dc->pc);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, CC_MASK_NZ);
	cris_alu(dc, CC_OP_OR,
		    cpu_R[dc->op2], t[0], t[1], memsize_zz(dc));
	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_move_mp(DisasContext *dc)
{
	TCGv t[2];
	int memsize = memsize_zz(dc);
	int insn_len = 2;

	LOG_DIS("move.%c [$r%u%s, $p%u\n",
		    memsize_char(memsize),
		    dc->op1,
		    dc->postinc ? "+]" : "]",
		    dc->op2);

	cris_alu_m_alloc_temps(t);
	insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
	cris_cc_mask(dc, 0);
	if (dc->op2 == PR_CCS) {
		cris_evaluate_flags(dc);
		if (dc->tb_flags & U_FLAG) {
			/* User space is not allowed to touch all flags.  */
			tcg_gen_andi_tl(t[1], t[1], 0x39f);
			tcg_gen_andi_tl(t[0], cpu_PR[PR_CCS], ~0x39f);
			tcg_gen_or_tl(t[1], t[0], t[1]);
		}
	}

	t_gen_mov_preg_TN(dc, dc->op2, t[1]);

	do_postinc(dc, memsize);
	cris_alu_m_free_temps(t);
	return insn_len;
}

static int dec_move_pm(DisasContext *dc)
{
	TCGv t0;
	int memsize;

	memsize = preg_sizes[dc->op2];

	LOG_DIS("move.%c $p%u, [$r%u%s\n",
		     memsize_char(memsize), 
		     dc->op2, dc->op1, dc->postinc ? "+]" : "]");

	/* prepare store. Address in T0, value in T1.  */
	if (dc->op2 == PR_CCS)
		cris_evaluate_flags(dc);
	t0 = tcg_temp_new();
	t_gen_mov_TN_preg(t0, dc->op2);
	cris_flush_cc_state(dc);
	gen_store(dc, cpu_R[dc->op1], t0, memsize);
	tcg_temp_free(t0);

	cris_cc_mask(dc, 0);
	if (dc->postinc)
		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
	return 2;
}

static int dec_movem_mr(DisasContext *dc)
{
	TCGv_i64 tmp[16];
        TCGv tmp32;
	TCGv addr;
	int i;
	int nr = dc->op2 + 1;

	LOG_DIS("movem [$r%u%s, $r%u\n", dc->op1,
		    dc->postinc ? "+]" : "]", dc->op2);

	addr = tcg_temp_new();
	/* There are probably better ways of doing this.  */
	cris_flush_cc_state(dc);
	for (i = 0; i < (nr >> 1); i++) {
		tmp[i] = tcg_temp_new_i64();
		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
		gen_load64(dc, tmp[i], addr);
	}
	if (nr & 1) {
		tmp32 = tcg_temp_new_i32();
		tcg_gen_addi_tl(addr, cpu_R[dc->op1], i * 8);
		gen_load(dc, tmp32, addr, 4, 0);
	} else
		TCGV_UNUSED(tmp32);
	tcg_temp_free(addr);

	for (i = 0; i < (nr >> 1); i++) {
		tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]);
		tcg_gen_shri_i64(tmp[i], tmp[i], 32);
		tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]);
		tcg_temp_free_i64(tmp[i]);
	}
	if (nr & 1) {
		tcg_gen_mov_tl(cpu_R[dc->op2], tmp32);
		tcg_temp_free(tmp32);
	}

	/* writeback the updated pointer value.  */
	if (dc->postinc)
		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], nr * 4);

	/* gen_load might want to evaluate the previous insns flags.  */
	cris_cc_mask(dc, 0);
	return 2;
}

static int dec_movem_rm(DisasContext *dc)
{
	TCGv tmp;
	TCGv addr;
	int i;

	LOG_DIS("movem $r%u, [$r%u%s\n", dc->op2, dc->op1,
		     dc->postinc ? "+]" : "]");

	cris_flush_cc_state(dc);

	tmp = tcg_temp_new();
	addr = tcg_temp_new();
	tcg_gen_movi_tl(tmp, 4);
	tcg_gen_mov_tl(addr, cpu_R[dc->op1]);
	for (i = 0; i <= dc->op2; i++) {
		/* Displace addr.  */
		/* Perform the store.  */
		gen_store(dc, addr, cpu_R[i], 4);
		tcg_gen_add_tl(addr, addr, tmp);
	}
	if (dc->postinc)
		tcg_gen_mov_tl(cpu_R[dc->op1], addr);
	cris_cc_mask(dc, 0);
	tcg_temp_free(tmp);
	tcg_temp_free(addr);
	return 2;
}

static int dec_move_rm(DisasContext *dc)
{
	int memsize;

	memsize = memsize_zz(dc);

	LOG_DIS("move.%c $r%u, [$r%u]\n",
		     memsize_char(memsize), dc->op2, dc->op1);

	/* prepare store.  */
	cris_flush_cc_state(dc);
	gen_store(dc, cpu_R[dc->op1], cpu_R[dc->op2], memsize);

	if (dc->postinc)
		tcg_gen_addi_tl(cpu_R[dc->op1], cpu_R[dc->op1], memsize);
	cris_cc_mask(dc, 0);
	return 2;
}

static int dec_lapcq(DisasContext *dc)
{
	LOG_DIS("lapcq %x, $r%u\n",
		    dc->pc + dc->op1*2, dc->op2);
	cris_cc_mask(dc, 0);
	tcg_gen_movi_tl(cpu_R[dc->op2], dc->pc + dc->op1 * 2);
	return 2;
}

static int dec_lapc_im(DisasContext *dc)
{
	unsigned int rd;
	int32_t imm;
	int32_t pc;

	rd = dc->op2;

	cris_cc_mask(dc, 0);
	imm = cris_fetch(dc, dc->pc + 2, 4, 0);
	LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);

	pc = dc->pc;
	pc += imm;
	tcg_gen_movi_tl(cpu_R[rd], pc);
	return 6;
}

/* Jump to special reg.  */
static int dec_jump_p(DisasContext *dc)
{
	LOG_DIS("jump $p%u\n", dc->op2);

	if (dc->op2 == PR_CCS)
		cris_evaluate_flags(dc);
	t_gen_mov_TN_preg(env_btarget, dc->op2);
	/* rete will often have low bit set to indicate delayslot.  */
	tcg_gen_andi_tl(env_btarget, env_btarget, ~1);
	cris_cc_mask(dc, 0);
	cris_prepare_jmp(dc, JMP_INDIRECT);
	return 2;
}

/* Jump and save.  */
static int dec_jas_r(DisasContext *dc)
{
	LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
	if (dc->op2 > 15)
		abort();
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4));

	cris_prepare_jmp(dc, JMP_INDIRECT);
	return 2;
}

static int dec_jas_im(DisasContext *dc)
{
	uint32_t imm;

	imm = cris_fetch(dc, dc->pc + 2, 4, 0);

	LOG_DIS("jas 0x%x\n", imm);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));

	dc->jmp_pc = imm;
	cris_prepare_jmp(dc, JMP_DIRECT);
	return 6;
}

static int dec_jasc_im(DisasContext *dc)
{
	uint32_t imm;

	imm = cris_fetch(dc, dc->pc + 2, 4, 0);

	LOG_DIS("jasc 0x%x\n", imm);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8 + 4));

	dc->jmp_pc = imm;
	cris_prepare_jmp(dc, JMP_DIRECT);
	return 6;
}

static int dec_jasc_r(DisasContext *dc)
{
	LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	tcg_gen_mov_tl(env_btarget, cpu_R[dc->op1]);
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 4 + 4));
	cris_prepare_jmp(dc, JMP_INDIRECT);
	return 2;
}

static int dec_bcc_im(DisasContext *dc)
{
	int32_t offset;
	uint32_t cond = dc->op2;

	offset = cris_fetch(dc, dc->pc + 2, 2, 1);

	LOG_DIS("b%s %d pc=%x dst=%x\n",
		    cc_name(cond), offset,
		    dc->pc, dc->pc + offset);

	cris_cc_mask(dc, 0);
	/* op2 holds the condition-code.  */
	cris_prepare_cc_branch (dc, offset, cond);
	return 4;
}

static int dec_bas_im(DisasContext *dc)
{
	int32_t simm;


	simm = cris_fetch(dc, dc->pc + 2, 4, 0);

	LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 8));

	dc->jmp_pc = dc->pc + simm;
	cris_prepare_jmp(dc, JMP_DIRECT);
	return 6;
}

static int dec_basc_im(DisasContext *dc)
{
	int32_t simm;
	simm = cris_fetch(dc, dc->pc + 2, 4, 0);

	LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
	cris_cc_mask(dc, 0);
	/* Store the return address in Pd.  */
	t_gen_mov_preg_TN(dc, dc->op2, tcg_const_tl(dc->pc + 12));

	dc->jmp_pc = dc->pc + simm;
	cris_prepare_jmp(dc, JMP_DIRECT);
	return 6;
}

static int dec_rfe_etc(DisasContext *dc)
{
	cris_cc_mask(dc, 0);

	if (dc->op2 == 15) {
		t_gen_mov_env_TN(halted, tcg_const_tl(1));
		tcg_gen_movi_tl(env_pc, dc->pc + 2);
		t_gen_raise_exception(EXCP_HLT);
		return 2;
	}

	switch (dc->op2 & 7) {
		case 2:
			/* rfe.  */
			LOG_DIS("rfe\n");
			cris_evaluate_flags(dc);
			gen_helper_rfe();
			dc->is_jmp = DISAS_UPDATE;
			break;
		case 5:
			/* rfn.  */
			LOG_DIS("rfn\n");
			cris_evaluate_flags(dc);
			gen_helper_rfn();
			dc->is_jmp = DISAS_UPDATE;
			break;
		case 6:
			LOG_DIS("break %d\n", dc->op1);
			cris_evaluate_flags (dc);
			/* break.  */
			tcg_gen_movi_tl(env_pc, dc->pc + 2);

			/* Breaks start at 16 in the exception vector.  */
			t_gen_mov_env_TN(trap_vector, 
					 tcg_const_tl(dc->op1 + 16));
			t_gen_raise_exception(EXCP_BREAK);
			dc->is_jmp = DISAS_UPDATE;
			break;
		default:
			printf ("op2=%x\n", dc->op2);
			BUG();
			break;

	}
	return 2;
}

static int dec_ftag_fidx_d_m(DisasContext *dc)
{
	return 2;
}

static int dec_ftag_fidx_i_m(DisasContext *dc)
{
	return 2;
}

static int dec_null(DisasContext *dc)
{
	printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
		dc->pc, dc->opcode, dc->op1, dc->op2);
	fflush(NULL);
	BUG();
	return 2;
}

static struct decoder_info {
	struct {
		uint32_t bits;
		uint32_t mask;
	};
	int (*dec)(DisasContext *dc);
} decinfo[] = {
	/* Order matters here.  */
	{DEC_MOVEQ, dec_moveq},
	{DEC_BTSTQ, dec_btstq},
	{DEC_CMPQ, dec_cmpq},
	{DEC_ADDOQ, dec_addoq},
	{DEC_ADDQ, dec_addq},
	{DEC_SUBQ, dec_subq},
	{DEC_ANDQ, dec_andq},
	{DEC_ORQ, dec_orq},
	{DEC_ASRQ, dec_asrq},
	{DEC_LSLQ, dec_lslq},
	{DEC_LSRQ, dec_lsrq},
	{DEC_BCCQ, dec_bccq},

	{DEC_BCC_IM, dec_bcc_im},
	{DEC_JAS_IM, dec_jas_im},
	{DEC_JAS_R, dec_jas_r},
	{DEC_JASC_IM, dec_jasc_im},
	{DEC_JASC_R, dec_jasc_r},
	{DEC_BAS_IM, dec_bas_im},
	{DEC_BASC_IM, dec_basc_im},
	{DEC_JUMP_P, dec_jump_p},
	{DEC_LAPC_IM, dec_lapc_im},
	{DEC_LAPCQ, dec_lapcq},

	{DEC_RFE_ETC, dec_rfe_etc},
	{DEC_ADDC_MR, dec_addc_mr},

	{DEC_MOVE_MP, dec_move_mp},
	{DEC_MOVE_PM, dec_move_pm},
	{DEC_MOVEM_MR, dec_movem_mr},
	{DEC_MOVEM_RM, dec_movem_rm},
	{DEC_MOVE_PR, dec_move_pr},
	{DEC_SCC_R, dec_scc_r},
	{DEC_SETF, dec_setclrf},
	{DEC_CLEARF, dec_setclrf},

	{DEC_MOVE_SR, dec_move_sr},
	{DEC_MOVE_RP, dec_move_rp},
	{DEC_SWAP_R, dec_swap_r},
	{DEC_ABS_R, dec_abs_r},
	{DEC_LZ_R, dec_lz_r},
	{DEC_MOVE_RS, dec_move_rs},
	{DEC_BTST_R, dec_btst_r},
	{DEC_ADDC_R, dec_addc_r},

	{DEC_DSTEP_R, dec_dstep_r},
	{DEC_XOR_R, dec_xor_r},
	{DEC_MCP_R, dec_mcp_r},
	{DEC_CMP_R, dec_cmp_r},

	{DEC_ADDI_R, dec_addi_r},
	{DEC_ADDI_ACR, dec_addi_acr},

	{DEC_ADD_R, dec_add_r},
	{DEC_SUB_R, dec_sub_r},

	{DEC_ADDU_R, dec_addu_r},
	{DEC_ADDS_R, dec_adds_r},
	{DEC_SUBU_R, dec_subu_r},
	{DEC_SUBS_R, dec_subs_r},
	{DEC_LSL_R, dec_lsl_r},

	{DEC_AND_R, dec_and_r},
	{DEC_OR_R, dec_or_r},
	{DEC_BOUND_R, dec_bound_r},
	{DEC_ASR_R, dec_asr_r},
	{DEC_LSR_R, dec_lsr_r},

	{DEC_MOVU_R, dec_movu_r},
	{DEC_MOVS_R, dec_movs_r},
	{DEC_NEG_R, dec_neg_r},
	{DEC_MOVE_R, dec_move_r},

	{DEC_FTAG_FIDX_I_M, dec_ftag_fidx_i_m},
	{DEC_FTAG_FIDX_D_M, dec_ftag_fidx_d_m},

	{DEC_MULS_R, dec_muls_r},
	{DEC_MULU_R, dec_mulu_r},

	{DEC_ADDU_M, dec_addu_m},
	{DEC_ADDS_M, dec_adds_m},
	{DEC_SUBU_M, dec_subu_m},
	{DEC_SUBS_M, dec_subs_m},

	{DEC_CMPU_M, dec_cmpu_m},
	{DEC_CMPS_M, dec_cmps_m},
	{DEC_MOVU_M, dec_movu_m},
	{DEC_MOVS_M, dec_movs_m},

	{DEC_CMP_M, dec_cmp_m},
	{DEC_ADDO_M, dec_addo_m},
	{DEC_BOUND_M, dec_bound_m},
	{DEC_ADD_M, dec_add_m},
	{DEC_SUB_M, dec_sub_m},
	{DEC_AND_M, dec_and_m},
	{DEC_OR_M, dec_or_m},
	{DEC_MOVE_RM, dec_move_rm},
	{DEC_TEST_M, dec_test_m},
	{DEC_MOVE_MR, dec_move_mr},

	{{0, 0}, dec_null}
};

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

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

	/* Load a halfword onto the instruction register.  */
	dc->ir = cris_fetch(dc, dc->pc, 2, 0);

	/* Now decode it.  */
	dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
	dc->op1      = EXTRACT_FIELD(dc->ir, 0, 3);
	dc->op2      = EXTRACT_FIELD(dc->ir, 12, 15);
	dc->zsize    = EXTRACT_FIELD(dc->ir, 4, 4);
	dc->zzsize   = EXTRACT_FIELD(dc->ir, 4, 5);
	dc->postinc  = EXTRACT_FIELD(dc->ir, 10, 10);

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

#if !defined(CONFIG_USER_ONLY)
	/* Single-stepping ?  */
	if (dc->tb_flags & S_FLAG) {
		int l1;

		l1 = gen_new_label();
		tcg_gen_brcondi_tl(TCG_COND_NE, cpu_PR[PR_SPC], dc->pc, l1);
		/* We treat SPC as a break with an odd trap vector.  */
		cris_evaluate_flags (dc);
		t_gen_mov_env_TN(trap_vector, tcg_const_tl(3));
		tcg_gen_movi_tl(env_pc, dc->pc + insn_len);
		tcg_gen_movi_tl(cpu_PR[PR_SPC], dc->pc + insn_len);
		t_gen_raise_exception(EXCP_BREAK);
		gen_set_label(l1);
	}
#endif
	return insn_len;
}

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

	if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
		QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
			if (bp->pc == dc->pc) {
				cris_evaluate_flags (dc);
				tcg_gen_movi_tl(env_pc, dc->pc);
				t_gen_raise_exception(EXCP_DEBUG);
				dc->is_jmp = DISAS_UPDATE;
			}
		}
	}
}

#include "translate_v10.c"

/*
 * Delay slots on QEMU/CRIS.
 *
 * If an exception hits on a delayslot, the core will let ERP (the Exception
 * Return Pointer) point to the branch (the previous) insn and set the lsb to
 * to give SW a hint that the exception actually hit on the dslot.
 *
 * CRIS expects all PC addresses to be 16-bit aligned. The lsb is ignored by
 * the core and any jmp to an odd addresses will mask off that lsb. It is 
 * simply there to let sw know there was an exception on a dslot.
 *
 * When the software returns from an exception, the branch will re-execute.
 * On QEMU care needs to be taken when a branch+delayslot sequence is broken
 * and the branch and delayslot dont share pages.
 *
 * The TB contaning the branch insn will set up env->btarget and evaluate 
 * env->btaken. When the translation loop exits we will note that the branch 
 * sequence is broken and let env->dslot be the size of the branch insn (those
 * vary in length).
 *
 * The TB contaning the delayslot will have the PC of its real insn (i.e no lsb
 * set). It will also expect to have env->dslot setup with the size of the 
 * delay slot so that env->pc - env->dslot point to the branch insn. This TB 
 * will execute the dslot and take the branch, either to btarget or just one 
 * insn ahead.
 *
 * When exceptions occur, we check for env->dslot in do_interrupt to detect 
 * broken branch sequences and setup $erp accordingly (i.e let it point to the
 * branch and set lsb). Then env->dslot gets cleared so that the exception 
 * handler can enter. When returning from exceptions (jump $erp) the lsb gets
 * masked off and we will reexecute the branch insn.
 *
 */

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

	qemu_log_try_set_file(stderr);

	if (env->pregs[PR_VR] == 32) {
		dc->decoder = crisv32_decoder;
		dc->clear_locked_irq = 0;
	} else {
		dc->decoder = crisv10_decoder;
		dc->clear_locked_irq = 1;
	}

	/* Odd PC indicates that branch is rexecuting due to exception in the
	 * delayslot, like in real hw.
	 */
	pc_start = tb->pc & ~1;
	dc->env = env;
	dc->tb = tb;

	gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

	dc->is_jmp = DISAS_NEXT;
	dc->ppc = pc_start;
	dc->pc = pc_start;
	dc->singlestep_enabled = env->singlestep_enabled;
	dc->flags_uptodate = 1;
	dc->flagx_known = 1;
	dc->flags_x = tb->flags & X_FLAG;
	dc->cc_x_uptodate = 0;
	dc->cc_mask = 0;
	dc->update_cc = 0;
	dc->clear_prefix = 0;

	cris_update_cc_op(dc, CC_OP_FLAGS, 4);
	dc->cc_size_uptodate = -1;

	/* Decode TB flags.  */
	dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
					| X_FLAG | PFIX_FLAG);
	dc->delayed_branch = !!(tb->flags & 7);
	if (dc->delayed_branch)
		dc->jmp = JMP_INDIRECT;
	else
		dc->jmp = JMP_NOJMP;

	dc->cpustate_changed = 0;

	if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
		qemu_log(
                        "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n"
			"pid=%x usp=%x\n"
			"%x.%x.%x.%x\n"
			"%x.%x.%x.%x\n"
			"%x.%x.%x.%x\n"
			"%x.%x.%x.%x\n",
			search_pc, dc->pc, dc->ppc,
                        (uint64_t)tb->flags,
			env->btarget, (unsigned)tb->flags & 7,
			env->pregs[PR_CCS], 
			env->pregs[PR_PID], env->pregs[PR_USP],
			env->regs[0], env->regs[1], env->regs[2], env->regs[3],
			env->regs[4], env->regs[5], env->regs[6], env->regs[7],
			env->regs[8], env->regs[9],
			env->regs[10], env->regs[11],
			env->regs[12], env->regs[13],
			env->regs[14], env->regs[15]);
		qemu_log("--------------\n");
		qemu_log("IN: %s\n", lookup_symbol(pc_start));
	}

	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
	{
		check_breakpoint(env, dc);

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

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

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

		insn_len = dc->decoder(dc);
		dc->ppc = dc->pc;
		dc->pc += insn_len;
		if (dc->clear_x)
			cris_clear_x_flag(dc);

                num_insns++;
		/* Check for delayed branches here. If we do it before
		   actually generating any host code, the simulator will just
		   loop doing nothing for on this program location.  */
		if (dc->delayed_branch) {
			dc->delayed_branch--;
			if (dc->delayed_branch == 0)
			{
				if (tb->flags & 7)
					t_gen_mov_env_TN(dslot, 
						tcg_const_tl(0));
				if (dc->cpustate_changed || !dc->flagx_known
				    || (dc->flags_x != (tb->flags & X_FLAG))) {
					cris_store_direct_jmp(dc);
				}

				if (dc->clear_locked_irq) {
					dc->clear_locked_irq = 0;
					t_gen_mov_env_TN(locked_irq,
							 tcg_const_tl(0));
				}

				if (dc->jmp == JMP_DIRECT_CC) {
					int l1;

					l1 = gen_new_label();
					cris_evaluate_flags(dc);

					/* Conditional jmp.  */
					tcg_gen_brcondi_tl(TCG_COND_EQ,
							   env_btaken, 0, l1);
					gen_goto_tb(dc, 1, dc->jmp_pc);
					gen_set_label(l1);
					gen_goto_tb(dc, 0, dc->pc);
					dc->is_jmp = DISAS_TB_JUMP;
					dc->jmp = JMP_NOJMP;
				} else if (dc->jmp == JMP_DIRECT) {
					cris_evaluate_flags(dc);
					gen_goto_tb(dc, 0, dc->jmp_pc);
					dc->is_jmp = DISAS_TB_JUMP;
					dc->jmp = JMP_NOJMP;
				} else {
					t_gen_cc_jmp(env_btarget, 
						     tcg_const_tl(dc->pc));
					dc->is_jmp = DISAS_JUMP;
				}
				break;
			}
		}

		/* If we are rexecuting a branch due to exceptions on
		   delay slots dont break.  */
		if (!(tb->pc & 1) && env->singlestep_enabled)
			break;
	} while (!dc->is_jmp && !dc->cpustate_changed
		 && gen_opc_ptr < gen_opc_end
                 && !singlestep
		 && (dc->pc < next_page_start)
                 && num_insns < max_insns);

	if (dc->clear_locked_irq)
		t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));

	npc = dc->pc;

        if (tb->cflags & CF_LAST_IO)
            gen_io_end();
	/* Force an update if the per-tb cpu state has changed.  */
	if (dc->is_jmp == DISAS_NEXT
	    && (dc->cpustate_changed || !dc->flagx_known 
	    || (dc->flags_x != (tb->flags & X_FLAG)))) {
		dc->is_jmp = DISAS_UPDATE;
		tcg_gen_movi_tl(env_pc, npc);
	}
	/* Broken branch+delayslot sequence.  */
	if (dc->delayed_branch == 1) {
		/* Set env->dslot to the size of the branch insn.  */
		t_gen_mov_env_TN(dslot, tcg_const_tl(dc->pc - dc->ppc));
		cris_store_direct_jmp(dc);
	}

	cris_evaluate_flags (dc);

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

#ifdef DEBUG_DISAS
#if !DISAS_CRIS
	if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
		log_target_disas(pc_start, dc->pc - pc_start,
                                 dc->env->pregs[PR_VR]);
		qemu_log("\nisize=%d osize=%td\n",
			dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
	}
#endif
#endif
}

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

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

void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
{
	int i;
	uint32_t srs;

	if (!env || !f)
		return;

	cpu_fprintf(f, "PC=%x CCS=%x btaken=%d btarget=%x\n"
		    "cc_op=%d cc_src=%d cc_dest=%d cc_result=%x cc_mask=%x\n",
		    env->pc, env->pregs[PR_CCS], env->btaken, env->btarget,
		    env->cc_op,
		    env->cc_src, env->cc_dest, env->cc_result, env->cc_mask);


	for (i = 0; i < 16; i++) {
		cpu_fprintf(f, "%s=%8.8x ",regnames[i], env->regs[i]);
		if ((i + 1) % 4 == 0)
			cpu_fprintf(f, "\n");
	}
	cpu_fprintf(f, "\nspecial regs:\n");
	for (i = 0; i < 16; i++) {
		cpu_fprintf(f, "%s=%8.8x ", pregnames[i], env->pregs[i]);
		if ((i + 1) % 4 == 0)
			cpu_fprintf(f, "\n");
	}
	srs = env->pregs[PR_SRS];
	cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
	if (srs < 256) {
		for (i = 0; i < 16; i++) {
			cpu_fprintf(f, "s%2.2d=%8.8x ",
				    i, env->sregs[srs][i]);
			if ((i + 1) % 4 == 0)
				cpu_fprintf(f, "\n");
		}
	}
	cpu_fprintf(f, "\n\n");

}

struct
{
    uint32_t vr;
    const char *name;
} cris_cores[] = {
	{8, "crisv8"},
	{9, "crisv9"},
	{10, "crisv10"},
	{11, "crisv11"},
	{32, "crisv32"},
};

void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
{
    unsigned int i;

    (*cpu_fprintf)(f, "Available CPUs:\n");
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
        (*cpu_fprintf)(f, "  %s\n", cris_cores[i].name);
    }
}

static uint32_t vr_by_name(const char *name)
{
    unsigned int i;
    for (i = 0; i < ARRAY_SIZE(cris_cores); i++) {
        if (strcmp(name, cris_cores[i].name) == 0) {
            return cris_cores[i].vr;
        }
    }
    return 32;
}

CPUCRISState *cpu_cris_init (const char *cpu_model)
{
	CPUCRISState *env;
	static int tcg_initialized = 0;
	int i;

	env = qemu_mallocz(sizeof(CPUCRISState));

	env->pregs[PR_VR] = vr_by_name(cpu_model);
	cpu_exec_init(env);
	cpu_reset(env);
	qemu_init_vcpu(env);

	if (tcg_initialized)
		return env;

	tcg_initialized = 1;

#define GEN_HELPER 2
#include "helper.h"

	if (env->pregs[PR_VR] < 32) {
		cpu_crisv10_init(env);
		return env; 
	}


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

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

	return env;
}

void cpu_reset (CPUCRISState *env)
{
	uint32_t vr;

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

	vr = env->pregs[PR_VR];
	memset(env, 0, offsetof(CPUCRISState, breakpoints));
	env->pregs[PR_VR] = vr;
	tlb_flush(env, 1);

#if defined(CONFIG_USER_ONLY)
	/* start in user mode with interrupts enabled.  */
	env->pregs[PR_CCS] |= U_FLAG | I_FLAG | P_FLAG;
#else
	cris_mmu_init(env);
	env->pregs[PR_CCS] = 0;
#endif
}

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