]> Git Repo - qemu.git/blobdiff - target-m68k/translate.c
log: do not unnecessarily include qom/cpu.h
[qemu.git] / target-m68k / translate.c
index e3e56d036429122c56dbda96a834bfd55f3804c2..a402bd847ac90b61bb87fd93a1fd37721aafc05f 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 "qemu/osdep.h"
 #include "cpu.h"
-#include "exec-all.h"
-#include "disas.h"
+#include "disas/disas.h"
 #include "tcg-op.h"
+#include "qemu/log.h"
+#include "exec/cpu_ldst.h"
+
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
+
+#include "trace-tcg.h"
+#include "exec/log.h"
 
-#define GEN_HELPER 1
-#include "helpers.h"
 
 //#define DEBUG_DISPATCH 1
 
 /* 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 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_i32 cpu_halted;
+static TCGv_i32 cpu_exception_index;
+
+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]
@@ -70,63 +65,59 @@ 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;
 
-#include "gen-icount.h"
+#include "exec/gen-icount.h"
 
 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_halted = tcg_global_mem_new_i32(TCG_AREG0,
+                                        -offsetof(M68kCPU, env) +
+                                        offsetof(CPUState, halted), "HALTED");
+    cpu_exception_index = tcg_global_mem_new_i32(TCG_AREG0,
+                                                 -offsetof(M68kCPU, env) +
+                                                 offsetof(CPUState, exception_index),
+                                                 "EXCEPTION");
+
+    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_F64, 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_I64, 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");
-
-#define DEF_HELPER(name, ret, args) \
-    tcg_register_helper(HELPER(name), #name);
-#include "helpers.h"
-}
-
-static inline void qemu_assert(int cond, const char *msg)
-{
-    if (!cond) {
-        fprintf (stderr, "badness: %s\n", msg);
-        abort();
-    }
+    NULL_QREG = tcg_global_mem_new(TCG_AREG0, -4, "NULL");
+    store_dummy = tcg_global_mem_new(TCG_AREG0, -8, "NULL");
 }
 
 /* internal defines */
@@ -140,8 +131,8 @@ typedef struct DisasContext {
     uint32_t fpcr;
     struct TranslationBlock *tb;
     int singlestep_enabled;
-    int is_mem;
-    TCGv mactmp;
+    TCGv_i64 mactmp;
+    int done_mac;
 } DisasContext;
 
 #define DISAS_JUMP_NEXT 4
@@ -157,87 +148,77 @@ 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)
-
-#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)
 {
     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");
+        g_assert_not_reached();
     }
     gen_throws_exception = gen_last_qop;
     return tmp;
 }
 
+static inline TCGv_i64 gen_load64(DisasContext * s, TCGv addr)
+{
+    TCGv_i64 tmp;
+    int index = IS_USER(s);
+    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)
 {
     int index = IS_USER(s);
-    s->is_mem = 1;
     switch(opsize) {
     case OS_BYTE:
         tcg_gen_qemu_st8(val, addr, index);
@@ -246,20 +227,22 @@ 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");
+        g_assert_not_reached();
     }
     gen_throws_exception = gen_last_qop;
 }
 
+static inline void gen_store64(DisasContext *s, TCGv addr, TCGv_i64 val)
+{
+    int index = IS_USER(s);
+    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,7 @@ 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, TCGv base)
 {
     uint32_t offset;
     uint16_t ext;
@@ -320,7 +303,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 +317,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 +335,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 +351,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 +366,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 +381,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);
@@ -450,7 +433,7 @@ static inline int opsize_bytes(int opsize)
     case OS_SINGLE: return 4;
     case OS_DOUBLE: return 8;
     default:
-        qemu_assert(0, "bad operand size");
+        g_assert_not_reached();
     }
 }
 
@@ -462,25 +445,22 @@ 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");
-        break;
+        g_assert_not_reached();
     }
 }
 
@@ -491,35 +471,33 @@ 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");
+        g_assert_not_reached();
     }
     return tmp;
 }
 
 /* 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 +513,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, 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, NULL_QREG);
         case 4: /* Immediate.  */
         default:
             return NULL_QREG;
@@ -576,15 +553,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)
@@ -593,11 +571,11 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize,
     return gen_ldst(s, opsize, tmp, val, what);
 }
 
-/* Generate code to load/store a value ito/from an EA.  If VAL > 0 this is
+/* Generate code to load/store a value from/into 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 +615,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,36 +632,38 @@ 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");
+                g_assert_not_reached();
             }
             return tcg_const_i32(offset);
         default:
@@ -695,7 +675,7 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val,
 }
 
 /* This generates a conditional branch, clobbering all temporaries.  */
-static void gen_jmpcc(DisasContext *s, int cond, int l1)
+static void gen_jmpcc(DisasContext *s, int cond, TCGLabel *l1)
 {
     TCGv tmp;
 
@@ -709,57 +689,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 +747,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 +755,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 +764,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);
@@ -800,7 +780,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
 
 DISAS_INSN(scc)
 {
-    int l1;
+    TCGLabel *l1;
     int cond;
     TCGv reg;
 
@@ -843,7 +823,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 +831,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.  */
@@ -879,7 +860,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
                (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((uintptr_t)tb + n);
     } else {
         gen_jmp_im(s, dest);
         tcg_gen_exit_tb(0);
@@ -899,9 +880,10 @@ DISAS_INSN(undef_fpu)
 
 DISAS_INSN(undef)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
+
     gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED);
-    cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x",
-              insn, s->pc - 2);
+    cpu_abort(CPU(cpu), "Illegal instruction: %04x @ %08x", insn, s->pc - 2);
 }
 
 DISAS_INSN(mulw)
@@ -913,12 +895,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 +921,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 +929,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 +944,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 +953,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 +981,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 +1000,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 +1030,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 +1065,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 +1081,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 +1096,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 +1140,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 +1156,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 +1182,7 @@ DISAS_INSN(bitop_im)
         default: /* btst */
             break;
         }
-        DEST_EA(insn, opsize, tmp, &addr);
+        DEST_EA(env, insn, opsize, tmp, &addr);
     }
 }
 
@@ -1213,9 +1195,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 +1209,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 +1228,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 +1244,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 +1267,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 +1278,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 +1299,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 +1324,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 +1333,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 +1355,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 +1373,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 +1382,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 +1394,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 +1422,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 +1435,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 +1451,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 +1481,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 +1502,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 +1518,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 +1539,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 +1556,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 +1583,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 +1603,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 +1618,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 +1630,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 +1645,7 @@ DISAS_INSN(tpf)
     case 4: /* No extension words.  */
         break;
     default:
-        disas_undef(s, insn);
+        disas_undef(env, s, insn);
     }
 }
 
@@ -1671,20 +1654,20 @@ DISAS_INSN(branch)
     int32_t offset;
     uint32_t base;
     int op;
-    int l1;
+    TCGLabel *l1;
 
     base = s->pc;
     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 +1702,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 +1716,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 +1734,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 +1758,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 +1788,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 +1807,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 +1822,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 +1838,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 +1856,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 +1884,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 +1933,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 +1945,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 +1981,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);
 }
 
@@ -2008,8 +1991,8 @@ DISAS_INSN(move_from_usp)
         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
         return;
     }
-    /* TODO: Implement USP.  */
-    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
+    tcg_gen_ld_i32(AREG(insn, 0), cpu_env,
+                   offsetof(CPUM68KState, sp[M68K_USP]));
 }
 
 DISAS_INSN(move_to_usp)
@@ -2018,8 +2001,8 @@ DISAS_INSN(move_to_usp)
         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
         return;
     }
-    /* TODO: Implement USP.  */
-    gen_exception(s, s->pc - 2, EXCP_ILLEGAL);
+    tcg_gen_st_i32(AREG(insn, 0), cpu_env,
+                   offsetof(CPUM68KState, sp[M68K_USP]));
 }
 
 DISAS_INSN(halt)
@@ -2036,11 +2019,11 @@ 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);
-    tcg_gen_movi_i32(QREG_HALTED, 1);
+    tcg_gen_movi_i32(cpu_halted, 1);
     gen_exception(s, s->pc, EXCP_HLT);
 }
 
@@ -2063,7 +2046,7 @@ DISAS_INSN(movec)
         return;
     }
 
-    ext = lduw_code(s->pc);
+    ext = cpu_lduw_code(env, s->pc);
     s->pc += 2;
 
     if (ext & 0x8000) {
@@ -2100,12 +2083,14 @@ DISAS_INSN(wddata)
 
 DISAS_INSN(wdebug)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
+
     if (IS_USER(s)) {
         gen_exception(s, s->pc - 2, EXCP_PRIVILEGE);
         return;
     }
     /* TODO: Implement wdebug.  */
-    qemu_assert(0, "WDEBUG not implemented");
+    cpu_abort(CPU(cpu), "WDEBUG not implemented");
 }
 
 DISAS_INSN(trap)
@@ -2118,14 +2103,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 +2123,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 +2194,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 +2203,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,17 +2213,16 @@ 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) {
-                    s->is_mem = 1;
                     dest = FREG(i, 0);
                     if (ext & (1 << 13)) {
                         /* store */
@@ -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)
@@ -2343,19 +2390,19 @@ DISAS_INSN(fbcc)
     uint32_t offset;
     uint32_t addr;
     TCGv flag;
-    int l1;
+    TCGLabel *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) {
@@ -2416,19 +2463,23 @@ DISAS_INSN(fbcc)
 
 DISAS_INSN(frestore)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
+
     /* TODO: Implement frestore.  */
-    qemu_assert(0, "FRESTORE not implemented");
+    cpu_abort(CPU(cpu), "FRESTORE not implemented");
 }
 
 DISAS_INSN(fsave)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
+
     /* TODO: Implement fsave.  */
-    qemu_assert(0, "FSAVE not implemented");
+    cpu_abort(CPU(cpu), "FSAVE not implemented");
 }
 
 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 +2517,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 +2556,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 +2586,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 +2597,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 +2631,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,16 +2673,16 @@ 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);
+        tcg_gen_extrl_i64_i32(rx, acc);
     } else if (s->env->macsr & MACSR_SU) {
         gen_helper_get_macs(rx, acc);
     } else {
@@ -2689,12 +2742,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 +2764,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 +2772,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 +2780,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 +2953,24 @@ 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);
+    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,
-                               int search_pc)
+void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
 {
+    M68kCPU *cpu = m68k_env_get_cpu(env);
+    CPUState *cs = CPU(cpu);
     DisasContext dc1, *dc = &dc1;
-    uint16_t *gen_opc_end;
-    int j, lj;
     target_ulong pc_start;
     int pc_offset;
-    int last_cc_op;
     int num_insns;
     int max_insns;
 
@@ -2929,75 +2979,62 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
     dc->tb = tb;
 
-    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-
     dc->env = env;
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
     dc->cc_op = CC_OP_DYNAMIC;
-    dc->singlestep_enabled = env->singlestep_enabled;
+    dc->singlestep_enabled = cs->singlestep_enabled;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
-    dc->is_mem = 0;
-    dc->mactmp = NULL_QREG;
-    lj = -1;
+    dc->done_mac = 0;
     num_insns = 0;
     max_insns = tb->cflags & CF_COUNT_MASK;
-    if (max_insns == 0)
+    if (max_insns == 0) {
         max_insns = CF_COUNT_MASK;
+    }
+    if (max_insns > TCG_MAX_INSNS) {
+        max_insns = TCG_MAX_INSNS;
+    }
 
-    gen_icount_start();
+    gen_tb_start(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) {
-                    gen_exception(dc, dc->pc, EXCP_DEBUG);
-                    dc->is_jmp = DISAS_JUMP;
-                    break;
-                }
-            }
-            if (dc->is_jmp)
-                break;
-        }
-        if (search_pc) {
-            j = gen_opc_ptr - gen_opc_buf;
-            if (lj < j) {
-                lj++;
-                while (lj < j)
-                    gen_opc_instr_start[lj++] = 0;
-            }
-            gen_opc_pc[lj] = dc->pc;
-            gen_opc_instr_start[lj] = 1;
-            gen_opc_icount[lj] = num_insns;
+        tcg_gen_insn_start(dc->pc);
+        num_insns++;
+
+        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
+            gen_exception(dc, dc->pc, EXCP_DEBUG);
+            dc->is_jmp = DISAS_JUMP;
+            /* The address covered by the breakpoint must be included in
+               [tb->pc, tb->pc + tb->size) in order to for it to be
+               properly cleared -- thus we increment the PC here so that
+               the logic setting tb->size below does the right thing.  */
+            dc->pc += 2;
+            break;
         }
-        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+
+        if (num_insns == 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 replaced 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 &&
-             !env->singlestep_enabled &&
+    } while (!dc->is_jmp && !tcg_op_buf_full() &&
+             !cs->singlestep_enabled &&
+             !singlestep &&
              (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
              num_insns < max_insns);
 
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
-    if (unlikely(env->singlestep_enabled)) {
+    if (unlikely(cs->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:
@@ -3016,46 +3053,25 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
             break;
         }
     }
-    gen_icount_end(tb, num_insns);
-    *gen_opc_ptr = INDEX_op_end;
+    gen_tb_end(tb, num_insns);
 
 #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(cs, pc_start, dc->pc - pc_start, 0);
+        qemu_log("\n");
     }
 #endif
-    if (search_pc) {
-        j = gen_opc_ptr - gen_opc_buf;
-        lj++;
-        while (lj <= j)
-            gen_opc_instr_start[lj++] = 0;
-    } else {
-        tb->size = dc->pc - pc_start;
-        tb->icount = num_insns;
-    }
-
-    //optimize_flags();
-    //expand_target_qops();
-    return 0;
-}
-
-int gen_intermediate_code(CPUState *env, TranslationBlock *tb)
-{
-    return gen_intermediate_code_internal(env, tb, 0);
-}
-
-int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
-{
-    return gen_intermediate_code_internal(env, tb, 1);
+    tb->size = dc->pc - pc_start;
+    tb->icount = num_insns;
 }
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-                    int flags)
+void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+                         int flags)
 {
+    M68kCPU *cpu = M68K_CPU(cs);
+    CPUM68KState *env = &cpu->env;
     int i;
     uint16_t sr;
     CPU_DoubleU u;
@@ -3074,8 +3090,8 @@ 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,
+                          target_ulong *data)
 {
-    env->pc = gen_opc_pc[pc_pos];
+    env->pc = data[0];
 }
This page took 0.108072 seconds and 4 git commands to generate.