use the TCG code generator
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 1 Feb 2008 10:50:11 +0000 (10:50 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Fri, 1 Feb 2008 10:50:11 +0000 (10:50 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3944 c046a42c-6fe2-441c-8c8c-71466251a162

35 files changed:
LICENSE
Makefile.target
configure
cpu-all.h
cpu-defs.h
cpu-exec.c
dyngen-op.h [deleted file]
dyngen.c
dyngen.h [deleted file]
exec-all.h
exec.c
target-alpha/op.c
target-alpha/translate.c
target-arm/op.c
target-arm/translate.c
target-cris/op.c
target-cris/translate.c
target-i386/exec.h
target-i386/helper.c
target-i386/helper.h [new file with mode: 0644]
target-i386/op.c
target-i386/opreg_template.h
target-i386/translate.c
target-m68k/op.c
target-m68k/translate.c
target-mips/op.c
target-mips/translate.c
target-ppc/op.c
target-ppc/translate.c
target-sh4/op.c
target-sh4/translate.c
target-sparc/op.c
target-sparc/translate.c
translate-all.c
translate-op.c [deleted file]

diff --git a/LICENSE b/LICENSE
index 8bf5f94..2fa7dda 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -10,6 +10,9 @@ In particular, the QEMU virtual CPU core library (libqemu.a) is
 released under the GNU Lesser General Public License. Many hardware
 device emulation sources are released under the BSD license.
 
 released under the GNU Lesser General Public License. Many hardware
 device emulation sources are released under the BSD license.
 
-3) QEMU is a trademark of Fabrice Bellard.
+3) The Tiny Code Generator (TCG) is released under the BSD license
+   (see license headers in files).
+
+4) QEMU is a trademark of Fabrice Bellard.
 
 Fabrice Bellard.
\ No newline at end of file
 
 Fabrice Bellard.
\ No newline at end of file
index 8a94ad8..fca2192 100644 (file)
@@ -172,8 +172,11 @@ all: $(PROGS)
 
 #########################################################
 # cpu emulator library
 
 #########################################################
 # cpu emulator library
-LIBOBJS=exec.o kqemu.o translate-op.o translate-all.o cpu-exec.o\
+LIBOBJS=exec.o kqemu.o translate-all.o cpu-exec.o\
         translate.o op.o host-utils.o
         translate.o op.o host-utils.o
+# TCG code generator
+LIBOBJS+= tcg/tcg.o tcg/tcg-dyngen.o tcg/tcg-runtime.o
+CPPFLAGS+=-I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/$(ARCH)
 ifdef CONFIG_SOFTFLOAT
 LIBOBJS+=fpu/softfloat.o
 else
 ifdef CONFIG_SOFTFLOAT
 LIBOBJS+=fpu/softfloat.o
 else
@@ -268,16 +271,16 @@ libqemu.a: $(LIBOBJS)
        rm -f $@
        $(AR) rcs $@ $(LIBOBJS)
 
        rm -f $@
        $(AR) rcs $@ $(LIBOBJS)
 
-translate.o: translate.c gen-op.h opc.h cpu.h
+translate.o: translate.c gen-op.h dyngen-opc.h cpu.h
 
 
-translate-all.o: translate-all.c opc.h cpu.h
+translate-all.o: translate-all.c dyngen-opc.h cpu.h
 
 
-translate-op.o: translate-all.c op.h opc.h cpu.h
+tcg/tcg.o: op.h dyngen-opc.h cpu.h
 
 op.h: op.o $(DYNGEN)
        $(DYNGEN) -o $@ $<
 
 
 op.h: op.o $(DYNGEN)
        $(DYNGEN) -o $@ $<
 
-opc.h: op.o $(DYNGEN)
+dyngen-opc.h: op.o $(DYNGEN)
        $(DYNGEN) -c -o $@ $<
 
 gen-op.h: op.o $(DYNGEN)
        $(DYNGEN) -c -o $@ $<
 
 gen-op.h: op.o $(DYNGEN)
@@ -648,8 +651,8 @@ endif # !CONFIG_USER_ONLY
        $(CC) $(CPPFLAGS) -c -o $@ $<
 
 clean:
        $(CC) $(CPPFLAGS) -c -o $@ $<
 
 clean:
-       rm -f *.o *.a *~ $(PROGS) gen-op.h opc.h op.h nwfpe/*.o fpu/*.o
-       rm -f *.d */*.d
+       rm -f *.o *.a *~ $(PROGS) gen-op.h dyngen-opc.h op.h nwfpe/*.o fpu/*.o
+       rm -f *.d */*.d tcg/*.o
 
 install: all
 ifneq ($(PROGS),)
 
 install: all
 ifneq ($(PROGS),)
index b8b3681..bcb958d 100755 (executable)
--- a/configure
+++ b/configure
@@ -1051,6 +1051,7 @@ test -f $config_h && mv $config_h ${config_h}~
 
 mkdir -p $target_dir
 mkdir -p $target_dir/fpu
 
 mkdir -p $target_dir
 mkdir -p $target_dir/fpu
+mkdir -p $target_dir/tcg
 if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" ; then
   mkdir -p $target_dir/nwfpe
 fi
 if test "$target" = "arm-linux-user" -o "$target" = "armeb-linux-user" ; then
   mkdir -p $target_dir/nwfpe
 fi
index 968323d..4215977 100644 (file)
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -1048,6 +1048,18 @@ extern int64_t kqemu_ret_int_count;
 extern int64_t kqemu_ret_excp_count;
 extern int64_t kqemu_ret_intr_count;
 
 extern int64_t kqemu_ret_excp_count;
 extern int64_t kqemu_ret_intr_count;
 
+extern int64_t dyngen_tb_count1;
+extern int64_t dyngen_tb_count;
+extern int64_t dyngen_op_count;
+extern int64_t dyngen_old_op_count;
+extern int64_t dyngen_tcg_del_op_count;
+extern int dyngen_op_count_max;
+extern int64_t dyngen_code_in_len;
+extern int64_t dyngen_code_out_len;
+extern int64_t dyngen_interm_time;
+extern int64_t dyngen_code_time;
+extern int64_t dyngen_restore_count;
+extern int64_t dyngen_restore_time;
 #endif
 
 #endif /* CPU_ALL_H */
 #endif
 
 #endif /* CPU_ALL_H */
index b581d94..6979c11 100644 (file)
@@ -145,6 +145,7 @@ typedef struct CPUTLBEntry {
     /* The meaning of the MMU modes is defined in the target code. */   \
     CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
     /* The meaning of the MMU modes is defined in the target code. */   \
     CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \
     struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
+    long temp_buf[128]; /* buffer for temporaries in the code generator */ \
                                                                         \
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
                                                                         \
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
index af5c58f..003d6e2 100644 (file)
@@ -354,7 +354,7 @@ int cpu_exec(CPUState *env1)
 #endif
 #endif
     int ret, interrupt_request;
 #endif
 #endif
     int ret, interrupt_request;
-    void (*gen_func)(void);
+    long (*gen_func)(void);
     TranslationBlock *tb;
     uint8_t *tc_ptr;
 
     TranslationBlock *tb;
     uint8_t *tc_ptr;
 
@@ -736,7 +736,7 @@ int cpu_exec(CPUState *env1)
                fp.gp = code_gen_buffer + 2 * (1 << 20);
                (*(void (*)(void)) &fp)();
 #else
                fp.gp = code_gen_buffer + 2 * (1 << 20);
                (*(void (*)(void)) &fp)();
 #else
-                gen_func();
+                T0 = gen_func();
 #endif
                 env->current_tb = NULL;
                 /* reset soft MMU for next block (it can currently
 #endif
                 env->current_tb = NULL;
                 /* reset soft MMU for next block (it can currently
diff --git a/dyngen-op.h b/dyngen-op.h
deleted file mode 100644 (file)
index f77a475..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-static inline int gen_new_label(void)
-{
-    return nb_gen_labels++;
-}
-
-static inline void gen_set_label(int n)
-{
-    gen_labels[n] = gen_opc_ptr - gen_opc_buf;
-}
index d301c71..08380f0 100644 (file)
--- a/dyngen.c
+++ b/dyngen.c
@@ -1212,14 +1212,16 @@ int load_object(const char *filename)
 
 #endif /* CONFIG_FORMAT_MACH */
 
 
 #endif /* CONFIG_FORMAT_MACH */
 
-void get_reloc_expr(char *name, int name_size, const char *sym_name)
+/* return true if the expression is a label reference */
+int get_reloc_expr(char *name, int name_size, const char *sym_name)
 {
     const char *p;
 
     if (strstart(sym_name, "__op_param", &p)) {
         snprintf(name, name_size, "param%s", p);
     } else if (strstart(sym_name, "__op_gen_label", &p)) {
 {
     const char *p;
 
     if (strstart(sym_name, "__op_param", &p)) {
         snprintf(name, name_size, "param%s", p);
     } else if (strstart(sym_name, "__op_gen_label", &p)) {
-        snprintf(name, name_size, "gen_labels[param%s]", p);
+        snprintf(name, name_size, "param%s", p);
+        return 1;
     } else {
 #ifdef HOST_SPARC
         if (sym_name[0] == '.')
     } else {
 #ifdef HOST_SPARC
         if (sym_name[0] == '.')
@@ -1230,6 +1232,7 @@ void get_reloc_expr(char *name, int name_size, const char *sym_name)
 #endif
             snprintf(name, name_size, "(long)(&%s)", sym_name);
     }
 #endif
             snprintf(name, name_size, "(long)(&%s)", sym_name);
     }
+    return 0;
 }
 
 #ifdef HOST_IA64
 }
 
 #ifdef HOST_IA64
@@ -1846,7 +1849,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
 #if defined(HOST_I386)
             {
                 char relname[256];
 #if defined(HOST_I386)
             {
                 char relname[256];
-                int type;
+                int type, is_label;
                 int addend;
                 int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                 int addend;
                 int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
@@ -1868,21 +1871,33 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                         continue;
                     }
 
                         continue;
                     }
 
-                    get_reloc_expr(relname, sizeof(relname), sym_name);
+                    is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
                     addend = get32((uint32_t *)(text + rel->r_offset));
 #ifdef CONFIG_FORMAT_ELF
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = get32((uint32_t *)(text + rel->r_offset));
 #ifdef CONFIG_FORMAT_ELF
                     type = ELF32_R_TYPE(rel->r_info);
-                    switch(type) {
-                    case R_386_32:
-                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
-                                reloc_offset, relname, addend);
-                        break;
-                    case R_386_PC32:
-                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
-                                reloc_offset, relname, reloc_offset, addend);
-                        break;
-                    default:
-                        error("unsupported i386 relocation (%d)", type);
+                    if (is_label) {
+                        switch(type) {
+                        case R_386_32:
+                        case R_386_PC32:
+                            fprintf(outfile, "    tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
+                                    reloc_offset, type, relname, addend);
+                            break;
+                        default:
+                            error("unsupported i386 relocation (%d)", type);
+                        }
+                    } else {
+                        switch(type) {
+                        case R_386_32:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+                                    reloc_offset, relname, addend);
+                            break;
+                        case R_386_PC32:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
+                                    reloc_offset, relname, reloc_offset, addend);
+                            break;
+                        default:
+                            error("unsupported i386 relocation (%d)", type);
+                        }
                     }
 #elif defined(CONFIG_FORMAT_COFF)
                     {
                     }
 #elif defined(CONFIG_FORMAT_COFF)
                     {
@@ -1920,32 +1935,45 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
 #elif defined(HOST_X86_64)
             {
                 char relname[256];
 #elif defined(HOST_X86_64)
             {
                 char relname[256];
-                int type;
+                int type, is_label;
                 int addend;
                 int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                 if (rel->r_offset >= start_offset &&
                    rel->r_offset < start_offset + copy_size) {
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
                 int addend;
                 int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                 if (rel->r_offset >= start_offset &&
                    rel->r_offset < start_offset + copy_size) {
                     sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
-                    get_reloc_expr(relname, sizeof(relname), sym_name);
+                    is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = rel->r_addend;
                     reloc_offset = rel->r_offset - start_offset;
                     type = ELF32_R_TYPE(rel->r_info);
                     addend = rel->r_addend;
                     reloc_offset = rel->r_offset - start_offset;
-                    switch(type) {
-                    case R_X86_64_32:
-                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
-                                reloc_offset, relname, addend);
-                        break;
-                    case R_X86_64_32S:
-                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
-                                reloc_offset, relname, addend);
-                        break;
-                    case R_X86_64_PC32:
-                        fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
-                                reloc_offset, relname, reloc_offset, addend);
-                        break;
-                    default:
-                        error("unsupported X86_64 relocation (%d)", type);
+                    if (is_label) {
+                        switch(type) {
+                        case R_X86_64_32:
+                        case R_X86_64_32S:
+                        case R_X86_64_PC32:
+                            fprintf(outfile, "    tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
+                                    reloc_offset, type, relname, addend);
+                            break;
+                        default:
+                            error("unsupported X86_64 relocation (%d)", type);
+                        }
+                    } else {
+                        switch(type) {
+                        case R_X86_64_32:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
+                                    reloc_offset, relname, addend);
+                            break;
+                        case R_X86_64_32S:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
+                                    reloc_offset, relname, addend);
+                            break;
+                        case R_X86_64_PC32:
+                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
+                                    reloc_offset, relname, reloc_offset, addend);
+                            break;
+                        default:
+                            error("unsupported X86_64 relocation (%d)", type);
+                        }
                     }
                 }
                 }
                     }
                 }
                 }
@@ -2639,11 +2667,6 @@ int gen_file(FILE *outfile, int out_type)
     EXE_SYM *sym;
 
     if (out_type == OUT_INDEX_OP) {
     EXE_SYM *sym;
 
     if (out_type == OUT_INDEX_OP) {
-        fprintf(outfile, "DEF(end, 0, 0)\n");
-        fprintf(outfile, "DEF(nop, 0, 0)\n");
-        fprintf(outfile, "DEF(nop1, 1, 0)\n");
-        fprintf(outfile, "DEF(nop2, 2, 0)\n");
-        fprintf(outfile, "DEF(nop3, 3, 0)\n");
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
@@ -2653,7 +2676,6 @@ int gen_file(FILE *outfile, int out_type)
         }
     } else if (out_type == OUT_GEN_OP) {
         /* generate gen_xxx functions */
         }
     } else if (out_type == OUT_GEN_OP) {
         /* generate gen_xxx functions */
-        fprintf(outfile, "#include \"dyngen-op.h\"\n");
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
@@ -2670,6 +2692,7 @@ int gen_file(FILE *outfile, int out_type)
         /* generate big code generation switch */
 
 #ifdef HOST_ARM
         /* generate big code generation switch */
 
 #ifdef HOST_ARM
+#error broken
         /* We need to know the size of all the ops so we can figure out when
            to emit constant pools.  This must be consistent with opc.h.  */
 fprintf(outfile,
         /* We need to know the size of all the ops so we can figure out when
            to emit constant pools.  This must be consistent with opc.h.  */
 fprintf(outfile,
@@ -2690,16 +2713,8 @@ fprintf(outfile,
 "};\n");
 #endif
 
 "};\n");
 #endif
 
-fprintf(outfile,
-"int dyngen_code(uint8_t *gen_code_buf,\n"
-"                uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
-"                const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels)\n"
-"{\n"
-"    uint8_t *gen_code_ptr;\n"
-"    const uint16_t *opc_ptr;\n"
-"    const uint32_t *opparam_ptr;\n");
-
 #ifdef HOST_ARM
 #ifdef HOST_ARM
+#error broken
 /* Arm is tricky because it uses constant pools for loading immediate values.
    We assume (and require) each function is code followed by a constant pool.
    All the ops are small so this should be ok.  For each op we figure
 /* Arm is tricky because it uses constant pools for loading immediate values.
    We assume (and require) each function is code followed by a constant pool.
    All the ops are small so this should be ok.  For each op we figure
@@ -2732,6 +2747,7 @@ fprintf(outfile,
 "    uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n");
 #endif
 #ifdef HOST_IA64
 "    uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n");
 #endif
 #ifdef HOST_IA64
+#error broken
     {
        long addend, not_first = 0;
        unsigned long sym_idx;
     {
        long addend, not_first = 0;
        unsigned long sym_idx;
@@ -2789,18 +2805,8 @@ fprintf(outfile,
     }
 #endif
 
     }
 #endif
 
-fprintf(outfile,
-"\n"
-"    gen_code_ptr = gen_code_buf;\n"
-"    opc_ptr = opc_buf;\n"
-"    opparam_ptr = opparam_buf;\n");
-
-       /* Generate prologue, if needed. */
-
-fprintf(outfile,
-"    for(;;) {\n");
-
 #ifdef HOST_ARM
 #ifdef HOST_ARM
+#error broken
 /* Generate constant pool if needed */
 fprintf(outfile,
 "            if (gen_code_ptr + arm_opc_size[*opc_ptr] >= arm_pool_ptr) {\n"
 /* Generate constant pool if needed */
 fprintf(outfile,
 "            if (gen_code_ptr + arm_opc_size[*opc_ptr] >= arm_pool_ptr) {\n"
@@ -2813,9 +2819,6 @@ fprintf(outfile,
 "            }\n");
 #endif
 
 "            }\n");
 #endif
 
-fprintf(outfile,
-"        switch(*opc_ptr++) {\n");
-
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name;
             name = get_sym_name(sym);
@@ -2831,51 +2834,6 @@ fprintf(outfile,
                 gen_code(name, sym->st_value, sym->st_size, outfile, 1);
             }
         }
                 gen_code(name, sym->st_value, sym->st_size, outfile, 1);
             }
         }
-
-fprintf(outfile,
-"        case INDEX_op_nop:\n"
-"            break;\n"
-"        case INDEX_op_nop1:\n"
-"            opparam_ptr++;\n"
-"            break;\n"
-"        case INDEX_op_nop2:\n"
-"            opparam_ptr += 2;\n"
-"            break;\n"
-"        case INDEX_op_nop3:\n"
-"            opparam_ptr += 3;\n"
-"            break;\n"
-"        default:\n"
-"            goto the_end;\n"
-"        }\n");
-
-
-fprintf(outfile,
-"    }\n"
-" the_end:\n"
-);
-#ifdef HOST_IA64
-    fprintf(outfile,
-           "    {\n"
-           "      extern char code_gen_buffer[];\n"
-           "      ia64_apply_fixes(&gen_code_ptr, ltoff_fixes, "
-           "(uint64_t) code_gen_buffer + 2*(1<<20), plt_fixes,\n\t\t\t"
-           "sizeof(plt_target)/sizeof(plt_target[0]),\n\t\t\t"
-           "plt_target, plt_offset);\n    }\n");
-#endif
-
-/* generate some code patching */
-#ifdef HOST_ARM
-fprintf(outfile,
-"if (arm_data_ptr != arm_data_table + ARM_LDR_TABLE_SIZE)\n"
-"    gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, "
-"arm_ldr_ptr, arm_data_ptr, arm_data_table + ARM_LDR_TABLE_SIZE, 0);\n");
-#endif
-    /* flush instruction cache */
-    fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");
-
-    fprintf(outfile, "return gen_code_ptr -  gen_code_buf;\n");
-    fprintf(outfile, "}\n\n");
-
     }
 
     return 0;
     }
 
     return 0;
diff --git a/dyngen.h b/dyngen.h
deleted file mode 100644 (file)
index 4451d54..0000000
--- a/dyngen.h
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * dyngen helpers
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-int __op_param1, __op_param2, __op_param3;
-#if defined(__sparc__) || defined(__arm__)
-  void __op_gen_label1(){}
-  void __op_gen_label2(){}
-  void __op_gen_label3(){}
-#else
-  int __op_gen_label1, __op_gen_label2, __op_gen_label3;
-#endif
-int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__s390__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-}
-#elif defined(__ia64__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    while (start < stop) {
-       asm volatile ("fc %0" :: "r"(start));
-       start += 32;
-    }
-    asm volatile (";;sync.i;;srlz.i;;");
-}
-#elif defined(__powerpc__)
-
-#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
-
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    unsigned long p;
-
-    start &= ~(MIN_CACHE_LINE_SIZE - 1);
-    stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
-
-    for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
-        asm volatile ("dcbst 0,%0" : : "r"(p) : "memory");
-    }
-    asm volatile ("sync" : : : "memory");
-    for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
-        asm volatile ("icbi 0,%0" : : "r"(p) : "memory");
-    }
-    asm volatile ("sync" : : : "memory");
-    asm volatile ("isync" : : : "memory");
-}
-#elif defined(__alpha__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    asm ("imb");
-}
-#elif defined(__sparc__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-       unsigned long p;
-
-       p = start & ~(8UL - 1UL);
-       stop = (stop + (8UL - 1UL)) & ~(8UL - 1UL);
-
-       for (; p < stop; p += 8)
-               __asm__ __volatile__("flush\t%0" : : "r" (p));
-}
-#elif defined(__arm__)
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    register unsigned long _beg __asm ("a1") = start;
-    register unsigned long _end __asm ("a2") = stop;
-    register unsigned long _flg __asm ("a3") = 0;
-    __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
-}
-#elif defined(__mc68000)
-
-# include <asm/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    cacheflush(start,FLUSH_SCOPE_LINE,FLUSH_CACHE_BOTH,stop-start+16);
-}
-#elif defined(__mips__)
-
-#include <sys/cachectl.h>
-static inline void flush_icache_range(unsigned long start, unsigned long stop)
-{
-    _flush_cache ((void *)start, stop - start, BCACHE);
-}
-#else
-#error unsupported CPU
-#endif
-
-#ifdef __alpha__
-
-register int gp asm("$29");
-
-static inline void immediate_ldah(void *p, int val) {
-    uint32_t *dest = p;
-    long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;
-
-    *dest &= ~0xffff;
-    *dest |= high;
-    *dest |= 31 << 16;
-}
-static inline void immediate_lda(void *dest, int val) {
-    *(uint16_t *) dest = val;
-}
-void fix_bsr(void *p, int offset) {
-    uint32_t *dest = p;
-    *dest &= ~((1 << 21) - 1);
-    *dest |= (offset >> 2) & ((1 << 21) - 1);
-}
-
-#endif /* __alpha__ */
-
-#ifdef __arm__
-
-#define ARM_LDR_TABLE_SIZE 1024
-
-typedef struct LDREntry {
-    uint8_t *ptr;
-    uint32_t *data_ptr;
-    unsigned type:2;
-} LDREntry;
-
-static LDREntry arm_ldr_table[1024];
-static uint32_t arm_data_table[ARM_LDR_TABLE_SIZE];
-
-extern char exec_loop;
-
-static inline void arm_reloc_pc24(uint32_t *ptr, uint32_t insn, int val)
-{
-    *ptr = (insn & ~0xffffff) | ((insn + ((val - (int)ptr) >> 2)) & 0xffffff);
-}
-
-static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr,
-                              LDREntry *ldr_start, LDREntry *ldr_end,
-                              uint32_t *data_start, uint32_t *data_end,
-                              int gen_jmp)
-{
-    LDREntry *le;
-    uint32_t *ptr;
-    int offset, data_size, target;
-    uint8_t *data_ptr;
-    uint32_t insn;
-    uint32_t mask;
-
-    data_size = (data_end - data_start) << 2;
-
-    if (gen_jmp) {
-        /* generate branch to skip the data */
-        if (data_size == 0)
-            return gen_code_ptr;
-        target = (long)gen_code_ptr + data_size + 4;
-        arm_reloc_pc24((uint32_t *)gen_code_ptr, 0xeafffffe, target);
-        gen_code_ptr += 4;
-    }
-
-    /* copy the data */
-    data_ptr = gen_code_ptr;
-    memcpy(gen_code_ptr, data_start, data_size);
-    gen_code_ptr += data_size;
-
-    /* patch the ldr to point to the data */
-    for(le = ldr_start; le < ldr_end; le++) {
-        ptr = (uint32_t *)le->ptr;
-        offset = ((unsigned long)(le->data_ptr) - (unsigned long)data_start) +
-            (unsigned long)data_ptr -
-            (unsigned long)ptr - 8;
-        if (offset < 0) {
-            fprintf(stderr, "Negative constant pool offset\n");
-            abort();
-        }
-        switch (le->type) {
-          case 0: /* ldr */
-            mask = ~0x00800fff;
-            if (offset >= 4096) {
-                fprintf(stderr, "Bad ldr offset\n");
-                abort();
-            }
-            break;
-          case 1: /* ldc */
-            mask = ~0x008000ff;
-            if (offset >= 1024 ) {
-                fprintf(stderr, "Bad ldc offset\n");
-                abort();
-            }
-            break;
-          case 2: /* add */
-            mask = ~0xfff;
-            if (offset >= 1024 ) {
-                fprintf(stderr, "Bad add offset\n");
-                abort();
-            }
-            break;
-          default:
-            fprintf(stderr, "Bad pc relative fixup\n");
-            abort();
-          }
-        insn = *ptr & mask;
-        switch (le->type) {
-          case 0: /* ldr */
-            insn |= offset | 0x00800000;
-            break;
-          case 1: /* ldc */
-            insn |= (offset >> 2) | 0x00800000;
-            break;
-          case 2: /* add */
-            insn |= (offset >> 2) | 0xf00;
-            break;
-          }
-        *ptr = insn;
-    }
-    return gen_code_ptr;
-}
-
-#endif /* __arm__ */
-
-#ifdef __ia64
-
-/* Patch instruction with "val" where "mask" has 1 bits. */
-static inline void ia64_patch (uint64_t insn_addr, uint64_t mask, uint64_t val)
-{
-    uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) (insn_addr & -16);
-#   define insn_mask ((1UL << 41) - 1)
-    unsigned long shift;
-
-    b0 = b[0]; b1 = b[1];
-    shift = 5 + 41 * (insn_addr % 16); /* 5 template, 3 x 41-bit insns */
-    if (shift >= 64) {
-       m1 = mask << (shift - 64);
-       v1 = val << (shift - 64);
-    } else {
-       m0 = mask << shift; m1 = mask >> (64 - shift);
-       v0 = val  << shift; v1 = val >> (64 - shift);
-       b[0] = (b0 & ~m0) | (v0 & m0);
-    }
-    b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
-static inline void ia64_patch_imm60 (uint64_t insn_addr, uint64_t val)
-{
-       ia64_patch(insn_addr,
-                  0x011ffffe000UL,
-                  (  ((val & 0x0800000000000000UL) >> 23) /* bit 59 -> 36 */
-                   | ((val & 0x00000000000fffffUL) << 13) /* bit 0 -> 13 */));
-       ia64_patch(insn_addr - 1, 0x1fffffffffcUL, val >> 18);
-}
-
-static inline void ia64_imm64 (void *insn, uint64_t val)
-{
-    /* Ignore the slot number of the relocation; GCC and Intel
-       toolchains differed for some time on whether IMM64 relocs are
-       against slot 1 (Intel) or slot 2 (GCC).  */
-    uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
-    ia64_patch(insn_addr + 2,
-              0x01fffefe000UL,
-              (  ((val & 0x8000000000000000UL) >> 27) /* bit 63 -> 36 */
-               | ((val & 0x0000000000200000UL) <<  0) /* bit 21 -> 21 */
-               | ((val & 0x00000000001f0000UL) <<  6) /* bit 16 -> 22 */
-               | ((val & 0x000000000000ff80UL) << 20) /* bit  7 -> 27 */
-               | ((val & 0x000000000000007fUL) << 13) /* bit  0 -> 13 */)
-           );
-    ia64_patch(insn_addr + 1, 0x1ffffffffffUL, val >> 22);
-}
-
-static inline void ia64_imm60b (void *insn, uint64_t val)
-{
-    /* Ignore the slot number of the relocation; GCC and Intel
-       toolchains differed for some time on whether IMM64 relocs are
-       against slot 1 (Intel) or slot 2 (GCC).  */
-    uint64_t insn_addr = (uint64_t) insn & ~3UL;
-
-    if (val + ((uint64_t) 1 << 59) >= (1UL << 60))
-       fprintf(stderr, "%s: value %ld out of IMM60 range\n",
-               __FUNCTION__, (int64_t) val);
-    ia64_patch_imm60(insn_addr + 2, val);
-}
-
-static inline void ia64_imm22 (void *insn, uint64_t val)
-{
-    if (val + (1 << 21) >= (1 << 22))
-       fprintf(stderr, "%s: value %li out of IMM22 range\n",
-               __FUNCTION__, (int64_t)val);
-    ia64_patch((uint64_t) insn, 0x01fffcfe000UL,
-              (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
-               | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
-               | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
-               | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
-}
-
-/* Like ia64_imm22(), but also clear bits 20-21.  For addl, this has
-   the effect of turning "addl rX=imm22,rY" into "addl
-   rX=imm22,r0".  */
-static inline void ia64_imm22_r0 (void *insn, uint64_t val)
-{
-    if (val + (1 << 21) >= (1 << 22))
-       fprintf(stderr, "%s: value %li out of IMM22 range\n",
-               __FUNCTION__, (int64_t)val);
-    ia64_patch((uint64_t) insn, 0x01fffcfe000UL | (0x3UL << 20),
-              (  ((val & 0x200000UL) << 15) /* bit 21 -> 36 */
-               | ((val & 0x1f0000UL) <<  6) /* bit 16 -> 22 */
-               | ((val & 0x00ff80UL) << 20) /* bit  7 -> 27 */
-               | ((val & 0x00007fUL) << 13) /* bit  0 -> 13 */));
-}
-
-static inline void ia64_imm21b (void *insn, uint64_t val)
-{
-    if (val + (1 << 20) >= (1 << 21))
-       fprintf(stderr, "%s: value %li out of IMM21b range\n",
-               __FUNCTION__, (int64_t)val);
-    ia64_patch((uint64_t) insn, 0x11ffffe000UL,
-              (  ((val & 0x100000UL) << 16) /* bit 20 -> 36 */
-               | ((val & 0x0fffffUL) << 13) /* bit  0 -> 13 */));
-}
-
-static inline void ia64_nop_b (void *insn)
-{
-    ia64_patch((uint64_t) insn, (1UL << 41) - 1, 2UL << 37);
-}
-
-static inline void ia64_ldxmov(void *insn, uint64_t val)
-{
-    if (val + (1 << 21) < (1 << 22))
-       ia64_patch((uint64_t) insn, 0x1fff80fe000UL, 8UL << 37);
-}
-
-static inline int ia64_patch_ltoff(void *insn, uint64_t val,
-                                  int relaxable)
-{
-    if (relaxable && (val + (1 << 21) < (1 << 22))) {
-       ia64_imm22_r0(insn, val);
-       return 0;
-    }
-    return 1;
-}
-
-struct ia64_fixup {
-    struct ia64_fixup *next;
-    void *addr;                        /* address that needs to be patched */
-    long value;
-};
-
-#define IA64_PLT(insn, plt_index)                      \
-do {                                                   \
-    struct ia64_fixup *fixup = alloca(sizeof(*fixup)); \
-    fixup->next = plt_fixes;                           \
-    plt_fixes = fixup;                                 \
-    fixup->addr = (insn);                              \
-    fixup->value = (plt_index);                                \
-    plt_offset[(plt_index)] = 1;                       \
-} while (0)
-
-#define IA64_LTOFF(insn, val, relaxable)                       \
-do {                                                           \
-    if (ia64_patch_ltoff(insn, val, relaxable)) {              \
-       struct ia64_fixup *fixup = alloca(sizeof(*fixup));      \
-       fixup->next = ltoff_fixes;                              \
-       ltoff_fixes = fixup;                                    \
-       fixup->addr = (insn);                                   \
-       fixup->value = (val);                                   \
-    }                                                          \
-} while (0)
-
-static inline void ia64_apply_fixes (uint8_t **gen_code_pp,
-                                    struct ia64_fixup *ltoff_fixes,
-                                    uint64_t gp,
-                                    struct ia64_fixup *plt_fixes,
-                                    int num_plts,
-                                    unsigned long *plt_target,
-                                    unsigned int *plt_offset)
-{
-    static const uint8_t plt_bundle[] = {
-       0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; movl r1=GP */
-       0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x60,
-
-       0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, /* nop 0; brl IP */
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0
-    };
-    uint8_t *gen_code_ptr = *gen_code_pp, *plt_start, *got_start;
-    uint64_t *vp;
-    struct ia64_fixup *fixup;
-    unsigned int offset = 0;
-    struct fdesc {
-       long ip;
-       long gp;
-    } *fdesc;
-    int i;
-
-    if (plt_fixes) {
-       plt_start = gen_code_ptr;
-
-       for (i = 0; i < num_plts; ++i) {
-           if (plt_offset[i]) {
-               plt_offset[i] = offset;
-               offset += sizeof(plt_bundle);
-
-               fdesc = (struct fdesc *) plt_target[i];
-               memcpy(gen_code_ptr, plt_bundle, sizeof(plt_bundle));
-               ia64_imm64 (gen_code_ptr + 0x02, fdesc->gp);
-               ia64_imm60b(gen_code_ptr + 0x12,
-                           (fdesc->ip - (long) (gen_code_ptr + 0x10)) >> 4);
-               gen_code_ptr += sizeof(plt_bundle);
-           }
-       }
-
-       for (fixup = plt_fixes; fixup; fixup = fixup->next)
-           ia64_imm21b(fixup->addr,
-                       ((long) plt_start + plt_offset[fixup->value]
-                        - ((long) fixup->addr & ~0xf)) >> 4);
-    }
-
-    got_start = gen_code_ptr;
-
-    /* First, create the GOT: */
-    for (fixup = ltoff_fixes; fixup; fixup = fixup->next) {
-       /* first check if we already have this value in the GOT: */
-       for (vp = (uint64_t *) got_start; vp < (uint64_t *) gen_code_ptr; ++vp)
-           if (*vp == fixup->value)
-               break;
-       if (vp == (uint64_t *) gen_code_ptr) {
-           /* Nope, we need to put the value in the GOT: */
-           *vp = fixup->value;
-           gen_code_ptr += 8;
-       }
-       ia64_imm22(fixup->addr, (long) vp - gp);
-    }
-    /* Keep code ptr aligned. */
-    if ((long) gen_code_ptr & 15)
-       gen_code_ptr += 8;
-    *gen_code_pp = gen_code_ptr;
-}
-
-#endif
index e7c4806..cf72399 100644 (file)
@@ -36,10 +36,6 @@ struct TranslationBlock;
 
 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
 
 
 #define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
 
-extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
-extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-extern long gen_labels[OPC_BUF_SIZE];
-extern int nb_gen_labels;
 extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
 extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
 extern target_ulong gen_opc_pc[OPC_BUF_SIZE];
 extern target_ulong gen_opc_npc[OPC_BUF_SIZE];
 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
@@ -63,8 +59,8 @@ extern int loglevel;
 
 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
 
 int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
 int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
 unsigned long code_gen_max_block_size(void);
 unsigned long code_gen_max_block_size(void);
+void cpu_gen_init(void);
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
 int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,
                  int *gen_code_size_ptr);
 int cpu_restore_state(struct TranslationBlock *tb,
@@ -120,6 +116,7 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
 #elif defined(__powerpc__)
 #define CODE_GEN_BUFFER_SIZE     (6 * 1024 * 1024)
 #else
 #elif defined(__powerpc__)
 #define CODE_GEN_BUFFER_SIZE     (6 * 1024 * 1024)
 #else
+/* XXX: make it dynamic on x86 */
 #define CODE_GEN_BUFFER_SIZE     (16 * 1024 * 1024)
 #endif
 
 #define CODE_GEN_BUFFER_SIZE     (16 * 1024 * 1024)
 #endif
 
@@ -136,7 +133,7 @@ static inline int tlb_set_page(CPUState *env, target_ulong vaddr,
 
 #define CODE_GEN_MAX_BLOCKS    (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
 
 
 #define CODE_GEN_MAX_BLOCKS    (CODE_GEN_BUFFER_SIZE / CODE_GEN_AVG_BLOCK_SIZE)
 
-#if defined(__powerpc__)
+#if defined(__powerpc__) || defined(__x86_64__)
 #define USE_DIRECT_JUMP
 #endif
 #if defined(__i386__) && !defined(_WIN32)
 #define USE_DIRECT_JUMP
 #endif
 #if defined(__i386__) && !defined(_WIN32)
@@ -169,7 +166,7 @@ typedef struct TranslationBlock {
 #ifdef USE_DIRECT_JUMP
     uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
 #else
 #ifdef USE_DIRECT_JUMP
     uint16_t tb_jmp_offset[4]; /* offset of jump instruction */
 #else
-    uint32_t tb_next[2]; /* address of jump generated code */
+    unsigned long tb_next[2]; /* address of jump generated code */
 #endif
     /* list of TBs jumping to this one. This is a circular list using
        the two least significant bits of the pointers to tell what is
 #endif
     /* list of TBs jumping to this one. This is a circular list using
        the two least significant bits of the pointers to tell what is
@@ -228,7 +225,7 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
     asm volatile ("sync" : : : "memory");
     asm volatile ("isync" : : : "memory");
 }
     asm volatile ("sync" : : : "memory");
     asm volatile ("isync" : : : "memory");
 }
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__x86_64__)
 static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
 {
     /* patch the branch destination */
 static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
 {
     /* patch the branch destination */
@@ -294,48 +291,6 @@ TranslationBlock *tb_find_pc(unsigned long pc_ptr);
 #define ASM_OP_LABEL_NAME(n, opname) \
     ASM_NAME(__op_label) #n "." ASM_NAME(opname)
 
 #define ASM_OP_LABEL_NAME(n, opname) \
     ASM_NAME(__op_label) #n "." ASM_NAME(opname)
 
-#if defined(__powerpc__)
-
-/* we patch the jump instruction directly */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
-    asm volatile (ASM_DATA_SECTION\
-                 ASM_OP_LABEL_NAME(n, opname) ":\n"\
-                 ".long 1f\n"\
-                 ASM_PREVIOUS_SECTION \
-                  "b " ASM_NAME(__op_jmp) #n "\n"\
-                 "1:\n");\
-} while (0)
-
-#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
-
-/* we patch the jump instruction directly */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
-    asm volatile (".section .data\n"\
-                 ASM_OP_LABEL_NAME(n, opname) ":\n"\
-                 ".long 1f\n"\
-                 ASM_PREVIOUS_SECTION \
-                  "jmp " ASM_NAME(__op_jmp) #n "\n"\
-                 "1:\n");\
-} while (0)
-
-#else
-
-/* jump to next block operations (more portable code, does not need
-   cache flushing, but slower because of indirect jump) */
-#define GOTO_TB(opname, tbparam, n)\
-do {\
-    static void __attribute__((used)) *dummy ## n = &&dummy_label ## n;\
-    static void __attribute__((used)) *__op_label ## n \
-        __asm__(ASM_OP_LABEL_NAME(n, opname)) = &&label ## n;\
-    goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\
-label ## n: ;\
-dummy_label ## n: ;\
-} while (0)
-
-#endif
-
 extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
 extern CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4];
 extern CPUReadMemoryFunc *io_mem_read[IO_MEM_NB_ENTRIES][4];
 extern void *io_mem_opaque[IO_MEM_NB_ENTRIES];
diff --git a/exec.c b/exec.c
index ab3f9c1..e9a5918 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -312,6 +312,7 @@ void cpu_exec_init(CPUState *env)
     int cpu_index;
 
     if (!code_gen_ptr) {
     int cpu_index;
 
     if (!code_gen_ptr) {
+        cpu_gen_init();
         code_gen_ptr = code_gen_buffer;
         page_init();
         io_mem_init();
         code_gen_ptr = code_gen_buffer;
         page_init();
         io_mem_init();
@@ -1238,10 +1239,10 @@ CPULogItem cpu_log_items[] = {
     { CPU_LOG_TB_IN_ASM, "in_asm",
       "show target assembly code for each compiled TB" },
     { CPU_LOG_TB_OP, "op",
     { CPU_LOG_TB_IN_ASM, "in_asm",
       "show target assembly code for each compiled TB" },
     { CPU_LOG_TB_OP, "op",
-      "show micro ops for each compiled TB (only usable if 'in_asm' used)" },
+      "show micro ops for each compiled TB" },
 #ifdef TARGET_I386
     { CPU_LOG_TB_OP_OPT, "op_opt",
 #ifdef TARGET_I386
     { CPU_LOG_TB_OP_OPT, "op_opt",
-      "show micro ops after optimization for each compiled TB" },
+      "show micro ops before eflags optimization" },
 #endif
     { CPU_LOG_INT, "int",
       "show interrupts/exceptions in short format" },
 #endif
     { CPU_LOG_INT, "int",
       "show interrupts/exceptions in short format" },
@@ -2935,6 +2936,7 @@ void dump_exec_info(FILE *f,
         }
     }
     /* XXX: avoid using doubles ? */
         }
     }
     /* XXX: avoid using doubles ? */
+    cpu_fprintf(f, "Translation buffer state:\n");
     cpu_fprintf(f, "TB count            %d\n", nb_tbs);
     cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n",
                 nb_tbs ? target_code_size / nb_tbs : 0,
     cpu_fprintf(f, "TB count            %d\n", nb_tbs);
     cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n",
                 nb_tbs ? target_code_size / nb_tbs : 0,
@@ -2950,9 +2952,49 @@ void dump_exec_info(FILE *f,
                 nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
                 direct_jmp2_count,
                 nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
                 nb_tbs ? (direct_jmp_count * 100) / nb_tbs : 0,
                 direct_jmp2_count,
                 nb_tbs ? (direct_jmp2_count * 100) / nb_tbs : 0);
+    cpu_fprintf(f, "\nStatistics:\n");
     cpu_fprintf(f, "TB flush count      %d\n", tb_flush_count);
     cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
     cpu_fprintf(f, "TLB flush count     %d\n", tlb_flush_count);
     cpu_fprintf(f, "TB flush count      %d\n", tb_flush_count);
     cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);
     cpu_fprintf(f, "TLB flush count     %d\n", tlb_flush_count);
+#ifdef CONFIG_PROFILER
+    {
+        int64_t tot;
+        tot = dyngen_interm_time + dyngen_code_time;
+        cpu_fprintf(f, "JIT cycles          %" PRId64 " (%0.3f s at 2.4 GHz)\n",
+                    tot, tot / 2.4e9);
+        cpu_fprintf(f, "translated TBs      %" PRId64 " (aborted=%" PRId64 " %0.1f%%)\n", 
+                    dyngen_tb_count, 
+                    dyngen_tb_count1 - dyngen_tb_count,
+                    dyngen_tb_count1 ? (double)(dyngen_tb_count1 - dyngen_tb_count) / dyngen_tb_count1 * 100.0 : 0);
+        cpu_fprintf(f, "avg ops/TB          %0.1f max=%d\n", 
+                    dyngen_tb_count ? (double)dyngen_op_count / dyngen_tb_count : 0, dyngen_op_count_max);
+        cpu_fprintf(f, "old ops/total ops   %0.1f%%\n", 
+                    dyngen_op_count ? (double)dyngen_old_op_count / dyngen_op_count * 100.0 : 0);
+        cpu_fprintf(f, "deleted ops/TB      %0.2f\n",
+                    dyngen_tb_count ? 
+                    (double)dyngen_tcg_del_op_count / dyngen_tb_count : 0);
+        cpu_fprintf(f, "cycles/op           %0.1f\n", 
+                    dyngen_op_count ? (double)tot / dyngen_op_count : 0);
+        cpu_fprintf(f, "cycles/in byte     %0.1f\n", 
+                    dyngen_code_in_len ? (double)tot / dyngen_code_in_len : 0);
+        cpu_fprintf(f, "cycles/out byte     %0.1f\n", 
+                    dyngen_code_out_len ? (double)tot / dyngen_code_out_len : 0);
+        if (tot == 0)
+            tot = 1;
+        cpu_fprintf(f, "  gen_interm time   %0.1f%%\n", 
+                    (double)dyngen_interm_time / tot * 100.0);
+        cpu_fprintf(f, "  gen_code time     %0.1f%%\n", 
+                    (double)dyngen_code_time / tot * 100.0);
+        cpu_fprintf(f, "cpu_restore count   %" PRId64 "\n",
+                    dyngen_restore_count);
+        cpu_fprintf(f, "  avg cycles        %0.1f\n",
+                    dyngen_restore_count ? (double)dyngen_restore_time / dyngen_restore_count : 0);
+        {
+            extern void dump_op_count(void);
+            dump_op_count();
+        }
+    }
+#endif
 }
 
 #if !defined(CONFIG_USER_ONLY)
 }
 
 #if !defined(CONFIG_USER_ONLY)
index da93e7c..957c651 100644 (file)
@@ -216,11 +216,6 @@ void OPPROTO op_clear_irf (void)
     RETURN();
 }
 
     RETURN();
 }
 
-void OPPROTO op_exit_tb (void)
-{
-    EXIT_TB();
-}
-
 /* Arithmetic */
 void OPPROTO op_addq (void)
 {
 /* Arithmetic */
 void OPPROTO op_addq (void)
 {
index 01e6ded..1c8587d 100644 (file)
@@ -25,6 +25,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 #define DO_SINGLE_STEP
 #define GENERATE_NOP
 
 #define DO_SINGLE_STEP
 #define GENERATE_NOP
@@ -41,24 +42,6 @@ struct DisasContext {
     uint32_t amask;
 };
 
     uint32_t amask;
 };
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
-
-#include "gen-op.h"
-
 static always_inline void gen_op_nop (void)
 {
 #if defined(GENERATE_NOP)
 static always_inline void gen_op_nop (void)
 {
 #if defined(GENERATE_NOP)
@@ -1988,10 +1971,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     int ret;
 
     pc_start = tb->pc;
     int ret;
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
-    nb_gen_labels = 0;
     ctx.pc = pc_start;
     ctx.amask = env->amask;
 #if defined (CONFIG_USER_ONLY)
     ctx.pc = pc_start;
     ctx.amask = env->amask;
 #if defined (CONFIG_USER_ONLY)
@@ -2051,12 +2031,11 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     if (ret != 1 && ret != 3) {
         gen_update_pc(&ctx);
     }
     if (ret != 1 && ret != 3) {
         gen_update_pc(&ctx);
     }
-    gen_op_reset_T0();
 #if defined (DO_TB_FLUSH)
     gen_op_tb_flush();
 #endif
     /* Generate the return instruction */
 #if defined (DO_TB_FLUSH)
     gen_op_tb_flush();
 #endif
     /* Generate the return instruction */
-    gen_op_exit_tb();
+    tcg_gen_exit_tb(0);
     *gen_opc_ptr = INDEX_op_end;
     if (search_pc) {
         j = gen_opc_ptr - gen_opc_buf;
     *gen_opc_ptr = INDEX_op_end;
     if (search_pc) {
         j = gen_opc_ptr - gen_opc_buf;
@@ -2075,11 +2054,6 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
         fprintf(logfile, "\n");
     }
        target_disas(logfile, pc_start, ctx.pc - pc_start, 1);
         fprintf(logfile, "\n");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-        fprintf(logfile, "OP:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
 #endif
 
     return 0;
 #endif
 
     return 0;
index 216944a..c2d33ca 100644 (file)
@@ -364,21 +364,6 @@ void OPPROTO op_testn_T0(void)
     FORCE_RET();
 }
 
     FORCE_RET();
 }
 
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-}
-
 void OPPROTO op_movl_T0_cpsr(void)
 {
     /* Execution state bits always read as zero.  */
 void OPPROTO op_movl_T0_cpsr(void)
 {
     /* Execution state bits always read as zero.  */
index 513b179..6de78f8 100644 (file)
@@ -28,6 +28,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 #define ENABLE_ARCH_5J    0
 #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
 
 #define ENABLE_ARCH_5J    0
 #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
@@ -68,27 +69,10 @@ typedef struct DisasContext {
 #define DISAS_WFI 4
 #define DISAS_SWI 5
 
 #define DISAS_WFI 4
 #define DISAS_SWI 5
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
 /* XXX: move that elsewhere */
 /* XXX: move that elsewhere */
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 extern FILE *logfile;
 extern int loglevel;
 
 extern FILE *logfile;
 extern int loglevel;
 
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-#include "gen-op.h"
-
 #define PAS_OP(pfx) {  \
     gen_op_ ## pfx ## add16_T0_T1, \
     gen_op_ ## pfx ## addsubx_T0_T1, \
 #define PAS_OP(pfx) {  \
     gen_op_ ## pfx ## add16_T0_T1, \
     gen_op_ ## pfx ## addsubx_T0_T1, \
@@ -2432,19 +2416,14 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
 
     tb = s->tb;
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
 
     tb = s->tb;
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
-        if (n == 0)
-            gen_op_goto_tb0(TBPARAM(tb));
-        else
-            gen_op_goto_tb1(TBPARAM(tb));
+        tcg_gen_goto_tb(n);
         gen_op_movl_T0_im(dest);
         gen_op_movl_r15_T0();
         gen_op_movl_T0_im(dest);
         gen_op_movl_r15_T0();
-        gen_op_movl_T0_im((long)tb + n);
-        gen_op_exit_tb();
+        tcg_gen_exit_tb((long)tb + n);
     } else {
         gen_op_movl_T0_im(dest);
         gen_op_movl_r15_T0();
     } else {
         gen_op_movl_T0_im(dest);
         gen_op_movl_r15_T0();
-        gen_op_movl_T0_0();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
 }
 
     }
 }
 
@@ -7486,9 +7465,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
 
     dc->tb = tb;
 
 
     dc->tb = tb;
 
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
 
     dc->is_jmp = DISAS_NEXT;
     dc->pc = pc_start;
@@ -7506,7 +7483,6 @@ static inline int gen_intermediate_code_internal(CPUState *env,
     }
 #endif
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
     }
 #endif
     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
-    nb_gen_labels = 0;
     lj = -1;
     /* Reset the conditional execution bits immediately. This avoids
        complications trying to do it at the end of the block.  */
     lj = -1;
     /* Reset the conditional execution bits immediately. This avoids
        complications trying to do it at the end of the block.  */
@@ -7625,8 +7601,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
         case DISAS_JUMP:
         case DISAS_UPDATE:
             /* indicate that the hash table must be used to find the next TB */
         case DISAS_JUMP:
         case DISAS_UPDATE:
             /* indicate that the hash table must be used to find the next TB */
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         case DISAS_TB_JUMP:
             /* nothing more to generate */
             break;
         case DISAS_TB_JUMP:
             /* nothing more to generate */
@@ -7654,11 +7629,6 @@ done_generating:
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
         fprintf(logfile, "\n");
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb);
         fprintf(logfile, "\n");
-        if (loglevel & (CPU_LOG_TB_OP)) {
-            fprintf(logfile, "OP:\n");
-            dump_ops(gen_opc_buf, gen_opparam_buf);
-            fprintf(logfile, "\n");
-        }
     }
 #endif
     if (search_pc) {
     }
 #endif
     if (search_pc) {
index 3c50574..c7243b1 100644 (file)
 
 /* Microcode.  */
 
 
 /* Microcode.  */
 
-void OPPROTO op_exit_tb (void)
-{
-       EXIT_TB();
-}
-
-void OPPROTO op_goto_tb0 (void)
-{
-       GOTO_TB(op_goto_tb0, PARAM1, 0);
-       RETURN();
-}
-
-void OPPROTO op_goto_tb1 (void)
-{
-       GOTO_TB(op_goto_tb1, PARAM1, 1);
-       RETURN();
-}
-
 void OPPROTO op_break_im(void)
 {
        env->trapnr = PARAM1;
 void OPPROTO op_break_im(void)
 {
        env->trapnr = PARAM1;
@@ -1268,7 +1251,7 @@ void OPPROTO op_movl_btarget_T0 (void)
        RETURN();
 }
 
        RETURN();
 }
 
-void OPPROTO op_jmp (void)
+void OPPROTO op_jmp1 (void)
 {
        env->pc = env->btarget;
        RETURN();
 {
        env->pc = env->btarget;
        RETURN();
index a05d139..3a5e5eb 100644 (file)
@@ -51,6 +51,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 #include "crisv32-decode.h"
 
 #define CRIS_STATS 0
 #include "crisv32-decode.h"
 
 #define CRIS_STATS 0
 #define DIS(x)
 #endif
 
 #define DIS(x)
 #endif
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
 #define BUG_ON(x) ({if (x) BUG();})
 
 #define BUG() (gen_BUG(dc, __FILE__, __LINE__))
 #define BUG_ON(x) ({if (x) BUG();})
 
 #define CC_MASK_NZVC 0xf
 #define CC_MASK_RNZV 0x10e
 
 #define CC_MASK_NZVC 0xf
 #define CC_MASK_RNZV 0x10e
 
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-#include "gen-op.h"
-
 /* This is the state at translation time.  */
 typedef struct DisasContext {
        CPUState *env;
 /* This is the state at translation time.  */
 typedef struct DisasContext {
        CPUState *env;
@@ -264,15 +248,14 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
        TranslationBlock *tb;
        tb = dc->tb;
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
        TranslationBlock *tb;
        tb = dc->tb;
        if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
-               if (n == 0)
-                       gen_op_goto_tb0(TBPARAM(tb));
-               else
-                       gen_op_goto_tb1(TBPARAM(tb));
-               gen_op_movl_T0_0();
+#if 0
+            /* XXX: this code is not finished */
+            tcg_gen_goto_tb(n);
+#endif
+            tcg_gen_exit_tb(0);
        } else {
        } else {
-               gen_op_movl_T0_0();
+            tcg_gen_exit_tb(0);
        }
        }
-       gen_op_exit_tb();
 }
 
 /* Sign extend at translation time.  */
 }
 
 /* Sign extend at translation time.  */
@@ -2325,9 +2308,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
        dc->env = env;
        dc->tb = tb;
 
        dc->env = env;
        dc->tb = tb;
 
-       gen_opc_ptr = gen_opc_buf;
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-       gen_opparam_ptr = gen_opparam_buf;
 
        dc->is_jmp = DISAS_NEXT;
        dc->pc = pc_start;
 
        dc->is_jmp = DISAS_NEXT;
        dc->pc = pc_start;
@@ -2374,7 +2355,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                        if (dc->delayed_branch == 0)
                        {
                                if (dc->bcc == CC_A) {
                        if (dc->delayed_branch == 0)
                        {
                                if (dc->bcc == CC_A) {
-                                       gen_op_jmp ();
+                                       gen_op_jmp1 ();
                                        dc->is_jmp = DISAS_UPDATE;
                                }
                                else {
                                        dc->is_jmp = DISAS_UPDATE;
                                }
                                else {
@@ -2409,9 +2390,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                        case DISAS_UPDATE:
                                /* indicate that the hash table must be used
                                   to find the next TB */
                        case DISAS_UPDATE:
                                /* indicate that the hash table must be used
                                   to find the next TB */
-                               /* T0 is used to index the jmp tables.  */
-                               gen_op_movl_T0_0();
-                               gen_op_exit_tb();
+                               tcg_gen_exit_tb(0);
                                break;
                        case DISAS_TB_JUMP:
                                /* nothing more to generate */
                                break;
                        case DISAS_TB_JUMP:
                                /* nothing more to generate */
@@ -2434,11 +2413,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
                fprintf(logfile, "\n");
                fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
                target_disas(logfile, pc_start, dc->pc + 4 - pc_start, 0);
                fprintf(logfile, "\n");
-               if (loglevel & CPU_LOG_TB_OP) {
-                       fprintf(logfile, "OP:\n");
-                       dump_ops(gen_opc_buf, gen_opparam_buf);
-                       fprintf(logfile, "\n");
-               }
        }
 #endif
        return 0;
        }
 #endif
        return 0;
index 20153f7..37fcdc0 100644 (file)
@@ -181,8 +181,9 @@ void __hidden cpu_loop_exit(void);
 
 void OPPROTO op_movl_eflags_T0(void);
 void OPPROTO op_movl_T0_eflags(void);
 
 void OPPROTO op_movl_eflags_T0(void);
 void OPPROTO op_movl_T0_eflags(void);
-void helper_divl_EAX_T0(void);
-void helper_idivl_EAX_T0(void);
+
+#include "helper.h"
+
 void helper_mulq_EAX_T0(void);
 void helper_imulq_EAX_T0(void);
 void helper_imulq_T0_T1(void);
 void helper_mulq_EAX_T0(void);
 void helper_imulq_EAX_T0(void);
 void helper_imulq_T0_T1(void);
index 3c7424f..f526809 100644 (file)
@@ -1608,13 +1608,13 @@ int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den)
 }
 #endif
 
 }
 #endif
 
-void helper_divl_EAX_T0(void)
+void helper_divl_EAX_T0(target_ulong t0)
 {
     unsigned int den, r;
     uint64_t num, q;
 
     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
 {
     unsigned int den, r;
     uint64_t num, q;
 
     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
-    den = T0;
+    den = t0;
     if (den == 0) {
         raise_exception(EXCP00_DIVZ);
     }
     if (den == 0) {
         raise_exception(EXCP00_DIVZ);
     }
@@ -1630,13 +1630,13 @@ void helper_divl_EAX_T0(void)
     EDX = (uint32_t)r;
 }
 
     EDX = (uint32_t)r;
 }
 
-void helper_idivl_EAX_T0(void)
+void helper_idivl_EAX_T0(target_ulong t0)
 {
     int den, r;
     int64_t num, q;
 
     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
 {
     int den, r;
     int64_t num, q;
 
     num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);
-    den = T0;
+    den = t0;
     if (den == 0) {
         raise_exception(EXCP00_DIVZ);
     }
     if (den == 0) {
         raise_exception(EXCP00_DIVZ);
     }
diff --git a/target-i386/helper.h b/target-i386/helper.h
new file mode 100644 (file)
index 0000000..1b247db
--- /dev/null
@@ -0,0 +1,4 @@
+#define TCG_HELPER_PROTO
+
+void TCG_HELPER_PROTO helper_divl_EAX_T0(target_ulong t0);
+void TCG_HELPER_PROTO helper_idivl_EAX_T0(target_ulong t0);
index 77930db..eb292fe 100644 (file)
@@ -172,31 +172,6 @@ void OPPROTO op_testl_T0_T1_cc(void)
 
 /* operations without flags */
 
 
 /* operations without flags */
 
-void OPPROTO op_addl_T0_T1(void)
-{
-    T0 += T1;
-}
-
-void OPPROTO op_orl_T0_T1(void)
-{
-    T0 |= T1;
-}
-
-void OPPROTO op_andl_T0_T1(void)
-{
-    T0 &= T1;
-}
-
-void OPPROTO op_subl_T0_T1(void)
-{
-    T0 -= T1;
-}
-
-void OPPROTO op_xorl_T0_T1(void)
-{
-    T0 ^= T1;
-}
-
 void OPPROTO op_negl_T0(void)
 {
     T0 = -T0;
 void OPPROTO op_negl_T0(void)
 {
     T0 = -T0;
@@ -217,18 +192,6 @@ void OPPROTO op_notl_T0(void)
     T0 = ~T0;
 }
 
     T0 = ~T0;
 }
 
-void OPPROTO op_bswapl_T0(void)
-{
-    T0 = bswap32(T0);
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_bswapq_T0(void)
-{
-    helper_bswapq_T0();
-}
-#endif
-
 /* multiply/divide */
 
 /* XXX: add eflags optimizations */
 /* multiply/divide */
 
 /* XXX: add eflags optimizations */
@@ -399,16 +362,6 @@ void OPPROTO op_idivw_AX_T0(void)
     EDX = (EDX & ~0xffff) | r;
 }
 
     EDX = (EDX & ~0xffff) | r;
 }
 
-void OPPROTO op_divl_EAX_T0(void)
-{
-    helper_divl_EAX_T0();
-}
-
-void OPPROTO op_idivl_EAX_T0(void)
-{
-    helper_idivl_EAX_T0();
-}
-
 #ifdef TARGET_X86_64
 void OPPROTO op_divq_EAX_T0(void)
 {
 #ifdef TARGET_X86_64
 void OPPROTO op_divq_EAX_T0(void)
 {
@@ -424,46 +377,6 @@ void OPPROTO op_idivq_EAX_T0(void)
 /* constant load & misc op */
 
 /* XXX: consistent names */
 /* constant load & misc op */
 
 /* XXX: consistent names */
-void OPPROTO op_movl_T0_imu(void)
-{
-    T0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T0_im(void)
-{
-    T0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_addl_T0_im(void)
-{
-    T0 += PARAM1;
-}
-
-void OPPROTO op_andl_T0_ffff(void)
-{
-    T0 = T0 & 0xffff;
-}
-
-void OPPROTO op_andl_T0_im(void)
-{
-    T0 = T0 & PARAM1;
-}
-
-void OPPROTO op_movl_T0_T1(void)
-{
-    T0 = T1;
-}
-
-void OPPROTO op_movl_T1_imu(void)
-{
-    T1 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_movl_T1_im(void)
-{
-    T1 = (int32_t)PARAM1;
-}
-
 void OPPROTO op_addl_T1_im(void)
 {
     T1 += PARAM1;
 void OPPROTO op_addl_T1_im(void)
 {
     T1 += PARAM1;
@@ -474,26 +387,6 @@ void OPPROTO op_movl_T1_A0(void)
     T1 = A0;
 }
 
     T1 = A0;
 }
 
-void OPPROTO op_movl_A0_im(void)
-{
-    A0 = (uint32_t)PARAM1;
-}
-
-void OPPROTO op_addl_A0_im(void)
-{
-    A0 = (uint32_t)(A0 + PARAM1);
-}
-
-void OPPROTO op_movl_A0_seg(void)
-{
-    A0 = (uint32_t)*(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_addl_A0_seg(void)
-{
-    A0 = (uint32_t)(A0 + *(target_ulong *)((char *)env + PARAM1));
-}
-
 void OPPROTO op_addl_A0_AL(void)
 {
     A0 = (uint32_t)(A0 + (EAX & 0xff));
 void OPPROTO op_addl_A0_AL(void)
 {
     A0 = (uint32_t)(A0 + (EAX & 0xff));
@@ -523,46 +416,6 @@ typedef union UREG64 {
 
 #ifdef TARGET_X86_64
 
 
 #ifdef TARGET_X86_64
 
-void OPPROTO op_movq_T0_im64(void)
-{
-    T0 = PARAMQ1;
-}
-
-void OPPROTO op_movq_T1_im64(void)
-{
-    T1 = PARAMQ1;
-}
-
-void OPPROTO op_movq_A0_im(void)
-{
-    A0 = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movq_A0_im64(void)
-{
-    A0 = PARAMQ1;
-}
-
-void OPPROTO op_addq_A0_im(void)
-{
-    A0 = (A0 + (int32_t)PARAM1);
-}
-
-void OPPROTO op_addq_A0_im64(void)
-{
-    A0 = (A0 + PARAMQ1);
-}
-
-void OPPROTO op_movq_A0_seg(void)
-{
-    A0 = *(target_ulong *)((char *)env + PARAM1);
-}
-
-void OPPROTO op_addq_A0_seg(void)
-{
-    A0 += *(target_ulong *)((char *)env + PARAM1);
-}
-
 void OPPROTO op_addq_A0_AL(void)
 {
     A0 = (A0 + (EAX & 0xff));
 void OPPROTO op_addq_A0_AL(void)
 {
     A0 = (A0 + (EAX & 0xff));
@@ -570,11 +423,6 @@ void OPPROTO op_addq_A0_AL(void)
 
 #endif
 
 
 #endif
 
-void OPPROTO op_andl_A0_ffff(void)
-{
-    A0 = A0 & 0xffff;
-}
-
 /* memory access */
 
 #define MEMSUFFIX _raw
 /* memory access */
 
 #define MEMSUFFIX _raw
@@ -588,30 +436,6 @@ void OPPROTO op_andl_A0_ffff(void)
 #include "ops_mem.h"
 #endif
 
 #include "ops_mem.h"
 #endif
 
-/* indirect jump */
-
-void OPPROTO op_jmp_T0(void)
-{
-    EIP = T0;
-}
-
-void OPPROTO op_movl_eip_im(void)
-{
-    EIP = (uint32_t)PARAM1;
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO op_movq_eip_im(void)
-{
-    EIP = (int32_t)PARAM1;
-}
-
-void OPPROTO op_movq_eip_im64(void)
-{
-    EIP = PARAMQ1;
-}
-#endif
-
 void OPPROTO op_hlt(void)
 {
     helper_hlt();
 void OPPROTO op_hlt(void)
 {
     helper_hlt();
@@ -735,16 +559,6 @@ void OPPROTO op_single_step(void)
     helper_single_step();
 }
 
     helper_single_step();
 }
 
-void OPPROTO op_movl_T0_0(void)
-{
-    T0 = 0;
-}
-
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-}
-
 /* multiple size ops */
 
 #define ldul ldl
 /* multiple size ops */
 
 #define ldul ldl
@@ -879,75 +693,6 @@ void OPPROTO op_decq_ECX(void)
 }
 #endif
 
 }
 #endif
 
-/* push/pop utils */
-
-void op_addl_A0_SS(void)
-{
-    A0 = (uint32_t)(A0 + env->segs[R_SS].base);
-}
-
-void op_subl_A0_2(void)
-{
-    A0 = (uint32_t)(A0 - 2);
-}
-
-void op_subl_A0_4(void)
-{
-    A0 = (uint32_t)(A0 - 4);
-}
-
-void op_addl_ESP_4(void)
-{
-    ESP = (uint32_t)(ESP + 4);
-}
-
-void op_addl_ESP_2(void)
-{
-    ESP = (uint32_t)(ESP + 2);
-}
-
-void op_addw_ESP_4(void)
-{
-    ESP = (ESP & ~0xffff) | ((ESP + 4) & 0xffff);
-}
-
-void op_addw_ESP_2(void)
-{
-    ESP = (ESP & ~0xffff) | ((ESP + 2) & 0xffff);
-}
-
-void op_addl_ESP_im(void)
-{
-    ESP = (uint32_t)(ESP + PARAM1);
-}
-
-void op_addw_ESP_im(void)
-{
-    ESP = (ESP & ~0xffff) | ((ESP + PARAM1) & 0xffff);
-}
-
-#ifdef TARGET_X86_64
-void op_subq_A0_2(void)
-{
-    A0 -= 2;
-}
-
-void op_subq_A0_8(void)
-{
-    A0 -= 8;
-}
-
-void op_addq_ESP_8(void)
-{
-    ESP += 8;
-}
-
-void op_addq_ESP_im(void)
-{
-    ESP += PARAM1;
-}
-#endif
-
 void OPPROTO op_rdtsc(void)
 {
     helper_rdtsc();
 void OPPROTO op_rdtsc(void)
 {
     helper_rdtsc();
@@ -1362,16 +1107,6 @@ void OPPROTO op_clts(void)
 
 /* flags handling */
 
 
 /* flags handling */
 
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
 void OPPROTO op_jmp_label(void)
 {
     GOTO_LABEL_PARAM(1);
 void OPPROTO op_jmp_label(void)
 {
     GOTO_LABEL_PARAM(1);
@@ -1451,11 +1186,6 @@ void OPPROTO op_xor_T0_1(void)
     T0 ^= 1;
 }
 
     T0 ^= 1;
 }
 
-void OPPROTO op_set_cc_op(void)
-{
-    CC_OP = PARAM1;
-}
-
 void OPPROTO op_mov_T0_cc(void)
 {
     T0 = cc_table[CC_OP].compute_all();
 void OPPROTO op_mov_T0_cc(void)
 {
     T0 = cc_table[CC_OP].compute_all();
index eae4139..67bee88 100644 (file)
  * 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, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-void OPPROTO glue(op_movl_A0,REGNAME)(void)
-{
-    A0 = (uint32_t)REG;
-}
-
-void OPPROTO glue(op_addl_A0,REGNAME)(void)
-{
-    A0 = (uint32_t)(A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s1)(void)
-{
-    A0 = (uint32_t)(A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s2)(void)
-{
-    A0 = (uint32_t)(A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addl_A0,REGNAME),_s3)(void)
-{
-    A0 = (uint32_t)(A0 + (REG << 3));
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(op_movq_A0,REGNAME)(void)
-{
-    A0 = REG;
-}
-
-void OPPROTO glue(op_addq_A0,REGNAME)(void)
-{
-    A0 = (A0 + REG);
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s1)(void)
-{
-    A0 = (A0 + (REG << 1));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s2)(void)
-{
-    A0 = (A0 + (REG << 2));
-}
-
-void OPPROTO glue(glue(op_addq_A0,REGNAME),_s3)(void)
-{
-    A0 = (A0 + (REG << 3));
-}
-#endif
-
-void OPPROTO glue(op_movl_T0,REGNAME)(void)
-{
-    T0 = REG;
-}
-
-void OPPROTO glue(op_movl_T1,REGNAME)(void)
-{
-    T1 = REG;
-}
-
-void OPPROTO glue(op_movh_T0,REGNAME)(void)
-{
-    T0 = REG >> 8;
-}
-
-void OPPROTO glue(op_movh_T1,REGNAME)(void)
-{
-    T1 = REG >> 8;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T0)(void)
-{
-    REG = (uint32_t)T0;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_T1)(void)
-{
-    REG = (uint32_t)T1;
-}
-
-void OPPROTO glue(glue(op_movl,REGNAME),_A0)(void)
-{
-    REG = (uint32_t)A0;
-}
-
-#ifdef TARGET_X86_64
-void OPPROTO glue(glue(op_movq,REGNAME),_T0)(void)
-{
-    REG = T0;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_T1)(void)
-{
-    REG = T1;
-}
-
-void OPPROTO glue(glue(op_movq,REGNAME),_A0)(void)
-{
-    REG = A0;
-}
-#endif
-
 /* mov T1 to REG if T0 is true */
 void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
 {
 /* mov T1 to REG if T0 is true */
 void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
 {
@@ -132,8 +28,15 @@ void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
 
 void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
 {
 
 void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
 {
+#ifdef TARGET_X86_64
     if (T0)
         REG = (uint32_t)T1;
     if (T0)
         REG = (uint32_t)T1;
+    else
+        REG = (uint32_t)REG;
+#else
+    if (T0)
+        REG = (uint32_t)T1;
+#endif
     FORCE_RET();
 }
 
     FORCE_RET();
 }
 
@@ -145,46 +48,3 @@ void OPPROTO glue(glue(op_cmovq,REGNAME),_T1_T0)(void)
     FORCE_RET();
 }
 #endif
     FORCE_RET();
 }
 #endif
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T0)(void)
-{
-    REG = (REG & ~0xffff) | (T0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_T1)(void)
-{
-    REG = (REG & ~0xffff) | (T1 & 0xffff);
-}
-
-/* NOTE: A0 high order bits are ignored */
-void OPPROTO glue(glue(op_movw,REGNAME),_A0)(void)
-{
-    REG = (REG & ~0xffff) | (A0 & 0xffff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T0)(void)
-{
-    REG = (REG & ~0xff) | (T0 & 0xff);
-}
-
-/* NOTE: T0 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T0)(void)
-{
-    REG = (REG & ~0xff00) | ((T0 & 0xff) << 8);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movb,REGNAME),_T1)(void)
-{
-    REG = (REG & ~0xff) | (T1 & 0xff);
-}
-
-/* NOTE: T1 high order bits are ignored */
-void OPPROTO glue(glue(op_movh,REGNAME),_T1)(void)
-{
-    REG = (REG & ~0xff00) | ((T1 & 0xff) << 8);
-}
-
index 9723e76..aa397f6 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
-
-/* XXX: move that elsewhere */
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
+#include "helper.h"
+#include "tcg-op.h"
 
 #define PREFIX_REPZ   0x01
 #define PREFIX_REPNZ  0x02
 
 #define PREFIX_REPZ   0x01
 #define PREFIX_REPNZ  0x02
@@ -57,14 +55,79 @@ static uint32_t *gen_opparam_ptr;
 #define REX_B(s) 0
 #endif
 
 #define REX_B(s) 0
 #endif
 
+//#define MACRO_TEST   1
+
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-static int x86_64_hregs;
+#define TCG_TYPE_TL TCG_TYPE_I64
+#define tcg_gen_movi_tl tcg_gen_movi_i64
+#define tcg_gen_mov_tl tcg_gen_mov_i64
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i64
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i64
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i64
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i64
+#define tcg_gen_ld32u_tl tcg_gen_ld32u_i64
+#define tcg_gen_ld32s_tl tcg_gen_ld32s_i64
+#define tcg_gen_ld_tl tcg_gen_ld_i64
+#define tcg_gen_st8_tl tcg_gen_st8_i64
+#define tcg_gen_st16_tl tcg_gen_st16_i64
+#define tcg_gen_st32_tl tcg_gen_st32_i64
+#define tcg_gen_st_tl tcg_gen_st_i64
+#define tcg_gen_add_tl tcg_gen_add_i64
+#define tcg_gen_addi_tl tcg_gen_addi_i64
+#define tcg_gen_sub_tl tcg_gen_sub_i64
+#define tcg_gen_subi_tl tcg_gen_subi_i64
+#define tcg_gen_and_tl tcg_gen_and_i64
+#define tcg_gen_andi_tl tcg_gen_andi_i64
+#define tcg_gen_or_tl tcg_gen_or_i64
+#define tcg_gen_ori_tl tcg_gen_ori_i64
+#define tcg_gen_xor_tl tcg_gen_xor_i64
+#define tcg_gen_xori_tl tcg_gen_xori_i64
+#define tcg_gen_shl_tl tcg_gen_shl_i64
+#define tcg_gen_shli_tl tcg_gen_shli_i64
+#define tcg_gen_shr_tl tcg_gen_shr_i64
+#define tcg_gen_shri_tl tcg_gen_shri_i64
+#define tcg_gen_sar_tl tcg_gen_sar_i64
+#define tcg_gen_sari_tl tcg_gen_sari_i64
+#else
+#define TCG_TYPE_TL TCG_TYPE_I32
+#define tcg_gen_movi_tl tcg_gen_movi_i32
+#define tcg_gen_mov_tl tcg_gen_mov_i32
+#define tcg_gen_ld8u_tl tcg_gen_ld8u_i32
+#define tcg_gen_ld8s_tl tcg_gen_ld8s_i32
+#define tcg_gen_ld16u_tl tcg_gen_ld16u_i32
+#define tcg_gen_ld16s_tl tcg_gen_ld16s_i32
+#define tcg_gen_ld32u_tl tcg_gen_ld_i32
+#define tcg_gen_ld32s_tl tcg_gen_ld_i32
+#define tcg_gen_ld_tl tcg_gen_ld_i32
+#define tcg_gen_st8_tl tcg_gen_st8_i32
+#define tcg_gen_st16_tl tcg_gen_st16_i32
+#define tcg_gen_st32_tl tcg_gen_st_i32
+#define tcg_gen_st_tl tcg_gen_st_i32
+#define tcg_gen_add_tl tcg_gen_add_i32
+#define tcg_gen_addi_tl tcg_gen_addi_i32
+#define tcg_gen_sub_tl tcg_gen_sub_i32
+#define tcg_gen_subi_tl tcg_gen_subi_i32
+#define tcg_gen_and_tl tcg_gen_and_i32
+#define tcg_gen_andi_tl tcg_gen_andi_i32
+#define tcg_gen_or_tl tcg_gen_or_i32
+#define tcg_gen_ori_tl tcg_gen_ori_i32
+#define tcg_gen_xor_tl tcg_gen_xor_i32
+#define tcg_gen_xori_tl tcg_gen_xori_i32
+#define tcg_gen_shl_tl tcg_gen_shl_i32
+#define tcg_gen_shli_tl tcg_gen_shli_i32
+#define tcg_gen_shr_tl tcg_gen_shr_i32
+#define tcg_gen_shri_tl tcg_gen_shri_i32
+#define tcg_gen_sar_tl tcg_gen_sar_i32
+#define tcg_gen_sari_tl tcg_gen_sari_i32
 #endif
 
 #endif
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
+/* global register indexes */
+static int cpu_env, cpu_T[2], cpu_A0;
+/* local register indexes (only used inside old micro ops) */
+static int cpu_tmp0;
+
+#ifdef TARGET_X86_64
+static int x86_64_hregs;
 #endif
 
 typedef struct DisasContext {
 #endif
 
 typedef struct DisasContext {
@@ -131,15 +194,6 @@ enum {
     OP_SAR = 7,
 };
 
     OP_SAR = 7,
 };
 
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-#include "gen-op.h"
-
 /* operand size */
 enum {
     OT_BYTE = 0,
 /* operand size */
 enum {
     OT_BYTE = 0,
@@ -164,6 +218,73 @@ enum {
     OR_A0, /* temporary register used when doing address evaluation */
 };
 
     OR_A0, /* temporary register used when doing address evaluation */
 };
 
+static inline void gen_op_movl_T0_0(void)
+{
+    tcg_gen_movi_tl(cpu_T[0], 0);
+}
+
+static inline void gen_op_movl_T0_im(int32_t val)
+{
+    tcg_gen_movi_tl(cpu_T[0], val);
+}
+
+static inline void gen_op_movl_T0_imu(uint32_t val)
+{
+    tcg_gen_movi_tl(cpu_T[0], val);
+}
+
+static inline void gen_op_movl_T1_im(int32_t val)
+{
+    tcg_gen_movi_tl(cpu_T[1], val);
+}
+
+static inline void gen_op_movl_T1_imu(uint32_t val)
+{
+    tcg_gen_movi_tl(cpu_T[1], val);
+}
+
+static inline void gen_op_movl_A0_im(uint32_t val)
+{
+    tcg_gen_movi_tl(cpu_A0, val);
+}
+
+#ifdef TARGET_X86_64
+static inline void gen_op_movq_A0_im(int64_t val)
+{
+    tcg_gen_movi_tl(cpu_A0, val);
+}
+#endif
+
+static inline void gen_movtl_T0_im(target_ulong val)
+{
+    tcg_gen_movi_tl(cpu_T[0], val);
+}
+
+static inline void gen_movtl_T1_im(target_ulong val)
+{
+    tcg_gen_movi_tl(cpu_T[1], val);
+}
+
+static inline void gen_op_andl_T0_ffff(void)
+{
+    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffff);
+}
+
+static inline void gen_op_andl_T0_im(uint32_t val)
+{
+    tcg_gen_andi_tl(cpu_T[0], cpu_T[0], val);
+}
+
+static inline void gen_op_movl_T0_T1(void)
+{
+    tcg_gen_mov_tl(cpu_T[0], cpu_T[1]);
+}
+
+static inline void gen_op_andl_A0_ffff(void)
+{
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffff);
+}
+
 #ifdef TARGET_X86_64
 
 #define NB_OP_SIZES 4
 #ifdef TARGET_X86_64
 
 #define NB_OP_SIZES 4
@@ -186,45 +307,6 @@ enum {
   prefix ## R14 ## suffix,\
   prefix ## R15 ## suffix,
 
   prefix ## R14 ## suffix,\
   prefix ## R15 ## suffix,
 
-#define DEF_BREGS(prefixb, prefixh, suffix)             \
-                                                        \
-static void prefixb ## ESP ## suffix ## _wrapper(void)  \
-{                                                       \
-    if (x86_64_hregs)                                 \
-        prefixb ## ESP ## suffix ();                    \
-    else                                                \
-        prefixh ## EAX ## suffix ();                    \
-}                                                       \
-                                                        \
-static void prefixb ## EBP ## suffix ## _wrapper(void)  \
-{                                                       \
-    if (x86_64_hregs)                                 \
-        prefixb ## EBP ## suffix ();                    \
-    else                                                \
-        prefixh ## ECX ## suffix ();                    \
-}                                                       \
-                                                        \
-static void prefixb ## ESI ## suffix ## _wrapper(void)  \
-{                                                       \
-    if (x86_64_hregs)                                 \
-        prefixb ## ESI ## suffix ();                    \
-    else                                                \
-        prefixh ## EDX ## suffix ();                    \
-}                                                       \
-                                                        \
-static void prefixb ## EDI ## suffix ## _wrapper(void)  \
-{                                                       \
-    if (x86_64_hregs)                                 \
-        prefixb ## EDI ## suffix ();                    \
-    else                                                \
-        prefixh ## EBX ## suffix ();                    \
-}
-
-DEF_BREGS(gen_op_movb_, gen_op_movh_, _T0)
-DEF_BREGS(gen_op_movb_, gen_op_movh_, _T1)
-DEF_BREGS(gen_op_movl_T0_, gen_op_movh_T0_, )
-DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
-
 #else /* !TARGET_X86_64 */
 
 #define NB_OP_SIZES 3
 #else /* !TARGET_X86_64 */
 
 #define NB_OP_SIZES 3
@@ -241,218 +323,227 @@ DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
 
 #endif /* !TARGET_X86_64 */
 
 
 #endif /* !TARGET_X86_64 */
 
-static GenOpFunc *gen_op_mov_reg_T0[NB_OP_SIZES][CPU_NB_REGS] = {
-    [OT_BYTE] = {
-        gen_op_movb_EAX_T0,
-        gen_op_movb_ECX_T0,
-        gen_op_movb_EDX_T0,
-        gen_op_movb_EBX_T0,
-#ifdef TARGET_X86_64
-        gen_op_movb_ESP_T0_wrapper,
-        gen_op_movb_EBP_T0_wrapper,
-        gen_op_movb_ESI_T0_wrapper,
-        gen_op_movb_EDI_T0_wrapper,
-        gen_op_movb_R8_T0,
-        gen_op_movb_R9_T0,
-        gen_op_movb_R10_T0,
-        gen_op_movb_R11_T0,
-        gen_op_movb_R12_T0,
-        gen_op_movb_R13_T0,
-        gen_op_movb_R14_T0,
-        gen_op_movb_R15_T0,
+#if defined(WORDS_BIGENDIAN)
+#define REG_B_OFFSET (sizeof(target_ulong) - 1)
+#define REG_H_OFFSET (sizeof(target_ulong) - 2)
+#define REG_W_OFFSET (sizeof(target_ulong) - 2)
+#define REG_L_OFFSET (sizeof(target_ulong) - 4)
+#define REG_LH_OFFSET (sizeof(target_ulong) - 8)
 #else
 #else
-        gen_op_movh_EAX_T0,
-        gen_op_movh_ECX_T0,
-        gen_op_movh_EDX_T0,
-        gen_op_movh_EBX_T0,
+#define REG_B_OFFSET 0
+#define REG_H_OFFSET 1
+#define REG_W_OFFSET 0
+#define REG_L_OFFSET 0
+#define REG_LH_OFFSET 4
 #endif
 #endif
-    },
-    [OT_WORD] = {
-        DEF_REGS(gen_op_movw_, _T0)
-    },
-    [OT_LONG] = {
-        DEF_REGS(gen_op_movl_, _T0)
-    },
+
+static inline void gen_op_mov_reg_TN(int ot, int t_index, int reg)
+{
+    switch(ot) {
+    case OT_BYTE:
+        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
+            tcg_gen_st8_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]) + REG_B_OFFSET);
+        } else {
+            tcg_gen_st8_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+        }
+        break;
+    case OT_WORD:
+        tcg_gen_st16_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        break;
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-    [OT_QUAD] = {
-        DEF_REGS(gen_op_movq_, _T0)
-    },
+    case OT_LONG:
+        tcg_gen_st32_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        /* high part of register set to zero */
+        tcg_gen_movi_tl(cpu_tmp0, 0);
+        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+        break;
+    default:
+    case OT_QUAD:
+        tcg_gen_st_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]));
+        break;
+#else
+    default:
+    case OT_LONG:
+        tcg_gen_st32_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        break;
 #endif
 #endif
-};
+    }
+}
 
 
-static GenOpFunc *gen_op_mov_reg_T1[NB_OP_SIZES][CPU_NB_REGS] = {
-    [OT_BYTE] = {
-        gen_op_movb_EAX_T1,
-        gen_op_movb_ECX_T1,
-        gen_op_movb_EDX_T1,
-        gen_op_movb_EBX_T1,
+static inline void gen_op_mov_reg_T0(int ot, int reg)
+{
+    gen_op_mov_reg_TN(ot, 0, reg);
+}
+
+static inline void gen_op_mov_reg_T1(int ot, int reg)
+{
+    gen_op_mov_reg_TN(ot, 1, reg);
+}
+
+static inline void gen_op_mov_reg_A0(int size, int reg)
+{
+    switch(size) {
+    case 0:
+        tcg_gen_st16_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_W_OFFSET);
+        break;
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-        gen_op_movb_ESP_T1_wrapper,
-        gen_op_movb_EBP_T1_wrapper,
-        gen_op_movb_ESI_T1_wrapper,
-        gen_op_movb_EDI_T1_wrapper,
-        gen_op_movb_R8_T1,
-        gen_op_movb_R9_T1,
-        gen_op_movb_R10_T1,
-        gen_op_movb_R11_T1,
-        gen_op_movb_R12_T1,
-        gen_op_movb_R13_T1,
-        gen_op_movb_R14_T1,
-        gen_op_movb_R15_T1,
+    case 1:
+        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        /* high part of register set to zero */
+        tcg_gen_movi_tl(cpu_tmp0, 0);
+        tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]) + REG_LH_OFFSET);
+        break;
+    default:
+    case 2:
+        tcg_gen_st_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
+        break;
 #else
 #else
-        gen_op_movh_EAX_T1,
-        gen_op_movh_ECX_T1,
-        gen_op_movh_EDX_T1,
-        gen_op_movh_EBX_T1,
+    default:
+    case 1:
+        tcg_gen_st32_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+        break;
 #endif
 #endif
-    },
-    [OT_WORD] = {
-        DEF_REGS(gen_op_movw_, _T1)
-    },
-    [OT_LONG] = {
-        DEF_REGS(gen_op_movl_, _T1)
-    },
+    }
+}
+
+static inline void gen_op_mov_TN_reg(int ot, int t_index, int reg)
+{
+    switch(ot) {
+    case OT_BYTE:
+        if (reg < 4 X86_64_DEF( || reg >= 8 || x86_64_hregs)) {
+            goto std_case;
+        } else {
+            tcg_gen_ld8u_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg - 4]) + REG_H_OFFSET);
+        }
+        break;
+    default:
+    std_case:
+        tcg_gen_ld_tl(cpu_T[t_index], cpu_env, offsetof(CPUState, regs[reg]));
+        break;
+    }
+}
+
+static inline void gen_op_movl_A0_reg(int reg)
+{
+    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]) + REG_L_OFFSET);
+}
+
+static inline void gen_op_addl_A0_im(int32_t val)
+{
+    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-    [OT_QUAD] = {
-        DEF_REGS(gen_op_movq_, _T1)
-    },
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
 #endif
 #endif
-};
+}
 
 
-static GenOpFunc *gen_op_mov_reg_A0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
-    [0] = {
-        DEF_REGS(gen_op_movw_, _A0)
-    },
-    [1] = {
-        DEF_REGS(gen_op_movl_, _A0)
-    },
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-    [2] = {
-        DEF_REGS(gen_op_movq_, _A0)
-    },
+static inline void gen_op_addq_A0_im(int64_t val)
+{
+    tcg_gen_addi_tl(cpu_A0, cpu_A0, val);
+}
 #endif
 #endif
-};
+    
+static void gen_add_A0_im(DisasContext *s, int val)
+{
+#ifdef TARGET_X86_64
+    if (CODE64(s))
+        gen_op_addq_A0_im(val);
+    else
+#endif
+        gen_op_addl_A0_im(val);
+}
 
 
-static GenOpFunc *gen_op_mov_TN_reg[NB_OP_SIZES][2][CPU_NB_REGS] =
+static inline void gen_op_addl_T0_T1(void)
 {
 {
-    [OT_BYTE] = {
-        {
-            gen_op_movl_T0_EAX,
-            gen_op_movl_T0_ECX,
-            gen_op_movl_T0_EDX,
-            gen_op_movl_T0_EBX,
+    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+}
+
+static inline void gen_op_jmp_T0(void)
+{
+    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, eip));
+}
+
+static inline void gen_op_addw_ESP_im(int32_t val)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]));
+    tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
+    tcg_gen_st16_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]) + REG_W_OFFSET);
+}
+
+static inline void gen_op_addl_ESP_im(int32_t val)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]));
+    tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-            gen_op_movl_T0_ESP_wrapper,
-            gen_op_movl_T0_EBP_wrapper,
-            gen_op_movl_T0_ESI_wrapper,
-            gen_op_movl_T0_EDI_wrapper,
-            gen_op_movl_T0_R8,
-            gen_op_movl_T0_R9,
-            gen_op_movl_T0_R10,
-            gen_op_movl_T0_R11,
-            gen_op_movl_T0_R12,
-            gen_op_movl_T0_R13,
-            gen_op_movl_T0_R14,
-            gen_op_movl_T0_R15,
-#else
-            gen_op_movh_T0_EAX,
-            gen_op_movh_T0_ECX,
-            gen_op_movh_T0_EDX,
-            gen_op_movh_T0_EBX,
+    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
 #endif
 #endif
-        },
-        {
-            gen_op_movl_T1_EAX,
-            gen_op_movl_T1_ECX,
-            gen_op_movl_T1_EDX,
-            gen_op_movl_T1_EBX,
+    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]));
+}
+
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-            gen_op_movl_T1_ESP_wrapper,
-            gen_op_movl_T1_EBP_wrapper,
-            gen_op_movl_T1_ESI_wrapper,
-            gen_op_movl_T1_EDI_wrapper,
-            gen_op_movl_T1_R8,
-            gen_op_movl_T1_R9,
-            gen_op_movl_T1_R10,
-            gen_op_movl_T1_R11,
-            gen_op_movl_T1_R12,
-            gen_op_movl_T1_R13,
-            gen_op_movl_T1_R14,
-            gen_op_movl_T1_R15,
-#else
-            gen_op_movh_T1_EAX,
-            gen_op_movh_T1_ECX,
-            gen_op_movh_T1_EDX,
-            gen_op_movh_T1_EBX,
+static inline void gen_op_addq_ESP_im(int32_t val)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]));
+    tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, val);
+    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[R_ESP]));
+}
 #endif
 #endif
-        },
-    },
-    [OT_WORD] = {
-        {
-            DEF_REGS(gen_op_movl_T0_, )
-        },
-        {
-            DEF_REGS(gen_op_movl_T1_, )
-        },
-    },
-    [OT_LONG] = {
-        {
-            DEF_REGS(gen_op_movl_T0_, )
-        },
-        {
-            DEF_REGS(gen_op_movl_T1_, )
-        },
-    },
+
+static inline void gen_op_set_cc_op(int32_t val)
+{
+    tcg_gen_movi_tl(cpu_tmp0, val);
+    tcg_gen_st32_tl(cpu_tmp0, cpu_env, offsetof(CPUState, cc_op));
+}
+
+static inline void gen_op_addl_A0_reg_sN(int shift, int reg)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+    if (shift != 0) 
+        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
+    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
 #ifdef TARGET_X86_64
 #ifdef TARGET_X86_64
-    [OT_QUAD] = {
-        {
-            DEF_REGS(gen_op_movl_T0_, )
-        },
-        {
-            DEF_REGS(gen_op_movl_T1_, )
-        },
-    },
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
 #endif
 #endif
-};
+}
 
 
-static GenOpFunc *gen_op_movl_A0_reg[CPU_NB_REGS] = {
-    DEF_REGS(gen_op_movl_A0_, )
-};
+static inline void gen_op_movl_A0_seg(int reg)
+{
+    tcg_gen_ld32u_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base) + REG_L_OFFSET);
+}
 
 
-static GenOpFunc *gen_op_addl_A0_reg_sN[4][CPU_NB_REGS] = {
-    [0] = {
-        DEF_REGS(gen_op_addl_A0_, )
-    },
-    [1] = {
-        DEF_REGS(gen_op_addl_A0_, _s1)
-    },
-    [2] = {
-        DEF_REGS(gen_op_addl_A0_, _s2)
-    },
-    [3] = {
-        DEF_REGS(gen_op_addl_A0_, _s3)
-    },
-};
+static inline void gen_op_addl_A0_seg(int reg)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
+    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+#ifdef TARGET_X86_64
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
+#endif
+}
 
 #ifdef TARGET_X86_64
 
 #ifdef TARGET_X86_64
-static GenOpFunc *gen_op_movq_A0_reg[CPU_NB_REGS] = {
-    DEF_REGS(gen_op_movq_A0_, )
-};
+static inline void gen_op_movq_A0_seg(int reg)
+{
+    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, segs[reg].base));
+}
 
 
-static GenOpFunc *gen_op_addq_A0_reg_sN[4][CPU_NB_REGS] = {
-    [0] = {
-        DEF_REGS(gen_op_addq_A0_, )
-    },
-    [1] = {
-        DEF_REGS(gen_op_addq_A0_, _s1)
-    },
-    [2] = {
-        DEF_REGS(gen_op_addq_A0_, _s2)
-    },
-    [3] = {
-        DEF_REGS(gen_op_addq_A0_, _s3)
-    },
-};
+static inline void gen_op_addq_A0_seg(int reg)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, segs[reg].base));
+    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+}
+
+static inline void gen_op_movq_A0_reg(int reg)
+{
+    tcg_gen_ld_tl(cpu_A0, cpu_env, offsetof(CPUState, regs[reg]));
+}
+
+static inline void gen_op_addq_A0_reg_sN(int shift, int reg)
+{
+    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUState, regs[reg]));
+    if (shift != 0) 
+        tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, shift);
+    tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
+}
 #endif
 
 static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
 #endif
 
 static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
@@ -469,17 +560,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
 #endif
 };
 
 #endif
 };
 
-static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
-    NULL,
-    gen_op_orl_T0_T1,
-    NULL,
-    NULL,
-    gen_op_andl_T0_T1,
-    NULL,
-    gen_op_xorl_T0_T1,
-    NULL,
-};
-
 #define DEF_ARITHC(SUFFIX)\
     {\
         gen_op_adcb ## SUFFIX ## _T0_T1_cc,\
 #define DEF_ARITHC(SUFFIX)\
     {\
         gen_op_adcb ## SUFFIX ## _T0_T1_cc,\
@@ -681,133 +761,113 @@ static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
 #endif
 };
 
 #endif
 };
 
-static GenOpFunc *gen_op_lds_T0_A0[3 * 4] = {
-    gen_op_ldsb_raw_T0_A0,
-    gen_op_ldsw_raw_T0_A0,
-    X86_64_ONLY(gen_op_ldsl_raw_T0_A0),
-    NULL,
-#ifndef CONFIG_USER_ONLY
-    gen_op_ldsb_kernel_T0_A0,
-    gen_op_ldsw_kernel_T0_A0,
-    X86_64_ONLY(gen_op_ldsl_kernel_T0_A0),
-    NULL,
-
-    gen_op_ldsb_user_T0_A0,
-    gen_op_ldsw_user_T0_A0,
-    X86_64_ONLY(gen_op_ldsl_user_T0_A0),
-    NULL,
-#endif
-};
-
-static GenOpFunc *gen_op_ldu_T0_A0[3 * 4] = {
-    gen_op_ldub_raw_T0_A0,
-    gen_op_lduw_raw_T0_A0,
-    NULL,
-    NULL,
-
-#ifndef CONFIG_USER_ONLY
-    gen_op_ldub_kernel_T0_A0,
-    gen_op_lduw_kernel_T0_A0,
-    NULL,
-    NULL,
-
-    gen_op_ldub_user_T0_A0,
-    gen_op_lduw_user_T0_A0,
-    NULL,
-    NULL,
-#endif
-};
+static inline void gen_op_lds_T0_A0(int idx)
+{
+    int mem_index = (idx >> 2) - 1;
+    switch(idx & 3) {
+    case 0:
+        tcg_gen_qemu_ld8s(cpu_T[0], cpu_A0, mem_index);
+        break;
+    case 1:
+        tcg_gen_qemu_ld16s(cpu_T[0], cpu_A0, mem_index);
+        break;
+    default:
+    case 2:
+        tcg_gen_qemu_ld32s(cpu_T[0], cpu_A0, mem_index);
+        break;
+    }
+}
 
 /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
 
 /* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
-static GenOpFunc *gen_op_ld_T0_A0[3 * 4] = {
-    gen_op_ldub_raw_T0_A0,
-    gen_op_lduw_raw_T0_A0,
-    gen_op_ldl_raw_T0_A0,
-    X86_64_ONLY(gen_op_ldq_raw_T0_A0),
-
-#ifndef CONFIG_USER_ONLY
-    gen_op_ldub_kernel_T0_A0,
-    gen_op_lduw_kernel_T0_A0,
-    gen_op_ldl_kernel_T0_A0,
-    X86_64_ONLY(gen_op_ldq_kernel_T0_A0),
-
-    gen_op_ldub_user_T0_A0,
-    gen_op_lduw_user_T0_A0,
-    gen_op_ldl_user_T0_A0,
-    X86_64_ONLY(gen_op_ldq_user_T0_A0),
-#endif
-};
-
-static GenOpFunc *gen_op_ld_T1_A0[3 * 4] = {
-    gen_op_ldub_raw_T1_A0,
-    gen_op_lduw_raw_T1_A0,
-    gen_op_ldl_raw_T1_A0,
-    X86_64_ONLY(gen_op_ldq_raw_T1_A0),
-
-#ifndef CONFIG_USER_ONLY
-    gen_op_ldub_kernel_T1_A0,
-    gen_op_lduw_kernel_T1_A0,
-    gen_op_ldl_kernel_T1_A0,
-    X86_64_ONLY(gen_op_ldq_kernel_T1_A0),
-
-    gen_op_ldub_user_T1_A0,
-    gen_op_lduw_user_T1_A0,
-    gen_op_ldl_user_T1_A0,
-    X86_64_ONLY(gen_op_ldq_user_T1_A0),
-#endif
-};
-
-static GenOpFunc *gen_op_st_T0_A0[3 * 4] = {
-    gen_op_stb_raw_T0_A0,
-    gen_op_stw_raw_T0_A0,
-    gen_op_stl_raw_T0_A0,
-    X86_64_ONLY(gen_op_stq_raw_T0_A0),
+static inline void gen_op_ld_T0_A0(int idx)
+{
+    int mem_index = (idx >> 2) - 1;
+    switch(idx & 3) {
+    case 0:
+        tcg_gen_qemu_ld8u(cpu_T[0], cpu_A0, mem_index);
+        break;
+    case 1:
+        tcg_gen_qemu_ld16u(cpu_T[0], cpu_A0, mem_index);
+        break;
+    case 2:
+        tcg_gen_qemu_ld32u(cpu_T[0], cpu_A0, mem_index);
+        break;
+    default:
+    case 3:
+        tcg_gen_qemu_ld64(cpu_T[0], cpu_A0, mem_index);
+        break;
+    }
+}
 
 
-#ifndef CONFIG_USER_ONLY
-    gen_op_stb_kernel_T0_A0,
-    gen_op_stw_kernel_T0_A0,
-    gen_op_stl_kernel_T0_A0,
-    X86_64_ONLY(gen_op_stq_kernel_T0_A0),
-
-    gen_op_stb_user_T0_A0,
-    gen_op_stw_user_T0_A0,
-    gen_op_stl_user_T0_A0,
-    X86_64_ONLY(gen_op_stq_user_T0_A0),
-#endif
-};
+static inline void gen_op_ldu_T0_A0(int idx)
+{
+    gen_op_ld_T0_A0(idx);
+}
 
 
-static GenOpFunc *gen_op_st_T1_A0[3 * 4] = {
-    NULL,
-    gen_op_stw_raw_T1_A0,
-    gen_op_stl_raw_T1_A0,
-    X86_64_ONLY(gen_op_stq_raw_T1_A0),
+static inline void gen_op_ld_T1_A0(int idx)
+{
+    int mem_index = (idx >> 2) - 1;
+    switch(idx & 3) {
+    case 0:
+        tcg_gen_qemu_ld8u(cpu_T[1], cpu_A0, mem_index);
+        break;
+    case 1:
+        tcg_gen_qemu_ld16u(cpu_T[1], cpu_A0, mem_index);
+        break;
+    case 2:
+        tcg_gen_qemu_ld32u(cpu_T[1], cpu_A0, mem_index);
+        break;
+    default:
+    case 3:
+        tcg_gen_qemu_ld64(cpu_T[1], cpu_A0, mem_index);
+        break;
+    }
+}
 
 
-#ifndef CONFIG_USER_ONLY
-    NULL,
-    gen_op_stw_kernel_T1_A0,
-    gen_op_stl_kernel_T1_A0,
-    X86_64_ONLY(gen_op_stq_kernel_T1_A0),
+static inline void gen_op_st_T0_A0(int idx)
+{
+    int mem_index = (idx >> 2) - 1;
+    switch(idx & 3) {
+    case 0:
+        tcg_gen_qemu_st8(cpu_T[0], cpu_A0, mem_index);
+        break;
+    case 1:
+        tcg_gen_qemu_st16(cpu_T[0], cpu_A0, mem_index);
+        break;
+    case 2:
+        tcg_gen_qemu_st32(cpu_T[0], cpu_A0, mem_index);
+        break;
+    default:
+    case 3:
+        tcg_gen_qemu_st64(cpu_T[0], cpu_A0, mem_index);
+        break;
+    }
+}
 
 
-    NULL,
-    gen_op_stw_user_T1_A0,
-    gen_op_stl_user_T1_A0,
-    X86_64_ONLY(gen_op_stq_user_T1_A0),
-#endif
-};
+static inline void gen_op_st_T1_A0(int idx)
+{
+    int mem_index = (idx >> 2) - 1;
+    switch(idx & 3) {
+    case 0:
+        tcg_gen_qemu_st8(cpu_T[1], cpu_A0, mem_index);
+        break;
+    case 1:
+        tcg_gen_qemu_st16(cpu_T[1], cpu_A0, mem_index);
+        break;
+    case 2:
+        tcg_gen_qemu_st32(cpu_T[1], cpu_A0, mem_index);
+        break;
+    default:
+    case 3:
+        tcg_gen_qemu_st64(cpu_T[1], cpu_A0, mem_index);
+        break;
+    }
+}
 
 static inline void gen_jmp_im(target_ulong pc)
 {
 
 static inline void gen_jmp_im(target_ulong pc)
 {
-#ifdef TARGET_X86_64
-    if (pc == (uint32_t)pc) {
-        gen_op_movl_eip_im(pc);
-    } else if (pc == (int32_t)pc) {
-        gen_op_movq_eip_im(pc);
-    } else {
-        gen_op_movq_eip_im64(pc >> 32, pc);
-    }
-#else
-    gen_op_movl_eip_im(pc);
-#endif
+    tcg_gen_movi_tl(cpu_tmp0, pc);
+    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, eip));
 }
 
 static inline void gen_string_movl_A0_ESI(DisasContext *s)
 }
 
 static inline void gen_string_movl_A0_ESI(DisasContext *s)
@@ -818,10 +878,10 @@ static inline void gen_string_movl_A0_ESI(DisasContext *s)
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
         if (override >= 0) {
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
         if (override >= 0) {
-            gen_op_movq_A0_seg(offsetof(CPUX86State,segs[override].base));
-            gen_op_addq_A0_reg_sN[0][R_ESI]();
+            gen_op_movq_A0_seg(override);
+            gen_op_addq_A0_reg_sN(0, R_ESI);
         } else {
         } else {
-            gen_op_movq_A0_reg[R_ESI]();
+            gen_op_movq_A0_reg(R_ESI);
         }
     } else
 #endif
         }
     } else
 #endif
@@ -830,18 +890,18 @@ static inline void gen_string_movl_A0_ESI(DisasContext *s)
         if (s->addseg && override < 0)
             override = R_DS;
         if (override >= 0) {
         if (s->addseg && override < 0)
             override = R_DS;
         if (override >= 0) {
-            gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));
-            gen_op_addl_A0_reg_sN[0][R_ESI]();
+            gen_op_movl_A0_seg(override);
+            gen_op_addl_A0_reg_sN(0, R_ESI);
         } else {
         } else {
-            gen_op_movl_A0_reg[R_ESI]();
+            gen_op_movl_A0_reg(R_ESI);
         }
     } else {
         /* 16 address, always override */
         if (override < 0)
             override = R_DS;
         }
     } else {
         /* 16 address, always override */
         if (override < 0)
             override = R_DS;
-        gen_op_movl_A0_reg[R_ESI]();
+        gen_op_movl_A0_reg(R_ESI);
         gen_op_andl_A0_ffff();
         gen_op_andl_A0_ffff();
-        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
+        gen_op_addl_A0_seg(override);
     }
 }
 
     }
 }
 
@@ -849,20 +909,20 @@ static inline void gen_string_movl_A0_EDI(DisasContext *s)
 {
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
 {
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
-        gen_op_movq_A0_reg[R_EDI]();
+        gen_op_movq_A0_reg(R_EDI);
     } else
 #endif
     if (s->aflag) {
         if (s->addseg) {
     } else
 #endif
     if (s->aflag) {
         if (s->addseg) {
-            gen_op_movl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
-            gen_op_addl_A0_reg_sN[0][R_EDI]();
+            gen_op_movl_A0_seg(R_ES);
+            gen_op_addl_A0_reg_sN(0, R_EDI);
         } else {
         } else {
-            gen_op_movl_A0_reg[R_EDI]();
+            gen_op_movl_A0_reg(R_EDI);
         }
     } else {
         }
     } else {
-        gen_op_movl_A0_reg[R_EDI]();
+        gen_op_movl_A0_reg(R_EDI);
         gen_op_andl_A0_ffff();
         gen_op_andl_A0_ffff();
-        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
+        gen_op_addl_A0_seg(R_ES);
     }
 }
 
     }
 }
 
@@ -958,9 +1018,9 @@ static void gen_check_io(DisasContext *s, int ot, int use_dx, target_ulong cur_e
 static inline void gen_movs(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
 static inline void gen_movs(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
-    gen_op_ld_T0_A0[ot + s->mem_index]();
+    gen_op_ld_T0_A0(ot + s->mem_index);
     gen_string_movl_A0_EDI(s);
     gen_string_movl_A0_EDI(s);
-    gen_op_st_T0_A0[ot + s->mem_index]();
+    gen_op_st_T0_A0(ot + s->mem_index);
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
@@ -1002,9 +1062,9 @@ static int gen_jz_ecx_string(DisasContext *s, target_ulong next_eip)
 
 static inline void gen_stos(DisasContext *s, int ot)
 {
 
 static inline void gen_stos(DisasContext *s, int ot)
 {
-    gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
+    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
     gen_string_movl_A0_EDI(s);
     gen_string_movl_A0_EDI(s);
-    gen_op_st_T0_A0[ot + s->mem_index]();
+    gen_op_st_T0_A0(ot + s->mem_index);
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
@@ -1021,8 +1081,8 @@ static inline void gen_stos(DisasContext *s, int ot)
 static inline void gen_lods(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
 static inline void gen_lods(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
-    gen_op_ld_T0_A0[ot + s->mem_index]();
-    gen_op_mov_reg_T0[ot][R_EAX]();
+    gen_op_ld_T0_A0(ot + s->mem_index);
+    gen_op_mov_reg_T0(ot, R_EAX);
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
@@ -1038,9 +1098,9 @@ static inline void gen_lods(DisasContext *s, int ot)
 
 static inline void gen_scas(DisasContext *s, int ot)
 {
 
 static inline void gen_scas(DisasContext *s, int ot)
 {
-    gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
+    gen_op_mov_TN_reg(OT_LONG, 0, R_EAX);
     gen_string_movl_A0_EDI(s);
     gen_string_movl_A0_EDI(s);
-    gen_op_ld_T1_A0[ot + s->mem_index]();
+    gen_op_ld_T1_A0(ot + s->mem_index);
     gen_op_cmpl_T0_T1_cc();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     gen_op_cmpl_T0_T1_cc();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
@@ -1058,9 +1118,9 @@ static inline void gen_scas(DisasContext *s, int ot)
 static inline void gen_cmps(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
 static inline void gen_cmps(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
-    gen_op_ld_T0_A0[ot + s->mem_index]();
+    gen_op_ld_T0_A0(ot + s->mem_index);
     gen_string_movl_A0_EDI(s);
     gen_string_movl_A0_EDI(s);
-    gen_op_ld_T1_A0[ot + s->mem_index]();
+    gen_op_ld_T1_A0(ot + s->mem_index);
     gen_op_cmpl_T0_T1_cc();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     gen_op_cmpl_T0_T1_cc();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
@@ -1082,9 +1142,9 @@ static inline void gen_ins(DisasContext *s, int ot)
 {
     gen_string_movl_A0_EDI(s);
     gen_op_movl_T0_0();
 {
     gen_string_movl_A0_EDI(s);
     gen_op_movl_T0_0();
-    gen_op_st_T0_A0[ot + s->mem_index]();
+    gen_op_st_T0_A0(ot + s->mem_index);
     gen_op_in_DX_T0[ot]();
     gen_op_in_DX_T0[ot]();
-    gen_op_st_T0_A0[ot + s->mem_index]();
+    gen_op_st_T0_A0(ot + s->mem_index);
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     if (s->aflag == 2) {
@@ -1101,7 +1161,7 @@ static inline void gen_ins(DisasContext *s, int ot)
 static inline void gen_outs(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
 static inline void gen_outs(DisasContext *s, int ot)
 {
     gen_string_movl_A0_ESI(s);
-    gen_op_ld_T0_A0[ot + s->mem_index]();
+    gen_op_ld_T0_A0(ot + s->mem_index);
     gen_op_out_DX_T0[ot]();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
     gen_op_out_DX_T0[ot]();
     gen_op_movl_T0_Dshift[ot]();
 #ifdef TARGET_X86_64
@@ -1320,9 +1380,9 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
     GenOpFunc *gen_update_cc;
 
     if (d != OR_TMP0) {
     GenOpFunc *gen_update_cc;
 
     if (d != OR_TMP0) {
-        gen_op_mov_TN_reg[ot][0][d]();
+        gen_op_mov_TN_reg(ot, 0, d);
     } else {
     } else {
-        gen_op_ld_T0_A0[ot + s1->mem_index]();
+        gen_op_ld_T0_A0(ot + s1->mem_index);
     }
     switch(op) {
     case OP_ADCL:
     }
     switch(op) {
     case OP_ADCL:
@@ -1331,7 +1391,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
             gen_op_set_cc_op(s1->cc_op);
         if (d != OR_TMP0) {
             gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
             gen_op_set_cc_op(s1->cc_op);
         if (d != OR_TMP0) {
             gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
-            gen_op_mov_reg_T0[ot][d]();
+            gen_op_mov_reg_T0(ot, d);
         } else {
             gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL]();
         }
         } else {
             gen_op_arithc_mem_T0_T1_cc[ot + s1->mem_index][op - OP_ADCL]();
         }
@@ -1343,15 +1403,23 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
         gen_update_cc = gen_op_update2_cc;
         break;
     case OP_SUBL:
         gen_update_cc = gen_op_update2_cc;
         break;
     case OP_SUBL:
-        gen_op_subl_T0_T1();
+        tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
         s1->cc_op = CC_OP_SUBB + ot;
         gen_update_cc = gen_op_update2_cc;
         break;
     default:
     case OP_ANDL:
         s1->cc_op = CC_OP_SUBB + ot;
         gen_update_cc = gen_op_update2_cc;
         break;
     default:
     case OP_ANDL:
+        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+        s1->cc_op = CC_OP_LOGICB + ot;
+        gen_update_cc = gen_op_update1_cc;
+        break;
     case OP_ORL:
     case OP_ORL:
+        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
+        s1->cc_op = CC_OP_LOGICB + ot;
+        gen_update_cc = gen_op_update1_cc;
+        break;
     case OP_XORL:
     case OP_XORL:
-        gen_op_arith_T0_T1_cc[op]();
+        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
         s1->cc_op = CC_OP_LOGICB + ot;
         gen_update_cc = gen_op_update1_cc;
         break;
         s1->cc_op = CC_OP_LOGICB + ot;
         gen_update_cc = gen_op_update1_cc;
         break;
@@ -1363,9 +1431,9 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
     }
     if (op != OP_CMPL) {
         if (d != OR_TMP0)
     }
     if (op != OP_CMPL) {
         if (d != OR_TMP0)
-            gen_op_mov_reg_T0[ot][d]();
+            gen_op_mov_reg_T0(ot, d);
         else
         else
-            gen_op_st_T0_A0[ot + s1->mem_index]();
+            gen_op_st_T0_A0(ot + s1->mem_index);
     }
     /* the flags update must happen after the memory write (precise
        exception support) */
     }
     /* the flags update must happen after the memory write (precise
        exception support) */
@@ -1378,9 +1446,9 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
 static void gen_inc(DisasContext *s1, int ot, int d, int c)
 {
     if (d != OR_TMP0)
 static void gen_inc(DisasContext *s1, int ot, int d, int c)
 {
     if (d != OR_TMP0)
-        gen_op_mov_TN_reg[ot][0][d]();
+        gen_op_mov_TN_reg(ot, 0, d);
     else
     else
-        gen_op_ld_T0_A0[ot + s1->mem_index]();
+        gen_op_ld_T0_A0(ot + s1->mem_index);
     if (s1->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s1->cc_op);
     if (c > 0) {
     if (s1->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s1->cc_op);
     if (c > 0) {
@@ -1391,20 +1459,20 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c)
         s1->cc_op = CC_OP_DECB + ot;
     }
     if (d != OR_TMP0)
         s1->cc_op = CC_OP_DECB + ot;
     }
     if (d != OR_TMP0)
-        gen_op_mov_reg_T0[ot][d]();
+        gen_op_mov_reg_T0(ot, d);
     else
     else
-        gen_op_st_T0_A0[ot + s1->mem_index]();
+        gen_op_st_T0_A0(ot + s1->mem_index);
     gen_op_update_inc_cc();
 }
 
 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
 {
     if (d != OR_TMP0)
     gen_op_update_inc_cc();
 }
 
 static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
 {
     if (d != OR_TMP0)
-        gen_op_mov_TN_reg[ot][0][d]();
+        gen_op_mov_TN_reg(ot, 0, d);
     else
     else
-        gen_op_ld_T0_A0[ot + s1->mem_index]();
+        gen_op_ld_T0_A0(ot + s1->mem_index);
     if (s != OR_TMP1)
     if (s != OR_TMP1)
-        gen_op_mov_TN_reg[ot][1][s]();
+        gen_op_mov_TN_reg(ot, 1, s);
     /* for zero counts, flags are not updated, so must do it dynamically */
     if (s1->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s1->cc_op);
     /* for zero counts, flags are not updated, so must do it dynamically */
     if (s1->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s1->cc_op);
@@ -1414,7 +1482,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
     else
         gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op]();
     if (d != OR_TMP0)
     else
         gen_op_shift_mem_T0_T1_cc[ot + s1->mem_index][op]();
     if (d != OR_TMP0)
-        gen_op_mov_reg_T0[ot][d]();
+        gen_op_mov_reg_T0(ot, d);
     s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 }
 
     s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
 }
 
@@ -1487,27 +1555,21 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
                 disp += s->popl_esp_hack;
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
                 disp += s->popl_esp_hack;
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
-                gen_op_movq_A0_reg[base]();
+                gen_op_movq_A0_reg(base);
                 if (disp != 0) {
                 if (disp != 0) {
-                    if ((int32_t)disp == disp)
-                        gen_op_addq_A0_im(disp);
-                    else
-                        gen_op_addq_A0_im64(disp >> 32, disp);
+                    gen_op_addq_A0_im(disp);
                 }
             } else
 #endif
             {
                 }
             } else
 #endif
             {
-                gen_op_movl_A0_reg[base]();
+                gen_op_movl_A0_reg(base);
                 if (disp != 0)
                     gen_op_addl_A0_im(disp);
             }
         } else {
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
                 if (disp != 0)
                     gen_op_addl_A0_im(disp);
             }
         } else {
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
-                if ((int32_t)disp == disp)
-                    gen_op_movq_A0_im(disp);
-                else
-                    gen_op_movq_A0_im64(disp >> 32, disp);
+                gen_op_movq_A0_im(disp);
             } else
 #endif
             {
             } else
 #endif
             {
@@ -1518,11 +1580,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
         if (havesib && (index != 4 || scale != 0)) {
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
         if (havesib && (index != 4 || scale != 0)) {
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
-                gen_op_addq_A0_reg_sN[scale][index]();
+                gen_op_addq_A0_reg_sN(scale, index);
             } else
 #endif
             {
             } else
 #endif
             {
-                gen_op_addl_A0_reg_sN[scale][index]();
+                gen_op_addl_A0_reg_sN(scale, index);
             }
         }
         if (must_add_seg) {
             }
         }
         if (must_add_seg) {
@@ -1534,11 +1596,11 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
             }
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
             }
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
-                gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
+                gen_op_addq_A0_seg(override);
             } else
 #endif
             {
             } else
 #endif
             {
-                gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
+                gen_op_addl_A0_seg(override);
             }
         }
     } else {
             }
         }
     } else {
@@ -1565,33 +1627,33 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
         }
         switch(rm) {
         case 0:
         }
         switch(rm) {
         case 0:
-            gen_op_movl_A0_reg[R_EBX]();
-            gen_op_addl_A0_reg_sN[0][R_ESI]();
+            gen_op_movl_A0_reg(R_EBX);
+            gen_op_addl_A0_reg_sN(0, R_ESI);
             break;
         case 1:
             break;
         case 1:
-            gen_op_movl_A0_reg[R_EBX]();
-            gen_op_addl_A0_reg_sN[0][R_EDI]();
+            gen_op_movl_A0_reg(R_EBX);
+            gen_op_addl_A0_reg_sN(0, R_EDI);
             break;
         case 2:
             break;
         case 2:
-            gen_op_movl_A0_reg[R_EBP]();
-            gen_op_addl_A0_reg_sN[0][R_ESI]();
+            gen_op_movl_A0_reg(R_EBP);
+            gen_op_addl_A0_reg_sN(0, R_ESI);
             break;
         case 3:
             break;
         case 3:
-            gen_op_movl_A0_reg[R_EBP]();
-            gen_op_addl_A0_reg_sN[0][R_EDI]();
+            gen_op_movl_A0_reg(R_EBP);
+            gen_op_addl_A0_reg_sN(0, R_EDI);
             break;
         case 4:
             break;
         case 4:
-            gen_op_movl_A0_reg[R_ESI]();
+            gen_op_movl_A0_reg(R_ESI);
             break;
         case 5:
             break;
         case 5:
-            gen_op_movl_A0_reg[R_EDI]();
+            gen_op_movl_A0_reg(R_EDI);
             break;
         case 6:
             break;
         case 6:
-            gen_op_movl_A0_reg[R_EBP]();
+            gen_op_movl_A0_reg(R_EBP);
             break;
         default:
         case 7:
             break;
         default:
         case 7:
-            gen_op_movl_A0_reg[R_EBX]();
+            gen_op_movl_A0_reg(R_EBX);
             break;
         }
         if (disp != 0)
             break;
         }
         if (disp != 0)
@@ -1605,7 +1667,7 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
                 else
                     override = R_DS;
             }
                 else
                     override = R_DS;
             }
-            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
+            gen_op_addl_A0_seg(override);
         }
     }
 
         }
     }
 
@@ -1680,11 +1742,11 @@ static void gen_add_A0_ds_seg(DisasContext *s)
     if (must_add_seg) {
 #ifdef TARGET_X86_64
         if (CODE64(s)) {
     if (must_add_seg) {
 #ifdef TARGET_X86_64
         if (CODE64(s)) {
-            gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
+            gen_op_addq_A0_seg(override);
         } else
 #endif
         {
         } else
 #endif
         {
-            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
+            gen_op_addl_A0_seg(override);
         }
     }
 }
         }
     }
 }
@@ -1700,23 +1762,23 @@ static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_s
     if (mod == 3) {
         if (is_store) {
             if (reg != OR_TMP0)
     if (mod == 3) {
         if (is_store) {
             if (reg != OR_TMP0)
-                gen_op_mov_TN_reg[ot][0][reg]();
-            gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_TN_reg(ot, 0, reg);
+            gen_op_mov_reg_T0(ot, rm);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
             if (reg != OR_TMP0)
             if (reg != OR_TMP0)
-                gen_op_mov_reg_T0[ot][reg]();
+                gen_op_mov_reg_T0(ot, reg);
         }
     } else {
         gen_lea_modrm(s, modrm, &opreg, &disp);
         if (is_store) {
             if (reg != OR_TMP0)
         }
     } else {
         gen_lea_modrm(s, modrm, &opreg, &disp);
         if (is_store) {
             if (reg != OR_TMP0)
-                gen_op_mov_TN_reg[ot][0][reg]();
-            gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_mov_TN_reg(ot, 0, reg);
+            gen_op_st_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
             if (reg != OR_TMP0)
             if (reg != OR_TMP0)
-                gen_op_mov_reg_T0[ot][reg]();
+                gen_op_mov_reg_T0(ot, reg);
         }
     }
 }
         }
     }
 }
@@ -1762,13 +1824,9 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip)
     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
-        if (tb_num == 0)
-            gen_op_goto_tb0(TBPARAM(tb));
-        else
-            gen_op_goto_tb1(TBPARAM(tb));
+        tcg_gen_goto_tb(tb_num);
         gen_jmp_im(eip);
         gen_jmp_im(eip);
-        gen_op_movl_T0_im((long)tb + tb_num);
-        gen_op_exit_tb();
+        tcg_gen_exit_tb((long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(eip);
@@ -1995,11 +2053,7 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, target_ulong cur_eip)
     }
 }
 
     }
 }
 
-#ifdef TARGET_X86_64
-#define SVM_movq_T1_im(x) gen_op_movq_T1_im64((x) >> 32, x)
-#else
-#define SVM_movq_T1_im(x) gen_op_movl_T1_im(x)
-#endif
+#define SVM_movq_T1_im(x) gen_movtl_T1_im(x)
 
 static inline int
 gen_svm_check_io(DisasContext *s, target_ulong pc_start, uint64_t type)
 
 static inline int
 gen_svm_check_io(DisasContext *s, target_ulong pc_start, uint64_t type)
@@ -2091,26 +2145,13 @@ static inline void gen_stack_update(DisasContext *s, int addend)
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
-        if (addend == 8)
-            gen_op_addq_ESP_8();
-        else
-            gen_op_addq_ESP_im(addend);
+        gen_op_addq_ESP_im(addend);
     } else
 #endif
     if (s->ss32) {
     } else
 #endif
     if (s->ss32) {
-        if (addend == 2)
-            gen_op_addl_ESP_2();
-        else if (addend == 4)
-            gen_op_addl_ESP_4();
-        else
-            gen_op_addl_ESP_im(addend);
+        gen_op_addl_ESP_im(addend);
     } else {
     } else {
-        if (addend == 2)
-            gen_op_addw_ESP_2();
-        else if (addend == 4)
-            gen_op_addw_ESP_4();
-        else
-            gen_op_addw_ESP_im(addend);
+        gen_op_addw_ESP_im(addend);
     }
 }
 
     }
 }
 
@@ -2119,38 +2160,38 @@ static void gen_push_T0(DisasContext *s)
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
-        gen_op_movq_A0_reg[R_ESP]();
+        gen_op_movq_A0_reg(R_ESP);
         if (s->dflag) {
         if (s->dflag) {
-            gen_op_subq_A0_8();
-            gen_op_st_T0_A0[OT_QUAD + s->mem_index]();
+            gen_op_addq_A0_im(-8);
+            gen_op_st_T0_A0(OT_QUAD + s->mem_index);
         } else {
         } else {
-            gen_op_subq_A0_2();
-            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
+            gen_op_addq_A0_im(-2);
+            gen_op_st_T0_A0(OT_WORD + s->mem_index);
         }
         }
-        gen_op_movq_ESP_A0();
+        gen_op_mov_reg_A0(2, R_ESP);
     } else
 #endif
     {
     } else
 #endif
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (!s->dflag)
         if (!s->dflag)
-            gen_op_subl_A0_2();
+            gen_op_addl_A0_im(-2);
         else
         else
-            gen_op_subl_A0_4();
+            gen_op_addl_A0_im(-4);
         if (s->ss32) {
             if (s->addseg) {
                 gen_op_movl_T1_A0();
         if (s->ss32) {
             if (s->addseg) {
                 gen_op_movl_T1_A0();
-                gen_op_addl_A0_SS();
+                gen_op_addl_A0_seg(R_SS);
             }
         } else {
             gen_op_andl_A0_ffff();
             gen_op_movl_T1_A0();
             }
         } else {
             gen_op_andl_A0_ffff();
             gen_op_movl_T1_A0();
-            gen_op_addl_A0_SS();
+            gen_op_addl_A0_seg(R_SS);
         }
         }
-        gen_op_st_T0_A0[s->dflag + 1 + s->mem_index]();
+        gen_op_st_T0_A0(s->dflag + 1 + s->mem_index);
         if (s->ss32 && !s->addseg)
         if (s->ss32 && !s->addseg)
-            gen_op_movl_ESP_A0();
+            gen_op_mov_reg_A0(1, R_ESP);
         else
         else
-            gen_op_mov_reg_T1[s->ss32 + 1][R_ESP]();
+            gen_op_mov_reg_T1(s->ss32 + 1, R_ESP);
     }
 }
 
     }
 }
 
@@ -2160,35 +2201,35 @@ static void gen_push_T1(DisasContext *s)
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
-        gen_op_movq_A0_reg[R_ESP]();
+        gen_op_movq_A0_reg(R_ESP);
         if (s->dflag) {
         if (s->dflag) {
-            gen_op_subq_A0_8();
-            gen_op_st_T1_A0[OT_QUAD + s->mem_index]();
+            gen_op_addq_A0_im(-8);
+            gen_op_st_T1_A0(OT_QUAD + s->mem_index);
         } else {
         } else {
-            gen_op_subq_A0_2();
-            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
+            gen_op_addq_A0_im(-2);
+            gen_op_st_T0_A0(OT_WORD + s->mem_index);
         }
         }
-        gen_op_movq_ESP_A0();
+        gen_op_mov_reg_A0(2, R_ESP);
     } else
 #endif
     {
     } else
 #endif
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (!s->dflag)
         if (!s->dflag)
-            gen_op_subl_A0_2();
+            gen_op_addl_A0_im(-2);
         else
         else
-            gen_op_subl_A0_4();
+            gen_op_addl_A0_im(-4);
         if (s->ss32) {
             if (s->addseg) {
         if (s->ss32) {
             if (s->addseg) {
-                gen_op_addl_A0_SS();
+                gen_op_addl_A0_seg(R_SS);
             }
         } else {
             gen_op_andl_A0_ffff();
             }
         } else {
             gen_op_andl_A0_ffff();
-            gen_op_addl_A0_SS();
+            gen_op_addl_A0_seg(R_SS);
         }
         }
-        gen_op_st_T1_A0[s->dflag + 1 + s->mem_index]();
+        gen_op_st_T1_A0(s->dflag + 1 + s->mem_index);
 
         if (s->ss32 && !s->addseg)
 
         if (s->ss32 && !s->addseg)
-            gen_op_movl_ESP_A0();
+            gen_op_mov_reg_A0(1, R_ESP);
         else
             gen_stack_update(s, (-2) << s->dflag);
     }
         else
             gen_stack_update(s, (-2) << s->dflag);
     }
@@ -2199,20 +2240,20 @@ static void gen_pop_T0(DisasContext *s)
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
 {
 #ifdef TARGET_X86_64
     if (CODE64(s)) {
-        gen_op_movq_A0_reg[R_ESP]();
-        gen_op_ld_T0_A0[(s->dflag ? OT_QUAD : OT_WORD) + s->mem_index]();
+        gen_op_movq_A0_reg(R_ESP);
+        gen_op_ld_T0_A0((s->dflag ? OT_QUAD : OT_WORD) + s->mem_index);
     } else
 #endif
     {
     } else
 #endif
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (s->ss32) {
             if (s->addseg)
         if (s->ss32) {
             if (s->addseg)
-                gen_op_addl_A0_SS();
+                gen_op_addl_A0_seg(R_SS);
         } else {
             gen_op_andl_A0_ffff();
         } else {
             gen_op_andl_A0_ffff();
-            gen_op_addl_A0_SS();
+            gen_op_addl_A0_seg(R_SS);
         }
         }
-        gen_op_ld_T0_A0[s->dflag + 1 + s->mem_index]();
+        gen_op_ld_T0_A0(s->dflag + 1 + s->mem_index);
     }
 }
 
     }
 }
 
@@ -2230,53 +2271,53 @@ static void gen_pop_update(DisasContext *s)
 
 static void gen_stack_A0(DisasContext *s)
 {
 
 static void gen_stack_A0(DisasContext *s)
 {
-    gen_op_movl_A0_ESP();
+    gen_op_movl_A0_reg(R_ESP);
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     if (s->addseg)
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     if (s->addseg)
-        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
+        gen_op_addl_A0_seg(R_SS);
 }
 
 /* NOTE: wrap around in 16 bit not fully handled */
 static void gen_pusha(DisasContext *s)
 {
     int i;
 }
 
 /* NOTE: wrap around in 16 bit not fully handled */
 static void gen_pusha(DisasContext *s)
 {
     int i;
-    gen_op_movl_A0_ESP();
+    gen_op_movl_A0_reg(R_ESP);
     gen_op_addl_A0_im(-16 <<  s->dflag);
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     if (s->addseg)
     gen_op_addl_A0_im(-16 <<  s->dflag);
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     if (s->addseg)
-        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
+        gen_op_addl_A0_seg(R_SS);
     for(i = 0;i < 8; i++) {
     for(i = 0;i < 8; i++) {
-        gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
-        gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
+        gen_op_mov_TN_reg(OT_LONG, 0, 7 - i);
+        gen_op_st_T0_A0(OT_WORD + s->dflag + s->mem_index);
         gen_op_addl_A0_im(2 <<  s->dflag);
     }
         gen_op_addl_A0_im(2 <<  s->dflag);
     }
-    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
+    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
 }
 
 /* NOTE: wrap around in 16 bit not fully handled */
 static void gen_popa(DisasContext *s)
 {
     int i;
 }
 
 /* NOTE: wrap around in 16 bit not fully handled */
 static void gen_popa(DisasContext *s)
 {
     int i;
-    gen_op_movl_A0_ESP();
+    gen_op_movl_A0_reg(R_ESP);
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     gen_op_addl_T1_im(16 <<  s->dflag);
     if (s->addseg)
     if (!s->ss32)
         gen_op_andl_A0_ffff();
     gen_op_movl_T1_A0();
     gen_op_addl_T1_im(16 <<  s->dflag);
     if (s->addseg)
-        gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
+        gen_op_addl_A0_seg(R_SS);
     for(i = 0;i < 8; i++) {
         /* ESP is not reloaded */
         if (i != 3) {
     for(i = 0;i < 8; i++) {
         /* ESP is not reloaded */
         if (i != 3) {
-            gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
-            gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
+            gen_op_ld_T0_A0(OT_WORD + s->dflag + s->mem_index);
+            gen_op_mov_reg_T0(OT_WORD + s->dflag, 7 - i);
         }
         gen_op_addl_A0_im(2 <<  s->dflag);
     }
         }
         gen_op_addl_A0_im(2 <<  s->dflag);
     }
-    gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
+    gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
 }
 
 static void gen_enter(DisasContext *s, int esp_addend, int level)
 }
 
 static void gen_enter(DisasContext *s, int esp_addend, int level)
@@ -2289,41 +2330,41 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
         ot = s->dflag ? OT_QUAD : OT_WORD;
         opsize = 1 << ot;
 
         ot = s->dflag ? OT_QUAD : OT_WORD;
         opsize = 1 << ot;
 
-        gen_op_movl_A0_ESP();
+        gen_op_movl_A0_reg(R_ESP);
         gen_op_addq_A0_im(-opsize);
         gen_op_movl_T1_A0();
 
         /* push bp */
         gen_op_addq_A0_im(-opsize);
         gen_op_movl_T1_A0();
 
         /* push bp */
-        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
-        gen_op_st_T0_A0[ot + s->mem_index]();
+        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
+        gen_op_st_T0_A0(ot + s->mem_index);
         if (level) {
             gen_op_enter64_level(level, (ot == OT_QUAD));
         }
         if (level) {
             gen_op_enter64_level(level, (ot == OT_QUAD));
         }
-        gen_op_mov_reg_T1[ot][R_EBP]();
+        gen_op_mov_reg_T1(ot, R_EBP);
         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
-        gen_op_mov_reg_T1[OT_QUAD][R_ESP]();
+        gen_op_mov_reg_T1(OT_QUAD, R_ESP);
     } else
 #endif
     {
         ot = s->dflag + OT_WORD;
         opsize = 2 << s->dflag;
 
     } else
 #endif
     {
         ot = s->dflag + OT_WORD;
         opsize = 2 << s->dflag;
 
-        gen_op_movl_A0_ESP();
+        gen_op_movl_A0_reg(R_ESP);
         gen_op_addl_A0_im(-opsize);
         if (!s->ss32)
             gen_op_andl_A0_ffff();
         gen_op_movl_T1_A0();
         if (s->addseg)
         gen_op_addl_A0_im(-opsize);
         if (!s->ss32)
             gen_op_andl_A0_ffff();
         gen_op_movl_T1_A0();
         if (s->addseg)
-            gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
+            gen_op_addl_A0_seg(R_SS);
         /* push bp */
         /* push bp */
-        gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
-        gen_op_st_T0_A0[ot + s->mem_index]();
+        gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
+        gen_op_st_T0_A0(ot + s->mem_index);
         if (level) {
             gen_op_enter_level(level, s->dflag);
         }
         if (level) {
             gen_op_enter_level(level, s->dflag);
         }
-        gen_op_mov_reg_T1[ot][R_EBP]();
+        gen_op_mov_reg_T1(ot, R_EBP);
         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
         gen_op_addl_T1_im( -esp_addend + (-opsize * level) );
-        gen_op_mov_reg_T1[OT_WORD + s->ss32][R_ESP]();
+        gen_op_mov_reg_T1(OT_WORD + s->ss32, R_ESP);
     }
 }
 
     }
 }
 
@@ -2371,8 +2412,7 @@ static void gen_eob(DisasContext *s)
     } else if (s->tf) {
        gen_op_single_step();
     } else {
     } else if (s->tf) {
        gen_op_single_step();
     } else {
-        gen_op_movl_T0_0();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     s->is_jmp = 3;
 }
     }
     s->is_jmp = 3;
 }
@@ -2399,42 +2439,6 @@ static void gen_jmp(DisasContext *s, target_ulong eip)
     gen_jmp_tb(s, eip, 0);
 }
 
     gen_jmp_tb(s, eip, 0);
 }
 
-static void gen_movtl_T0_im(target_ulong val)
-{
-#ifdef TARGET_X86_64
-    if ((int32_t)val == val) {
-        gen_op_movl_T0_im(val);
-    } else {
-        gen_op_movq_T0_im64(val >> 32, val);
-    }
-#else
-    gen_op_movl_T0_im(val);
-#endif
-}
-
-static void gen_movtl_T1_im(target_ulong val)
-{
-#ifdef TARGET_X86_64
-    if ((int32_t)val == val) {
-        gen_op_movl_T1_im(val);
-    } else {
-        gen_op_movq_T1_im64(val >> 32, val);
-    }
-#else
-    gen_op_movl_T1_im(val);
-#endif
-}
-
-static void gen_add_A0_im(DisasContext *s, int val)
-{
-#ifdef TARGET_X86_64
-    if (CODE64(s))
-        gen_op_addq_A0_im(val);
-    else
-#endif
-        gen_op_addl_A0_im(val);
-}
-
 static GenOpFunc1 *gen_ldq_env_A0[3] = {
     gen_op_ldq_raw_env_A0,
 #ifndef CONFIG_USER_ONLY
 static GenOpFunc1 *gen_ldq_env_A0[3] = {
     gen_op_ldq_raw_env_A0,
 #ifndef CONFIG_USER_ONLY
@@ -2764,7 +2768,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
         case 0x210: /* movss xmm, ea */
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         case 0x210: /* movss xmm, ea */
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
+                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                 gen_op_movl_T0_0();
                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
                 gen_op_movl_T0_0();
                 gen_op_movl_env_T0(offsetof(CPUX86State,xmm_regs[reg].XMM_L(1)));
@@ -2921,7 +2925,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 gen_op_movl_T0_env(offsetof(CPUX86State,xmm_regs[reg].XMM_L(0)));
-                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
+                gen_op_st_T0_A0(OT_LONG + s->mem_index);
             } else {
                 rm = (modrm & 7) | REX_B(s);
                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
             } else {
                 rm = (modrm & 7) | REX_B(s);
                 gen_op_movl(offsetof(CPUX86State,xmm_regs[rm].XMM_L(0)),
@@ -2991,12 +2995,12 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
         case 0x050: /* movmskps */
             rm = (modrm & 7) | REX_B(s);
             gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
         case 0x050: /* movmskps */
             rm = (modrm & 7) | REX_B(s);
             gen_op_movmskps(offsetof(CPUX86State,xmm_regs[rm]));
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             break;
         case 0x150: /* movmskpd */
             rm = (modrm & 7) | REX_B(s);
             gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
             break;
         case 0x150: /* movmskpd */
             rm = (modrm & 7) | REX_B(s);
             gen_op_movmskpd(offsetof(CPUX86State,xmm_regs[rm]));
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             break;
         case 0x02a: /* cvtpi2ps */
         case 0x12a: /* cvtpi2pd */
             break;
         case 0x02a: /* cvtpi2ps */
         case 0x12a: /* cvtpi2pd */
@@ -3066,7 +3070,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                 if ((b >> 8) & 1) {
                     gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
                 } else {
                 if ((b >> 8) & 1) {
                     gen_ldq_env_A0[s->mem_index >> 2](offsetof(CPUX86State,xmm_t0.XMM_Q(0)));
                 } else {
-                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
+                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                     gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                 }
                 op2_offset = offsetof(CPUX86State,xmm_t0);
                     gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                 }
                 op2_offset = offsetof(CPUX86State,xmm_t0);
@@ -3076,7 +3080,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
             }
             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
                           (b & 1) * 4](op2_offset);
             }
             sse_op_table3[(s->dflag == 2) * 2 + ((b >> 8) - 2) + 4 +
                           (b & 1) * 4](op2_offset);
-            gen_op_mov_reg_T0[ot][reg]();
+            gen_op_mov_reg_T0(ot, reg);
             break;
         case 0xc4: /* pinsrw */
         case 0x1c4:
             break;
         case 0xc4: /* pinsrw */
         case 0x1c4:
@@ -3106,7 +3110,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                 gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
             }
             reg = ((modrm >> 3) & 7) | rex_r;
                 gen_op_pextrw_mmx(offsetof(CPUX86State,fpregs[rm].mmx), val);
             }
             reg = ((modrm >> 3) & 7) | rex_r;
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             break;
         case 0x1d6: /* movq ea, xmm */
             if (mod != 3) {
             break;
         case 0x1d6: /* movq ea, xmm */
             if (mod != 3) {
@@ -3144,7 +3148,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                 gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
             }
             reg = ((modrm >> 3) & 7) | rex_r;
                 gen_op_pmovmskb_mmx(offsetof(CPUX86State,fpregs[rm].mmx));
             }
             reg = ((modrm >> 3) & 7) | rex_r;
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             break;
         default:
             goto illegal_op;
             break;
         default:
             goto illegal_op;
@@ -3158,11 +3162,11 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                 goto illegal_op;
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
                 goto illegal_op;
 #ifdef TARGET_X86_64
             if (s->aflag == 2) {
-                gen_op_movq_A0_reg[R_EDI]();
+                gen_op_movq_A0_reg(R_EDI);
             } else
 #endif
             {
             } else
 #endif
             {
-                gen_op_movl_A0_reg[R_EDI]();
+                gen_op_movl_A0_reg(R_EDI);
                 if (s->aflag == 0)
                     gen_op_andl_A0_ffff();
             }
                 if (s->aflag == 0)
                     gen_op_andl_A0_ffff();
             }
@@ -3186,7 +3190,7 @@ static void gen_sse(DisasContext *s, int b, target_ulong pc_start, int rex_r)
                     /* specific case for SSE single instructions */
                     if (b1 == 2) {
                         /* 32 bit access */
                     /* specific case for SSE single instructions */
                     if (b1 == 2) {
                         /* 32 bit access */
-                        gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
+                        gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                         gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                     } else {
                         /* 64 bit access */
                         gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0)));
                     } else {
                         /* 64 bit access */
@@ -3412,13 +3416,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     /* xor reg, reg optimisation */
                     gen_op_movl_T0_0();
                     s->cc_op = CC_OP_LOGICB + ot;
                     /* xor reg, reg optimisation */
                     gen_op_movl_T0_0();
                     s->cc_op = CC_OP_LOGICB + ot;
-                    gen_op_mov_reg_T0[ot][reg]();
+                    gen_op_mov_reg_T0(ot, reg);
                     gen_op_update1_cc();
                     break;
                 } else {
                     opreg = rm;
                 }
                     gen_op_update1_cc();
                     break;
                 } else {
                     opreg = rm;
                 }
-                gen_op_mov_TN_reg[ot][1][reg]();
+                gen_op_mov_TN_reg(ot, 1, reg);
                 gen_op(s, op, ot, opreg);
                 break;
             case 1: /* OP Gv, Ev */
                 gen_op(s, op, ot, opreg);
                 break;
             case 1: /* OP Gv, Ev */
@@ -3428,11 +3432,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 rm = (modrm & 7) | REX_B(s);
                 if (mod != 3) {
                     gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-                    gen_op_ld_T1_A0[ot + s->mem_index]();
+                    gen_op_ld_T1_A0(ot + s->mem_index);
                 } else if (op == OP_XORL && rm == reg) {
                     goto xor_zero;
                 } else {
                 } else if (op == OP_XORL && rm == reg) {
                     goto xor_zero;
                 } else {
-                    gen_op_mov_TN_reg[ot][1][rm]();
+                    gen_op_mov_TN_reg(ot, 1, rm);
                 }
                 gen_op(s, op, ot, reg);
                 break;
                 }
                 gen_op(s, op, ot, reg);
                 break;
@@ -3514,9 +3518,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             if (op == 0)
                 s->rip_offset = insn_const_size(ot);
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             if (op == 0)
                 s->rip_offset = insn_const_size(ot);
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
 
         switch(op) {
         }
 
         switch(op) {
@@ -3529,17 +3533,17 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         case 2: /* not */
             gen_op_notl_T0();
             if (mod != 3) {
         case 2: /* not */
             gen_op_notl_T0();
             if (mod != 3) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } else {
             } else {
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
             break;
         case 3: /* neg */
             gen_op_negl_T0();
             if (mod != 3) {
             }
             break;
         case 3: /* neg */
             gen_op_negl_T0();
             if (mod != 3) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } else {
             } else {
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
             gen_op_update_neg_cc();
             s->cc_op = CC_OP_SUBB + ot;
             }
             gen_op_update_neg_cc();
             s->cc_op = CC_OP_SUBB + ot;
@@ -3603,7 +3607,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             default:
             case OT_LONG:
                 gen_jmp_im(pc_start - s->cs_base);
             default:
             case OT_LONG:
                 gen_jmp_im(pc_start - s->cs_base);
-                gen_op_divl_EAX_T0();
+#ifdef MACRO_TEST
+                /* XXX: this is just a test */
+                tcg_gen_macro_2(cpu_T[0], cpu_T[0], MACRO_TEST);
+#else
+                tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]);
+#endif
                 break;
 #ifdef TARGET_X86_64
             case OT_QUAD:
                 break;
 #ifdef TARGET_X86_64
             case OT_QUAD:
@@ -3626,7 +3635,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             default:
             case OT_LONG:
                 gen_jmp_im(pc_start - s->cs_base);
             default:
             case OT_LONG:
                 gen_jmp_im(pc_start - s->cs_base);
-                gen_op_idivl_EAX_T0();
+                tcg_gen_helper_0_1(helper_idivl_EAX_T0, cpu_T[0]);
                 break;
 #ifdef TARGET_X86_64
             case OT_QUAD:
                 break;
 #ifdef TARGET_X86_64
             case OT_QUAD:
@@ -3671,9 +3680,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             if (op >= 2 && op != 3 && op != 5)
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             if (op >= 2 && op != 3 && op != 5)
-                gen_op_ld_T0_A0[ot + s->mem_index]();
+                gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
 
         switch(op) {
         }
 
         switch(op) {
@@ -3702,9 +3711,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             gen_eob(s);
             break;
         case 3: /* lcall Ev */
             gen_eob(s);
             break;
         case 3: /* lcall Ev */
-            gen_op_ld_T1_A0[ot + s->mem_index]();
+            gen_op_ld_T1_A0(ot + s->mem_index);
             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
-            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
+            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
         do_lcall:
             if (s->pe && !s->vm86) {
                 if (s->cc_op != CC_OP_DYNAMIC)
         do_lcall:
             if (s->pe && !s->vm86) {
                 if (s->cc_op != CC_OP_DYNAMIC)
@@ -3723,9 +3732,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             gen_eob(s);
             break;
         case 5: /* ljmp Ev */
             gen_eob(s);
             break;
         case 5: /* ljmp Ev */
-            gen_op_ld_T1_A0[ot + s->mem_index]();
+            gen_op_ld_T1_A0(ot + s->mem_index);
             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
             gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
-            gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
+            gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
         do_ljmp:
             if (s->pe && !s->vm86) {
                 if (s->cc_op != CC_OP_DYNAMIC)
         do_ljmp:
             if (s->pe && !s->vm86) {
                 if (s->cc_op != CC_OP_DYNAMIC)
@@ -3760,7 +3769,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         reg = ((modrm >> 3) & 7) | rex_r;
 
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
         reg = ((modrm >> 3) & 7) | rex_r;
 
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
-        gen_op_mov_TN_reg[ot][1][reg]();
+        gen_op_mov_TN_reg(ot, 1, reg);
         gen_op_testl_T0_T1_cc();
         s->cc_op = CC_OP_LOGICB + ot;
         break;
         gen_op_testl_T0_T1_cc();
         s->cc_op = CC_OP_LOGICB + ot;
         break;
@@ -3773,7 +3782,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             ot = dflag + OT_WORD;
         val = insn_get(s, ot);
 
             ot = dflag + OT_WORD;
         val = insn_get(s, ot);
 
-        gen_op_mov_TN_reg[ot][0][OR_EAX]();
+        gen_op_mov_TN_reg(ot, 0, OR_EAX);
         gen_op_movl_T1_im(val);
         gen_op_testl_T0_T1_cc();
         s->cc_op = CC_OP_LOGICB + ot;
         gen_op_movl_T1_im(val);
         gen_op_testl_T0_T1_cc();
         s->cc_op = CC_OP_LOGICB + ot;
@@ -3819,7 +3828,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             val = (int8_t)insn_get(s, OT_BYTE);
             gen_op_movl_T1_im(val);
         } else {
             val = (int8_t)insn_get(s, OT_BYTE);
             gen_op_movl_T1_im(val);
         } else {
-            gen_op_mov_TN_reg[ot][1][reg]();
+            gen_op_mov_TN_reg(ot, 1, reg);
         }
 
 #ifdef TARGET_X86_64
         }
 
 #ifdef TARGET_X86_64
@@ -3832,7 +3841,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         } else {
             gen_op_imulw_T0_T1();
         }
         } else {
             gen_op_imulw_T0_T1();
         }
-        gen_op_mov_reg_T0[ot][reg]();
+        gen_op_mov_reg_T0(ot, reg);
         s->cc_op = CC_OP_MULB + ot;
         break;
     case 0x1c0:
         s->cc_op = CC_OP_MULB + ot;
         break;
     case 0x1c0:
@@ -3846,18 +3855,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         mod = (modrm >> 6) & 3;
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
         mod = (modrm >> 6) & 3;
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
-            gen_op_mov_TN_reg[ot][0][reg]();
-            gen_op_mov_TN_reg[ot][1][rm]();
+            gen_op_mov_TN_reg(ot, 0, reg);
+            gen_op_mov_TN_reg(ot, 1, rm);
             gen_op_addl_T0_T1();
             gen_op_addl_T0_T1();
-            gen_op_mov_reg_T1[ot][reg]();
-            gen_op_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T1(ot, reg);
+            gen_op_mov_reg_T0(ot, rm);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_mov_TN_reg[ot][0][reg]();
-            gen_op_ld_T1_A0[ot + s->mem_index]();
+            gen_op_mov_TN_reg(ot, 0, reg);
+            gen_op_ld_T1_A0(ot + s->mem_index);
             gen_op_addl_T0_T1();
             gen_op_addl_T0_T1();
-            gen_op_st_T0_A0[ot + s->mem_index]();
-            gen_op_mov_reg_T1[ot][reg]();
+            gen_op_st_T0_A0(ot + s->mem_index);
+            gen_op_mov_reg_T1(ot, reg);
         }
         gen_op_update2_cc();
         s->cc_op = CC_OP_ADDB + ot;
         }
         gen_op_update2_cc();
         s->cc_op = CC_OP_ADDB + ot;
@@ -3871,15 +3880,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         modrm = ldub_code(s->pc++);
         reg = ((modrm >> 3) & 7) | rex_r;
         mod = (modrm >> 6) & 3;
         modrm = ldub_code(s->pc++);
         reg = ((modrm >> 3) & 7) | rex_r;
         mod = (modrm >> 6) & 3;
-        gen_op_mov_TN_reg[ot][1][reg]();
+        gen_op_mov_TN_reg(ot, 1, reg);
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
             gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
             gen_op_cmpxchg_T0_T1_EAX_cc[ot]();
-            gen_op_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T0(ot, rm);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
             gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
         }
         s->cc_op = CC_OP_SUBB + ot;
             gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot + s->mem_index]();
         }
         s->cc_op = CC_OP_SUBB + ot;
@@ -3900,7 +3909,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         /**************************/
         /* push/pop */
     case 0x50 ... 0x57: /* push */
         /**************************/
         /* push/pop */
     case 0x50 ... 0x57: /* push */
-        gen_op_mov_TN_reg[OT_LONG][0][(b & 7) | REX_B(s)]();
+        gen_op_mov_TN_reg(OT_LONG, 0, (b & 7) | REX_B(s));
         gen_push_T0(s);
         break;
     case 0x58 ... 0x5f: /* pop */
         gen_push_T0(s);
         break;
     case 0x58 ... 0x5f: /* pop */
@@ -3912,7 +3921,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         gen_pop_T0(s);
         /* NOTE: order is important for pop %sp */
         gen_pop_update(s);
         gen_pop_T0(s);
         /* NOTE: order is important for pop %sp */
         gen_pop_update(s);
-        gen_op_mov_reg_T0[ot][(b & 7) | REX_B(s)]();
+        gen_op_mov_reg_T0(ot, (b & 7) | REX_B(s));
         break;
     case 0x60: /* pusha */
         if (CODE64(s))
         break;
     case 0x60: /* pusha */
         if (CODE64(s))
@@ -3951,7 +3960,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             /* NOTE: order is important for pop %sp */
             gen_pop_update(s);
             rm = (modrm & 7) | REX_B(s);
             /* NOTE: order is important for pop %sp */
             gen_pop_update(s);
             rm = (modrm & 7) | REX_B(s);
-            gen_op_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T0(ot, rm);
         } else {
             /* NOTE: order is important too for MMU exceptions */
             s->popl_esp_hack = 1 << ot;
         } else {
             /* NOTE: order is important too for MMU exceptions */
             s->popl_esp_hack = 1 << ot;
@@ -3972,14 +3981,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
     case 0xc9: /* leave */
         /* XXX: exception not precise (ESP is updated before potential exception) */
         if (CODE64(s)) {
     case 0xc9: /* leave */
         /* XXX: exception not precise (ESP is updated before potential exception) */
         if (CODE64(s)) {
-            gen_op_mov_TN_reg[OT_QUAD][0][R_EBP]();
-            gen_op_mov_reg_T0[OT_QUAD][R_ESP]();
+            gen_op_mov_TN_reg(OT_QUAD, 0, R_EBP);
+            gen_op_mov_reg_T0(OT_QUAD, R_ESP);
         } else if (s->ss32) {
         } else if (s->ss32) {
-            gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
-            gen_op_mov_reg_T0[OT_LONG][R_ESP]();
+            gen_op_mov_TN_reg(OT_LONG, 0, R_EBP);
+            gen_op_mov_reg_T0(OT_LONG, R_ESP);
         } else {
         } else {
-            gen_op_mov_TN_reg[OT_WORD][0][R_EBP]();
-            gen_op_mov_reg_T0[OT_WORD][R_ESP]();
+            gen_op_mov_TN_reg(OT_WORD, 0, R_EBP);
+            gen_op_mov_reg_T0(OT_WORD, R_ESP);
         }
         gen_pop_T0(s);
         if (CODE64(s)) {
         }
         gen_pop_T0(s);
         if (CODE64(s)) {
@@ -3987,7 +3996,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         } else {
             ot = dflag + OT_WORD;
         }
         } else {
             ot = dflag + OT_WORD;
         }
-        gen_op_mov_reg_T0[ot][R_EBP]();
+        gen_op_mov_reg_T0(ot, R_EBP);
         gen_pop_update(s);
         break;
     case 0x06: /* push es */
         gen_pop_update(s);
         break;
     case 0x06: /* push es */
@@ -4066,9 +4075,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         val = insn_get(s, ot);
         gen_op_movl_T0_im(val);
         if (mod != 3)
         val = insn_get(s, ot);
         gen_op_movl_T0_im(val);
         if (mod != 3)
-            gen_op_st_T0_A0[ot + s->mem_index]();
+            gen_op_st_T0_A0(ot + s->mem_index);
         else
         else
-            gen_op_mov_reg_T0[ot][(modrm & 7) | REX_B(s)]();
+            gen_op_mov_reg_T0(ot, (modrm & 7) | REX_B(s));
         break;
     case 0x8a:
     case 0x8b: /* mov Ev, Gv */
         break;
     case 0x8a:
     case 0x8b: /* mov Ev, Gv */
@@ -4080,7 +4089,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         reg = ((modrm >> 3) & 7) | rex_r;
 
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
         reg = ((modrm >> 3) & 7) | rex_r;
 
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
-        gen_op_mov_reg_T0[ot][reg]();
+        gen_op_mov_reg_T0(ot, reg);
         break;
     case 0x8e: /* mov seg, Gv */
         modrm = ldub_code(s->pc++);
         break;
     case 0x8e: /* mov seg, Gv */
         modrm = ldub_code(s->pc++);
@@ -4132,7 +4141,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             rm = (modrm & 7) | REX_B(s);
 
             if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
 
             if (mod == 3) {
-                gen_op_mov_TN_reg[ot][0][rm]();
+                gen_op_mov_TN_reg(ot, 0, rm);
                 switch(ot | (b & 8)) {
                 case OT_BYTE:
                     gen_op_movzbl_T0_T0();
                 switch(ot | (b & 8)) {
                 case OT_BYTE:
                     gen_op_movzbl_T0_T0();
@@ -4148,15 +4157,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     gen_op_movswl_T0_T0();
                     break;
                 }
                     gen_op_movswl_T0_T0();
                     break;
                 }
-                gen_op_mov_reg_T0[d_ot][reg]();
+                gen_op_mov_reg_T0(d_ot, reg);
             } else {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 if (b & 8) {
             } else {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 if (b & 8) {
-                    gen_op_lds_T0_A0[ot + s->mem_index]();
+                    gen_op_lds_T0_A0(ot + s->mem_index);
                 } else {
                 } else {
-                    gen_op_ldu_T0_A0[ot + s->mem_index]();
+                    gen_op_ldu_T0_A0(ot + s->mem_index);
                 }
                 }
-                gen_op_mov_reg_T0[d_ot][reg]();
+                gen_op_mov_reg_T0(d_ot, reg);
             }
         }
         break;
             }
         }
         break;
@@ -4174,7 +4183,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         s->addseg = 0;
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         s->addseg = val;
         s->addseg = 0;
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         s->addseg = val;
-        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
+        gen_op_mov_reg_A0(ot - OT_WORD, reg);
         break;
 
     case 0xa0: /* mov EAX, Ov */
         break;
 
     case 0xa0: /* mov EAX, Ov */
@@ -4192,10 +4201,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             if (s->aflag == 2) {
                 offset_addr = ldq_code(s->pc);
                 s->pc += 8;
             if (s->aflag == 2) {
                 offset_addr = ldq_code(s->pc);
                 s->pc += 8;
-                if (offset_addr == (int32_t)offset_addr)
-                    gen_op_movq_A0_im(offset_addr);
-                else
-                    gen_op_movq_A0_im64(offset_addr >> 32, offset_addr);
+                gen_op_movq_A0_im(offset_addr);
             } else
 #endif
             {
             } else
 #endif
             {
@@ -4208,35 +4214,35 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             }
             gen_add_A0_ds_seg(s);
             if ((b & 2) == 0) {
             }
             gen_add_A0_ds_seg(s);
             if ((b & 2) == 0) {
-                gen_op_ld_T0_A0[ot + s->mem_index]();
-                gen_op_mov_reg_T0[ot][R_EAX]();
+                gen_op_ld_T0_A0(ot + s->mem_index);
+                gen_op_mov_reg_T0(ot, R_EAX);
             } else {
             } else {
-                gen_op_mov_TN_reg[ot][0][R_EAX]();
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_mov_TN_reg(ot, 0, R_EAX);
+                gen_op_st_T0_A0(ot + s->mem_index);
             }
         }
         break;
     case 0xd7: /* xlat */
 #ifdef TARGET_X86_64
         if (s->aflag == 2) {
             }
         }
         break;
     case 0xd7: /* xlat */
 #ifdef TARGET_X86_64
         if (s->aflag == 2) {
-            gen_op_movq_A0_reg[R_EBX]();
+            gen_op_movq_A0_reg(R_EBX);
             gen_op_addq_A0_AL();
         } else
 #endif
         {
             gen_op_addq_A0_AL();
         } else
 #endif
         {
-            gen_op_movl_A0_reg[R_EBX]();
+            gen_op_movl_A0_reg(R_EBX);
             gen_op_addl_A0_AL();
             if (s->aflag == 0)
                 gen_op_andl_A0_ffff();
         }
         gen_add_A0_ds_seg(s);
             gen_op_addl_A0_AL();
             if (s->aflag == 0)
                 gen_op_andl_A0_ffff();
         }
         gen_add_A0_ds_seg(s);
-        gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
-        gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
+        gen_op_ldu_T0_A0(OT_BYTE + s->mem_index);
+        gen_op_mov_reg_T0(OT_BYTE, R_EAX);
         break;
     case 0xb0 ... 0xb7: /* mov R, Ib */
         val = insn_get(s, OT_BYTE);
         gen_op_movl_T0_im(val);
         break;
     case 0xb0 ... 0xb7: /* mov R, Ib */
         val = insn_get(s, OT_BYTE);
         gen_op_movl_T0_im(val);
-        gen_op_mov_reg_T0[OT_BYTE][(b & 7) | REX_B(s)]();
+        gen_op_mov_reg_T0(OT_BYTE, (b & 7) | REX_B(s));
         break;
     case 0xb8 ... 0xbf: /* mov R, Iv */
 #ifdef TARGET_X86_64
         break;
     case 0xb8 ... 0xbf: /* mov R, Iv */
 #ifdef TARGET_X86_64
@@ -4247,7 +4253,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             s->pc += 8;
             reg = (b & 7) | REX_B(s);
             gen_movtl_T0_im(tmp);
             s->pc += 8;
             reg = (b & 7) | REX_B(s);
             gen_movtl_T0_im(tmp);
-            gen_op_mov_reg_T0[OT_QUAD][reg]();
+            gen_op_mov_reg_T0(OT_QUAD, reg);
         } else
 #endif
         {
         } else
 #endif
         {
@@ -4255,7 +4261,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             val = insn_get(s, ot);
             reg = (b & 7) | REX_B(s);
             gen_op_movl_T0_im(val);
             val = insn_get(s, ot);
             reg = (b & 7) | REX_B(s);
             gen_op_movl_T0_im(val);
-            gen_op_mov_reg_T0[ot][reg]();
+            gen_op_mov_reg_T0(ot, reg);
         }
         break;
 
         }
         break;
 
@@ -4276,21 +4282,21 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
         do_xchg_reg:
         if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
         do_xchg_reg:
-            gen_op_mov_TN_reg[ot][0][reg]();
-            gen_op_mov_TN_reg[ot][1][rm]();
-            gen_op_mov_reg_T0[ot][rm]();
-            gen_op_mov_reg_T1[ot][reg]();
+            gen_op_mov_TN_reg(ot, 0, reg);
+            gen_op_mov_TN_reg(ot, 1, rm);
+            gen_op_mov_reg_T0(ot, rm);
+            gen_op_mov_reg_T1(ot, reg);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         } else {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_mov_TN_reg[ot][0][reg]();
+            gen_op_mov_TN_reg(ot, 0, reg);
             /* for xchg, lock is implicit */
             if (!(prefixes & PREFIX_LOCK))
                 gen_op_lock();
             /* for xchg, lock is implicit */
             if (!(prefixes & PREFIX_LOCK))
                 gen_op_lock();
-            gen_op_ld_T1_A0[ot + s->mem_index]();
-            gen_op_st_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T1_A0(ot + s->mem_index);
+            gen_op_st_T0_A0(ot + s->mem_index);
             if (!(prefixes & PREFIX_LOCK))
                 gen_op_unlock();
             if (!(prefixes & PREFIX_LOCK))
                 gen_op_unlock();
-            gen_op_mov_reg_T1[ot][reg]();
+            gen_op_mov_reg_T1(ot, reg);
         }
         break;
     case 0xc4: /* les Gv */
         }
         break;
     case 0xc4: /* les Gv */
@@ -4319,13 +4325,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (mod == 3)
             goto illegal_op;
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         if (mod == 3)
             goto illegal_op;
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-        gen_op_ld_T1_A0[ot + s->mem_index]();
+        gen_op_ld_T1_A0(ot + s->mem_index);
         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
         /* load the segment first to handle exceptions properly */
         gen_add_A0_im(s, 1 << (ot - OT_WORD + 1));
         /* load the segment first to handle exceptions properly */
-        gen_op_ldu_T0_A0[OT_WORD + s->mem_index]();
+        gen_op_ldu_T0_A0(OT_WORD + s->mem_index);
         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
         /* then put the data */
         gen_movl_seg_T0(s, op, pc_start - s->cs_base);
         /* then put the data */
-        gen_op_mov_reg_T1[ot][reg]();
+        gen_op_mov_reg_T1(ot, reg);
         if (s->is_jmp) {
             gen_jmp_im(s->pc - s->cs_base);
             gen_eob(s);
         if (s->is_jmp) {
             gen_jmp_im(s->pc - s->cs_base);
             gen_eob(s);
@@ -4405,11 +4411,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
 
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
 
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
         }
-        gen_op_mov_TN_reg[ot][1][reg]();
+        gen_op_mov_TN_reg(ot, 1, reg);
 
         if (shift) {
             val = ldub_code(s->pc++);
 
         if (shift) {
             val = ldub_code(s->pc++);
@@ -4437,7 +4443,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
         }
         if (mod == 3) {
             s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
         }
         if (mod == 3) {
-            gen_op_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T0(ot, rm);
         }
         break;
 
         }
         break;
 
@@ -4969,7 +4975,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         else
             ot = dflag ? OT_LONG : OT_WORD;
         gen_check_io(s, ot, 1, pc_start - s->cs_base);
         else
             ot = dflag ? OT_LONG : OT_WORD;
         gen_check_io(s, ot, 1, pc_start - s->cs_base);
-        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
+        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
         gen_op_andl_T0_ffff();
         if (gen_svm_check_io(s, pc_start,
                              SVM_IOIO_TYPE_MASK | (1 << (4+ot)) |
         gen_op_andl_T0_ffff();
         if (gen_svm_check_io(s, pc_start,
                              SVM_IOIO_TYPE_MASK | (1 << (4+ot)) |
@@ -4988,7 +4994,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         else
             ot = dflag ? OT_LONG : OT_WORD;
         gen_check_io(s, ot, 1, pc_start - s->cs_base);
         else
             ot = dflag ? OT_LONG : OT_WORD;
         gen_check_io(s, ot, 1, pc_start - s->cs_base);
-        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
+        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
         gen_op_andl_T0_ffff();
         if (gen_svm_check_io(s, pc_start,
                              (1 << (4+ot)) | svm_is_rep(prefixes) |
         gen_op_andl_T0_ffff();
         if (gen_svm_check_io(s, pc_start,
                              (1 << (4+ot)) | svm_is_rep(prefixes) |
@@ -5018,7 +5024,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                              (1 << (4+ot))))
             break;
         gen_op_in[ot]();
                              (1 << (4+ot))))
             break;
         gen_op_in[ot]();
-        gen_op_mov_reg_T1[ot][R_EAX]();
+        gen_op_mov_reg_T1(ot, R_EAX);
         break;
     case 0xe6:
     case 0xe7:
         break;
     case 0xe6:
     case 0xe7:
@@ -5032,7 +5038,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) |
                              (1 << (4+ot))))
             break;
         if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) |
                              (1 << (4+ot))))
             break;
-        gen_op_mov_TN_reg[ot][1][R_EAX]();
+        gen_op_mov_TN_reg(ot, 1, R_EAX);
         gen_op_out[ot]();
         break;
     case 0xec:
         gen_op_out[ot]();
         break;
     case 0xec:
@@ -5041,7 +5047,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             ot = OT_BYTE;
         else
             ot = dflag ? OT_LONG : OT_WORD;
             ot = OT_BYTE;
         else
             ot = dflag ? OT_LONG : OT_WORD;
-        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
+        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
         gen_op_andl_T0_ffff();
         gen_check_io(s, ot, 0, pc_start - s->cs_base);
         if (gen_svm_check_io(s, pc_start,
         gen_op_andl_T0_ffff();
         gen_check_io(s, ot, 0, pc_start - s->cs_base);
         if (gen_svm_check_io(s, pc_start,
@@ -5049,7 +5055,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                              (1 << (4+ot))))
             break;
         gen_op_in[ot]();
                              (1 << (4+ot))))
             break;
         gen_op_in[ot]();
-        gen_op_mov_reg_T1[ot][R_EAX]();
+        gen_op_mov_reg_T1(ot, R_EAX);
         break;
     case 0xee:
     case 0xef:
         break;
     case 0xee:
     case 0xef:
@@ -5057,13 +5063,13 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             ot = OT_BYTE;
         else
             ot = dflag ? OT_LONG : OT_WORD;
             ot = OT_BYTE;
         else
             ot = dflag ? OT_LONG : OT_WORD;
-        gen_op_mov_TN_reg[OT_WORD][0][R_EDX]();
+        gen_op_mov_TN_reg(OT_WORD, 0, R_EDX);
         gen_op_andl_T0_ffff();
         gen_check_io(s, ot, 0, pc_start - s->cs_base);
         if (gen_svm_check_io(s, pc_start,
                              svm_is_rep(prefixes) | (1 << (4+ot))))
             break;
         gen_op_andl_T0_ffff();
         gen_check_io(s, ot, 0, pc_start - s->cs_base);
         if (gen_svm_check_io(s, pc_start,
                              svm_is_rep(prefixes) | (1 << (4+ot))))
             break;
-        gen_op_mov_TN_reg[ot][1][R_EAX]();
+        gen_op_mov_TN_reg(ot, 1, R_EAX);
         gen_op_out[ot]();
         break;
 
         gen_op_out[ot]();
         break;
 
@@ -5101,7 +5107,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         } else {
             gen_stack_A0(s);
             /* pop offset */
         } else {
             gen_stack_A0(s);
             /* pop offset */
-            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
+            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
             if (s->dflag == 0)
                 gen_op_andl_T0_ffff();
             /* NOTE: keeping EIP updated is not a problem in case of
             if (s->dflag == 0)
                 gen_op_andl_T0_ffff();
             /* NOTE: keeping EIP updated is not a problem in case of
@@ -5109,7 +5115,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             gen_op_jmp_T0();
             /* pop selector */
             gen_op_addl_A0_im(2 << s->dflag);
             gen_op_jmp_T0();
             /* pop selector */
             gen_op_addl_A0_im(2 << s->dflag);
-            gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
+            gen_op_ld_T0_A0(1 + s->dflag + s->mem_index);
             gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
             /* add stack offset */
             gen_stack_update(s, val + (4 << s->dflag));
             gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
             /* add stack offset */
             gen_stack_update(s, val + (4 << s->dflag));
@@ -5232,10 +5238,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         gen_setcc(s, b);
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         gen_setcc(s, b);
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_ld_T1_A0[ot + s->mem_index]();
+            gen_op_ld_T1_A0(ot + s->mem_index);
         } else {
             rm = (modrm & 7) | REX_B(s);
         } else {
             rm = (modrm & 7) | REX_B(s);
-            gen_op_mov_TN_reg[ot][1][rm]();
+            gen_op_mov_TN_reg(ot, 1, rm);
         }
         gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
         break;
         }
         gen_op_cmov_reg_T1_T0[ot - OT_WORD][reg]();
         break;
@@ -5292,7 +5298,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
     case 0x9e: /* sahf */
         if (CODE64(s))
             goto illegal_op;
     case 0x9e: /* sahf */
         if (CODE64(s))
             goto illegal_op;
-        gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
+        gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         gen_op_movb_eflags_T0();
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         gen_op_movb_eflags_T0();
@@ -5304,7 +5310,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         gen_op_movl_T0_eflags();
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         gen_op_movl_T0_eflags();
-        gen_op_mov_reg_T0[OT_BYTE][R_AH]();
+        gen_op_mov_reg_T0(OT_BYTE, R_AH);
         break;
     case 0xf5: /* cmc */
         if (s->cc_op != CC_OP_DYNAMIC)
         break;
     case 0xf5: /* cmc */
         if (s->cc_op != CC_OP_DYNAMIC)
@@ -5342,9 +5348,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         if (mod != 3) {
             s->rip_offset = 1;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         if (mod != 3) {
             s->rip_offset = 1;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
         /* load shift */
         val = ldub_code(s->pc++);
         }
         /* load shift */
         val = ldub_code(s->pc++);
@@ -5356,9 +5362,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         s->cc_op = CC_OP_SARB + ot;
         if (op != 0) {
             if (mod != 3)
         s->cc_op = CC_OP_SARB + ot;
         if (op != 0) {
             if (mod != 3)
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             else
             else
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             gen_op_update_bt_cc();
         }
         break;
             gen_op_update_bt_cc();
         }
         break;
@@ -5379,22 +5385,22 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         reg = ((modrm >> 3) & 7) | rex_r;
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
         reg = ((modrm >> 3) & 7) | rex_r;
         mod = (modrm >> 6) & 3;
         rm = (modrm & 7) | REX_B(s);
-        gen_op_mov_TN_reg[OT_LONG][1][reg]();
+        gen_op_mov_TN_reg(OT_LONG, 1, reg);
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             /* specific case: we need to add a displacement */
             gen_op_add_bit_A0_T1[ot - OT_WORD]();
         if (mod != 3) {
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             /* specific case: we need to add a displacement */
             gen_op_add_bit_A0_T1[ot - OT_WORD]();
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
         s->cc_op = CC_OP_SARB + ot;
         if (op != 0) {
             if (mod != 3)
         }
         gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
         s->cc_op = CC_OP_SARB + ot;
         if (op != 0) {
             if (mod != 3)
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             else
             else
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             gen_op_update_bt_cc();
         }
         break;
             gen_op_update_bt_cc();
         }
         break;
@@ -5406,9 +5412,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
         /* NOTE: in order to handle the 0 case, we must load the
            result. It could be optimized with a generated jump */
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
         /* NOTE: in order to handle the 0 case, we must load the
            result. It could be optimized with a generated jump */
-        gen_op_mov_TN_reg[ot][1][reg]();
+        gen_op_mov_TN_reg(ot, 1, reg);
         gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
         gen_op_bsx_T0_cc[ot - OT_WORD][b & 1]();
-        gen_op_mov_reg_T1[ot][reg]();
+        gen_op_mov_reg_T1(ot, reg);
         s->cc_op = CC_OP_LOGICB + ot;
         break;
         /************************/
         s->cc_op = CC_OP_LOGICB + ot;
         break;
         /************************/
@@ -5569,7 +5575,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
         mod = (modrm >> 6) & 3;
         if (mod == 3)
             goto illegal_op;
-        gen_op_mov_TN_reg[ot][0][reg]();
+        gen_op_mov_TN_reg(ot, 0, reg);
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         gen_jmp_im(pc_start - s->cs_base);
         if (ot == OT_WORD)
         gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
         gen_jmp_im(pc_start - s->cs_base);
         if (ot == OT_WORD)
@@ -5581,16 +5587,27 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         reg = (b & 7) | REX_B(s);
 #ifdef TARGET_X86_64
         if (dflag == 2) {
         reg = (b & 7) | REX_B(s);
 #ifdef TARGET_X86_64
         if (dflag == 2) {
-            gen_op_mov_TN_reg[OT_QUAD][0][reg]();
-            gen_op_bswapq_T0();
-            gen_op_mov_reg_T0[OT_QUAD][reg]();
+            gen_op_mov_TN_reg(OT_QUAD, 0, reg);
+            tcg_gen_bswap_i64(cpu_T[0], cpu_T[0]);
+            gen_op_mov_reg_T0(OT_QUAD, reg);
         } else
         } else
-#endif
         {
         {
-            gen_op_mov_TN_reg[OT_LONG][0][reg]();
-            gen_op_bswapl_T0();
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            int tmp0;
+            gen_op_mov_TN_reg(OT_LONG, 0, reg);
+            
+            tmp0 = tcg_temp_new(TCG_TYPE_I32);
+            tcg_gen_trunc_i64_i32(tmp0, cpu_T[0]);
+            tcg_gen_bswap_i32(tmp0, tmp0);
+            tcg_gen_extu_i32_i64(cpu_T[0], tmp0);
+            gen_op_mov_reg_T0(OT_LONG, reg);
+        }
+#else
+        {
+            gen_op_mov_TN_reg(OT_LONG, 0, reg);
+            tcg_gen_bswap_i32(cpu_T[0], cpu_T[0]);
+            gen_op_mov_reg_T0(OT_LONG, reg);
         }
         }
+#endif
         break;
     case 0xd6: /* salc */
         if (CODE64(s))
         break;
     case 0xd6: /* salc */
         if (CODE64(s))
@@ -5821,12 +5838,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                 break;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit));
                 break;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             gen_op_movl_T0_env(offsetof(CPUX86State, gdt.limit));
-            gen_op_st_T0_A0[OT_WORD + s->mem_index]();
+            gen_op_st_T0_A0(OT_WORD + s->mem_index);
             gen_add_A0_im(s, 2);
             gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base));
             if (!s->dflag)
                 gen_op_andl_T0_im(0xffffff);
             gen_add_A0_im(s, 2);
             gen_op_movtl_T0_env(offsetof(CPUX86State, gdt.base));
             if (!s->dflag)
                 gen_op_andl_T0_im(0xffffff);
-            gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
+            gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
             break;
         case 1:
             if (mod == 3) {
             break;
         case 1:
             if (mod == 3) {
@@ -5840,12 +5857,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     gen_jmp_im(pc_start - s->cs_base);
 #ifdef TARGET_X86_64
                     if (s->aflag == 2) {
                     gen_jmp_im(pc_start - s->cs_base);
 #ifdef TARGET_X86_64
                     if (s->aflag == 2) {
-                        gen_op_movq_A0_reg[R_EBX]();
+                        gen_op_movq_A0_reg(R_EBX);
                         gen_op_addq_A0_AL();
                     } else
 #endif
                     {
                         gen_op_addq_A0_AL();
                     } else
 #endif
                     {
-                        gen_op_movl_A0_reg[R_EBX]();
+                        gen_op_movl_A0_reg(R_EBX);
                         gen_op_addl_A0_AL();
                         if (s->aflag == 0)
                             gen_op_andl_A0_ffff();
                         gen_op_addl_A0_AL();
                         if (s->aflag == 0)
                             gen_op_andl_A0_ffff();
@@ -5875,12 +5892,12 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     break;
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit));
                     break;
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 gen_op_movl_T0_env(offsetof(CPUX86State, idt.limit));
-                gen_op_st_T0_A0[OT_WORD + s->mem_index]();
+                gen_op_st_T0_A0(OT_WORD + s->mem_index);
                 gen_add_A0_im(s, 2);
                 gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base));
                 if (!s->dflag)
                     gen_op_andl_T0_im(0xffffff);
                 gen_add_A0_im(s, 2);
                 gen_op_movtl_T0_env(offsetof(CPUX86State, idt.base));
                 if (!s->dflag)
                     gen_op_andl_T0_im(0xffffff);
-                gen_op_st_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
+                gen_op_st_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
             }
             break;
         case 2: /* lgdt */
             }
             break;
         case 2: /* lgdt */
@@ -5943,9 +5960,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                                             op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE))
                     break;
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                                             op==2 ? SVM_EXIT_GDTR_WRITE : SVM_EXIT_IDTR_WRITE))
                     break;
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-                gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
+                gen_op_ld_T1_A0(OT_WORD + s->mem_index);
                 gen_add_A0_im(s, 2);
                 gen_add_A0_im(s, 2);
-                gen_op_ld_T0_A0[CODE64(s) + OT_LONG + s->mem_index]();
+                gen_op_ld_T0_A0(CODE64(s) + OT_LONG + s->mem_index);
                 if (!s->dflag)
                     gen_op_andl_T0_im(0xffffff);
                 if (op == 2) {
                 if (!s->dflag)
                     gen_op_andl_T0_im(0xffffff);
                 if (op == 2) {
@@ -6029,19 +6046,19 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             rm = (modrm & 7) | REX_B(s);
 
             if (mod == 3) {
             rm = (modrm & 7) | REX_B(s);
 
             if (mod == 3) {
-                gen_op_mov_TN_reg[OT_LONG][0][rm]();
+                gen_op_mov_TN_reg(OT_LONG, 0, rm);
                 /* sign extend */
                 if (d_ot == OT_QUAD)
                     gen_op_movslq_T0_T0();
                 /* sign extend */
                 if (d_ot == OT_QUAD)
                     gen_op_movslq_T0_T0();
-                gen_op_mov_reg_T0[d_ot][reg]();
+                gen_op_mov_reg_T0(d_ot, reg);
             } else {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 if (d_ot == OT_QUAD) {
             } else {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
                 if (d_ot == OT_QUAD) {
-                    gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
+                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
                 } else {
                 } else {
-                    gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
+                    gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                 }
                 }
-                gen_op_mov_reg_T0[d_ot][reg]();
+                gen_op_mov_reg_T0(d_ot, reg);
             }
         } else
 #endif
             }
         } else
 #endif
@@ -6055,18 +6072,18 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             rm = modrm & 7;
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             rm = modrm & 7;
             if (mod != 3) {
                 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
-                gen_op_ld_T0_A0[ot + s->mem_index]();
+                gen_op_ld_T0_A0(ot + s->mem_index);
             } else {
             } else {
-                gen_op_mov_TN_reg[ot][0][rm]();
+                gen_op_mov_TN_reg(ot, 0, rm);
             }
             if (s->cc_op != CC_OP_DYNAMIC)
                 gen_op_set_cc_op(s->cc_op);
             gen_op_arpl();
             s->cc_op = CC_OP_EFLAGS;
             if (mod != 3) {
             }
             if (s->cc_op != CC_OP_DYNAMIC)
                 gen_op_set_cc_op(s->cc_op);
             gen_op_arpl();
             s->cc_op = CC_OP_EFLAGS;
             if (mod != 3) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } else {
             } else {
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
             gen_op_arpl_update();
         }
             }
             gen_op_arpl_update();
         }
@@ -6079,7 +6096,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         modrm = ldub_code(s->pc++);
         reg = ((modrm >> 3) & 7) | rex_r;
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
         modrm = ldub_code(s->pc++);
         reg = ((modrm >> 3) & 7) | rex_r;
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
-        gen_op_mov_TN_reg[ot][1][reg]();
+        gen_op_mov_TN_reg(ot, 1, reg);
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         if (b == 0x102)
         if (s->cc_op != CC_OP_DYNAMIC)
             gen_op_set_cc_op(s->cc_op);
         if (b == 0x102)
@@ -6087,7 +6104,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         else
             gen_op_lsl();
         s->cc_op = CC_OP_EFLAGS;
         else
             gen_op_lsl();
         s->cc_op = CC_OP_EFLAGS;
-        gen_op_mov_reg_T1[ot][reg]();
+        gen_op_mov_reg_T1(ot, reg);
         break;
     case 0x118:
         modrm = ldub_code(s->pc++);
         break;
     case 0x118:
         modrm = ldub_code(s->pc++);
@@ -6134,7 +6151,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             case 8:
                 if (b & 2) {
                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
             case 8:
                 if (b & 2) {
                     gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_CR0 + reg);
-                    gen_op_mov_TN_reg[ot][0][rm]();
+                    gen_op_mov_TN_reg(ot, 0, rm);
                     gen_op_movl_crN_T0(reg);
                     gen_jmp_im(s->pc - s->cs_base);
                     gen_eob(s);
                     gen_op_movl_crN_T0(reg);
                     gen_jmp_im(s->pc - s->cs_base);
                     gen_eob(s);
@@ -6146,7 +6163,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     else
 #endif
                         gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
                     else
 #endif
                         gen_op_movtl_T0_env(offsetof(CPUX86State,cr[reg]));
-                    gen_op_mov_reg_T0[ot][rm]();
+                    gen_op_mov_reg_T0(ot, rm);
                 }
                 break;
             default:
                 }
                 break;
             default:
@@ -6173,14 +6190,14 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                 goto illegal_op;
             if (b & 2) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
                 goto illegal_op;
             if (b & 2) {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_WRITE_DR0 + reg);
-                gen_op_mov_TN_reg[ot][0][rm]();
+                gen_op_mov_TN_reg(ot, 0, rm);
                 gen_op_movl_drN_T0(reg);
                 gen_jmp_im(s->pc - s->cs_base);
                 gen_eob(s);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
                 gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
                 gen_op_movl_drN_T0(reg);
                 gen_jmp_im(s->pc - s->cs_base);
                 gen_eob(s);
             } else {
                 gen_svm_check_intercept(s, pc_start, SVM_EXIT_READ_DR0 + reg);
                 gen_op_movtl_T0_env(offsetof(CPUX86State,dr[reg]));
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
         }
         break;
             }
         }
         break;
@@ -6246,11 +6263,11 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                 goto illegal_op;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             if (op == 2) {
                 goto illegal_op;
             gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
             if (op == 2) {
-                gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
+                gen_op_ld_T0_A0(OT_LONG + s->mem_index);
                 gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
             } else {
                 gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
                 gen_op_movl_env_T0(offsetof(CPUX86State, mxcsr));
             } else {
                 gen_op_movl_T0_env(offsetof(CPUX86State, mxcsr));
-                gen_op_st_T0_A0[OT_LONG + s->mem_index]();
+                gen_op_st_T0_A0(OT_LONG + s->mem_index);
             }
             break;
         case 5: /* lfence */
             }
             break;
         case 5: /* lfence */
@@ -6647,6 +6664,17 @@ static uint16_t opc_simpler[NB_OPS] = {
 #endif
 };
 
 #endif
 };
 
+static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
+{
+    switch(macro_id) {
+#ifdef MACRO_TEST
+    case MACRO_TEST:
+        tcg_gen_helper_0_1(helper_divl_EAX_T0, cpu_T[0]);
+        break;
+#endif
+    }
+}
+
 void optimize_flags_init(void)
 {
     int i;
 void optimize_flags_init(void)
 {
     int i;
@@ -6655,6 +6683,25 @@ void optimize_flags_init(void)
         if (opc_simpler[i] == 0)
             opc_simpler[i] = i;
     }
         if (opc_simpler[i] == 0)
             opc_simpler[i] = i;
     }
+
+    tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
+
+    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+#if TARGET_LONG_BITS > HOST_LONG_BITS
+    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, 
+                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
+    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
+                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
+    cpu_A0 = tcg_global_mem_new(TCG_TYPE_TL,
+                                TCG_AREG0, offsetof(CPUState, t2), "A0");
+#else
+    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
+    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
+    cpu_A0 = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "A0");
+#endif
+    /* the helpers are only registered to print debug info */
+    TCG_HELPER(helper_divl_EAX_T0);
+    TCG_HELPER(helper_idivl_EAX_T0);
 }
 
 /* CPU flags computation optimization: we move backward thru the
 }
 
 /* CPU flags computation optimization: we move backward thru the
@@ -6746,10 +6793,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
         printf("ERROR addseg\n");
 #endif
 
         printf("ERROR addseg\n");
 #endif
 
-    gen_opc_ptr = gen_opc_buf;
+    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
+
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
-    nb_gen_labels = 0;
 
     dc->is_jmp = DISAS_NEXT;
     pc_ptr = pc_start;
 
     dc->is_jmp = DISAS_NEXT;
     pc_ptr = pc_start;
@@ -6824,9 +6870,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
             disas_flags = !dc->code32;
        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
         fprintf(logfile, "\n");
             disas_flags = !dc->code32;
        target_disas(logfile, pc_start, pc_ptr - pc_start, disas_flags);
         fprintf(logfile, "\n");
-        if (loglevel & CPU_LOG_TB_OP) {
-            fprintf(logfile, "OP:\n");
-            dump_ops(gen_opc_buf, gen_opparam_buf);
+        if (loglevel & CPU_LOG_TB_OP_OPT) {
+            fprintf(logfile, "OP before opt:\n");
+            tcg_dump_ops(&tcg_ctx, logfile);
             fprintf(logfile, "\n");
         }
     }
             fprintf(logfile, "\n");
         }
     }
@@ -6835,13 +6881,6 @@ static inline int gen_intermediate_code_internal(CPUState *env,
     /* optimize flag computations */
     optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
 
     /* optimize flag computations */
     optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
 
-#ifdef DEBUG_DISAS
-    if (loglevel & CPU_LOG_TB_OP_OPT) {
-        fprintf(logfile, "AFTER FLAGS OPT:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
-#endif
     if (!search_pc)
         tb->size = pc_ptr - pc_start;
     return 0;
     if (!search_pc)
         tb->size = pc_ptr - pc_start;
     return 0;
index 140c71d..b9412d8 100644 (file)
@@ -482,7 +482,7 @@ OP(set_sr)
     FORCE_RET();
 }
 
     FORCE_RET();
 }
 
-OP(jmp)
+OP(jmp_im)
 {
     GOTO_LABEL_PARAM(1);
 }
 {
     GOTO_LABEL_PARAM(1);
 }
@@ -522,22 +522,6 @@ OP(jmp_T0)
     FORCE_RET();
 }
 
     FORCE_RET();
 }
 
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
-OP(exit_tb)
-{
-    EXIT_TB();
-}
-
-
 /* Floating point.  */
 OP(f64_to_i32)
 {
 /* Floating point.  */
 OP(f64_to_i32)
 {
index 68f39aa..39816f4 100644 (file)
@@ -28,6 +28,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 #include "m68k-qreg.h"
 
 //#define DEBUG_DISPATCH 1
 #include "m68k-qreg.h"
 
 //#define DEBUG_DISPATCH 1
@@ -67,20 +68,9 @@ typedef struct DisasContext {
 static void *gen_throws_exception;
 #define gen_last_qop NULL
 
 static void *gen_throws_exception;
 #define gen_last_qop NULL
 
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 extern FILE *logfile;
 extern int loglevel;
 
 extern FILE *logfile;
 extern int loglevel;
 
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-#include "gen-op.h"
-
 #if defined(CONFIG_USER_ONLY)
 #define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
 #define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
 #if defined(CONFIG_USER_ONLY)
 #define gen_st(s, name, addr, val) gen_op_st##name##_raw(addr, val)
 #define gen_ld(s, name, val, addr) gen_op_ld##name##_raw(val, addr)
@@ -622,7 +612,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
     gen_flush_flags(s);
     switch (cond) {
     case 0: /* T */
     gen_flush_flags(s);
     switch (cond) {
     case 0: /* T */
-        gen_op_jmp(l1);
+        gen_op_jmp_im(l1);
         break;
     case 1: /* F */
         break;
         break;
     case 1: /* F */
         break;
@@ -702,7 +692,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
             gen_op_xor32(tmp, tmp, QREG_CC_DEST);
             gen_op_and32(tmp, tmp, gen_im32(CCF_V));
             gen_op_jmp_nz32(tmp, l2);
             gen_op_xor32(tmp, tmp, QREG_CC_DEST);
             gen_op_and32(tmp, tmp, gen_im32(CCF_V));
             gen_op_jmp_nz32(tmp, l2);
-            gen_op_jmp(l1);
+            gen_op_jmp_im(l1);
             gen_set_label(l2);
         }
         break;
             gen_set_label(l2);
         }
         break;
@@ -791,14 +781,12 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
         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)) {
         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)) {
-        gen_op_goto_tb(0, n, (long)tb);
+        tcg_gen_goto_tb(n);
         gen_op_mov32(QREG_PC, gen_im32(dest));
         gen_op_mov32(QREG_PC, gen_im32(dest));
-        gen_op_mov32(QREG_T0, gen_im32((long)tb + n));
-        gen_op_exit_tb();
+        tcg_gen_exit_tb((long)tb + n);
     } else {
         gen_jmp(s, gen_im32(dest));
     } else {
         gen_jmp(s, gen_im32(dest));
-        gen_op_mov32(QREG_T0, gen_im32(0));
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     s->is_jmp = DISAS_TB_JUMP;
 }
     }
     s->is_jmp = DISAS_TB_JUMP;
 }
@@ -3073,7 +3061,7 @@ static void expand_op_addx_cc(qOP *qop)
     gen_op_add32(arg0, arg0, gen_im32(1));
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
     gen_op_add32(arg0, arg0, gen_im32(1));
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADDX));
     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
-    gen_op_jmp(l2);
+    gen_op_jmp_im(l2);
     gen_set_label(l1);
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
     gen_set_label(l1);
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_ADD));
     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
@@ -3093,7 +3081,7 @@ static void expand_op_subx_cc(qOP *qop)
     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
     gen_op_sub32(arg0, arg0, gen_im32(1));
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
     gen_op_set_leu32(QREG_CC_X, arg0, arg1);
     gen_op_sub32(arg0, arg0, gen_im32(1));
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUBX));
-    gen_op_jmp(l2);
+    gen_op_jmp_im(l2);
     gen_set_label(l1);
     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
     gen_set_label(l1);
     gen_op_set_ltu32(QREG_CC_X, arg0, arg1);
     gen_op_mov32(QREG_CC_OP, gen_im32(CC_OP_SUB));
@@ -3162,9 +3150,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
     dc->tb = tb;
 
 
     dc->tb = tb;
 
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
 
     dc->env = env;
     dc->is_jmp = DISAS_NEXT;
 
     dc->env = env;
     dc->is_jmp = DISAS_NEXT;
@@ -3174,7 +3160,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->is_mem = 0;
     dc->fpcr = env->fpcr;
     dc->user = (env->sr & SR_S) == 0;
     dc->is_mem = 0;
-    nb_gen_labels = 0;
     lj = -1;
     do {
         free_qreg = 0;
     lj = -1;
     do {
         free_qreg = 0;
@@ -3232,8 +3217,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
         case DISAS_UPDATE:
             gen_flush_cc_op(dc);
             /* indicate that the hash table must be used to find the next TB */
         case DISAS_UPDATE:
             gen_flush_cc_op(dc);
             /* indicate that the hash table must be used to find the next TB */
-            gen_op_mov32(QREG_T0, gen_im32(0));
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         case DISAS_TB_JUMP:
             /* nothing more to generate */
             break;
         case DISAS_TB_JUMP:
             /* nothing more to generate */
@@ -3248,11 +3232,6 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, dc->pc - pc_start, 0);
         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 (loglevel & (CPU_LOG_TB_OP)) {
-            fprintf(logfile, "OP:\n");
-            dump_ops(gen_opc_buf, gen_opparam_buf);
-            fprintf(logfile, "\n");
-        }
     }
 #endif
     if (search_pc) {
     }
 #endif
     if (search_pc) {
index cf965fa..cece7f1 100644 (file)
@@ -1093,18 +1093,6 @@ OP_COND(lez, (target_long)T0 <= 0);
 OP_COND(ltz, (target_long)T0 < 0);
 
 /* Branches */
 OP_COND(ltz, (target_long)T0 < 0);
 
 /* Branches */
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-    FORCE_RET();
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-    FORCE_RET();
-}
-
 /* Branch to register */
 void op_save_breg_target (void)
 {
 /* Branch to register */
 void op_save_breg_target (void)
 {
@@ -3252,12 +3240,6 @@ void op_raise_exception_err (void)
     FORCE_RET();
 }
 
     FORCE_RET();
 }
 
-void op_exit_tb (void)
-{
-    EXIT_TB();
-    FORCE_RET();
-}
-
 void op_wait (void)
 {
     env->halted = 1;
 void op_wait (void)
 {
     env->halted = 1;
index 719af3a..1231c00 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
 //#define MIPS_SINGLE_STEP
 
 
 //#define MIPS_DEBUG_DISAS
 //#define MIPS_DEBUG_SIGN_EXTENSIONS
 //#define MIPS_SINGLE_STEP
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
-
-#include "gen-op.h"
-
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
 
 /* MIPS major opcodes */
 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
 
@@ -1777,17 +1760,13 @@ static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong des
     TranslationBlock *tb;
     tb = ctx->tb;
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
     TranslationBlock *tb;
     tb = ctx->tb;
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
-        if (n == 0)
-            gen_op_goto_tb0(TBPARAM(tb));
-        else
-            gen_op_goto_tb1(TBPARAM(tb));
+        tcg_gen_goto_tb(n);
         gen_save_pc(dest);
         gen_save_pc(dest);
-        gen_op_set_T0((long)tb + n);
+        tcg_gen_exit_tb((long)tb + n);
     } else {
         gen_save_pc(dest);
     } else {
         gen_save_pc(dest);
-        gen_op_reset_T0();
+        tcg_gen_exit_tb(0);
     }
     }
-    gen_op_exit_tb();
 }
 
 /* Branches (before delay slot) */
 }
 
 /* Branches (before delay slot) */
@@ -6642,8 +6621,7 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
             /* unconditional branch to register */
             MIPS_DEBUG("branch to register");
             gen_op_breg();
             /* unconditional branch to register */
             MIPS_DEBUG("branch to register");
             gen_op_breg();
-            gen_op_reset_T0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         default:
             MIPS_DEBUG("unknown branch");
             break;
         default:
             MIPS_DEBUG("unknown branch");
@@ -6665,10 +6643,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
         fprintf (logfile, "search pc %d\n", search_pc);
 
     pc_start = tb->pc;
         fprintf (logfile, "search pc %d\n", search_pc);
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
-    nb_gen_labels = 0;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
     ctx.tb = tb;
     ctx.pc = pc_start;
     ctx.saved_pc = -1;
     ctx.tb = tb;
@@ -6748,8 +6723,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
             break;
         case BS_EXCP:
             gen_op_interrupt_restart();
             break;
         case BS_EXCP:
             gen_op_interrupt_restart();
-            gen_op_reset_T0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         case BS_BRANCH:
         default:
             break;
         case BS_BRANCH:
         default:
@@ -6777,11 +6751,6 @@ done_generating:
         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
         fprintf(logfile, "\n");
     }
         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
         fprintf(logfile, "\n");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-        fprintf(logfile, "OP:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
     if (loglevel & CPU_LOG_TB_CPU) {
         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
     }
     if (loglevel & CPU_LOG_TB_CPU) {
         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
     }
index c950579..6cda0f0 100644 (file)
@@ -222,11 +222,6 @@ void OPPROTO op_debug (void)
     do_raise_exception(EXCP_DEBUG);
 }
 
     do_raise_exception(EXCP_DEBUG);
 }
 
-void OPPROTO op_exit_tb (void)
-{
-    EXIT_TB();
-}
-
 /* Load/store special registers */
 void OPPROTO op_load_cr (void)
 {
 /* Load/store special registers */
 void OPPROTO op_load_cr (void)
 {
@@ -674,16 +669,6 @@ void OPPROTO op_setlr_64 (void)
 }
 #endif
 
 }
 #endif
 
-void OPPROTO op_goto_tb0 (void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1 (void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
 void OPPROTO op_b_T1 (void)
 {
     env->nip = (uint32_t)(T1 & ~3);
 void OPPROTO op_b_T1 (void)
 {
     env->nip = (uint32_t)(T1 & ~3);
index 1313a77..c9530eb 100644 (file)
@@ -26,6 +26,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 /* Include definitions for instructions classes and implementations flags */
 //#define DO_SINGLE_STEP
 
 /* Include definitions for instructions classes and implementations flags */
 //#define DO_SINGLE_STEP
 
 /*****************************************************************************/
 /* Code translation helpers                                                  */
 
 /*****************************************************************************/
 /* Code translation helpers                                                  */
-#if defined(USE_DIRECT_JUMP)
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
 
 
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 #if defined(OPTIMIZE_FPRF_UPDATE)
 static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
 static uint16_t **gen_fprf_ptr;
 #endif
 
 #if defined(OPTIMIZE_FPRF_UPDATE)
 static uint16_t *gen_fprf_buf[OPC_BUF_SIZE];
 static uint16_t **gen_fprf_ptr;
 #endif
 
-#include "gen-op.h"
-
 static always_inline void gen_set_T0 (target_ulong val)
 {
 #if defined(TARGET_PPC64)
 static always_inline void gen_set_T0 (target_ulong val)
 {
 #if defined(TARGET_PPC64)
@@ -2798,11 +2783,9 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
 {
     TranslationBlock *tb;
     tb = ctx->tb;
 {
     TranslationBlock *tb;
     tb = ctx->tb;
-    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
-        if (n == 0)
-            gen_op_goto_tb0(TBPARAM(tb));
-        else
-            gen_op_goto_tb1(TBPARAM(tb));
+    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+        !ctx->singlestep_enabled) {
+        tcg_gen_goto_tb(n);
         gen_set_T1(dest);
 #if defined(TARGET_PPC64)
         if (ctx->sf_mode)
         gen_set_T1(dest);
 #if defined(TARGET_PPC64)
         if (ctx->sf_mode)
@@ -2810,10 +2793,7 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
         else
 #endif
             gen_op_b_T1();
         else
 #endif
             gen_op_b_T1();
-        gen_op_set_T0((long)tb + n);
-        if (ctx->singlestep_enabled)
-            gen_op_debug();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb((long)tb + n);
     } else {
         gen_set_T1(dest);
 #if defined(TARGET_PPC64)
     } else {
         gen_set_T1(dest);
 #if defined(TARGET_PPC64)
@@ -2822,10 +2802,9 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
         else
 #endif
             gen_op_b_T1();
         else
 #endif
             gen_op_b_T1();
-        gen_op_reset_T0();
         if (ctx->singlestep_enabled)
             gen_op_debug();
         if (ctx->singlestep_enabled)
             gen_op_debug();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
 }
 
     }
 }
 
@@ -2934,7 +2913,6 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
                 else
 #endif
                     gen_op_b_T1();
                 else
 #endif
                     gen_op_b_T1();
-                gen_op_reset_T0();
                 goto no_test;
             }
             break;
                 goto no_test;
             }
             break;
@@ -3005,11 +2983,10 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
         else
 #endif
             gen_op_btest_T1(ctx->nip);
         else
 #endif
             gen_op_btest_T1(ctx->nip);
-        gen_op_reset_T0();
     no_test:
         if (ctx->singlestep_enabled)
             gen_op_debug();
     no_test:
         if (ctx->singlestep_enabled)
             gen_op_debug();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
  out:
     ctx->exception = POWERPC_EXCP_BRANCH;
     }
  out:
     ctx->exception = POWERPC_EXCP_BRANCH;
@@ -6176,13 +6153,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     int j, lj = -1;
 
     pc_start = tb->pc;
     int j, lj = -1;
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
 #if defined(OPTIMIZE_FPRF_UPDATE)
     gen_fprf_ptr = gen_fprf_buf;
 #endif
 #if defined(OPTIMIZE_FPRF_UPDATE)
     gen_fprf_ptr = gen_fprf_buf;
 #endif
-    nb_gen_labels = 0;
     ctx.nip = pc_start;
     ctx.tb = tb;
     ctx.exception = POWERPC_EXCP_NONE;
     ctx.nip = pc_start;
     ctx.tb = tb;
     ctx.exception = POWERPC_EXCP_NONE;
@@ -6332,9 +6306,8 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     if (ctx.exception == POWERPC_EXCP_NONE) {
         gen_goto_tb(&ctx, 0, ctx.nip);
     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
     if (ctx.exception == POWERPC_EXCP_NONE) {
         gen_goto_tb(&ctx, 0, ctx.nip);
     } else if (ctx.exception != POWERPC_EXCP_BRANCH) {
-        gen_op_reset_T0();
         /* Generate the return instruction */
         /* Generate the return instruction */
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     *gen_opc_ptr = INDEX_op_end;
     if (unlikely(search_pc)) {
     }
     *gen_opc_ptr = INDEX_op_end;
     if (unlikely(search_pc)) {
@@ -6358,11 +6331,6 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
         fprintf(logfile, "\n");
     }
         target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
         fprintf(logfile, "\n");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-        fprintf(logfile, "OP:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
 #endif
     return 0;
 }
 #endif
     return 0;
 }
index 1004ef4..955610a 100644 (file)
@@ -161,12 +161,6 @@ void OPPROTO op_rts(void)
     RETURN();
 }
 
     RETURN();
 }
 
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-    RETURN();
-}
-
 void OPPROTO op_addl_imm_T0(void)
 {
     T0 += PARAM1;
 void OPPROTO op_addl_imm_T0(void)
 {
     T0 += PARAM1;
@@ -947,18 +941,6 @@ void OPPROTO op_movl_FT0_fpul(void)
     RETURN();
 }
 
     RETURN();
 }
 
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-    RETURN();
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-    RETURN();
-}
-
 void OPPROTO op_movl_imm_PC(void)
 {
     env->pc = PARAM1;
 void OPPROTO op_movl_imm_PC(void)
 {
     env->pc = PARAM1;
index 802f926..0c66e0b 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) ((long)(x))
-#endif
-
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
-
-#include "gen-op.h"
+#include "tcg-op.h"
 
 typedef struct DisasContext {
     struct TranslationBlock *tb;
 
 typedef struct DisasContext {
     struct TranslationBlock *tb;
@@ -172,18 +155,15 @@ static void gen_goto_tb(DisasContext * ctx, int n, target_ulong dest)
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
        !ctx->singlestep_enabled) {
        /* Use a direct jump if in same page and singlestep not enabled */
     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
        !ctx->singlestep_enabled) {
        /* Use a direct jump if in same page and singlestep not enabled */
-       if (n == 0)
-           gen_op_goto_tb0(TBPARAM(tb));
-       else
-           gen_op_goto_tb1(TBPARAM(tb));
-       gen_op_movl_imm_T0((long) tb + n);
+        tcg_gen_goto_tb(n);
+        gen_op_movl_imm_PC(dest);
+        tcg_gen_exit_tb((long) tb + n);
     } else {
     } else {
-       gen_op_movl_imm_T0(0);
+        gen_op_movl_imm_PC(dest);
+        if (ctx->singlestep_enabled)
+            gen_op_debug();
+        tcg_gen_exit_tb(0);
     }
     }
-    gen_op_movl_imm_PC(dest);
-    if (ctx->singlestep_enabled)
-       gen_op_debug();
-    gen_op_exit_tb();
 }
 
 static void gen_jump(DisasContext * ctx)
 }
 
 static void gen_jump(DisasContext * ctx)
@@ -192,10 +172,9 @@ static void gen_jump(DisasContext * ctx)
        /* Target is not statically known, it comes necessarily from a
           delayed jump as immediate jump are conditinal jumps */
        gen_op_movl_delayed_pc_PC();
        /* Target is not statically known, it comes necessarily from a
           delayed jump as immediate jump are conditinal jumps */
        gen_op_movl_delayed_pc_PC();
-       gen_op_movl_imm_T0(0);
        if (ctx->singlestep_enabled)
            gen_op_debug();
        if (ctx->singlestep_enabled)
            gen_op_debug();
-       gen_op_exit_tb();
+       tcg_gen_exit_tb(0);
     } else {
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
     }
     } else {
        gen_goto_tb(ctx, 0, ctx->delayed_pc);
     }
@@ -1176,9 +1155,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
     int i, ii;
 
     pc_start = tb->pc;
     int i, ii;
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
     ctx.pc = pc_start;
     ctx.flags = (uint32_t)tb->flags;
     ctx.bstate = BS_NONE;
     ctx.pc = pc_start;
     ctx.flags = (uint32_t)tb->flags;
     ctx.bstate = BS_NONE;
@@ -1190,7 +1167,6 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
     ctx.tb = tb;
     ctx.singlestep_enabled = env->singlestep_enabled;
     ctx.delayed_pc = -1; /* use delayed pc from env pointer */
     ctx.tb = tb;
     ctx.singlestep_enabled = env->singlestep_enabled;
-    nb_gen_labels = 0;
 
 #ifdef DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_CPU) {
 
 #ifdef DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_CPU) {
@@ -1254,8 +1230,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
             break;
         case BS_EXCP:
             /* gen_op_interrupt_restart(); */
             break;
         case BS_EXCP:
             /* gen_op_interrupt_restart(); */
-            gen_op_movl_imm_T0(0);
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         case BS_BRANCH:
         default:
             break;
         case BS_BRANCH:
         default:
@@ -1283,11 +1258,6 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
        fprintf(logfile, "\n");
     }
        target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
        fprintf(logfile, "\n");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-       fprintf(logfile, "OP:\n");
-       dump_ops(gen_opc_buf, gen_opparam_buf);
-       fprintf(logfile, "\n");
-    }
 #endif
     return 0;
 }
 #endif
     return 0;
 }
index 52b824c..1b5b21b 100644 (file)
@@ -1277,11 +1277,6 @@ void OPPROTO op_debug(void)
     helper_debug();
 }
 
     helper_debug();
 }
 
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-}
-
 void OPPROTO op_eval_ba(void)
 {
     T2 = 1;
 void OPPROTO op_eval_ba(void)
 {
     T2 = 1;
@@ -1542,16 +1537,6 @@ void OPPROTO op_next_insn(void)
     env->npc = env->npc + 4;
 }
 
     env->npc = env->npc + 4;
 }
 
-void OPPROTO op_goto_tb0(void)
-{
-    GOTO_TB(op_goto_tb0, PARAM1, 0);
-}
-
-void OPPROTO op_goto_tb1(void)
-{
-    GOTO_TB(op_goto_tb1, PARAM1, 1);
-}
-
 void OPPROTO op_jmp_label(void)
 {
     GOTO_LABEL_PARAM(1);
 void OPPROTO op_jmp_label(void)
 {
     GOTO_LABEL_PARAM(1);
index ecec372..8286c42 100644 (file)
@@ -36,6 +36,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 #define DEBUG_DISAS
 
 
 #define DEBUG_DISAS
 
@@ -65,20 +66,9 @@ struct sparc_def_t {
 
 static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
 
 
 static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
 
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 extern FILE *logfile;
 extern int loglevel;
 
 extern FILE *logfile;
 extern int loglevel;
 
-enum {
-#define DEF(s,n,copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS
-};
-
-#include "gen-op.h"
-
 // This function uses non-native bit order
 #define GET_FIELD(X, FROM, TO) \
   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
 // This function uses non-native bit order
 #define GET_FIELD(X, FROM, TO) \
   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
@@ -98,12 +88,6 @@ enum {
 #define QFPREG(r) (r & 0x1c)
 #endif
 
 #define QFPREG(r) (r & 0x1c)
 #endif
 
-#ifdef USE_DIRECT_JUMP
-#define TBPARAM(x)
-#else
-#define TBPARAM(x) (long)(x)
-#endif
-
 static int sign_extend(int x, int len)
 {
     len = 32 - len;
 static int sign_extend(int x, int len)
 {
     len = 32 - len;
@@ -699,20 +683,15 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num,
     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
         (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
         (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
-        if (tb_num == 0)
-            gen_op_goto_tb0(TBPARAM(tb));
-        else
-            gen_op_goto_tb1(TBPARAM(tb));
+        tcg_gen_goto_tb(tb_num);
         gen_jmp_im(pc);
         gen_movl_npc_im(npc);
         gen_jmp_im(pc);
         gen_movl_npc_im(npc);
-        gen_op_movl_T0_im((long)tb + tb_num);
-        gen_op_exit_tb();
+        tcg_gen_exit_tb((long)tb + tb_num);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(pc);
         gen_movl_npc_im(npc);
     } else {
         /* jump to another page: currently not optimized */
         gen_jmp_im(pc);
         gen_movl_npc_im(npc);
-        gen_op_movl_T0_0();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
 }
 
     }
 }
 
@@ -1281,8 +1260,7 @@ static void disas_sparc_insn(DisasContext * dc)
                     gen_op_trapcc_T0();
                 }
                 gen_op_next_insn();
                     gen_op_trapcc_T0();
                 }
                 gen_op_next_insn();
-                gen_op_movl_T0_0();
-                gen_op_exit_tb();
+                tcg_gen_exit_tb(0);
                 dc->is_br = 1;
                 goto jmp_insn;
             } else if (xop == 0x28) {
                 dc->is_br = 1;
                 goto jmp_insn;
             } else if (xop == 0x28) {
@@ -2341,8 +2319,7 @@ static void disas_sparc_insn(DisasContext * dc)
                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
                                 save_state(dc);
                                 gen_op_next_insn();
                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
                                 save_state(dc);
                                 gen_op_next_insn();
-                                gen_op_movl_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 dc->is_br = 1;
                                 break;
                             case 0xf: /* V9 sir, nop if user */
                                 dc->is_br = 1;
                                 break;
                             case 0xf: /* V9 sir, nop if user */
@@ -2422,8 +2399,7 @@ static void disas_sparc_insn(DisasContext * dc)
                             gen_op_wrpsr();
                             save_state(dc);
                             gen_op_next_insn();
                             gen_op_wrpsr();
                             save_state(dc);
                             gen_op_next_insn();
-                            gen_op_movl_T0_0();
-                            gen_op_exit_tb();
+                            tcg_gen_exit_tb(0);
                             dc->is_br = 1;
 #endif
                         }
                             dc->is_br = 1;
 #endif
                         }
@@ -2457,8 +2433,7 @@ static void disas_sparc_insn(DisasContext * dc)
                                 gen_op_wrpstate();
                                 save_state(dc);
                                 gen_op_next_insn();
                                 gen_op_wrpstate();
                                 save_state(dc);
                                 gen_op_next_insn();
-                                gen_op_movl_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 dc->is_br = 1;
                                 break;
                             case 7: // tl
                                 dc->is_br = 1;
                                 break;
                             case 7: // tl
@@ -2517,8 +2492,7 @@ static void disas_sparc_insn(DisasContext * dc)
                                 // XXX gen_op_wrhpstate();
                                 save_state(dc);
                                 gen_op_next_insn();
                                 // XXX gen_op_wrhpstate();
                                 save_state(dc);
                                 gen_op_next_insn();
-                                gen_op_movl_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 dc->is_br = 1;
                                 break;
                             case 1: // htstate
                                 dc->is_br = 1;
                                 break;
                             case 1: // htstate
@@ -3635,10 +3609,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
     dc->npc = (target_ulong) tb->cs_base;
     dc->mem_idx = cpu_mmu_index(env);
     dc->fpu_enabled = cpu_fpu_enabled(env);
     dc->npc = (target_ulong) tb->cs_base;
     dc->mem_idx = cpu_mmu_index(env);
     dc->fpu_enabled = cpu_fpu_enabled(env);
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
-    nb_gen_labels = 0;
 
     do {
         if (env->nb_breakpoints > 0) {
 
     do {
         if (env->nb_breakpoints > 0) {
@@ -3647,8 +3618,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
                     if (dc->pc != pc_start)
                         save_state(dc);
                     gen_op_debug();
                     if (dc->pc != pc_start)
                         save_state(dc);
                     gen_op_debug();
-                    gen_op_movl_T0_0();
-                    gen_op_exit_tb();
+                    tcg_gen_exit_tb(0);
                     dc->is_br = 1;
                     goto exit_gen_loop;
                 }
                     dc->is_br = 1;
                     goto exit_gen_loop;
                 }
@@ -3683,8 +3653,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
            generate an exception */
         if (env->singlestep_enabled) {
             gen_jmp_im(dc->pc);
            generate an exception */
         if (env->singlestep_enabled) {
             gen_jmp_im(dc->pc);
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             break;
         }
     } while ((gen_opc_ptr < gen_opc_end) &&
             break;
         }
     } while ((gen_opc_ptr < gen_opc_end) &&
@@ -3700,8 +3669,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
             if (dc->pc != DYNAMIC_PC)
                 gen_jmp_im(dc->pc);
             save_npc(dc);
             if (dc->pc != DYNAMIC_PC)
                 gen_jmp_im(dc->pc);
             save_npc(dc);
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
         }
     }
     *gen_opc_ptr = INDEX_op_end;
         }
     }
     *gen_opc_ptr = INDEX_op_end;
@@ -3726,11 +3694,6 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
         fprintf(logfile, "\n");
         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
         target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
         fprintf(logfile, "\n");
-        if (loglevel & CPU_LOG_TB_OP) {
-            fprintf(logfile, "OP:\n");
-            dump_ops(gen_opc_buf, gen_opparam_buf);
-            fprintf(logfile, "\n");
-        }
     }
 #endif
     return 0;
     }
 #endif
     return 0;
@@ -3746,8 +3709,6 @@ int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
     return gen_intermediate_code_internal(tb, 1, env);
 }
 
     return gen_intermediate_code_internal(tb, 1, env);
 }
 
-extern int ram_size;
-
 void cpu_reset(CPUSPARCState *env)
 {
     tlb_flush(env, 1);
 void cpu_reset(CPUSPARCState *env)
 {
     tlb_flush(env, 1);
index d8b9102..9639612 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg.h"
 
 
-extern int dyngen_code(uint8_t *gen_code_buf,
-                       uint16_t *label_offsets, uint16_t *jmp_offsets,
-                       const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels);
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
+/* code generation context */
+TCGContext tcg_ctx;
 
 uint16_t gen_opc_buf[OPC_BUF_SIZE];
 
 uint16_t gen_opc_buf[OPC_BUF_SIZE];
-uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
-long gen_labels[OPC_BUF_SIZE];
-int nb_gen_labels;
+TCGArg gen_opparam_buf[OPPARAM_BUF_SIZE];
 
 target_ulong gen_opc_pc[OPC_BUF_SIZE];
 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
 
 target_ulong gen_opc_pc[OPC_BUF_SIZE];
 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
@@ -59,86 +50,29 @@ uint32_t gen_opc_hflags[OPC_BUF_SIZE];
 
 int code_copy_enabled = 1;
 
 
 int code_copy_enabled = 1;
 
-#ifdef DEBUG_DISAS
-static const char *op_str[] = {
-#define DEF(s, n, copy_size) #s,
-#include "opc.h"
-#undef DEF
-};
-
-static uint8_t op_nb_args[] = {
-#define DEF(s, n, copy_size) n,
-#include "opc.h"
-#undef DEF
-};
-
-static const unsigned short opc_copy_size[] = {
-#define DEF(s, n, copy_size) copy_size,
-#include "opc.h"
-#undef DEF
-};
-
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
-{
-    const uint16_t *opc_ptr;
-    const uint32_t *opparam_ptr;
-    int c, n, i;
-
-    opc_ptr = opc_buf;
-    opparam_ptr = opparam_buf;
-    for(;;) {
-        c = *opc_ptr++;
-        n = op_nb_args[c];
-        fprintf(logfile, "0x%04x: %s",
-                (int)(opc_ptr - opc_buf - 1), op_str[c]);
-        for(i = 0; i < n; i++) {
-            fprintf(logfile, " 0x%x", opparam_ptr[i]);
-        }
-        fprintf(logfile, "\n");
-        if (c == INDEX_op_end)
-            break;
-        opparam_ptr += n;
-    }
-}
-
+#ifdef CONFIG_PROFILER
+int64_t dyngen_tb_count1;
+int64_t dyngen_tb_count;
+int64_t dyngen_op_count;
+int64_t dyngen_old_op_count;
+int64_t dyngen_tcg_del_op_count;
+int dyngen_op_count_max;
+int64_t dyngen_code_in_len;
+int64_t dyngen_code_out_len;
+int64_t dyngen_interm_time;
+int64_t dyngen_code_time;
+int64_t dyngen_restore_count;
+int64_t dyngen_restore_time;
 #endif
 
 #endif
 
-/* compute label info */
-static void dyngen_labels(long *gen_labels, int nb_gen_labels,
-                          uint8_t *gen_code_buf, const uint16_t *opc_buf)
-{
-    uint8_t *gen_code_ptr;
-    int c, i;
-    unsigned long gen_code_addr[OPC_BUF_SIZE];
-
-    if (nb_gen_labels == 0)
-        return;
-    /* compute the address of each op code */
-
-    gen_code_ptr = gen_code_buf;
-    i = 0;
-    for(;;) {
-        c = opc_buf[i];
-        gen_code_addr[i] =(unsigned long)gen_code_ptr;
-        if (c == INDEX_op_end)
-            break;
-        gen_code_ptr += opc_copy_size[c];
-        i++;
-    }
-
-    /* compute the address of each label */
-    for(i = 0; i < nb_gen_labels; i++) {
-        gen_labels[i] = gen_code_addr[gen_labels[i]];
-    }
-}
-
+/* XXX: suppress that */
 unsigned long code_gen_max_block_size(void)
 {
     static unsigned long max;
 
     if (max == 0) {
 #define DEF(s, n, copy_size) max = copy_size > max? copy_size : max;
 unsigned long code_gen_max_block_size(void)
 {
     static unsigned long max;
 
     if (max == 0) {
 #define DEF(s, n, copy_size) max = copy_size > max? copy_size : max;
-#include "opc.h"
+#include "tcg-opc.h"
 #undef DEF
         max *= OPC_MAX_SIZE;
     }
 #undef DEF
         max *= OPC_MAX_SIZE;
     }
@@ -146,6 +80,13 @@ unsigned long code_gen_max_block_size(void)
     return max;
 }
 
     return max;
 }
 
+void cpu_gen_init(void)
+{
+    tcg_context_init(&tcg_ctx); 
+    tcg_set_frame(&tcg_ctx, TCG_AREG0, offsetof(CPUState, temp_buf),
+                  128 * sizeof(long));
+}
+
 /* return non zero if the very first instruction is invalid so that
    the virtual CPU can trigger an exception.
 
 /* return non zero if the very first instruction is invalid so that
    the virtual CPU can trigger an exception.
 
@@ -154,31 +95,53 @@ unsigned long code_gen_max_block_size(void)
 */
 int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 {
 */
 int cpu_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr)
 {
+    TCGContext *s = &tcg_ctx;
     uint8_t *gen_code_buf;
     int gen_code_size;
     uint8_t *gen_code_buf;
     int gen_code_size;
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
+
+#ifdef CONFIG_PROFILER
+    dyngen_tb_count1++; /* includes aborted translations because of
+                           exceptions */
+    ti = profile_getclock();
+#endif
+    tcg_func_start(s);
 
     if (gen_intermediate_code(env, tb) < 0)
         return -1;
     
     /* generate machine code */
 
     if (gen_intermediate_code(env, tb) < 0)
         return -1;
     
     /* generate machine code */
+    gen_code_buf = tb->tc_ptr;
     tb->tb_next_offset[0] = 0xffff;
     tb->tb_next_offset[1] = 0xffff;
     tb->tb_next_offset[0] = 0xffff;
     tb->tb_next_offset[1] = 0xffff;
-    gen_code_buf = tb->tc_ptr;
+    s->tb_next_offset = tb->tb_next_offset;
 #ifdef USE_DIRECT_JUMP
 #ifdef USE_DIRECT_JUMP
+    s->tb_jmp_offset = tb->tb_jmp_offset;
+    s->tb_next = NULL;
     /* the following two entries are optional (only used for string ops) */
     /* the following two entries are optional (only used for string ops) */
+    /* XXX: not used ? */
     tb->tb_jmp_offset[2] = 0xffff;
     tb->tb_jmp_offset[3] = 0xffff;
     tb->tb_jmp_offset[2] = 0xffff;
     tb->tb_jmp_offset[3] = 0xffff;
-#endif
-    dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
-    
-    gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
-#ifdef USE_DIRECT_JUMP
-                                tb->tb_jmp_offset,
 #else
 #else
-                                NULL,
+    s->tb_jmp_offset = NULL;
+    s->tb_next = tb->tb_next;
 #endif
 #endif
-                                gen_opc_buf, gen_opparam_buf, gen_labels);
+
+#ifdef CONFIG_PROFILER
+    dyngen_tb_count++;
+    dyngen_interm_time += profile_getclock() - ti;
+    dyngen_code_time -= profile_getclock();
+#endif
+    gen_code_size = dyngen_code(s, gen_code_buf);
     *gen_code_size_ptr = gen_code_size;
     *gen_code_size_ptr = gen_code_size;
+#ifdef CONFIG_PROFILER
+    dyngen_code_time += profile_getclock();
+    dyngen_code_in_len += tb->size;
+    dyngen_code_out_len += gen_code_size;
+#endif
+
 #ifdef DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_OUT_ASM) {
         fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
 #ifdef DEBUG_DISAS
     if (loglevel & CPU_LOG_TB_OUT_ASM) {
         fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
@@ -196,9 +159,17 @@ int cpu_restore_state(TranslationBlock *tb,
                       CPUState *env, unsigned long searched_pc,
                       void *puc)
 {
                       CPUState *env, unsigned long searched_pc,
                       void *puc)
 {
-    int j, c;
+    TCGContext *s = &tcg_ctx;
+    int j;
     unsigned long tc_ptr;
     unsigned long tc_ptr;
-    uint16_t *opc_ptr;
+#ifdef CONFIG_PROFILER
+    int64_t ti;
+#endif
+
+#ifdef CONFIG_PROFILER
+    ti = profile_getclock();
+#endif
+    tcg_func_start(s);
 
     if (gen_intermediate_code_pc(env, tb) < 0)
         return -1;
 
     if (gen_intermediate_code_pc(env, tb) < 0)
         return -1;
@@ -207,18 +178,19 @@ int cpu_restore_state(TranslationBlock *tb,
     tc_ptr = (unsigned long)tb->tc_ptr;
     if (searched_pc < tc_ptr)
         return -1;
     tc_ptr = (unsigned long)tb->tc_ptr;
     if (searched_pc < tc_ptr)
         return -1;
-    j = 0;
-    opc_ptr = gen_opc_buf;
-    for(;;) {
-        c = *opc_ptr;
-        if (c == INDEX_op_end)
-            return -1;
-        tc_ptr += opc_copy_size[c];
-        if (searched_pc < tc_ptr)
-            break;
-        opc_ptr++;
-    }
-    j = opc_ptr - gen_opc_buf;
+
+    s->tb_next_offset = tb->tb_next_offset;
+#ifdef USE_DIRECT_JUMP
+    s->tb_jmp_offset = tb->tb_jmp_offset;
+    s->tb_next = NULL;
+#else
+    s->tb_jmp_offset = NULL;
+    s->tb_next = tb->tb_next;
+#endif
+    j = dyngen_code_search_pc(s, (uint8_t *)tc_ptr, 
+                              (void *)searched_pc); 
+    if (j < 0)
+        return -1;
     /* now find start of instruction before */
     while (gen_opc_instr_start[j] == 0)
         j--;
     /* now find start of instruction before */
     while (gen_opc_instr_start[j] == 0)
         j--;
@@ -266,10 +238,11 @@ int cpu_restore_state(TranslationBlock *tb,
     }
 #elif defined(TARGET_PPC)
     {
     }
 #elif defined(TARGET_PPC)
     {
-        int type;
+        int type, c;
         /* for PPC, we need to look at the micro operation to get the
            access type */
         env->nip = gen_opc_pc[j];
         /* for PPC, we need to look at the micro operation to get the
            access type */
         env->nip = gen_opc_pc[j];
+        c = gen_opc_buf[j];
         switch(c) {
 #if defined(CONFIG_USER_ONLY)
 #define CASE3(op)\
         switch(c) {
 #if defined(CONFIG_USER_ONLY)
 #define CASE3(op)\
@@ -315,5 +288,10 @@ int cpu_restore_state(TranslationBlock *tb,
     env->pc = gen_opc_pc[j];
     env->flags = gen_opc_hflags[j];
 #endif
     env->pc = gen_opc_pc[j];
     env->flags = gen_opc_hflags[j];
 #endif
+
+#ifdef CONFIG_PROFILER
+    dyngen_restore_time += profile_getclock() - ti;
+    dyngen_restore_count++;
+#endif
     return 0;
 }
     return 0;
 }
diff --git a/translate-op.c b/translate-op.c
deleted file mode 100644 (file)
index 8104e86..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Host code generation
- *
- *  Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-#include "config.h"
-#include "osdep.h"
-
-enum {
-#define DEF(s, n, copy_size) INDEX_op_ ## s,
-#include "opc.h"
-#undef DEF
-    NB_OPS,
-};
-
-#include "dyngen.h"
-extern int dyngen_code(uint8_t *gen_code_buf,
-                       uint16_t *label_offsets, uint16_t *jmp_offsets,
-                       const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels);
-#include "op.h"
-