]> git.proxmox.com Git - qemu.git/blobdiff - target-cris/translate.c
Merge remote-tracking branch 'stefanha/net' into staging
[qemu.git] / target-cris / translate.c
index 836136921408ea6aab38f60d5b73f303154a87fb..19144b5e2989232aeb7dc9c5b0fa75cddcabefbb 100644 (file)
  * 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 "exec-all.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"
@@ -82,11 +74,11 @@ static TCGv env_pc;
 
 /* This is the state at translation time.  */
 typedef struct DisasContext {
-       CPUState *env;
+       CPUCRISState *env;
        target_ulong pc, ppc;
 
        /* Decoder.  */
-       unsigned int (*decoder)(struct DisasContext *dc);
+        unsigned int (*decoder)(CPUCRISState *env, struct DisasContext *dc);
        uint32_t ir;
        uint32_t opcode;
        unsigned int op1;
@@ -120,9 +112,10 @@ typedef struct DisasContext {
        unsigned int tb_flags; /* tb dependent flags.  */
        int is_jmp;
 
-#define JMP_NOJMP    0
-#define JMP_DIRECT   1
-#define JMP_INDIRECT 2
+#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;
 
@@ -167,9 +160,9 @@ static int preg_sizes[] = {
 };
 
 #define t_gen_mov_TN_env(tn, member) \
- _t_gen_mov_TN_env((tn), offsetof(CPUState, member))
+ _t_gen_mov_TN_env((tn), offsetof(CPUCRISState, member))
 #define t_gen_mov_env_TN(member, tn) \
- _t_gen_mov_env_TN(offsetof(CPUState, member), (tn))
+ _t_gen_mov_env_TN(offsetof(CPUCRISState, member), (tn))
 
 static inline void t_gen_mov_TN_reg(TCGv tn, int r)
 {
@@ -186,13 +179,13 @@ static inline void t_gen_mov_reg_TN(int r, TCGv tn)
 
 static inline void _t_gen_mov_TN_env(TCGv tn, int offset)
 {
-       if (offset > sizeof (CPUState))
+       if (offset > sizeof (CPUCRISState))
                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))
+       if (offset > sizeof (CPUCRISState))
                fprintf(stderr, "wrong store to env at off=%d\n", offset);
        tcg_gen_st_tl(tn, cpu_env, offset);
 }
@@ -218,9 +211,9 @@ static inline void t_gen_mov_preg_TN(DisasContext *dc, int r, TCGv tn)
                tcg_gen_andi_tl(cpu_PR[r], tn, 3);
        else {
                if (r == PR_PID) 
-                       gen_helper_tlb_flush_pid(tn);
+                        gen_helper_tlb_flush_pid(cpu_env, tn);
                if (dc->tb_flags & S_FLAG && r == PR_SPC) 
-                       gen_helper_spc_write(tn);
+                        gen_helper_spc_write(cpu_env, tn);
                else if (r == PR_CCS)
                        dc->cpustate_changed = 1;
                tcg_gen_mov_tl(cpu_PR[r], tn);
@@ -240,7 +233,7 @@ static int sign_extend(unsigned int val, unsigned int width)
        return sval;
 }
 
-static int cris_fetch(DisasContext *dc, uint32_t addr,
+static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr,
                      unsigned int size, unsigned int sign)
 {
        int r;
@@ -248,24 +241,24 @@ static int cris_fetch(DisasContext *dc, uint32_t addr,
        switch (size) {
                case 4:
                {
-                       r = ldl_code(addr);
+                        r = cpu_ldl_code(env, addr);
                        break;
                }
                case 2:
                {
                        if (sign) {
-                               r = ldsw_code(addr);
+                                r = cpu_ldsw_code(env, addr);
                        } else {
-                               r = lduw_code(addr);
+                                r = cpu_lduw_code(env, addr);
                        }
                        break;
                }
                case 1:
                {
                        if (sign) {
-                               r = ldsb_code(addr);
+                                r = cpu_ldsb_code(env, addr);
                        } else {
-                               r = ldub_code(addr);
+                                r = cpu_ldub_code(env, addr);
                        }
                        break;
                }
@@ -285,7 +278,7 @@ static void cris_lock_irq(DisasContext *dc)
 static inline void t_gen_raise_exception(uint32_t index)
 {
         TCGv_i32 tmp = tcg_const_i32(index);
-       gen_helper_raise_exception(tmp);
+        gen_helper_raise_exception(cpu_env, tmp);
         tcg_temp_free_i32(tmp);
 }
 
@@ -577,20 +570,15 @@ static inline void t_gen_swapr(TCGv d, TCGv s)
 
 static void t_gen_cc_jmp(TCGv pc_true, TCGv pc_false)
 {
-       TCGv btaken;
        int l1;
 
        l1 = gen_new_label();
-       btaken = tcg_temp_new();
 
        /* Conditional jmp.  */
-       tcg_gen_mov_tl(btaken, env_btaken);
        tcg_gen_mov_tl(env_pc, pc_false);
-       tcg_gen_brcondi_tl(TCG_COND_EQ, btaken, 0, l1);
+       tcg_gen_brcondi_tl(TCG_COND_EQ, env_btaken, 0, l1);
        tcg_gen_mov_tl(env_pc, pc_true);
        gen_set_label(l1);
-
-       tcg_temp_free(btaken);
 }
 
 static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
@@ -600,7 +588,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
        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((long)tb + n);
+                tcg_gen_exit_tb((tcg_target_long)tb + n);
        } else {
                tcg_gen_movi_tl(env_pc, dest);
                tcg_gen_exit_tb(0);
@@ -636,17 +624,17 @@ static void cris_evaluate_flags(DisasContext *dc)
        switch (dc->cc_op)
        {
        case CC_OP_MCP:
-               gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS],
+                gen_helper_evaluate_flags_mcp(cpu_PR[PR_CCS], cpu_env,
                                        cpu_PR[PR_CCS], cc_src,
                                        cc_dest, cc_result);
                break;
        case CC_OP_MULS:
-               gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS],
+                gen_helper_evaluate_flags_muls(cpu_PR[PR_CCS], cpu_env,
                                        cpu_PR[PR_CCS], cc_result,
                                        cpu_PR[PR_MOF]);
                break;
        case CC_OP_MULU:
-               gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS],
+                gen_helper_evaluate_flags_mulu(cpu_PR[PR_CCS], cpu_env,
                                        cpu_PR[PR_CCS], cc_result,
                                        cpu_PR[PR_MOF]);
                break;
@@ -660,15 +648,15 @@ static void cris_evaluate_flags(DisasContext *dc)
                switch (dc->cc_size)
                {
                case 4:
-                       gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
-                                               cpu_PR[PR_CCS], cc_result);
+                        gen_helper_evaluate_flags_move_4(cpu_PR[PR_CCS],
+                                           cpu_env, 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);
+                        gen_helper_evaluate_flags_move_2(cpu_PR[PR_CCS],
+                                           cpu_env, cpu_PR[PR_CCS], cc_result);
                        break;
                default:
-                       gen_helper_evaluate_flags();
+                        gen_helper_evaluate_flags(cpu_env);
                        break;
                }
                break;
@@ -678,21 +666,21 @@ static void cris_evaluate_flags(DisasContext *dc)
        case CC_OP_SUB:
        case CC_OP_CMP:
                if (dc->cc_size == 4)
-                       gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS],
+                        gen_helper_evaluate_flags_sub_4(cpu_PR[PR_CCS], cpu_env,
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
                else
-                       gen_helper_evaluate_flags();
+                        gen_helper_evaluate_flags(cpu_env);
 
                break;
        default:
                switch (dc->cc_size)
                {
                        case 4:
-                       gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS],
+                        gen_helper_evaluate_flags_alu_4(cpu_PR[PR_CCS], cpu_env,
                                cpu_PR[PR_CCS], cc_src, cc_dest, cc_result);
                                break;
                        default:
-                               gen_helper_evaluate_flags();
+                                gen_helper_evaluate_flags(cpu_env);
                                break;
                }
                break;
@@ -951,15 +939,8 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
                case CC_EQ:
                        if ((arith_opt || move_opt)
                            && dc->cc_x_uptodate != (2 | X_FLAG)) {
-                               /* If cc_result is zero, T0 should be 
-                                  non-zero otherwise T0 should be zero.  */
-                               int l1;
-                               l1 = gen_new_label();
-                               tcg_gen_movi_tl(cc, 0);
-                               tcg_gen_brcondi_tl(TCG_COND_NE, cc_result, 
-                                                  0, l1);
-                               tcg_gen_movi_tl(cc, 1);
-                               gen_set_label(l1);
+                               tcg_gen_setcond_tl(TCG_COND_EQ, cc,
+                                                  cc_result, tcg_const_tl(0));
                        }
                        else {
                                cris_evaluate_flags(dc);
@@ -1132,9 +1113,12 @@ static void gen_tst_cc (DisasContext *dc, TCGv cc, int cond)
 static void cris_store_direct_jmp(DisasContext *dc)
 {
        /* Store the direct jmp state into the cpu-state.  */
-       if (dc->jmp == JMP_DIRECT) {
+       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);
-               tcg_gen_movi_tl(env_btaken, 1);
+               dc->jmp = JMP_INDIRECT;
        }
 }
 
@@ -1144,17 +1128,11 @@ static void cris_prepare_cc_branch (DisasContext *dc,
        /* 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;
 
-       if (cond != CC_A)
-       {
-               dc->jmp = JMP_INDIRECT;
-               gen_tst_cc (dc, env_btaken, cond);
-               tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
-       } else {
-               /* Allow chaining.  */
-               dc->jmp = JMP_DIRECT;
-       }
+       gen_tst_cc (dc, env_btaken, cond);
+       tcg_gen_movi_tl(env_btarget, dc->jmp_pc);
 }
 
 
@@ -1166,8 +1144,9 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type)
           before the actual jump.  */
        dc->delayed_branch = 2;
        dc->jmp = type;
-       if (type == JMP_INDIRECT)
+       if (type == JMP_INDIRECT) {
                tcg_gen_movi_tl(env_btaken, 1);
+       }
 }
 
 static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr)
@@ -1325,8 +1304,8 @@ static void dec_prep_alu_r(DisasContext *dc, int rs, int rd,
                t_gen_zext(dst, cpu_R[rd], size);
 }
 
-static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
-                          TCGv dst)
+static int dec_prep_move_m(CPUCRISState *env, DisasContext *dc,
+                           int s_ext, int memsize, TCGv dst)
 {
        unsigned int rs;
        uint32_t imm;
@@ -1342,7 +1321,7 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
                if (memsize == 1)
                        insn_len++;
 
-               imm = cris_fetch(dc, dc->pc + 2, memsize, s_ext);
+                imm = cris_fetch(env, dc, dc->pc + 2, memsize, s_ext);
                tcg_gen_movi_tl(dst, imm);
                dc->postinc = 0;
        } else {
@@ -1359,12 +1338,12 @@ static int dec_prep_move_m(DisasContext *dc, int s_ext, int memsize,
 /* 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)
+static int dec_prep_alu_m(CPUCRISState *env, 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);
+        insn_len = dec_prep_move_m(env, dc, s_ext, memsize, src);
        tcg_gen_mov_tl(dst, cpu_R[dc->op2]);
        return insn_len;
 }
@@ -1383,7 +1362,7 @@ static const char *cc_name(int cc)
 
 /* Start of insn decoders.  */
 
-static int dec_bccq(DisasContext *dc)
+static int dec_bccq(CPUCRISState *env, DisasContext *dc)
 {
        int32_t offset;
        int sign;
@@ -1403,7 +1382,7 @@ static int dec_bccq(DisasContext *dc)
        cris_prepare_cc_branch (dc, offset, cond);
        return 2;
 }
-static int dec_addoq(DisasContext *dc)
+static int dec_addoq(CPUCRISState *env, DisasContext *dc)
 {
        int32_t imm;
 
@@ -1417,7 +1396,7 @@ static int dec_addoq(DisasContext *dc)
 
        return 2;
 }
-static int dec_addq(DisasContext *dc)
+static int dec_addq(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("addq %u, $r%u\n", dc->op1, dc->op2);
 
@@ -1429,7 +1408,7 @@ static int dec_addq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
        return 2;
 }
-static int dec_moveq(DisasContext *dc)
+static int dec_moveq(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
 
@@ -1440,7 +1419,7 @@ static int dec_moveq(DisasContext *dc)
        tcg_gen_movi_tl(cpu_R[dc->op2], imm);
        return 2;
 }
-static int dec_subq(DisasContext *dc)
+static int dec_subq(CPUCRISState *env, DisasContext *dc)
 {
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
 
@@ -1451,7 +1430,7 @@ static int dec_subq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(dc->op1), 4);
        return 2;
 }
-static int dec_cmpq(DisasContext *dc)
+static int dec_cmpq(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
@@ -1464,7 +1443,7 @@ static int dec_cmpq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
        return 2;
 }
-static int dec_andq(DisasContext *dc)
+static int dec_andq(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
@@ -1477,7 +1456,7 @@ static int dec_andq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
        return 2;
 }
-static int dec_orq(DisasContext *dc)
+static int dec_orq(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 5);
@@ -1489,14 +1468,14 @@ static int dec_orq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], tcg_const_tl(imm), 4);
        return 2;
 }
-static int dec_btstq(DisasContext *dc)
+static int dec_btstq(CPUCRISState *env, 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],
+        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, 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);
@@ -1504,7 +1483,7 @@ static int dec_btstq(DisasContext *dc)
        dc->flags_uptodate = 1;
        return 2;
 }
-static int dec_asrq(DisasContext *dc)
+static int dec_asrq(CPUCRISState *env, DisasContext *dc)
 {
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
        LOG_DIS("asrq %u, $r%d\n", dc->op1, dc->op2);
@@ -1516,7 +1495,7 @@ static int dec_asrq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
        return 2;
 }
-static int dec_lslq(DisasContext *dc)
+static int dec_lslq(CPUCRISState *env, DisasContext *dc)
 {
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
        LOG_DIS("lslq %u, $r%d\n", dc->op1, dc->op2);
@@ -1530,7 +1509,7 @@ static int dec_lslq(DisasContext *dc)
                    cpu_R[dc->op2], cpu_R[dc->op2], 4);
        return 2;
 }
-static int dec_lsrq(DisasContext *dc)
+static int dec_lsrq(CPUCRISState *env, DisasContext *dc)
 {
        dc->op1 = EXTRACT_FIELD(dc->ir, 0, 4);
        LOG_DIS("lsrq %u, $r%d\n", dc->op1, dc->op2);
@@ -1544,7 +1523,7 @@ static int dec_lsrq(DisasContext *dc)
        return 2;
 }
 
-static int dec_move_r(DisasContext *dc)
+static int dec_move_r(CPUCRISState *env, DisasContext *dc)
 {
        int size = memsize_zz(dc);
 
@@ -1572,7 +1551,7 @@ static int dec_move_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_scc_r(DisasContext *dc)
+static int dec_scc_r(CPUCRISState *env, DisasContext *dc)
 {
        int cond = dc->op2;
 
@@ -1615,7 +1594,7 @@ static inline void cris_alu_free_temps(DisasContext *dc, int size, TCGv *t)
        }
 }
 
-static int dec_and_r(DisasContext *dc)
+static int dec_and_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1632,7 +1611,7 @@ static int dec_and_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_lz_r(DisasContext *dc)
+static int dec_lz_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        LOG_DIS("lz $r%u, $r%u\n",
@@ -1645,7 +1624,7 @@ static int dec_lz_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_lsl_r(DisasContext *dc)
+static int dec_lsl_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1662,7 +1641,7 @@ static int dec_lsl_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_lsr_r(DisasContext *dc)
+static int dec_lsr_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1679,7 +1658,7 @@ static int dec_lsr_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_asr_r(DisasContext *dc)
+static int dec_asr_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1696,7 +1675,7 @@ static int dec_asr_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_muls_r(DisasContext *dc)
+static int dec_muls_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1712,7 +1691,7 @@ static int dec_muls_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_mulu_r(DisasContext *dc)
+static int dec_mulu_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1729,7 +1708,7 @@ static int dec_mulu_r(DisasContext *dc)
 }
 
 
-static int dec_dstep_r(DisasContext *dc)
+static int dec_dstep_r(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("dstep $r%u, $r%u\n", dc->op1, dc->op2);
        cris_cc_mask(dc, CC_MASK_NZ);
@@ -1738,7 +1717,7 @@ static int dec_dstep_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_xor_r(DisasContext *dc)
+static int dec_xor_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1754,7 +1733,7 @@ static int dec_xor_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_bound_r(DisasContext *dc)
+static int dec_bound_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv l0;
        int size = memsize_zz(dc);
@@ -1768,7 +1747,7 @@ static int dec_bound_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_cmp_r(DisasContext *dc)
+static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1783,7 +1762,7 @@ static int dec_cmp_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_abs_r(DisasContext *dc)
+static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
 
@@ -1802,7 +1781,7 @@ static int dec_abs_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_add_r(DisasContext *dc)
+static int dec_add_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1817,7 +1796,7 @@ static int dec_add_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_addc_r(DisasContext *dc)
+static int dec_addc_r(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("addc $r%u, $r%u\n",
                    dc->op1, dc->op2);
@@ -1832,7 +1811,7 @@ static int dec_addc_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_mcp_r(DisasContext *dc)
+static int dec_mcp_r(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("mcp $p%u, $r%u\n",
                     dc->op2, dc->op1);
@@ -1859,7 +1838,7 @@ static char * swapmode_name(int mode, char *modename) {
 }
 #endif
 
-static int dec_swap_r(DisasContext *dc)
+static int dec_swap_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
 #if DISAS_CRIS
@@ -1885,7 +1864,7 @@ static int dec_swap_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_or_r(DisasContext *dc)
+static int dec_or_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1899,7 +1878,7 @@ static int dec_or_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_addi_r(DisasContext *dc)
+static int dec_addi_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        LOG_DIS("addi.%c $r%u, $r%u\n",
@@ -1912,7 +1891,7 @@ static int dec_addi_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_addi_acr(DisasContext *dc)
+static int dec_addi_acr(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        LOG_DIS("addi.%c $r%u, $r%u, $acr\n",
@@ -1925,7 +1904,7 @@ static int dec_addi_acr(DisasContext *dc)
        return 2;
 }
 
-static int dec_neg_r(DisasContext *dc)
+static int dec_neg_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1940,13 +1919,13 @@ static int dec_neg_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_btst_r(DisasContext *dc)
+static int dec_btst_r(CPUCRISState *env, 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],
+        gen_helper_btst(cpu_PR[PR_CCS], cpu_env, 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);
@@ -1955,7 +1934,7 @@ static int dec_btst_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_sub_r(DisasContext *dc)
+static int dec_sub_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int size = memsize_zz(dc);
@@ -1970,7 +1949,7 @@ static int dec_sub_r(DisasContext *dc)
 }
 
 /* Zero extension. From size to dword.  */
-static int dec_movu_r(DisasContext *dc)
+static int dec_movu_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -1987,7 +1966,7 @@ static int dec_movu_r(DisasContext *dc)
 }
 
 /* Sign extension. From size to dword.  */
-static int dec_movs_r(DisasContext *dc)
+static int dec_movs_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -2006,7 +1985,7 @@ static int dec_movs_r(DisasContext *dc)
 }
 
 /* zero extension. From size to dword.  */
-static int dec_addu_r(DisasContext *dc)
+static int dec_addu_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -2025,7 +2004,7 @@ static int dec_addu_r(DisasContext *dc)
 }
 
 /* Sign extension. From size to dword.  */
-static int dec_adds_r(DisasContext *dc)
+static int dec_adds_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -2044,7 +2023,7 @@ static int dec_adds_r(DisasContext *dc)
 }
 
 /* Zero extension. From size to dword.  */
-static int dec_subu_r(DisasContext *dc)
+static int dec_subu_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -2063,7 +2042,7 @@ static int dec_subu_r(DisasContext *dc)
 }
 
 /* Sign extension. From size to dword.  */
-static int dec_subs_r(DisasContext *dc)
+static int dec_subs_r(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int size = memsize_z(dc);
@@ -2081,7 +2060,7 @@ static int dec_subs_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_setclrf(DisasContext *dc)
+static int dec_setclrf(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t flags;
        int set = (~dc->opcode >> 2) & 1;
@@ -2152,22 +2131,24 @@ static int dec_setclrf(DisasContext *dc)
        return 2;
 }
 
-static int dec_move_rs(DisasContext *dc)
+static int dec_move_rs(CPUCRISState *env, 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));
+        gen_helper_movl_sreg_reg(cpu_env, tcg_const_tl(dc->op2),
+                                 tcg_const_tl(dc->op1));
        return 2;
 }
-static int dec_move_sr(DisasContext *dc)
+static int dec_move_sr(CPUCRISState *env, 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));
+        gen_helper_movl_reg_sreg(cpu_env, tcg_const_tl(dc->op1),
+                                 tcg_const_tl(dc->op2));
        return 2;
 }
 
-static int dec_move_rp(DisasContext *dc)
+static int dec_move_rp(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        LOG_DIS("move $r%u, $p%u\n", dc->op1, dc->op2);
@@ -2197,7 +2178,7 @@ static int dec_move_rp(DisasContext *dc)
        tcg_temp_free(t[0]);
        return 2;
 }
-static int dec_move_pr(DisasContext *dc)
+static int dec_move_pr(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        LOG_DIS("move $p%u, $r%u\n", dc->op2, dc->op1);
@@ -2219,7 +2200,7 @@ static int dec_move_pr(DisasContext *dc)
        return 2;
 }
 
-static int dec_move_mr(DisasContext *dc)
+static int dec_move_mr(CPUCRISState *env, DisasContext *dc)
 {
        int memsize = memsize_zz(dc);
        int insn_len;
@@ -2229,7 +2210,7 @@ static int dec_move_mr(DisasContext *dc)
                    dc->op2);
 
        if (memsize == 4) {
-               insn_len = dec_prep_move_m(dc, 0, 4, cpu_R[dc->op2]);
+                insn_len = dec_prep_move_m(env, 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);
@@ -2239,7 +2220,7 @@ static int dec_move_mr(DisasContext *dc)
                TCGv t0;
 
                t0 = tcg_temp_new();
-               insn_len = dec_prep_move_m(dc, 0, memsize, t0);
+                insn_len = dec_prep_move_m(env, 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);
@@ -2261,7 +2242,7 @@ static inline void cris_alu_m_free_temps(TCGv *t)
        tcg_temp_free(t[1]);
 }
 
-static int dec_movs_m(DisasContext *dc)
+static int dec_movs_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2273,7 +2254,7 @@ static int dec_movs_m(DisasContext *dc)
 
        cris_alu_m_alloc_temps(t);
        /* sign extend.  */
-       insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2282,7 +2263,7 @@ static int dec_movs_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_addu_m(DisasContext *dc)
+static int dec_addu_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2294,7 +2275,7 @@ static int dec_addu_m(DisasContext *dc)
 
        cris_alu_m_alloc_temps(t);
        /* sign extend.  */
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2303,7 +2284,7 @@ static int dec_addu_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_adds_m(DisasContext *dc)
+static int dec_adds_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2315,7 +2296,7 @@ static int dec_adds_m(DisasContext *dc)
 
        cris_alu_m_alloc_temps(t);
        /* sign extend.  */
-       insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2323,7 +2304,7 @@ static int dec_adds_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_subu_m(DisasContext *dc)
+static int dec_subu_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2335,7 +2316,7 @@ static int dec_subu_m(DisasContext *dc)
 
        cris_alu_m_alloc_temps(t);
        /* sign extend.  */
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2343,7 +2324,7 @@ static int dec_subu_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_subs_m(DisasContext *dc)
+static int dec_subs_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2355,7 +2336,7 @@ static int dec_subs_m(DisasContext *dc)
 
        cris_alu_m_alloc_temps(t);
        /* sign extend.  */
-       insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2363,7 +2344,7 @@ static int dec_subs_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_movu_m(DisasContext *dc)
+static int dec_movu_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2375,7 +2356,7 @@ static int dec_movu_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2383,7 +2364,7 @@ static int dec_movu_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_cmpu_m(DisasContext *dc)
+static int dec_cmpu_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2394,7 +2375,7 @@ static int dec_cmpu_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2402,7 +2383,7 @@ static int dec_cmpu_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_cmps_m(DisasContext *dc)
+static int dec_cmps_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_z(dc);
@@ -2413,7 +2394,7 @@ static int dec_cmps_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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],
@@ -2423,7 +2404,7 @@ static int dec_cmps_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_cmp_m(DisasContext *dc)
+static int dec_cmp_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2434,7 +2415,7 @@ static int dec_cmp_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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],
@@ -2444,7 +2425,7 @@ static int dec_cmp_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_test_m(DisasContext *dc)
+static int dec_test_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2457,7 +2438,7 @@ static int dec_test_m(DisasContext *dc)
        cris_evaluate_flags(dc);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
 
@@ -2468,7 +2449,7 @@ static int dec_test_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_and_m(DisasContext *dc)
+static int dec_and_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2479,7 +2460,7 @@ static int dec_and_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2487,7 +2468,7 @@ static int dec_and_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_add_m(DisasContext *dc)
+static int dec_add_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2498,7 +2479,7 @@ static int dec_add_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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));
@@ -2507,7 +2488,7 @@ static int dec_add_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_addo_m(DisasContext *dc)
+static int dec_addo_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2518,7 +2499,7 @@ static int dec_addo_m(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 1, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2526,7 +2507,7 @@ static int dec_addo_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_bound_m(DisasContext *dc)
+static int dec_bound_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv l[2];
        int memsize = memsize_zz(dc);
@@ -2538,7 +2519,7 @@ static int dec_bound_m(DisasContext *dc)
 
        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]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2547,7 +2528,7 @@ static int dec_bound_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_addc_mr(DisasContext *dc)
+static int dec_addc_mr(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int insn_len = 2;
@@ -2562,7 +2543,7 @@ static int dec_addc_mr(DisasContext *dc)
        dc->flags_x = X_FLAG;
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2570,7 +2551,7 @@ static int dec_addc_mr(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_sub_m(DisasContext *dc)
+static int dec_sub_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2581,7 +2562,7 @@ static int dec_sub_m(DisasContext *dc)
                    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]);
+        insn_len = dec_prep_alu_m(env, 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);
@@ -2589,7 +2570,7 @@ static int dec_sub_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_or_m(DisasContext *dc)
+static int dec_or_m(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2600,7 +2581,7 @@ static int dec_or_m(DisasContext *dc)
                    dc->op2, dc->pc);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, 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));
@@ -2609,7 +2590,7 @@ static int dec_or_m(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_move_mp(DisasContext *dc)
+static int dec_move_mp(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t[2];
        int memsize = memsize_zz(dc);
@@ -2622,7 +2603,7 @@ static int dec_move_mp(DisasContext *dc)
                    dc->op2);
 
        cris_alu_m_alloc_temps(t);
-       insn_len = dec_prep_alu_m(dc, 0, memsize, t[0], t[1]);
+        insn_len = dec_prep_alu_m(env, dc, 0, memsize, t[0], t[1]);
        cris_cc_mask(dc, 0);
        if (dc->op2 == PR_CCS) {
                cris_evaluate_flags(dc);
@@ -2641,7 +2622,7 @@ static int dec_move_mp(DisasContext *dc)
        return insn_len;
 }
 
-static int dec_move_pm(DisasContext *dc)
+static int dec_move_pm(CPUCRISState *env, DisasContext *dc)
 {
        TCGv t0;
        int memsize;
@@ -2667,7 +2648,7 @@ static int dec_move_pm(DisasContext *dc)
        return 2;
 }
 
-static int dec_movem_mr(DisasContext *dc)
+static int dec_movem_mr(CPUCRISState *env, DisasContext *dc)
 {
        TCGv_i64 tmp[16];
         TCGv tmp32;
@@ -2714,7 +2695,7 @@ static int dec_movem_mr(DisasContext *dc)
        return 2;
 }
 
-static int dec_movem_rm(DisasContext *dc)
+static int dec_movem_rm(CPUCRISState *env, DisasContext *dc)
 {
        TCGv tmp;
        TCGv addr;
@@ -2743,7 +2724,7 @@ static int dec_movem_rm(DisasContext *dc)
        return 2;
 }
 
-static int dec_move_rm(DisasContext *dc)
+static int dec_move_rm(CPUCRISState *env, DisasContext *dc)
 {
        int memsize;
 
@@ -2762,7 +2743,7 @@ static int dec_move_rm(DisasContext *dc)
        return 2;
 }
 
-static int dec_lapcq(DisasContext *dc)
+static int dec_lapcq(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("lapcq %x, $r%u\n",
                    dc->pc + dc->op1*2, dc->op2);
@@ -2771,7 +2752,7 @@ static int dec_lapcq(DisasContext *dc)
        return 2;
 }
 
-static int dec_lapc_im(DisasContext *dc)
+static int dec_lapc_im(CPUCRISState *env, DisasContext *dc)
 {
        unsigned int rd;
        int32_t imm;
@@ -2780,7 +2761,7 @@ static int dec_lapc_im(DisasContext *dc)
        rd = dc->op2;
 
        cris_cc_mask(dc, 0);
-       imm = cris_fetch(dc, dc->pc + 2, 4, 0);
+        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
        LOG_DIS("lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2);
 
        pc = dc->pc;
@@ -2790,7 +2771,7 @@ static int dec_lapc_im(DisasContext *dc)
 }
 
 /* Jump to special reg.  */
-static int dec_jump_p(DisasContext *dc)
+static int dec_jump_p(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("jump $p%u\n", dc->op2);
 
@@ -2805,7 +2786,7 @@ static int dec_jump_p(DisasContext *dc)
 }
 
 /* Jump and save.  */
-static int dec_jas_r(DisasContext *dc)
+static int dec_jas_r(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("jas $r%u, $p%u\n", dc->op1, dc->op2);
        cris_cc_mask(dc, 0);
@@ -2819,11 +2800,11 @@ static int dec_jas_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_jas_im(DisasContext *dc)
+static int dec_jas_im(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
 
-       imm = cris_fetch(dc, dc->pc + 2, 4, 0);
+        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
 
        LOG_DIS("jas 0x%x\n", imm);
        cris_cc_mask(dc, 0);
@@ -2835,11 +2816,11 @@ static int dec_jas_im(DisasContext *dc)
        return 6;
 }
 
-static int dec_jasc_im(DisasContext *dc)
+static int dec_jasc_im(CPUCRISState *env, DisasContext *dc)
 {
        uint32_t imm;
 
-       imm = cris_fetch(dc, dc->pc + 2, 4, 0);
+        imm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
 
        LOG_DIS("jasc 0x%x\n", imm);
        cris_cc_mask(dc, 0);
@@ -2851,7 +2832,7 @@ static int dec_jasc_im(DisasContext *dc)
        return 6;
 }
 
-static int dec_jasc_r(DisasContext *dc)
+static int dec_jasc_r(CPUCRISState *env, DisasContext *dc)
 {
        LOG_DIS("jasc_r $r%u, $p%u\n", dc->op1, dc->op2);
        cris_cc_mask(dc, 0);
@@ -2862,12 +2843,12 @@ static int dec_jasc_r(DisasContext *dc)
        return 2;
 }
 
-static int dec_bcc_im(DisasContext *dc)
+static int dec_bcc_im(CPUCRISState *env, DisasContext *dc)
 {
        int32_t offset;
        uint32_t cond = dc->op2;
 
-       offset = cris_fetch(dc, dc->pc + 2, 2, 1);
+        offset = cris_fetch(env, dc, dc->pc + 2, 2, 1);
 
        LOG_DIS("b%s %d pc=%x dst=%x\n",
                    cc_name(cond), offset,
@@ -2879,12 +2860,12 @@ static int dec_bcc_im(DisasContext *dc)
        return 4;
 }
 
-static int dec_bas_im(DisasContext *dc)
+static int dec_bas_im(CPUCRISState *env, DisasContext *dc)
 {
        int32_t simm;
 
 
-       simm = cris_fetch(dc, dc->pc + 2, 4, 0);
+        simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
 
        LOG_DIS("bas 0x%x, $p%u\n", dc->pc + simm, dc->op2);
        cris_cc_mask(dc, 0);
@@ -2896,10 +2877,10 @@ static int dec_bas_im(DisasContext *dc)
        return 6;
 }
 
-static int dec_basc_im(DisasContext *dc)
+static int dec_basc_im(CPUCRISState *env, DisasContext *dc)
 {
        int32_t simm;
-       simm = cris_fetch(dc, dc->pc + 2, 4, 0);
+        simm = cris_fetch(env, dc, dc->pc + 2, 4, 0);
 
        LOG_DIS("basc 0x%x, $p%u\n", dc->pc + simm, dc->op2);
        cris_cc_mask(dc, 0);
@@ -2911,7 +2892,7 @@ static int dec_basc_im(DisasContext *dc)
        return 6;
 }
 
-static int dec_rfe_etc(DisasContext *dc)
+static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc)
 {
        cris_cc_mask(dc, 0);
 
@@ -2927,14 +2908,14 @@ static int dec_rfe_etc(DisasContext *dc)
                        /* rfe.  */
                        LOG_DIS("rfe\n");
                        cris_evaluate_flags(dc);
-                       gen_helper_rfe();
+                        gen_helper_rfe(cpu_env);
                        dc->is_jmp = DISAS_UPDATE;
                        break;
                case 5:
                        /* rfn.  */
                        LOG_DIS("rfn\n");
                        cris_evaluate_flags(dc);
-                       gen_helper_rfn();
+                        gen_helper_rfn(cpu_env);
                        dc->is_jmp = DISAS_UPDATE;
                        break;
                case 6:
@@ -2958,17 +2939,17 @@ static int dec_rfe_etc(DisasContext *dc)
        return 2;
 }
 
-static int dec_ftag_fidx_d_m(DisasContext *dc)
+static int dec_ftag_fidx_d_m(CPUCRISState *env, DisasContext *dc)
 {
        return 2;
 }
 
-static int dec_ftag_fidx_i_m(DisasContext *dc)
+static int dec_ftag_fidx_i_m(CPUCRISState *env, DisasContext *dc)
 {
        return 2;
 }
 
-static int dec_null(DisasContext *dc)
+static int dec_null(CPUCRISState *env, DisasContext *dc)
 {
        printf ("unknown insn pc=%x opc=%x op1=%x op2=%x\n",
                dc->pc, dc->opcode, dc->op1, dc->op2);
@@ -2982,7 +2963,7 @@ static struct decoder_info {
                uint32_t bits;
                uint32_t mask;
        };
-       int (*dec)(DisasContext *dc);
+        int (*dec)(CPUCRISState *env, DisasContext *dc);
 } decinfo[] = {
        /* Order matters here.  */
        {DEC_MOVEQ, dec_moveq},
@@ -3088,7 +3069,7 @@ static struct decoder_info {
        {{0, 0}, dec_null}
 };
 
-static unsigned int crisv32_decoder(DisasContext *dc)
+static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc)
 {
        int insn_len = 2;
        int i;
@@ -3097,7 +3078,7 @@ static unsigned int crisv32_decoder(DisasContext *dc)
                tcg_gen_debug_insn_start(dc->pc);
 
        /* Load a halfword onto the instruction register.  */
-       dc->ir = cris_fetch(dc, dc->pc, 2, 0);
+        dc->ir = cris_fetch(env, dc, dc->pc, 2, 0);
 
        /* Now decode it.  */
        dc->opcode   = EXTRACT_FIELD(dc->ir, 4, 11);
@@ -3111,7 +3092,7 @@ static unsigned int crisv32_decoder(DisasContext *dc)
        for (i = 0; i < ARRAY_SIZE(decinfo); i++) {
                if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits)
                {
-                       insn_len = decinfo[i].dec(dc);
+                        insn_len = decinfo[i].dec(env, dc);
                        break;
                }
        }
@@ -3135,7 +3116,7 @@ static unsigned int crisv32_decoder(DisasContext *dc)
        return insn_len;
 }
 
-static void check_breakpoint(CPUState *env, DisasContext *dc)
+static void check_breakpoint(CPUCRISState *env, DisasContext *dc)
 {
        CPUBreakpoint *bp;
 
@@ -3189,12 +3170,12 @@ static void check_breakpoint(CPUState *env, DisasContext *dc)
 
 /* generate intermediate code for basic block 'tb'.  */
 static void
-gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
+gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb,
                                int search_pc)
 {
        uint16_t *gen_opc_end;
        uint32_t pc_start;
-       unsigned int insn_len, orig_flags;
+       unsigned int insn_len;
        int j, lj;
        struct DisasContext ctx;
        struct DisasContext *dc = &ctx;
@@ -3205,10 +3186,13 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
        qemu_log_try_set_file(stderr);
 
-       if (env->pregs[PR_VR] == 32)
+       if (env->pregs[PR_VR] == 32) {
                dc->decoder = crisv32_decoder;
-       else
+               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.
@@ -3230,13 +3214,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
        dc->cc_mask = 0;
        dc->update_cc = 0;
        dc->clear_prefix = 0;
-       dc->clear_locked_irq = 1;
 
        cris_update_cc_op(dc, CC_OP_FLAGS, 4);
        dc->cc_size_uptodate = -1;
 
        /* Decode TB flags.  */
-       orig_flags = dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG \
+       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)
@@ -3303,7 +3286,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                     gen_io_start();
                dc->clear_x = 1;
 
-               insn_len = dc->decoder(dc);
+                insn_len = dc->decoder(env, dc);
                dc->ppc = dc->pc;
                dc->pc += insn_len;
                if (dc->clear_x)
@@ -3320,8 +3303,36 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                                if (tb->flags & 7)
                                        t_gen_mov_env_TN(dslot, 
                                                tcg_const_tl(0));
-                               if (dc->jmp == JMP_DIRECT) {
-                                       dc->is_jmp = DISAS_NEXT;
+                               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));
@@ -3341,16 +3352,10 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                 && (dc->pc < next_page_start)
                  && num_insns < max_insns);
 
-       if (dc->tb_flags != orig_flags) {
-               dc->cpustate_changed = 1;
-       }
-
        if (dc->clear_locked_irq)
                t_gen_mov_env_TN(locked_irq, tcg_const_tl(0));
 
        npc = dc->pc;
-       if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
-               npc = dc->jmp_pc;
 
         if (tb->cflags & CF_LAST_IO)
             gen_io_end();
@@ -3416,18 +3421,17 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 #endif
 }
 
-void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 0);
 }
 
-void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
+void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb)
 {
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
        int i;
@@ -3456,7 +3460,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
        }
        srs = env->pregs[PR_SRS];
        cpu_fprintf(f, "\nsupport function regs bank %x:\n", srs);
-       if (srs < 256) {
+       if (srs < ARRAY_SIZE(env->sregs)) {
                for (i = 0; i < 16; i++) {
                        cpu_fprintf(f, "s%2.2d=%8.8x ",
                                    i, env->sregs[srs][i]);
@@ -3480,7 +3484,7 @@ struct
        {32, "crisv32"},
 };
 
-void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     unsigned int i;
 
@@ -3501,101 +3505,80 @@ static uint32_t vr_by_name(const char *name)
     return 32;
 }
 
-CPUCRISState *cpu_cris_init (const char *cpu_model)
+CRISCPU *cpu_cris_init(const char *cpu_model)
 {
-       CPUCRISState *env;
-       static int tcg_initialized = 0;
-       int i;
+    CRISCPU *cpu;
+    CPUCRISState *env;
+    static int tcg_initialized = 0;
+    int i;
 
-       env = qemu_mallocz(sizeof(CPUCRISState));
+    cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU));
+    env = &cpu->env;
 
-       env->pregs[PR_VR] = vr_by_name(cpu_model);
-       cpu_exec_init(env);
-       cpu_reset(env);
-       qemu_init_vcpu(env);
+    env->pregs[PR_VR] = vr_by_name(cpu_model);
 
-       if (tcg_initialized)
-               return env;
+    cpu_reset(CPU(cpu));
+    qemu_init_vcpu(env);
 
-       tcg_initialized = 1;
+    if (tcg_initialized) {
+        return cpu;
+    }
+
+    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;
-}
+    if (env->pregs[PR_VR] < 32) {
+        cpu_crisv10_init(env);
+        return cpu;
+    }
 
-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);
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
+    cc_x = tcg_global_mem_new(TCG_AREG0,
+                              offsetof(CPUCRISState, cc_x), "cc_x");
+    cc_src = tcg_global_mem_new(TCG_AREG0,
+                                offsetof(CPUCRISState, cc_src), "cc_src");
+    cc_dest = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUCRISState, cc_dest),
+                                 "cc_dest");
+    cc_result = tcg_global_mem_new(TCG_AREG0,
+                                   offsetof(CPUCRISState, cc_result),
+                                   "cc_result");
+    cc_op = tcg_global_mem_new(TCG_AREG0,
+                               offsetof(CPUCRISState, cc_op), "cc_op");
+    cc_size = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUCRISState, cc_size),
+                                 "cc_size");
+    cc_mask = tcg_global_mem_new(TCG_AREG0,
+                                 offsetof(CPUCRISState, cc_mask),
+                                 "cc_mask");
+
+    env_pc = tcg_global_mem_new(TCG_AREG0,
+                                offsetof(CPUCRISState, pc),
+                                "pc");
+    env_btarget = tcg_global_mem_new(TCG_AREG0,
+                                     offsetof(CPUCRISState, btarget),
+                                     "btarget");
+    env_btaken = tcg_global_mem_new(TCG_AREG0,
+                                    offsetof(CPUCRISState, btaken),
+                                    "btaken");
+    for (i = 0; i < 16; i++) {
+        cpu_R[i] = tcg_global_mem_new(TCG_AREG0,
+                                      offsetof(CPUCRISState, regs[i]),
+                                      regnames[i]);
+    }
+    for (i = 0; i < 16; i++) {
+        cpu_PR[i] = tcg_global_mem_new(TCG_AREG0,
+                                       offsetof(CPUCRISState, pregs[i]),
+                                       pregnames[i]);
+    }
 
-#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
+    return cpu;
 }
 
-void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
-                 unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos)
 {
        env->pc = gen_opc_pc[pc_pos];
 }