]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target-m68k/translate.c
Merge remote-tracking branch 'aneesh/for-upstream' into staging
[mirror_qemu.git] / target-m68k / translate.c
index a920d213b049dc088c9b8ef4efec5cf2e41e1794..11defc6e040097b741dcffed8b7c0d53b924ddf9 100644 (file)
  * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "config.h"
+
 #include "cpu.h"
-#include "exec-all.h"
 #include "disas.h"
 #include "tcg-op.h"
+#include "qemu-log.h"
 
+#include "helpers.h"
 #define GEN_HELPER 1
 #include "helpers.h"
 
 //#define DEBUG_DISPATCH 1
 
+/* Fake floating point.  */
+#define tcg_gen_mov_f64 tcg_gen_mov_i64
+#define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64
+#define tcg_gen_qemu_stf64 tcg_gen_qemu_st64
+
 #define DEFO32(name, offset) static TCGv QREG_##name;
-#define DEFO64(name, offset) static TCGv QREG_##name;
-#define DEFF64(name, offset) static TCGv QREG_##name;
+#define DEFO64(name, offset) static TCGv_i64 QREG_##name;
+#define DEFF64(name, offset) static TCGv_i64 QREG_##name;
 #include "qregs.def"
 #undef DEFO32
 #undef DEFO64
 #undef DEFF64
 
-static TCGv cpu_env;
+static TCGv_ptr cpu_env;
 
 static char cpu_reg_names[3*8*3 + 5*4];
 static TCGv cpu_dregs[8];
 static TCGv cpu_aregs[8];
-static TCGv cpu_fregs[8];
-static TCGv cpu_macc[4];
+static TCGv_i64 cpu_fregs[8];
+static TCGv_i64 cpu_macc[4];
 
 #define DREG(insn, pos) cpu_dregs[((insn) >> (pos)) & 7]
 #define AREG(insn, pos) cpu_aregs[((insn) >> (pos)) & 7]
@@ -59,7 +57,7 @@ static TCGv cpu_macc[4];
 #define QREG_SP cpu_aregs[7]
 
 static TCGv NULL_QREG;
-#define IS_NULL_QREG(t) (GET_TCGV(t) == GET_TCGV(NULL_QREG))
+#define IS_NULL_QREG(t) (TCGV_EQUAL(t, NULL_QREG))
 /* Used to distinguish stores from bad addressing modes.  */
 static TCGv store_dummy;
 
@@ -70,43 +68,42 @@ void m68k_tcg_init(void)
     char *p;
     int i;
 
-#define DEFO32(name,  offset) QREG_##name = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, offsetof(CPUState, offset), #name);
-#define DEFO64(name,  offset) QREG_##name = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0, offsetof(CPUState, offset), #name);
+#define DEFO32(name,  offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
+#define DEFO64(name,  offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
 #define DEFF64(name,  offset) DEFO64(name, offset)
 #include "qregs.def"
 #undef DEFO32
 #undef DEFO64
 #undef DEFF64
 
-    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
     p = cpu_reg_names;
     for (i = 0; i < 8; i++) {
         sprintf(p, "D%d", i);
-        cpu_dregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+        cpu_dregs[i] = tcg_global_mem_new(TCG_AREG0,
                                           offsetof(CPUM68KState, dregs[i]), p);
         p += 3;
         sprintf(p, "A%d", i);
-        cpu_aregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+        cpu_aregs[i] = tcg_global_mem_new(TCG_AREG0,
                                           offsetof(CPUM68KState, aregs[i]), p);
         p += 3;
         sprintf(p, "F%d", i);
-        cpu_fregs[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+        cpu_fregs[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                           offsetof(CPUM68KState, fregs[i]), p);
         p += 3;
     }
     for (i = 0; i < 4; i++) {
         sprintf(p, "ACC%d", i);
-        cpu_macc[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+        cpu_macc[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                          offsetof(CPUM68KState, macc[i]), p);
         p += 5;
     }
 
-    NULL_QREG = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, -4, "NULL");
-    store_dummy = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, -8, "NULL");
+    NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
+    store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
 
-#define DEF_HELPER(name, ret, args) \
-    tcg_register_helper(HELPER(name), #name);
+#define GEN_HELPER 2
 #include "helpers.h"
 }
 
@@ -130,7 +127,8 @@ typedef struct DisasContext {
     struct TranslationBlock *tb;
     int singlestep_enabled;
     int is_mem;
-    TCGv mactmp;
+    TCGv_i64 mactmp;
+    int done_mac;
 } DisasContext;
 
 #define DISAS_JUMP_NEXT 4
@@ -146,52 +144,32 @@ typedef struct DisasContext {
 static void *gen_throws_exception;
 #define gen_last_qop NULL
 
-extern FILE *logfile;
-extern int loglevel;
-
 #define OS_BYTE 0
 #define OS_WORD 1
 #define OS_LONG 2
 #define OS_SINGLE 4
 #define OS_DOUBLE 5
 
-typedef void (*disas_proc)(DisasContext *, uint16_t);
+typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn);
 
 #ifdef DEBUG_DISPATCH
-#define DISAS_INSN(name) \
-  static void real_disas_##name (DisasContext *s, uint16_t insn); \
-  static void disas_##name (DisasContext *s, uint16_t insn) { \
-    if (logfile) fprintf(logfile, "Dispatch " #name "\n"); \
-    real_disas_##name(s, insn); } \
-  static void real_disas_##name (DisasContext *s, uint16_t insn)
+#define DISAS_INSN(name)                                                \
+    static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
+                                  uint16_t insn);                       \
+    static void disas_##name(CPUM68KState *env, DisasContext *s,        \
+                             uint16_t insn)                             \
+    {                                                                   \
+        qemu_log("Dispatch " #name "\n");                               \
+        real_disas_##name(s, env, insn);                                \
+    }                                                                   \
+    static void real_disas_##name(CPUM68KState *env, DisasContext *s,   \
+                                  uint16_t insn)
 #else
-#define DISAS_INSN(name) \
-  static void disas_##name (DisasContext *s, uint16_t insn)
+#define DISAS_INSN(name)                                                \
+    static void disas_##name(CPUM68KState *env, DisasContext *s,        \
+                             uint16_t insn)
 #endif
 
-/* FIXME: Remove this.  */
-#define gen_im32(val) tcg_const_i32(val)
-
-/* Fake floating point.  */
-#define TCG_TYPE_F32 TCG_TYPE_I32
-#define TCG_TYPE_F64 TCG_TYPE_I64
-#define tcg_gen_mov_f64 tcg_gen_mov_i64
-#define tcg_gen_qemu_ldf32 tcg_gen_qemu_ld32u
-#define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64
-#define tcg_gen_qemu_stf32 tcg_gen_qemu_st32
-#define tcg_gen_qemu_stf64 tcg_gen_qemu_st64
-#define gen_helper_pack_32_f32 tcg_gen_mov_i32
-#define gen_helper_pack_f32_32 tcg_gen_mov_i32
-
-#define QMODE_I32 TCG_TYPE_I32
-#define QMODE_I64 TCG_TYPE_I64
-#define QMODE_F32 TCG_TYPE_F32
-#define QMODE_F64 TCG_TYPE_F64
-static inline TCGv gen_new_qreg(int mode)
-{
-    return tcg_temp_new(mode);
-}
-
 /* Generate a load from the specified address.  Narrow values are
    sign extended to full register width.  */
 static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
@@ -199,32 +177,23 @@ static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
     TCGv tmp;
     int index = IS_USER(s);
     s->is_mem = 1;
+    tmp = tcg_temp_new_i32();
     switch(opsize) {
     case OS_BYTE:
-        tmp = gen_new_qreg(QMODE_I32);
         if (sign)
             tcg_gen_qemu_ld8s(tmp, addr, index);
         else
             tcg_gen_qemu_ld8u(tmp, addr, index);
         break;
     case OS_WORD:
-        tmp = gen_new_qreg(QMODE_I32);
         if (sign)
             tcg_gen_qemu_ld16s(tmp, addr, index);
         else
             tcg_gen_qemu_ld16u(tmp, addr, index);
         break;
     case OS_LONG:
-        tmp = gen_new_qreg(QMODE_I32);
-        tcg_gen_qemu_ld32u(tmp, addr, index);
-        break;
     case OS_SINGLE:
-        tmp = gen_new_qreg(QMODE_F32);
-        tcg_gen_qemu_ldf32(tmp, addr, index);
-        break;
-    case OS_DOUBLE:
-        tmp  = gen_new_qreg(QMODE_F64);
-        tcg_gen_qemu_ldf64(tmp, addr, index);
+        tcg_gen_qemu_ld32u(tmp, addr, index);
         break;
     default:
         qemu_assert(0, "bad load size");
@@ -233,6 +202,17 @@ static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
     return tmp;
 }
 
+static inline TCGv_i64 gen_load64(DisasContext * s, TCGv addr)
+{
+    TCGv_i64 tmp;
+    int index = IS_USER(s);
+    s->is_mem = 1;
+    tmp = tcg_temp_new_i64();
+    tcg_gen_qemu_ldf64(tmp, addr, index);
+    gen_throws_exception = gen_last_qop;
+    return tmp;
+}
+
 /* Generate a store.  */
 static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
 {
@@ -246,13 +226,8 @@ static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
         tcg_gen_qemu_st16(val, addr, index);
         break;
     case OS_LONG:
-        tcg_gen_qemu_st32(val, addr, index);
-        break;
     case OS_SINGLE:
-        tcg_gen_qemu_stf32(val, addr, index);
-        break;
-    case OS_DOUBLE:
-        tcg_gen_qemu_stf64(val, addr, index);
+        tcg_gen_qemu_st32(val, addr, index);
         break;
     default:
         qemu_assert(0, "bad store size");
@@ -260,6 +235,14 @@ static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
     gen_throws_exception = gen_last_qop;
 }
 
+static inline void gen_store64(DisasContext *s, TCGv addr, TCGv_i64 val)
+{
+    int index = IS_USER(s);
+    s->is_mem = 1;
+    tcg_gen_qemu_stf64(val, addr, index);
+    gen_throws_exception = gen_last_qop;
+}
+
 typedef enum {
     EA_STORE,
     EA_LOADU,
@@ -280,12 +263,12 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
 }
 
 /* Read a 32-bit immediate constant.  */
-static inline uint32_t read_im32(DisasContext *s)
+static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s)
 {
     uint32_t im;
-    im = ((uint32_t)lduw_code(s->pc)) << 16;
+    im = ((uint32_t)cpu_lduw_code(env, s->pc)) << 16;
     s->pc += 2;
-    im |= lduw_code(s->pc);
+    im |= cpu_lduw_code(env, s->pc);
     s->pc += 2;
     return im;
 }
@@ -311,7 +294,8 @@ static TCGv gen_addr_index(uint16_t ext, TCGv tmp)
 
 /* Handle a base + index + displacement effective addresss.
    A NULL_QREG base means pc-relative.  */
-static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
+static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, int opsize,
+                            TCGv base)
 {
     uint32_t offset;
     uint16_t ext;
@@ -320,7 +304,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
     uint32_t bd, od;
 
     offset = s->pc;
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
     if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX))
@@ -334,15 +318,15 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
         if ((ext & 0x30) > 0x10) {
             /* base displacement */
             if ((ext & 0x30) == 0x20) {
-                bd = (int16_t)lduw_code(s->pc);
+                bd = (int16_t)cpu_lduw_code(env, s->pc);
                 s->pc += 2;
             } else {
-                bd = read_im32(s);
+                bd = read_im32(env, s);
             }
         } else {
             bd = 0;
         }
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         if ((ext & 0x44) == 0) {
             /* pre-index */
             add = gen_addr_index(ext, tmp);
@@ -352,7 +336,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
         if ((ext & 0x80) == 0) {
             /* base not suppressed */
             if (IS_NULL_QREG(base)) {
-                base = gen_im32(offset + bd);
+                base = tcg_const_i32(offset + bd);
                 bd = 0;
             }
             if (!IS_NULL_QREG(add)) {
@@ -368,7 +352,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
                 add = tmp;
             }
         } else {
-            add = gen_im32(bd);
+            add = tcg_const_i32(bd);
         }
         if ((ext & 3) != 0) {
             /* memory indirect */
@@ -383,10 +367,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
             if ((ext & 3) > 1) {
                 /* outer displacement */
                 if ((ext & 3) == 2) {
-                    od = (int16_t)lduw_code(s->pc);
+                    od = (int16_t)cpu_lduw_code(env, s->pc);
                     s->pc += 2;
                 } else {
-                    od = read_im32(s);
+                    od = read_im32(env, s);
                 }
             } else {
                 od = 0;
@@ -398,7 +382,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base)
         }
     } else {
         /* brief extension word format */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         add = gen_addr_index(ext, tmp);
         if (!IS_NULL_QREG(base)) {
             tcg_gen_add_i32(tmp, add, base);
@@ -451,6 +435,7 @@ static inline int opsize_bytes(int opsize)
     case OS_DOUBLE: return 8;
     default:
         qemu_assert(0, "bad operand size");
+        return 0;
     }
 }
 
@@ -462,21 +447,19 @@ static void gen_partset_reg(int opsize, TCGv reg, TCGv val)
     switch (opsize) {
     case OS_BYTE:
         tcg_gen_andi_i32(reg, reg, 0xffffff00);
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_ext8u_i32(tmp, val);
         tcg_gen_or_i32(reg, reg, tmp);
         break;
     case OS_WORD:
         tcg_gen_andi_i32(reg, reg, 0xffff0000);
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_ext16u_i32(tmp, val);
         tcg_gen_or_i32(reg, reg, tmp);
         break;
     case OS_LONG:
-        tcg_gen_mov_i32(reg, val);
-        break;
     case OS_SINGLE:
-        gen_helper_pack_32_f32(reg, val);
+        tcg_gen_mov_i32(reg, val);
         break;
     default:
         qemu_assert(0, "Bad operand size");
@@ -491,25 +474,22 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign)
 
     switch (opsize) {
     case OS_BYTE:
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         if (sign)
             tcg_gen_ext8s_i32(tmp, val);
         else
             tcg_gen_ext8u_i32(tmp, val);
         break;
     case OS_WORD:
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         if (sign)
             tcg_gen_ext16s_i32(tmp, val);
         else
             tcg_gen_ext16u_i32(tmp, val);
         break;
     case OS_LONG:
-        tmp = val;
-        break;
     case OS_SINGLE:
-        tmp = gen_new_qreg(QMODE_F32);
-        gen_helper_pack_f32_32(tmp, val);
+        tmp = val;
         break;
     default:
         qemu_assert(0, "Bad operand size");
@@ -518,8 +498,9 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign)
 }
 
 /* Generate code for an "effective address".  Does not adjust the base
-   register for autoincrememnt addressing modes.  */
-static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+   register for autoincrement addressing modes.  */
+static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
+                    int opsize)
 {
     TCGv reg;
     TCGv tmp;
@@ -535,36 +516,35 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
         return AREG(insn, 0);
     case 4: /* Indirect predecrememnt.  */
         reg = AREG(insn, 0);
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_subi_i32(tmp, reg, opsize_bytes(opsize));
         return tmp;
     case 5: /* Indirect displacement.  */
         reg = AREG(insn, 0);
-        tmp = gen_new_qreg(QMODE_I32);
-        ext = lduw_code(s->pc);
+        tmp = tcg_temp_new();
+        ext = cpu_lduw_code(env, s->pc);
         s->pc += 2;
         tcg_gen_addi_i32(tmp, reg, (int16_t)ext);
         return tmp;
     case 6: /* Indirect index + displacement.  */
         reg = AREG(insn, 0);
-        return gen_lea_indexed(s, opsize, reg);
+        return gen_lea_indexed(env, s, opsize, reg);
     case 7: /* Other */
         switch (insn & 7) {
         case 0: /* Absolute short.  */
-            offset = ldsw_code(s->pc);
+            offset = cpu_ldsw_code(env, s->pc);
             s->pc += 2;
-            return gen_im32(offset);
+            return tcg_const_i32(offset);
         case 1: /* Absolute long.  */
-            offset = read_im32(s);
-            return gen_im32(offset);
+            offset = read_im32(env, s);
+            return tcg_const_i32(offset);
         case 2: /* pc displacement  */
-            tmp = gen_new_qreg(QMODE_I32);
             offset = s->pc;
-            offset += ldsw_code(s->pc);
+            offset += cpu_ldsw_code(env, s->pc);
             s->pc += 2;
-            return gen_im32(offset);
+            return tcg_const_i32(offset);
         case 3: /* pc index+displacement.  */
-            return gen_lea_indexed(s, opsize, NULL_QREG);
+            return gen_lea_indexed(env, s, opsize, NULL_QREG);
         case 4: /* Immediate.  */
         default:
             return NULL_QREG;
@@ -576,15 +556,16 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
 
 /* Helper function for gen_ea. Reuse the computed address between the
    for read/write operands.  */
-static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
-                              TCGv val, TCGv *addrp, ea_what what)
+static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s,
+                               uint16_t insn, int opsize, TCGv val,
+                               TCGv *addrp, ea_what what)
 {
     TCGv tmp;
 
     if (addrp && what == EA_STORE) {
         tmp = *addrp;
     } else {
-        tmp = gen_lea(s, insn, opsize);
+        tmp = gen_lea(env, s, insn, opsize);
         if (IS_NULL_QREG(tmp))
             return tmp;
         if (addrp)
@@ -596,8 +577,8 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
 /* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
    a write otherwise it is a read (0 == sign extend, -1 == zero extend).
    ADDRP is non-null for readwrite operands.  */
-static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
-                   TCGv *addrp, ea_what what)
+static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
+                   int opsize, TCGv val, TCGv *addrp, ea_what what)
 {
     TCGv reg;
     TCGv result;
@@ -637,7 +618,7 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
             if (addrp && what == EA_STORE) {
                 tmp = *addrp;
             } else {
-                tmp = gen_lea(s, insn, opsize);
+                tmp = gen_lea(env, s, insn, opsize);
                 if (IS_NULL_QREG(tmp))
                     return tmp;
                 if (addrp)
@@ -654,33 +635,35 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
         return result;
     case 5: /* Indirect displacement.  */
     case 6: /* Indirect index + displacement.  */
-        return gen_ea_once(s, insn, opsize, val, addrp, what);
+        return gen_ea_once(env, s, insn, opsize, val, addrp, what);
     case 7: /* Other */
         switch (insn & 7) {
         case 0: /* Absolute short.  */
         case 1: /* Absolute long.  */
         case 2: /* pc displacement  */
         case 3: /* pc index+displacement.  */
-            return gen_ea_once(s, insn, opsize, val, addrp, what);
+            return gen_ea_once(env, s, insn, opsize, val, addrp, what);
         case 4: /* Immediate.  */
             /* Sign extend values for consistency.  */
             switch (opsize) {
             case OS_BYTE:
-                if (what == EA_LOADS)
-                    offset = ldsb_code(s->pc + 1);
-                else
-                    offset = ldub_code(s->pc + 1);
+                if (what == EA_LOADS) {
+                    offset = cpu_ldsb_code(env, s->pc + 1);
+                } else {
+                    offset = cpu_ldub_code(env, s->pc + 1);
+                }
                 s->pc += 2;
                 break;
             case OS_WORD:
-                if (what == EA_LOADS)
-                    offset = ldsw_code(s->pc);
-                else
-                    offset = lduw_code(s->pc);
+                if (what == EA_LOADS) {
+                    offset = cpu_ldsw_code(env, s->pc);
+                } else {
+                    offset = cpu_lduw_code(env, s->pc);
+                }
                 s->pc += 2;
                 break;
             case OS_LONG:
-                offset = read_im32(s);
+                offset = read_im32(env, s);
                 break;
             default:
                 qemu_assert(0, "Bad immediate operand");
@@ -709,57 +692,57 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
     case 1: /* F */
         break;
     case 2: /* HI (!C && !Z) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 3: /* LS (C || Z) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C | CCF_Z);
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 4: /* CC (!C) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 5: /* CS (C) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_C);
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 6: /* NE (!Z) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 7: /* EQ (Z) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_Z);
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 8: /* VC (!V) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 9: /* VS (V) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_V);
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 10: /* PL (!N) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 11: /* MI (N) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 12: /* GE (!(N ^ V)) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         assert(CCF_V == (CCF_N >> 2));
         tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
@@ -767,7 +750,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 13: /* LT (N ^ V) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         assert(CCF_V == (CCF_N >> 2));
         tcg_gen_shri_i32(tmp, QREG_CC_DEST, 2);
         tcg_gen_xor_i32(tmp, tmp, QREG_CC_DEST);
@@ -775,7 +758,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1);
         break;
     case 14: /* GT (!(Z || (N ^ V))) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         assert(CCF_V == (CCF_N >> 2));
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
         tcg_gen_shri_i32(tmp, tmp, 2);
@@ -784,7 +767,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1);
         break;
     case 15: /* LE (Z || (N ^ V)) */
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         assert(CCF_V == (CCF_N >> 2));
         tcg_gen_andi_i32(tmp, QREG_CC_DEST, CCF_N);
         tcg_gen_shri_i32(tmp, tmp, 2);
@@ -843,7 +826,7 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr)
 {
     gen_flush_cc_op(s);
     gen_jmp_im(s, where);
-    gen_helper_raise_exception(tcg_const_i32(nr));
+    gen_helper_raise_exception(cpu_env, tcg_const_i32(nr));
 }
 
 static inline void gen_addr_fault(DisasContext *s)
@@ -851,20 +834,21 @@ static inline void gen_addr_fault(DisasContext *s)
     gen_exception(s, s->insn_pc, EXCP_ADDRESS);
 }
 
-#define SRC_EA(result, opsize, op_sign, addrp) do { \
-    result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \
-    if (IS_NULL_QREG(result)) { \
-        gen_addr_fault(s); \
-        return; \
-    } \
+#define SRC_EA(env, result, opsize, op_sign, addrp) do {                \
+        result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp,         \
+                        op_sign ? EA_LOADS : EA_LOADU);                 \
+        if (IS_NULL_QREG(result)) {                                     \
+            gen_addr_fault(s);                                          \
+            return;                                                     \
+        }                                                               \
     } while (0)
 
-#define DEST_EA(insn, opsize, val, addrp) do { \
-    TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \
-    if (IS_NULL_QREG(ea_result)) { \
-        gen_addr_fault(s); \
-        return; \
-    } \
+#define DEST_EA(env, insn, opsize, val, addrp) do {                     \
+        TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \
+        if (IS_NULL_QREG(ea_result)) {                                  \
+            gen_addr_fault(s);                                          \
+            return;                                                     \
+        }                                                               \
     } while (0)
 
 /* Generate a jump to an immediate address.  */
@@ -873,13 +857,13 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
     TranslationBlock *tb;
 
     tb = s->tb;
-    if (__builtin_expect (s->singlestep_enabled, 0)) {
+    if (unlikely(s->singlestep_enabled)) {
         gen_exception(s, dest, EXCP_DEBUG);
     } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(QREG_PC, dest);
-        tcg_gen_exit_tb((long)tb + n);
+        tcg_gen_exit_tb((tcg_target_long)tb + n);
     } else {
         gen_jmp_im(s, dest);
         tcg_gen_exit_tb(0);
@@ -900,8 +884,7 @@ DISAS_INSN(undef_fpu)
 DISAS_INSN(undef)
 {
     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
-    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
-              insn, s->pc - 2);
+    cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2);
 }
 
 DISAS_INSN(mulw)
@@ -913,12 +896,12 @@ DISAS_INSN(mulw)
 
     sign = (insn & 0x100) != 0;
     reg = DREG(insn, 9);
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     if (sign)
         tcg_gen_ext16s_i32(tmp, reg);
     else
         tcg_gen_ext16u_i32(tmp, reg);
-    SRC_EA(src, OS_WORD, sign, NULL);
+    SRC_EA(env, src, OS_WORD, sign, NULL);
     tcg_gen_mul_i32(tmp, tmp, src);
     tcg_gen_mov_i32(reg, tmp);
     /* Unlike m68k, coldfire always clears the overflow bit.  */
@@ -939,7 +922,7 @@ DISAS_INSN(divw)
     } else {
         tcg_gen_ext16u_i32(QREG_DIV1, reg);
     }
-    SRC_EA(src, OS_WORD, sign, NULL);
+    SRC_EA(env, src, OS_WORD, sign, NULL);
     tcg_gen_mov_i32(QREG_DIV2, src);
     if (sign) {
         gen_helper_divs(cpu_env, tcg_const_i32(1));
@@ -947,8 +930,8 @@ DISAS_INSN(divw)
         gen_helper_divu(cpu_env, tcg_const_i32(1));
     }
 
-    tmp = gen_new_qreg(QMODE_I32);
-    src = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
+    src = tcg_temp_new();
     tcg_gen_ext16u_i32(tmp, QREG_DIV1);
     tcg_gen_shli_i32(src, QREG_DIV2, 16);
     tcg_gen_or_i32(reg, tmp, src);
@@ -962,7 +945,7 @@ DISAS_INSN(divl)
     TCGv reg;
     uint16_t ext;
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     if (ext & 0x87f8) {
         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
@@ -971,7 +954,7 @@ DISAS_INSN(divl)
     num = DREG(ext, 12);
     reg = DREG(ext, 0);
     tcg_gen_mov_i32(QREG_DIV1, num);
-    SRC_EA(den, OS_LONG, 0, NULL);
+    SRC_EA(env, den, OS_LONG, 0, NULL);
     tcg_gen_mov_i32(QREG_DIV2, den);
     if (ext & 0x0800) {
         gen_helper_divs(cpu_env, tcg_const_i32(0));
@@ -999,13 +982,13 @@ DISAS_INSN(addsub)
 
     add = (insn & 0x4000) != 0;
     reg = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     if (insn & 0x100) {
-        SRC_EA(tmp, OS_LONG, 0, &addr);
+        SRC_EA(env, tmp, OS_LONG, 0, &addr);
         src = reg;
     } else {
         tmp = reg;
-        SRC_EA(src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, OS_LONG, 0, NULL);
     }
     if (add) {
         tcg_gen_add_i32(dest, tmp, src);
@@ -1018,7 +1001,7 @@ DISAS_INSN(addsub)
     }
     gen_update_cc_add(dest, src);
     if (insn & 0x100) {
-        DEST_EA(insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, OS_LONG, dest, &addr);
     } else {
         tcg_gen_mov_i32(reg, dest);
     }
@@ -1048,18 +1031,18 @@ DISAS_INSN(bitop_reg)
     else
         opsize = OS_LONG;
     op = (insn >> 6) & 3;
-    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
+    SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
     src2 = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
 
     gen_flush_flags(s);
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     if (opsize == OS_BYTE)
         tcg_gen_andi_i32(tmp, src2, 7);
     else
         tcg_gen_andi_i32(tmp, src2, 31);
     src2 = tmp;
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     tcg_gen_shr_i32(tmp, src1, src2);
     tcg_gen_andi_i32(tmp, tmp, 1);
     tcg_gen_shli_i32(tmp, tmp, 2);
@@ -1083,7 +1066,7 @@ DISAS_INSN(bitop_reg)
         break;
     }
     if (op)
-        DEST_EA(insn, opsize, dest, &addr);
+        DEST_EA(env, insn, opsize, dest, &addr);
 }
 
 DISAS_INSN(sats)
@@ -1099,7 +1082,7 @@ static void gen_push(DisasContext *s, TCGv val)
 {
     TCGv tmp;
 
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     tcg_gen_subi_i32(tmp, QREG_SP, 4);
     gen_store(s, OS_LONG, tmp, val);
     tcg_gen_mov_i32(QREG_SP, tmp);
@@ -1114,14 +1097,14 @@ DISAS_INSN(movem)
     TCGv tmp;
     int is_load;
 
-    mask = lduw_code(s->pc);
+    mask = cpu_lduw_code(env, s->pc);
     s->pc += 2;
-    tmp = gen_lea(s, insn, OS_LONG);
+    tmp = gen_lea(env, s, insn, OS_LONG);
     if (IS_NULL_QREG(tmp)) {
         gen_addr_fault(s);
         return;
     }
-    addr = gen_new_qreg(QMODE_I32);
+    addr = tcg_temp_new();
     tcg_gen_mov_i32(addr, tmp);
     is_load = ((insn & 0x0400) != 0);
     for (i = 0; i < 16; i++, mask >>= 1) {
@@ -1158,14 +1141,14 @@ DISAS_INSN(bitop_im)
         opsize = OS_LONG;
     op = (insn >> 6) & 3;
 
-    bitnum = lduw_code(s->pc);
+    bitnum = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     if (bitnum & 0xff00) {
-        disas_undef(s, insn);
+        disas_undef(env, s, insn);
         return;
     }
 
-    SRC_EA(src1, opsize, 0, op ? &addr: NULL);
+    SRC_EA(env, src1, opsize, 0, op ? &addr: NULL);
 
     gen_flush_flags(s);
     if (opsize == OS_BYTE)
@@ -1174,7 +1157,7 @@ DISAS_INSN(bitop_im)
         bitnum &= 31;
     mask = 1 << bitnum;
 
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     assert (CCF_Z == (1 << 2));
     if (bitnum > 2)
         tcg_gen_shri_i32(tmp, src1, bitnum - 2);
@@ -1200,7 +1183,7 @@ DISAS_INSN(bitop_im)
         default: /* btst */
             break;
         }
-        DEST_EA(insn, opsize, tmp, &addr);
+        DEST_EA(env, insn, opsize, tmp, &addr);
     }
 }
 
@@ -1213,9 +1196,9 @@ DISAS_INSN(arith_im)
     TCGv addr;
 
     op = (insn >> 9) & 7;
-    SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
-    im = read_im32(s);
-    dest = gen_new_qreg(QMODE_I32);
+    SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr);
+    im = read_im32(env, s);
+    dest = tcg_temp_new();
     switch (op) {
     case 0: /* ori */
         tcg_gen_ori_i32(dest, src1, im);
@@ -1227,16 +1210,16 @@ DISAS_INSN(arith_im)
         break;
     case 2: /* subi */
         tcg_gen_mov_i32(dest, src1);
-        gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
+        gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
         tcg_gen_subi_i32(dest, dest, im);
-        gen_update_cc_add(dest, gen_im32(im));
+        gen_update_cc_add(dest, tcg_const_i32(im));
         s->cc_op = CC_OP_SUB;
         break;
     case 3: /* addi */
         tcg_gen_mov_i32(dest, src1);
         tcg_gen_addi_i32(dest, dest, im);
-        gen_update_cc_add(dest, gen_im32(im));
-        gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
+        gen_update_cc_add(dest, tcg_const_i32(im));
+        gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
         s->cc_op = CC_OP_ADD;
         break;
     case 5: /* eori */
@@ -1246,14 +1229,14 @@ DISAS_INSN(arith_im)
     case 6: /* cmpi */
         tcg_gen_mov_i32(dest, src1);
         tcg_gen_subi_i32(dest, dest, im);
-        gen_update_cc_add(dest, gen_im32(im));
+        gen_update_cc_add(dest, tcg_const_i32(im));
         s->cc_op = CC_OP_SUB;
         break;
     default:
         abort();
     }
     if (op != 6) {
-        DEST_EA(insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, OS_LONG, dest, &addr);
     }
 }
 
@@ -1262,7 +1245,7 @@ DISAS_INSN(byterev)
     TCGv reg;
 
     reg = DREG(insn, 0);
-    tcg_gen_bswap_i32(reg, reg);
+    tcg_gen_bswap32_i32(reg, reg);
 }
 
 DISAS_INSN(move)
@@ -1285,7 +1268,7 @@ DISAS_INSN(move)
     default:
         abort();
     }
-    SRC_EA(src, opsize, 1, NULL);
+    SRC_EA(env, src, opsize, 1, NULL);
     op = (insn >> 6) & 7;
     if (op == 1) {
         /* movea */
@@ -1296,7 +1279,7 @@ DISAS_INSN(move)
         /* normal move */
         uint16_t dest_ea;
         dest_ea = ((insn >> 9) & 7) | (op << 3);
-        DEST_EA(dest_ea, opsize, src, NULL);
+        DEST_EA(env, dest_ea, opsize, src, NULL);
         /* This will be correct because loads sign extend.  */
         gen_logic_cc(s, src);
     }
@@ -1317,7 +1300,7 @@ DISAS_INSN(lea)
     TCGv tmp;
 
     reg = AREG(insn, 9);
-    tmp = gen_lea(s, insn, OS_LONG);
+    tmp = gen_lea(env, s, insn, OS_LONG);
     if (IS_NULL_QREG(tmp)) {
         gen_addr_fault(s);
         return;
@@ -1342,8 +1325,8 @@ DISAS_INSN(clr)
     default:
         abort();
     }
-    DEST_EA(insn, opsize, gen_im32(0), NULL);
-    gen_logic_cc(s, gen_im32(0));
+    DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL);
+    gen_logic_cc(s, tcg_const_i32(0));
 }
 
 static TCGv gen_get_ccr(DisasContext *s)
@@ -1351,7 +1334,7 @@ static TCGv gen_get_ccr(DisasContext *s)
     TCGv dest;
 
     gen_flush_flags(s);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     tcg_gen_shli_i32(dest, QREG_CC_X, 4);
     tcg_gen_or_i32(dest, dest, QREG_CC_DEST);
     return dest;
@@ -1373,7 +1356,7 @@ DISAS_INSN(neg)
     TCGv src1;
 
     reg = DREG(insn, 0);
-    src1 = gen_new_qreg(QMODE_I32);
+    src1 = tcg_temp_new();
     tcg_gen_mov_i32(src1, reg);
     tcg_gen_neg_i32(reg, src1);
     s->cc_op = CC_OP_SUB;
@@ -1391,7 +1374,8 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only)
     }
 }
 
-static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
+static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn,
+                       int ccr_only)
 {
     TCGv tmp;
     TCGv reg;
@@ -1399,7 +1383,7 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
     s->cc_op = CC_OP_FLAGS;
     if ((insn & 0x38) == 0)
       {
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         reg = DREG(insn, 0);
         tcg_gen_andi_i32(QREG_CC_DEST, reg, 0xf);
         tcg_gen_shri_i32(tmp, reg, 4);
@@ -1411,17 +1395,17 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only)
     else if ((insn & 0x3f) == 0x3c)
       {
         uint16_t val;
-        val = lduw_code(s->pc);
+        val = cpu_lduw_code(env, s->pc);
         s->pc += 2;
         gen_set_sr_im(s, val, ccr_only);
       }
     else
-        disas_undef(s, insn);
+        disas_undef(env, s, insn);
 }
 
 DISAS_INSN(move_to_ccr)
 {
-    gen_set_sr(s, insn, 1);
+    gen_set_sr(env, s, insn, 1);
 }
 
 DISAS_INSN(not)
@@ -1439,8 +1423,8 @@ DISAS_INSN(swap)
     TCGv src2;
     TCGv reg;
 
-    src1 = gen_new_qreg(QMODE_I32);
-    src2 = gen_new_qreg(QMODE_I32);
+    src1 = tcg_temp_new();
+    src2 = tcg_temp_new();
     reg = DREG(insn, 0);
     tcg_gen_shli_i32(src1, reg, 16);
     tcg_gen_shri_i32(src2, reg, 16);
@@ -1452,7 +1436,7 @@ DISAS_INSN(pea)
 {
     TCGv tmp;
 
-    tmp = gen_lea(s, insn, OS_LONG);
+    tmp = gen_lea(env, s, insn, OS_LONG);
     if (IS_NULL_QREG(tmp)) {
         gen_addr_fault(s);
         return;
@@ -1468,7 +1452,7 @@ DISAS_INSN(ext)
 
     reg = DREG(insn, 0);
     op = (insn >> 6) & 7;
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     if (op == 3)
         tcg_gen_ext16s_i32(tmp, reg);
     else
@@ -1498,7 +1482,7 @@ DISAS_INSN(tst)
     default:
         abort();
     }
-    SRC_EA(tmp, opsize, 1, NULL);
+    SRC_EA(env, tmp, opsize, 1, NULL);
     gen_logic_cc(s, tmp);
 }
 
@@ -1519,11 +1503,11 @@ DISAS_INSN(tas)
     TCGv src1;
     TCGv addr;
 
-    dest = gen_new_qreg(QMODE_I32);
-    SRC_EA(src1, OS_BYTE, 1, &addr);
+    dest = tcg_temp_new();
+    SRC_EA(env, src1, OS_BYTE, 1, &addr);
     gen_logic_cc(s, src1);
     tcg_gen_ori_i32(dest, src1, 0x80);
-    DEST_EA(insn, OS_BYTE, dest, &addr);
+    DEST_EA(env, insn, OS_BYTE, dest, &addr);
 }
 
 DISAS_INSN(mull)
@@ -1535,15 +1519,15 @@ DISAS_INSN(mull)
 
     /* The upper 32 bits of the product are discarded, so
        muls.l and mulu.l are functionally equivalent.  */
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     if (ext & 0x87ff) {
         gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED);
         return;
     }
     reg = DREG(ext, 12);
-    SRC_EA(src1, OS_LONG, 0, NULL);
-    dest = gen_new_qreg(QMODE_I32);
+    SRC_EA(env, src1, OS_LONG, 0, NULL);
+    dest = tcg_temp_new();
     tcg_gen_mul_i32(dest, src1, reg);
     tcg_gen_mov_i32(reg, dest);
     /* Unlike m68k, coldfire always clears the overflow bit.  */
@@ -1556,10 +1540,10 @@ DISAS_INSN(link)
     TCGv reg;
     TCGv tmp;
 
-    offset = ldsw_code(s->pc);
+    offset = cpu_ldsw_code(env, s->pc);
     s->pc += 2;
     reg = AREG(insn, 0);
-    tmp = gen_new_qreg(QMODE_I32);
+    tmp = tcg_temp_new();
     tcg_gen_subi_i32(tmp, QREG_SP, 4);
     gen_store(s, OS_LONG, tmp, reg);
     if ((insn & 7) != 7)
@@ -1573,7 +1557,7 @@ DISAS_INSN(unlk)
     TCGv reg;
     TCGv tmp;
 
-    src = gen_new_qreg(QMODE_I32);
+    src = tcg_temp_new();
     reg = AREG(insn, 0);
     tcg_gen_mov_i32(src, reg);
     tmp = gen_load(s, OS_LONG, src, 0);
@@ -1600,14 +1584,14 @@ DISAS_INSN(jump)
 
     /* Load the target address first to ensure correct exception
        behavior.  */
-    tmp = gen_lea(s, insn, OS_LONG);
+    tmp = gen_lea(env, s, insn, OS_LONG);
     if (IS_NULL_QREG(tmp)) {
         gen_addr_fault(s);
         return;
     }
     if ((insn & 0x40) == 0) {
         /* jsr */
-        gen_push(s, gen_im32(s->pc));
+        gen_push(s, tcg_const_i32(s->pc));
     }
     gen_jmp(s, tmp);
 }
@@ -1620,11 +1604,11 @@ DISAS_INSN(addsubq)
     int val;
     TCGv addr;
 
-    SRC_EA(src1, OS_LONG, 0, &addr);
+    SRC_EA(env, src1, OS_LONG, 0, &addr);
     val = (insn >> 9) & 7;
     if (val == 0)
         val = 8;
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     tcg_gen_mov_i32(dest, src1);
     if ((insn & 0x38) == 0x08) {
         /* Don't update condition codes if the destination is an
@@ -1635,7 +1619,7 @@ DISAS_INSN(addsubq)
             tcg_gen_addi_i32(dest, dest, val);
         }
     } else {
-        src2 = gen_im32(val);
+        src2 = tcg_const_i32(val);
         if (insn & 0x0100) {
             gen_helper_xflag_lt(QREG_CC_X, dest, src2);
             tcg_gen_subi_i32(dest, dest, val);
@@ -1647,7 +1631,7 @@ DISAS_INSN(addsubq)
         }
         gen_update_cc_add(dest, src2);
     }
-    DEST_EA(insn, OS_LONG, dest, &addr);
+    DEST_EA(env, insn, OS_LONG, dest, &addr);
 }
 
 DISAS_INSN(tpf)
@@ -1662,7 +1646,7 @@ DISAS_INSN(tpf)
     case 4: /* No extension words.  */
         break;
     default:
-        disas_undef(s, insn);
+        disas_undef(env, s, insn);
     }
 }
 
@@ -1677,14 +1661,14 @@ DISAS_INSN(branch)
     op = (insn >> 8) & 0xf;
     offset = (int8_t)insn;
     if (offset == 0) {
-        offset = ldsw_code(s->pc);
+        offset = cpu_ldsw_code(env, s->pc);
         s->pc += 2;
     } else if (offset == -1) {
-        offset = read_im32(s);
+        offset = read_im32(env, s);
     }
     if (op == 1) {
         /* bsr */
-        gen_push(s, gen_im32(s->pc));
+        gen_push(s, tcg_const_i32(s->pc));
     }
     gen_flush_cc_op(s);
     if (op > 1) {
@@ -1719,7 +1703,7 @@ DISAS_INSN(mvzs)
         opsize = OS_WORD;
     else
         opsize = OS_BYTE;
-    SRC_EA(src, opsize, (insn & 0x80) != 0, NULL);
+    SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL);
     reg = DREG(insn, 9);
     tcg_gen_mov_i32(reg, src);
     gen_logic_cc(s, src);
@@ -1733,13 +1717,13 @@ DISAS_INSN(or)
     TCGv addr;
 
     reg = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     if (insn & 0x100) {
-        SRC_EA(src, OS_LONG, 0, &addr);
+        SRC_EA(env, src, OS_LONG, 0, &addr);
         tcg_gen_or_i32(dest, src, reg);
-        DEST_EA(insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, OS_LONG, dest, &addr);
     } else {
-        SRC_EA(src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, OS_LONG, 0, NULL);
         tcg_gen_or_i32(dest, src, reg);
         tcg_gen_mov_i32(reg, dest);
     }
@@ -1751,7 +1735,7 @@ DISAS_INSN(suba)
     TCGv src;
     TCGv reg;
 
-    SRC_EA(src, OS_LONG, 0, NULL);
+    SRC_EA(env, src, OS_LONG, 0, NULL);
     reg = AREG(insn, 9);
     tcg_gen_sub_i32(reg, reg, src);
 }
@@ -1775,9 +1759,9 @@ DISAS_INSN(mov3q)
     val = (insn >> 9) & 7;
     if (val == 0)
         val = -1;
-    src = gen_im32(val);
+    src = tcg_const_i32(val);
     gen_logic_cc(s, src);
-    DEST_EA(insn, OS_LONG, src, NULL);
+    DEST_EA(env, insn, OS_LONG, src, NULL);
 }
 
 DISAS_INSN(cmp)
@@ -1805,9 +1789,9 @@ DISAS_INSN(cmp)
     default:
         abort();
     }
-    SRC_EA(src, opsize, 1, NULL);
+    SRC_EA(env, src, opsize, 1, NULL);
     reg = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     tcg_gen_sub_i32(dest, reg, src);
     gen_update_cc_add(dest, src);
 }
@@ -1824,9 +1808,9 @@ DISAS_INSN(cmpa)
     } else {
         opsize = OS_WORD;
     }
-    SRC_EA(src, opsize, 1, NULL);
+    SRC_EA(env, src, opsize, 1, NULL);
     reg = AREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     tcg_gen_sub_i32(dest, reg, src);
     gen_update_cc_add(dest, src);
     s->cc_op = CC_OP_SUB;
@@ -1839,12 +1823,12 @@ DISAS_INSN(eor)
     TCGv dest;
     TCGv addr;
 
-    SRC_EA(src, OS_LONG, 0, &addr);
+    SRC_EA(env, src, OS_LONG, 0, &addr);
     reg = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     tcg_gen_xor_i32(dest, src, reg);
     gen_logic_cc(s, dest);
-    DEST_EA(insn, OS_LONG, dest, &addr);
+    DEST_EA(env, insn, OS_LONG, dest, &addr);
 }
 
 DISAS_INSN(and)
@@ -1855,13 +1839,13 @@ DISAS_INSN(and)
     TCGv addr;
 
     reg = DREG(insn, 9);
-    dest = gen_new_qreg(QMODE_I32);
+    dest = tcg_temp_new();
     if (insn & 0x100) {
-        SRC_EA(src, OS_LONG, 0, &addr);
+        SRC_EA(env, src, OS_LONG, 0, &addr);
         tcg_gen_and_i32(dest, src, reg);
-        DEST_EA(insn, OS_LONG, dest, &addr);
+        DEST_EA(env, insn, OS_LONG, dest, &addr);
     } else {
-        SRC_EA(src, OS_LONG, 0, NULL);
+        SRC_EA(env, src, OS_LONG, 0, NULL);
         tcg_gen_and_i32(dest, src, reg);
         tcg_gen_mov_i32(reg, dest);
     }
@@ -1873,7 +1857,7 @@ DISAS_INSN(adda)
     TCGv src;
     TCGv reg;
 
-    SRC_EA(src, OS_LONG, 0, NULL);
+    SRC_EA(env, src, OS_LONG, 0, NULL);
     reg = AREG(insn, 9);
     tcg_gen_add_i32(reg, reg, src);
 }
@@ -1901,7 +1885,7 @@ DISAS_INSN(shift_im)
     tmp = (insn >> 9) & 7;
     if (tmp == 0)
         tmp = 8;
-    shift = gen_im32(tmp);
+    shift = tcg_const_i32(tmp);
     /* No need to flush flags becuse we know we will set C flag.  */
     if (insn & 0x100) {
         gen_helper_shl_cc(reg, cpu_env, reg, shift);
@@ -1950,7 +1934,7 @@ static TCGv gen_get_sr(DisasContext *s)
     TCGv sr;
 
     ccr = gen_get_ccr(s);
-    sr = gen_new_qreg(QMODE_I32);
+    sr = tcg_temp_new();
     tcg_gen_andi_i32(sr, QREG_SR, 0xffe0);
     tcg_gen_or_i32(sr, sr, ccr);
     return sr;
@@ -1962,13 +1946,13 @@ DISAS_INSN(strldsr)
     uint32_t addr;
 
     addr = s->pc - 2;
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     if (ext != 0x46FC) {
         gen_exception(s, addr, EXCP_UNSUPPORTED);
         return;
     }
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     if (IS_USER(s) || (ext & SR_S) == 0) {
         gen_exception(s, addr, EXCP_PRIVILEGE);
@@ -1998,7 +1982,7 @@ DISAS_INSN(move_to_sr)
         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
         return;
     }
-    gen_set_sr(s, insn, 0);
+    gen_set_sr(env, s, insn, 0);
     gen_lookup_tb(s);
 }
 
@@ -2036,7 +2020,7 @@ DISAS_INSN(stop)
         return;
     }
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
     gen_set_sr_im(s, ext, 0);
@@ -2063,7 +2047,7 @@ DISAS_INSN(movec)
         return;
     }
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
     if (ext & 0x8000) {
@@ -2118,14 +2102,17 @@ DISAS_INSN(trap)
 DISAS_INSN(fpu)
 {
     uint16_t ext;
+    int32_t offset;
     int opmode;
-    TCGv src;
-    TCGv dest;
-    TCGv res;
+    TCGv_i64 src;
+    TCGv_i64 dest;
+    TCGv_i64 res;
+    TCGv tmp32;
     int round;
+    int set_dest;
     int opsize;
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
     opmode = ext & 0x7f;
     switch ((ext >> 13) & 7) {
@@ -2135,37 +2122,60 @@ DISAS_INSN(fpu)
         goto undef;
     case 3: /* fmove out */
         src = FREG(ext, 7);
+        tmp32 = tcg_temp_new_i32();
         /* fmove */
         /* ??? TODO: Proper behavior on overflow.  */
         switch ((ext >> 10) & 7) {
         case 0:
             opsize = OS_LONG;
-            res = gen_new_qreg(QMODE_I32);
-            gen_helper_f64_to_i32(res, cpu_env, src);
+            gen_helper_f64_to_i32(tmp32, cpu_env, src);
             break;
         case 1:
             opsize = OS_SINGLE;
-            res = gen_new_qreg(QMODE_F32);
-            gen_helper_f64_to_f32(res, cpu_env, src);
+            gen_helper_f64_to_f32(tmp32, cpu_env, src);
             break;
         case 4:
             opsize = OS_WORD;
-            res = gen_new_qreg(QMODE_I32);
-            gen_helper_f64_to_i32(res, cpu_env, src);
-            break;
-        case 5:
-            opsize = OS_DOUBLE;
-            res = src;
+            gen_helper_f64_to_i32(tmp32, cpu_env, src);
             break;
+        case 5: /* OS_DOUBLE */
+            tcg_gen_mov_i32(tmp32, AREG(insn, 0));
+            switch ((insn >> 3) & 7) {
+            case 2:
+            case 3:
+                break;
+            case 4:
+                tcg_gen_addi_i32(tmp32, tmp32, -8);
+                break;
+            case 5:
+                offset = cpu_ldsw_code(env, s->pc);
+                s->pc += 2;
+                tcg_gen_addi_i32(tmp32, tmp32, offset);
+                break;
+            default:
+                goto undef;
+            }
+            gen_store64(s, tmp32, src);
+            switch ((insn >> 3) & 7) {
+            case 3:
+                tcg_gen_addi_i32(tmp32, tmp32, 8);
+                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
+                break;
+            case 4:
+                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
+                break;
+            }
+            tcg_temp_free_i32(tmp32);
+            return;
         case 6:
             opsize = OS_BYTE;
-            res = gen_new_qreg(QMODE_I32);
-            gen_helper_f64_to_i32(res, cpu_env, src);
+            gen_helper_f64_to_i32(tmp32, cpu_env, src);
             break;
         default:
             goto undef;
         }
-        DEST_EA(insn, opsize, res, NULL);
+        DEST_EA(env, insn, opsize, tmp32, NULL);
+        tcg_temp_free_i32(tmp32);
         return;
     case 4: /* fmove to control register.  */
         switch ((ext >> 10) & 7) {
@@ -2183,7 +2193,7 @@ DISAS_INSN(fpu)
         switch ((ext >> 10) & 7) {
         case 4: /* FPCR */
             /* Not implemented.  Always return zero.  */
-            res = gen_im32(0);
+            tmp32 = tcg_const_i32(0);
             break;
         case 1: /* FPIAR */
         case 2: /* FPSR */
@@ -2192,7 +2202,7 @@ DISAS_INSN(fpu)
                       (ext >> 10) & 7);
             goto undef;
         }
-        DEST_EA(insn, OS_LONG, res, NULL);
+        DEST_EA(env, insn, OS_LONG, tmp32, NULL);
         break;
     case 6: /* fmovem */
     case 7:
@@ -2202,13 +2212,13 @@ DISAS_INSN(fpu)
             int i;
             if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0)
                 goto undef;
-            src = gen_lea(s, insn, OS_LONG);
-            if (IS_NULL_QREG(src)) {
+            tmp32 = gen_lea(env, s, insn, OS_LONG);
+            if (IS_NULL_QREG(tmp32)) {
                 gen_addr_fault(s);
                 return;
             }
-            addr = gen_new_qreg(QMODE_I32);
-            tcg_gen_mov_i32(addr, src);
+            addr = tcg_temp_new_i32();
+            tcg_gen_mov_i32(addr, tmp32);
             mask = 0x80;
             for (i = 0; i < 8; i++) {
                 if (ext & mask) {
@@ -2226,12 +2236,11 @@ DISAS_INSN(fpu)
                 }
                 mask >>= 1;
             }
+            tcg_temp_free_i32(addr);
         }
         return;
     }
     if (ext & (1 << 14)) {
-        TCGv tmp;
-
         /* Source effective address.  */
         switch ((ext >> 10) & 7) {
         case 0: opsize = OS_LONG; break;
@@ -2242,19 +2251,52 @@ DISAS_INSN(fpu)
         default:
             goto undef;
         }
-        SRC_EA(tmp, opsize, 1, NULL);
         if (opsize == OS_DOUBLE) {
-            src = tmp;
+            tmp32 = tcg_temp_new_i32();
+            tcg_gen_mov_i32(tmp32, AREG(insn, 0));
+            switch ((insn >> 3) & 7) {
+            case 2:
+            case 3:
+                break;
+            case 4:
+                tcg_gen_addi_i32(tmp32, tmp32, -8);
+                break;
+            case 5:
+                offset = cpu_ldsw_code(env, s->pc);
+                s->pc += 2;
+                tcg_gen_addi_i32(tmp32, tmp32, offset);
+                break;
+            case 7:
+                offset = cpu_ldsw_code(env, s->pc);
+                offset += s->pc - 2;
+                s->pc += 2;
+                tcg_gen_addi_i32(tmp32, tmp32, offset);
+                break;
+            default:
+                goto undef;
+            }
+            src = gen_load64(s, tmp32);
+            switch ((insn >> 3) & 7) {
+            case 3:
+                tcg_gen_addi_i32(tmp32, tmp32, 8);
+                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
+                break;
+            case 4:
+                tcg_gen_mov_i32(AREG(insn, 0), tmp32);
+                break;
+            }
+            tcg_temp_free_i32(tmp32);
         } else {
-            src = gen_new_qreg(QMODE_F64);
+            SRC_EA(env, tmp32, opsize, 1, NULL);
+            src = tcg_temp_new_i64();
             switch (opsize) {
             case OS_LONG:
             case OS_WORD:
             case OS_BYTE:
-                gen_helper_i32_to_f64(src, cpu_env, tmp);
+                gen_helper_i32_to_f64(src, cpu_env, tmp32);
                 break;
             case OS_SINGLE:
-                gen_helper_f32_to_f64(src, cpu_env, tmp);
+                gen_helper_f32_to_f64(src, cpu_env, tmp32);
                 break;
             }
         }
@@ -2263,10 +2305,11 @@ DISAS_INSN(fpu)
         src = FREG(ext, 10);
     }
     dest = FREG(ext, 7);
-    res = gen_new_qreg(QMODE_F64);
+    res = tcg_temp_new_i64();
     if (opmode != 0x3a)
         tcg_gen_mov_f64(res, dest);
     round = 1;
+    set_dest = 1;
     switch (opmode) {
     case 0: case 0x40: case 0x44: /* fmove */
         tcg_gen_mov_f64(res, src);
@@ -2302,17 +2345,20 @@ DISAS_INSN(fpu)
         break;
     case 0x38: /* fcmp */
         gen_helper_sub_cmp_f64(res, cpu_env, res, src);
-        dest = NULL_QREG;
+        set_dest = 0;
         round = 0;
         break;
     case 0x3a: /* ftst */
         tcg_gen_mov_f64(res, src);
-        dest = NULL_QREG;
+        set_dest = 0;
         round = 0;
         break;
     default:
         goto undef;
     }
+    if (ext & (1 << 14)) {
+        tcg_temp_free_i64(src);
+    }
     if (round) {
         if (opmode & 0x40) {
             if ((opmode & 0x4) != 0)
@@ -2322,20 +2368,21 @@ DISAS_INSN(fpu)
         }
     }
     if (round) {
-        TCGv tmp;
-
-        tmp = gen_new_qreg(QMODE_F32);
+        TCGv tmp = tcg_temp_new_i32();
         gen_helper_f64_to_f32(tmp, cpu_env, res);
         gen_helper_f32_to_f64(res, cpu_env, tmp);
+        tcg_temp_free_i32(tmp);
     }
     tcg_gen_mov_f64(QREG_FP_RESULT, res);
-    if (!IS_NULL_QREG(dest)) {
+    if (set_dest) {
         tcg_gen_mov_f64(dest, res);
     }
+    tcg_temp_free_i64(res);
     return;
 undef:
+    /* FIXME: Is this right for offset addressing modes?  */
     s->pc -= 2;
-    disas_undef_fpu(s, insn);
+    disas_undef_fpu(env, s, insn);
 }
 
 DISAS_INSN(fbcc)
@@ -2346,16 +2393,16 @@ DISAS_INSN(fbcc)
     int l1;
 
     addr = s->pc;
-    offset = ldsw_code(s->pc);
+    offset = cpu_ldsw_code(env, s->pc);
     s->pc += 2;
     if (insn & (1 << 6)) {
-        offset = (offset << 16) | lduw_code(s->pc);
+        offset = (offset << 16) | cpu_lduw_code(env, s->pc);
         s->pc += 2;
     }
 
     l1 = gen_new_label();
     /* TODO: Raise BSUN exception.  */
-    flag = gen_new_qreg(QMODE_I32);
+    flag = tcg_temp_new();
     gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT);
     /* Jump to l1 if condition is true.  */
     switch (insn & 0xf) {
@@ -2428,7 +2475,7 @@ DISAS_INSN(fsave)
 
 static inline TCGv gen_mac_extract_word(DisasContext *s, TCGv val, int upper)
 {
-    TCGv tmp = gen_new_qreg(QMODE_I32);
+    TCGv tmp = tcg_temp_new();
     if (s->env->macsr & MACSR_FI) {
         if (upper)
             tcg_gen_andi_i32(tmp, val, 0xffff0000);
@@ -2466,22 +2513,24 @@ DISAS_INSN(mac)
     int dual;
     TCGv saved_flags;
 
-    if (IS_NULL_QREG(s->mactmp))
-        s->mactmp = tcg_temp_new(TCG_TYPE_I64);
+    if (!s->done_mac) {
+        s->mactmp = tcg_temp_new_i64();
+        s->done_mac = 1;
+    }
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
     acc = ((insn >> 7) & 1) | ((ext >> 3) & 2);
     dual = ((insn & 0x30) != 0 && (ext & 3) != 0);
     if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) {
-        disas_undef(s, insn);
+        disas_undef(env, s, insn);
         return;
     }
     if (insn & 0x30) {
         /* MAC with load.  */
-        tmp = gen_lea(s, insn, OS_LONG);
-        addr = gen_new_qreg(QMODE_I32);
+        tmp = gen_lea(env, s, insn, OS_LONG);
+        addr = tcg_temp_new();
         tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
         /* Load the value now to ensure correct exception behavior.
            Perform writeback after reading the MAC inputs.  */
@@ -2503,7 +2552,7 @@ DISAS_INSN(mac)
     if ((s->env->macsr & MACSR_OMC) != 0 && !dual) {
         /* Skip the multiply if we know we will ignore it.  */
         l1 = gen_new_label();
-        tmp = gen_new_qreg(QMODE_I32);
+        tmp = tcg_temp_new();
         tcg_gen_andi_i32(tmp, QREG_MACSR, 1 << (acc + 8));
         gen_op_jmp_nz32(tmp, l1);
     }
@@ -2533,7 +2582,7 @@ DISAS_INSN(mac)
 
     if (dual) {
         /* Save the overflow flag from the multiply.  */
-        saved_flags = gen_new_qreg(QMODE_I32);
+        saved_flags = tcg_temp_new();
         tcg_gen_mov_i32(saved_flags, QREG_MACSR);
     } else {
         saved_flags = NULL_QREG;
@@ -2544,8 +2593,8 @@ DISAS_INSN(mac)
     if ((s->env->macsr & MACSR_OMC) != 0 && dual) {
         /* Skip the accumulate if the value is already saturated.  */
         l1 = gen_new_label();
-        tmp = gen_new_qreg(QMODE_I32);
-        gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+        tmp = tcg_temp_new();
+        gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
         gen_op_jmp_nz32(tmp, l1);
     }
 #endif
@@ -2578,8 +2627,8 @@ DISAS_INSN(mac)
         if ((s->env->macsr & MACSR_OMC) != 0) {
             /* Skip the accumulate if the value is already saturated.  */
             l1 = gen_new_label();
-            tmp = gen_new_qreg(QMODE_I32);
-            gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+            tmp = tcg_temp_new();
+            gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
             gen_op_jmp_nz32(tmp, l1);
         }
 #endif
@@ -2620,14 +2669,14 @@ DISAS_INSN(mac)
 DISAS_INSN(from_mac)
 {
     TCGv rx;
-    TCGv acc;
+    TCGv_i64 acc;
     int accnum;
 
     rx = (insn & 8) ? AREG(insn, 0) : DREG(insn, 0);
     accnum = (insn >> 9) & 3;
     acc = MACREG(accnum);
     if (s->env->macsr & MACSR_FI) {
-        gen_helper_get_macf(cpu_env, rx, acc);
+        gen_helper_get_macf(rx, cpu_env, acc);
     } else if ((s->env->macsr & MACSR_OMC) == 0) {
         tcg_gen_trunc_i64_i32(rx, acc);
     } else if (s->env->macsr & MACSR_SU) {
@@ -2689,12 +2738,12 @@ DISAS_INSN(macsr_to_ccr)
 
 DISAS_INSN(to_mac)
 {
-    TCGv acc;
+    TCGv_i64 acc;
     TCGv val;
     int accnum;
     accnum = (insn >> 9) & 3;
     acc = MACREG(accnum);
-    SRC_EA(val, OS_LONG, 0, NULL);
+    SRC_EA(env, val, OS_LONG, 0, NULL);
     if (s->env->macsr & MACSR_FI) {
         tcg_gen_ext_i32_i64(acc, val);
         tcg_gen_shli_i64(acc, acc, 8);
@@ -2711,7 +2760,7 @@ DISAS_INSN(to_mac)
 DISAS_INSN(to_macsr)
 {
     TCGv val;
-    SRC_EA(val, OS_LONG, 0, NULL);
+    SRC_EA(env, val, OS_LONG, 0, NULL);
     gen_helper_set_macsr(cpu_env, val);
     gen_lookup_tb(s);
 }
@@ -2719,7 +2768,7 @@ DISAS_INSN(to_macsr)
 DISAS_INSN(to_mask)
 {
     TCGv val;
-    SRC_EA(val, OS_LONG, 0, NULL);
+    SRC_EA(env, val, OS_LONG, 0, NULL);
     tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000);
 }
 
@@ -2727,7 +2776,7 @@ DISAS_INSN(to_mext)
 {
     TCGv val;
     TCGv acc;
-    SRC_EA(val, OS_LONG, 0, NULL);
+    SRC_EA(env, val, OS_LONG, 0, NULL);
     acc = tcg_const_i32((insn & 0x400) ? 2 : 0);
     if (s->env->macsr & MACSR_FI)
         gen_helper_set_mac_extf(cpu_env, val, acc);
@@ -2900,27 +2949,31 @@ void register_m68k_insns (CPUM68KState *env)
 
 /* ??? Some of this implementation is not exception safe.  We should always
    write back the result to memory before setting the condition codes.  */
-static void disas_m68k_insn(CPUState * env, DisasContext *s)
+static void disas_m68k_insn(CPUM68KState * env, DisasContext *s)
 {
     uint16_t insn;
 
-    insn = lduw_code(s->pc);
+    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
+        tcg_gen_debug_insn_start(s->pc);
+    }
+
+    insn = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
-    opcode_table[insn](s, insn);
+    opcode_table[insn](env, s, insn);
 }
 
 /* generate intermediate code for basic block 'tb'.  */
-static inline int
-gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
+static inline void
+gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
                                int search_pc)
 {
     DisasContext dc1, *dc = &dc1;
     uint16_t *gen_opc_end;
+    CPUBreakpoint *bp;
     int j, lj;
     target_ulong pc_start;
     int pc_offset;
-    int last_cc_op;
     int num_insns;
     int max_insns;
 
@@ -2929,7 +2982,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
     dc->tb = tb;
 
-    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 
     dc->env = env;
     dc->is_jmp = DISAS_NEXT;
@@ -2939,7 +2992,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->is_mem = 0;
-    dc->mactmp = NULL_QREG;
+    dc->done_mac = 0;
     lj = -1;
     num_insns = 0;
     max_insns = tb->cflags & CF_COUNT_MASK;
@@ -2950,9 +3003,9 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
     do {
         pc_offset = dc->pc - pc_start;
         gen_throws_exception = NULL;
-        if (env->nb_breakpoints > 0) {
-            for(j = 0; j < env->nb_breakpoints; j++) {
-                if (env->breakpoints[j] == dc->pc) {
+        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+                if (bp->pc == dc->pc) {
                     gen_exception(dc, dc->pc, EXCP_DEBUG);
                     dc->is_jmp = DISAS_JUMP;
                     break;
@@ -2962,42 +3015,36 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                 break;
         }
         if (search_pc) {
-            j = gen_opc_ptr - gen_opc_buf;
+            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
             if (lj < j) {
                 lj++;
                 while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
+                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
             }
-            gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+            tcg_ctx.gen_opc_pc[lj] = dc->pc;
+            tcg_ctx.gen_opc_instr_start[lj] = 1;
+            tcg_ctx.gen_opc_icount[lj] = num_insns;
         }
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
-        last_cc_op = dc->cc_op;
         dc->insn_pc = dc->pc;
        disas_m68k_insn(env, dc);
         num_insns++;
-
-        /* Terminate the TB on memory ops if watchpoints are present.  */
-        /* FIXME: This should be replacd by the deterministic execution
-         * IRQ raising bits.  */
-        if (dc->is_mem && env->nb_watchpoints)
-            break;
-    } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
+    } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
              !env->singlestep_enabled &&
+             !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (__builtin_expect(env->singlestep_enabled, 0)) {
+    if (unlikely(env->singlestep_enabled)) {
         /* Make sure the pc is updated, and raise a debug exception.  */
         if (!dc->is_jmp) {
             gen_flush_cc_op(dc);
             tcg_gen_movi_i32(QREG_PC, dc->pc);
         }
-        gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG));
+        gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG));
     } else {
         switch(dc->is_jmp) {
         case DISAS_NEXT:
@@ -3017,21 +3064,21 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
         }
     }
     gen_icount_end(tb, num_insns);
-    *gen_opc_ptr = INDEX_op_end;
+    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
 
 #ifdef DEBUG_DISAS
-    if (loglevel & CPU_LOG_TB_IN_ASM) {
-        fprintf(logfile, "----------------\n");
-        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
-        target_disas(logfile, pc_start, dc->pc - pc_start, 0);
-        fprintf(logfile, "\n");
+    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+        qemu_log("----------------\n");
+        qemu_log("IN: %s\n", lookup_symbol(pc_start));
+        log_target_disas(env, pc_start, dc->pc - pc_start, 0);
+        qemu_log("\n");
     }
 #endif
     if (search_pc) {
-        j = gen_opc_ptr - gen_opc_buf;
+        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
         lj++;
         while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
+            tcg_ctx.gen_opc_instr_start[lj++] = 0;
     } else {
         tb->size = dc->pc - pc_start;
         tb->icount = num_insns;
@@ -3039,21 +3086,19 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
     //optimize_flags();
     //expand_target_qops();
-    return 0;
 }
 
-int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
 {
-    return gen_intermediate_code_internal(env, tb, 0);
+    gen_intermediate_code_internal(env, tb, 0);
 }
 
-int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
 {
-    return gen_intermediate_code_internal(env, tb, 1);
+    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(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
@@ -3074,8 +3119,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
     cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
 }
 
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
-                unsigned long searched_pc, int pc_pos, void *puc)
+void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, int pc_pos)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = tcg_ctx.gen_opc_pc[pc_pos];
 }