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.
 
-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
index 8a94ad8..fca2192 100644 (file)
@@ -172,8 +172,11 @@ all: $(PROGS)
 
 #########################################################
 # 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
+# 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
@@ -268,16 +271,16 @@ libqemu.a: $(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 $@ $<
 
-opc.h: op.o $(DYNGEN)
+dyngen-opc.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:
-       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),)
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/tcg
 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 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 */
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];           \
+    long temp_buf[128]; /* buffer for temporaries in the code generator */ \
                                                                         \
     /* 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;
-    void (*gen_func)(void);
+    long (*gen_func)(void);
     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
-                gen_func();
+                T0 = gen_func();
 #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 */
 
-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)) {
-        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] == '.')
@@ -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);
     }
+    return 0;
 }
 
 #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];
-                int type;
+                int type, is_label;
                 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;
                     }
 
-                    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);
-                    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)
                     {
@@ -1920,32 +1935,45 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
 #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;
-                    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;
-                    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) {
-        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);
@@ -2653,7 +2676,6 @@ int gen_file(FILE *outfile, int out_type)
         }
     } 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);
@@ -2670,6 +2692,7 @@ int gen_file(FILE *outfile, int out_type)
         /* 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,
@@ -2690,16 +2713,8 @@ fprintf(outfile,
 "};\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
+#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
@@ -2732,6 +2747,7 @@ fprintf(outfile,
 "    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;
@@ -2789,18 +2805,8 @@ fprintf(outfile,
     }
 #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
+#error broken
 /* 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
 
-fprintf(outfile,
-"        switch(*opc_ptr++) {\n");
-
         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);
             }
         }
-
-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;
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)
 
-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];
@@ -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);
-void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf);
 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,
@@ -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
+/* XXX: make it dynamic on x86 */
 #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)
 
-#if defined(__powerpc__)
+#if defined(__powerpc__) || defined(__x86_64__)
 #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
-    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
@@ -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");
 }
-#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 */
@@ -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)
 
-#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];
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) {
+        cpu_gen_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",
-      "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",
-      "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" },
@@ -2935,6 +2936,7 @@ void dump_exec_info(FILE *f,
         }
     }
     /* 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,
@@ -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);
+    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);
+#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)
index da93e7c..957c651 100644 (file)
@@ -216,11 +216,6 @@ void OPPROTO op_clear_irf (void)
     RETURN();
 }
 
-void OPPROTO op_exit_tb (void)
-{
-    EXIT_TB();
-}
-
 /* 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 "tcg-op.h"
 
 #define DO_SINGLE_STEP
 #define GENERATE_NOP
@@ -41,24 +42,6 @@ struct DisasContext {
     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)
@@ -1988,10 +1971,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     int ret;
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     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)
@@ -2051,12 +2031,11 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
     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 */
-    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;
@@ -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");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-        fprintf(logfile, "OP:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
 #endif
 
     return 0;
index 216944a..c2d33ca 100644 (file)
@@ -364,21 +364,6 @@ void OPPROTO op_testn_T0(void)
     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.  */
index 513b179..6de78f8 100644 (file)
@@ -28,6 +28,7 @@
 #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)
@@ -68,27 +69,10 @@ typedef struct DisasContext {
 #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 */
-static uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 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, \
@@ -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)) {
-        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((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();
-        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;
 
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
 
     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;
-    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.  */
@@ -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 */
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             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");
-        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) {
index 3c50574..c7243b1 100644 (file)
 
 /* 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;
@@ -1268,7 +1251,7 @@ void OPPROTO op_movl_btarget_T0 (void)
        RETURN();
 }
 
-void OPPROTO op_jmp (void)
+void OPPROTO op_jmp1 (void)
 {
        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 "tcg-op.h"
 #include "crisv32-decode.h"
 
 #define CRIS_STATS 0
 #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 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;
@@ -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)) {
-               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 {
-               gen_op_movl_T0_0();
+            tcg_gen_exit_tb(0);
        }
-       gen_op_exit_tb();
 }
 
 /* Sign extend at translation time.  */
@@ -2325,9 +2308,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
        dc->env = env;
        dc->tb = tb;
 
-       gen_opc_ptr = gen_opc_buf;
        gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-       gen_opparam_ptr = gen_opparam_buf;
 
        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) {
-                                       gen_op_jmp ();
+                                       gen_op_jmp1 ();
                                        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 */
-                               /* 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 */
@@ -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");
-               if (loglevel & CPU_LOG_TB_OP) {
-                       fprintf(logfile, "OP:\n");
-                       dump_ops(gen_opc_buf, gen_opparam_buf);
-                       fprintf(logfile, "\n");
-               }
        }
 #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 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);
index 3c7424f..f526809 100644 (file)
@@ -1608,13 +1608,13 @@ int32_t idiv32(int64_t *q_ptr, int64_t num, int32_t den)
 }
 #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);
-    den = T0;
+    den = t0;
     if (den == 0) {
         raise_exception(EXCP00_DIVZ);
     }
@@ -1630,13 +1630,13 @@ void helper_divl_EAX_T0(void)
     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);
-    den = T0;
+    den = t0;
     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 */
 
-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;
@@ -217,18 +192,6 @@ void OPPROTO op_notl_T0(void)
     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 */
@@ -399,16 +362,6 @@ void OPPROTO op_idivw_AX_T0(void)
     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)
 {
@@ -424,46 +377,6 @@ void OPPROTO op_idivq_EAX_T0(void)
 /* 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;
@@ -474,26 +387,6 @@ void OPPROTO op_movl_T1_A0(void)
     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));
@@ -523,46 +416,6 @@ typedef union UREG64 {
 
 #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));
@@ -570,11 +423,6 @@ void OPPROTO op_addq_A0_AL(void)
 
 #endif
 
-void OPPROTO op_andl_A0_ffff(void)
-{
-    A0 = A0 & 0xffff;
-}
-
 /* memory access */
 
 #define MEMSUFFIX _raw
@@ -588,30 +436,6 @@ void OPPROTO op_andl_A0_ffff(void)
 #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();
@@ -735,16 +559,6 @@ void OPPROTO op_single_step(void)
     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
@@ -879,75 +693,6 @@ void OPPROTO op_decq_ECX(void)
 }
 #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();
@@ -1362,16 +1107,6 @@ void OPPROTO op_clts(void)
 
 /* 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);
@@ -1451,11 +1186,6 @@ void OPPROTO op_xor_T0_1(void)
     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();
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
  */
-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)
 {
@@ -132,8 +28,15 @@ void OPPROTO glue(glue(op_cmovw,REGNAME),_T1_T0)(void)
 
 void OPPROTO glue(glue(op_cmovl,REGNAME),_T1_T0)(void)
 {
+#ifdef TARGET_X86_64
     if (T0)
         REG = (uint32_t)T1;
+    else
+        REG = (uint32_t)REG;
+#else
+    if (T0)
+        REG = (uint32_t)T1;
+#endif
     FORCE_RET();
 }
 
@@ -145,46 +48,3 @@ void OPPROTO glue(glue(op_cmovq,REGNAME),_T1_T0)(void)
     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"
-
-/* 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
@@ -57,14 +55,79 @@ static uint32_t *gen_opparam_ptr;
 #define REX_B(s) 0
 #endif
 
+//#define MACRO_TEST   1
+
 #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
 
-#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 {
@@ -131,15 +194,6 @@ enum {
     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,
@@ -164,6 +218,73 @@ enum {
     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
@@ -186,45 +307,6 @@ enum {
   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
@@ -241,218 +323,227 @@ DEF_BREGS(gen_op_movl_T1_, gen_op_movh_T1_, )
 
 #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
-        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
-    },
-    [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
-    [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
-};
+    }
+}
 
-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
-        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
-        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
-    },
-    [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
-    [OT_QUAD] = {
-        DEF_REGS(gen_op_movq_, _T1)
-    },
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
 #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
-    [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
-};
+    
+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
-            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
-        },
-        {
-            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
-            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
-        },
-    },
-    [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
-    [OT_QUAD] = {
-        {
-            DEF_REGS(gen_op_movl_T0_, )
-        },
-        {
-            DEF_REGS(gen_op_movl_T1_, )
-        },
-    },
+    tcg_gen_andi_tl(cpu_A0, cpu_A0, 0xffffffff);
 #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
-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] = {
@@ -469,17 +560,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
 #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,\
@@ -681,133 +761,113 @@ static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
 #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) */
-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)
 {
-#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)
@@ -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) {
-            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 {
-            gen_op_movq_A0_reg[R_ESI]();
+            gen_op_movq_A0_reg(R_ESI);
         }
     } 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) {
-            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 {
-            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;
-        gen_op_movl_A0_reg[R_ESI]();
+        gen_op_movl_A0_reg(R_ESI);
         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) {
-        gen_op_movq_A0_reg[R_EDI]();
+        gen_op_movq_A0_reg(R_EDI);
     } 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 {
-            gen_op_movl_A0_reg[R_EDI]();
+            gen_op_movl_A0_reg(R_EDI);
         }
     } else {
-        gen_op_movl_A0_reg[R_EDI]();
+        gen_op_movl_A0_reg(R_EDI);
         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);
-    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_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) {
@@ -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)
 {
-    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_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) {
@@ -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);
-    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) {
@@ -1038,9 +1098,9 @@ static inline void gen_lods(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_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
@@ -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);
-    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_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
@@ -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_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_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) {
@@ -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);
-    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
@@ -1320,9 +1380,9 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
     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 {
-        gen_op_ld_T0_A0[ot + s1->mem_index]();
+        gen_op_ld_T0_A0(ot + s1->mem_index);
     }
     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_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]();
         }
@@ -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_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:
+        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:
+        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:
-        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;
@@ -1363,9 +1431,9 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
     }
     if (op != OP_CMPL) {
         if (d != OR_TMP0)
-            gen_op_mov_reg_T0[ot][d]();
+            gen_op_mov_reg_T0(ot, d);
         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) */
@@ -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)
-        gen_op_mov_TN_reg[ot][0][d]();
+        gen_op_mov_TN_reg(ot, 0, d);
     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) {
@@ -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)
-        gen_op_mov_reg_T0[ot][d]();
+        gen_op_mov_reg_T0(ot, d);
     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_mov_TN_reg[ot][0][d]();
+        gen_op_mov_TN_reg(ot, 0, d);
     else
-        gen_op_ld_T0_A0[ot + s1->mem_index]();
+        gen_op_ld_T0_A0(ot + s1->mem_index);
     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);
@@ -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)
-        gen_op_mov_reg_T0[ot][d]();
+        gen_op_mov_reg_T0(ot, d);
     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) {
-                gen_op_movq_A0_reg[base]();
+                gen_op_movq_A0_reg(base);
                 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
             {
-                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 ((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
             {
@@ -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) {
-                gen_op_addq_A0_reg_sN[scale][index]();
+                gen_op_addq_A0_reg_sN(scale, index);
             } else
 #endif
             {
-                gen_op_addl_A0_reg_sN[scale][index]();
+                gen_op_addl_A0_reg_sN(scale, index);
             }
         }
         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) {
-                gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
+                gen_op_addq_A0_seg(override);
             } else
 #endif
             {
-                gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
+                gen_op_addl_A0_seg(override);
             }
         }
     } else {
@@ -1565,33 +1627,33 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
         }
         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:
-            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:
-            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:
-            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:
-            gen_op_movl_A0_reg[R_ESI]();
+            gen_op_movl_A0_reg(R_ESI);
             break;
         case 5:
-            gen_op_movl_A0_reg[R_EDI]();
+            gen_op_movl_A0_reg(R_EDI);
             break;
         case 6:
-            gen_op_movl_A0_reg[R_EBP]();
+            gen_op_movl_A0_reg(R_EBP);
             break;
         default:
         case 7:
-            gen_op_movl_A0_reg[R_EBX]();
+            gen_op_movl_A0_reg(R_EBX);
             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;
             }
-            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)) {
-            gen_op_addq_A0_seg(offsetof(CPUX86State,segs[override].base));
+            gen_op_addq_A0_seg(override);
         } 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)
-                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 {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
             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)
-                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 {
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
             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 (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_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);
@@ -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)
@@ -2091,26 +2145,13 @@ static inline void gen_stack_update(DisasContext *s, int addend)
 {
 #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) {
-        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 {
-        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)) {
-        gen_op_movq_A0_reg[R_ESP]();
+        gen_op_movq_A0_reg(R_ESP);
         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 {
-            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
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (!s->dflag)
-            gen_op_subl_A0_2();
+            gen_op_addl_A0_im(-2);
         else
-            gen_op_subl_A0_4();
+            gen_op_addl_A0_im(-4);
         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();
-            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)
-            gen_op_movl_ESP_A0();
+            gen_op_mov_reg_A0(1, R_ESP);
         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)) {
-        gen_op_movq_A0_reg[R_ESP]();
+        gen_op_movq_A0_reg(R_ESP);
         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 {
-            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
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (!s->dflag)
-            gen_op_subl_A0_2();
+            gen_op_addl_A0_im(-2);
         else
-            gen_op_subl_A0_4();
+            gen_op_addl_A0_im(-4);
         if (s->ss32) {
             if (s->addseg) {
-                gen_op_addl_A0_SS();
+                gen_op_addl_A0_seg(R_SS);
             }
         } 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)
-            gen_op_movl_ESP_A0();
+            gen_op_mov_reg_A0(1, R_ESP);
         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)) {
-        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
     {
-        gen_op_movl_A0_reg[R_ESP]();
+        gen_op_movl_A0_reg(R_ESP);
         if (s->ss32) {
             if (s->addseg)
-                gen_op_addl_A0_SS();
+                gen_op_addl_A0_seg(R_SS);
         } 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)
 {
-    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)
-        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;
-    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_seg(offsetof(CPUX86State,segs[R_SS].base));
+        gen_op_addl_A0_seg(R_SS);
     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_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;
-    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)
-        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) {
-            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_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)
@@ -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;
 
-        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_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));
         }
-        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_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;
 
-        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_seg(offsetof(CPUX86State,segs[R_SS].base));
+            gen_op_addl_A0_seg(R_SS);
         /* 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);
         }
-        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_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 {
-        gen_op_movl_T0_0();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     s->is_jmp = 3;
 }
@@ -2399,42 +2439,6 @@ static void gen_jmp(DisasContext *s, target_ulong eip)
     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
@@ -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);
-                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)));
@@ -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)));
-                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)),
@@ -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]));
-            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]));
-            gen_op_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             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 {
-                    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);
@@ -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);
-            gen_op_mov_reg_T0[ot][reg]();
+            gen_op_mov_reg_T0(ot, reg);
             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_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             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_mov_reg_T0[OT_LONG][reg]();
+            gen_op_mov_reg_T0(OT_LONG, reg);
             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) {
-                gen_op_movq_A0_reg[R_EDI]();
+                gen_op_movq_A0_reg(R_EDI);
             } 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();
             }
@@ -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 */
-                        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 */
@@ -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;
-                    gen_op_mov_reg_T0[ot][reg]();
+                    gen_op_mov_reg_T0(ot, reg);
                     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 */
@@ -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);
-                    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 {
-                    gen_op_mov_TN_reg[ot][1][rm]();
+                    gen_op_mov_TN_reg(ot, 1, rm);
                 }
                 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);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
 
         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) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } 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) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } 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;
@@ -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);
-                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:
@@ -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);
-                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:
@@ -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)
-                gen_op_ld_T0_A0[ot + s->mem_index]();
+                gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
 
         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_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_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)
@@ -3723,9 +3732,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             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_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)
@@ -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);
-        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;
@@ -3773,7 +3782,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             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;
@@ -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 {
-            gen_op_mov_TN_reg[ot][1][reg]();
+            gen_op_mov_TN_reg(ot, 1, reg);
         }
 
 #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();
         }
-        gen_op_mov_reg_T0[ot][reg]();
+        gen_op_mov_reg_T0(ot, reg);
         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);
-            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_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);
-            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_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;
@@ -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;
-        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);
-            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_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T0(ot, rm);
         } 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;
@@ -3900,7 +3909,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         /**************************/
         /* 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 */
@@ -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_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))
@@ -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);
-            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;
@@ -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)) {
-            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) {
-            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 {
-            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)) {
@@ -3987,7 +3996,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
         } 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 */
@@ -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)
-            gen_op_st_T0_A0[ot + s->mem_index]();
+            gen_op_st_T0_A0(ot + s->mem_index);
         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 */
@@ -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);
-        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++);
@@ -4132,7 +4141,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             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();
@@ -4148,15 +4157,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                     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) {
-                    gen_op_lds_T0_A0[ot + s->mem_index]();
+                    gen_op_lds_T0_A0(ot + s->mem_index);
                 } 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;
@@ -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;
-        gen_op_mov_reg_A0[ot - OT_WORD][reg]();
+        gen_op_mov_reg_A0(ot - OT_WORD, reg);
         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 (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
             {
@@ -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_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 {
-                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) {
-            gen_op_movq_A0_reg[R_EBX]();
+            gen_op_movq_A0_reg(R_EBX);
             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_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);
-        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
@@ -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);
-            gen_op_mov_reg_T0[OT_QUAD][reg]();
+            gen_op_mov_reg_T0(OT_QUAD, reg);
         } 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);
-            gen_op_mov_reg_T0[ot][reg]();
+            gen_op_mov_reg_T0(ot, reg);
         }
         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:
-            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);
-            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();
-            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();
-            gen_op_mov_reg_T1[ot][reg]();
+            gen_op_mov_reg_T1(ot, reg);
         }
         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);
-        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_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_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);
@@ -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);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } 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++);
@@ -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) {
-            gen_op_mov_reg_T0[ot][rm]();
+            gen_op_mov_reg_T0(ot, rm);
         }
         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);
-        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)) |
@@ -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);
-        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) |
@@ -5018,7 +5024,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                              (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:
@@ -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;
-        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:
@@ -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;
-        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,
@@ -5049,7 +5055,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
                              (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:
@@ -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;
-        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_mov_TN_reg[ot][1][R_EAX]();
+        gen_op_mov_TN_reg(ot, 1, R_EAX);
         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 */
-            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
@@ -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_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));
@@ -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_op_ld_T1_A0[ot + s->mem_index]();
+            gen_op_ld_T1_A0(ot + s->mem_index);
         } 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;
@@ -5292,7 +5298,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
     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();
@@ -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();
-        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)
@@ -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);
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } else {
-            gen_op_mov_TN_reg[ot][0][rm]();
+            gen_op_mov_TN_reg(ot, 0, rm);
         }
         /* 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)
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             else
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             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);
-        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]();
-            gen_op_ld_T0_A0[ot + s->mem_index]();
+            gen_op_ld_T0_A0(ot + s->mem_index);
         } 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_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             else
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             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_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_mov_reg_T1[ot][reg]();
+        gen_op_mov_reg_T1(ot, reg);
         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;
-        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)
@@ -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) {
-            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
-#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))
@@ -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));
-            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_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) {
@@ -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_op_movq_A0_reg[R_EBX]();
+                        gen_op_movq_A0_reg(R_EBX);
                         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();
@@ -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));
-                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_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 */
@@ -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);
-                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_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) {
@@ -6029,19 +6046,19 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
             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();
-                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) {
-                    gen_op_lds_T0_A0[OT_LONG + s->mem_index]();
+                    gen_op_lds_T0_A0(OT_LONG + s->mem_index);
                 } 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
@@ -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);
-                gen_op_ld_T0_A0[ot + s->mem_index]();
+                gen_op_ld_T0_A0(ot + s->mem_index);
             } 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) {
-                gen_op_st_T0_A0[ot + s->mem_index]();
+                gen_op_st_T0_A0(ot + s->mem_index);
             } else {
-                gen_op_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
             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);
-        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)
@@ -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;
-        gen_op_mov_reg_T1[ot][reg]();
+        gen_op_mov_reg_T1(ot, reg);
         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);
-                    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);
@@ -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]));
-                    gen_op_mov_reg_T0[ot][rm]();
+                    gen_op_mov_reg_T0(ot, rm);
                 }
                 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);
-                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_mov_reg_T0[ot][rm]();
+                gen_op_mov_reg_T0(ot, rm);
             }
         }
         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) {
-                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_st_T0_A0[OT_LONG + s->mem_index]();
+                gen_op_st_T0_A0(OT_LONG + s->mem_index);
             }
             break;
         case 5: /* lfence */
@@ -6647,6 +6664,17 @@ static uint16_t opc_simpler[NB_OPS] = {
 #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;
@@ -6655,6 +6683,25 @@ void optimize_flags_init(void)
         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
@@ -6746,10 +6793,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
         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_opparam_ptr = gen_opparam_buf;
-    nb_gen_labels = 0;
 
     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");
-        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");
         }
     }
@@ -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);
 
-#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;
index 140c71d..b9412d8 100644 (file)
@@ -482,7 +482,7 @@ OP(set_sr)
     FORCE_RET();
 }
 
-OP(jmp)
+OP(jmp_im)
 {
     GOTO_LABEL_PARAM(1);
 }
@@ -522,22 +522,6 @@ OP(jmp_T0)
     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)
 {
index 68f39aa..39816f4 100644 (file)
@@ -28,6 +28,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 #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 uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 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)
@@ -622,7 +612,7 @@ static void gen_jmpcc(DisasContext *s, int cond, int l1)
     gen_flush_flags(s);
     switch (cond) {
     case 0: /* T */
-        gen_op_jmp(l1);
+        gen_op_jmp_im(l1);
         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_jmp(l1);
+            gen_op_jmp_im(l1);
             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_op_goto_tb(0, n, (long)tb);
+        tcg_gen_goto_tb(n);
         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));
-        gen_op_mov32(QREG_T0, gen_im32(0));
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     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_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);
@@ -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_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));
@@ -3162,9 +3150,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
 
     dc->tb = tb;
 
-    gen_opc_ptr = gen_opc_buf;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
-    gen_opparam_ptr = gen_opparam_buf;
 
     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;
-    nb_gen_labels = 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 */
-            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 */
@@ -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");
-        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) {
index cf965fa..cece7f1 100644 (file)
@@ -1093,18 +1093,6 @@ OP_COND(lez, (target_long)T0 <= 0);
 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)
 {
@@ -3252,12 +3240,6 @@ void op_raise_exception_err (void)
     FORCE_RET();
 }
 
-void op_exit_tb (void)
-{
-    EXIT_TB();
-    FORCE_RET();
-}
-
 void op_wait (void)
 {
     env->halted = 1;
index 719af3a..1231c00 100644 (file)
 #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
 
-#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))
 
@@ -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)) {
-        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_op_set_T0((long)tb + n);
+        tcg_gen_exit_tb((long)tb + n);
     } else {
         gen_save_pc(dest);
-        gen_op_reset_T0();
+        tcg_gen_exit_tb(0);
     }
-    gen_op_exit_tb();
 }
 
 /* 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();
-            gen_op_reset_T0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             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;
-    gen_opc_ptr = gen_opc_buf;
     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;
@@ -6748,8 +6723,7 @@ gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
             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:
@@ -6777,11 +6751,6 @@ done_generating:
         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);
     }
index c950579..6cda0f0 100644 (file)
@@ -222,11 +222,6 @@ void OPPROTO op_debug (void)
     do_raise_exception(EXCP_DEBUG);
 }
 
-void OPPROTO op_exit_tb (void)
-{
-    EXIT_TB();
-}
-
 /* Load/store special registers */
 void OPPROTO op_load_cr (void)
 {
@@ -674,16 +669,6 @@ void OPPROTO op_setlr_64 (void)
 }
 #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);
index 1313a77..c9530eb 100644 (file)
@@ -26,6 +26,7 @@
 #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
 
 /*****************************************************************************/
 /* 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
 
-#include "gen-op.h"
-
 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;
-    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)
@@ -2810,10 +2793,7 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
         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)
@@ -2822,10 +2802,9 @@ static always_inline void gen_goto_tb (DisasContext *ctx, int n,
         else
 #endif
             gen_op_b_T1();
-        gen_op_reset_T0();
         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();
-                gen_op_reset_T0();
                 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);
-        gen_op_reset_T0();
     no_test:
         if (ctx->singlestep_enabled)
             gen_op_debug();
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
  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;
-    gen_opc_ptr = gen_opc_buf;
     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
-    nb_gen_labels = 0;
     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) {
-        gen_op_reset_T0();
         /* Generate the return instruction */
-        gen_op_exit_tb();
+        tcg_gen_exit_tb(0);
     }
     *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");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-        fprintf(logfile, "OP:\n");
-        dump_ops(gen_opc_buf, gen_opparam_buf);
-        fprintf(logfile, "\n");
-    }
 #endif
     return 0;
 }
index 1004ef4..955610a 100644 (file)
@@ -161,12 +161,6 @@ void OPPROTO op_rts(void)
     RETURN();
 }
 
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-    RETURN();
-}
-
 void OPPROTO op_addl_imm_T0(void)
 {
     T0 += PARAM1;
@@ -947,18 +941,6 @@ void OPPROTO op_movl_FT0_fpul(void)
     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;
index 802f926..0c66e0b 100644 (file)
 #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;
@@ -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 (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 {
-       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)
@@ -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();
-       gen_op_movl_imm_T0(0);
        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);
     }
@@ -1176,9 +1155,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
     int i, ii;
 
     pc_start = tb->pc;
-    gen_opc_ptr = gen_opc_buf;
     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;
@@ -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;
-    nb_gen_labels = 0;
 
 #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(); */
-            gen_op_movl_imm_T0(0);
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             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");
     }
-    if (loglevel & CPU_LOG_TB_OP) {
-       fprintf(logfile, "OP:\n");
-       dump_ops(gen_opc_buf, gen_opparam_buf);
-       fprintf(logfile, "\n");
-    }
 #endif
     return 0;
 }
index 52b824c..1b5b21b 100644 (file)
@@ -1277,11 +1277,6 @@ void OPPROTO op_debug(void)
     helper_debug();
 }
 
-void OPPROTO op_exit_tb(void)
-{
-    EXIT_TB();
-}
-
 void OPPROTO op_eval_ba(void)
 {
     T2 = 1;
@@ -1542,16 +1537,6 @@ void OPPROTO op_next_insn(void)
     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);
index ecec372..8286c42 100644 (file)
@@ -36,6 +36,7 @@
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
+#include "tcg-op.h"
 
 #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 uint16_t *gen_opc_ptr;
-static uint32_t *gen_opparam_ptr;
 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))
@@ -98,12 +88,6 @@ enum {
 #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;
@@ -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 (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_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);
-        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_movl_T0_0();
-                gen_op_exit_tb();
+                tcg_gen_exit_tb(0);
                 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_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 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_movl_T0_0();
-                            gen_op_exit_tb();
+                            tcg_gen_exit_tb(0);
                             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_movl_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 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();
-                                gen_op_movl_T0_0();
-                                gen_op_exit_tb();
+                                tcg_gen_exit_tb(0);
                                 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);
-    gen_opc_ptr = gen_opc_buf;
     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) {
@@ -3647,8 +3618,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
                     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;
                 }
@@ -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);
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
             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);
-            gen_op_movl_T0_0();
-            gen_op_exit_tb();
+            tcg_gen_exit_tb(0);
         }
     }
     *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");
-        if (loglevel & CPU_LOG_TB_OP) {
-            fprintf(logfile, "OP:\n");
-            dump_ops(gen_opc_buf, gen_opparam_buf);
-            fprintf(logfile, "\n");
-        }
     }
 #endif
     return 0;
@@ -3746,8 +3709,6 @@ int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
     return gen_intermediate_code_internal(tb, 1, env);
 }
 
-extern int ram_size;
-
 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 "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];
-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];
@@ -59,86 +50,29 @@ uint32_t gen_opc_hflags[OPC_BUF_SIZE];
 
 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
 
-/* 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;
-#include "opc.h"
+#include "tcg-opc.h"
 #undef DEF
         max *= OPC_MAX_SIZE;
     }
@@ -146,6 +80,13 @@ unsigned long code_gen_max_block_size(void)
     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.
 
@@ -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)
 {
+    TCGContext *s = &tcg_ctx;
     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 */
+    gen_code_buf = tb->tc_ptr;
     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
+    s->tb_jmp_offset = tb->tb_jmp_offset;
+    s->tb_next = NULL;
     /* 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;
-#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
-                                NULL,
+    s->tb_jmp_offset = NULL;
+    s->tb_next = tb->tb_next;
 #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;
+#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);
@@ -196,9 +159,17 @@ int cpu_restore_state(TranslationBlock *tb,
                       CPUState *env, unsigned long searched_pc,
                       void *puc)
 {
-    int j, c;
+    TCGContext *s = &tcg_ctx;
+    int j;
     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;
@@ -207,18 +178,19 @@ int cpu_restore_state(TranslationBlock *tb,
     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--;
@@ -266,10 +238,11 @@ int cpu_restore_state(TranslationBlock *tb,
     }
 #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];
+        c = gen_opc_buf[j];
         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
+
+#ifdef CONFIG_PROFILER
+    dyngen_restore_time += profile_getclock() - ti;
+    dyngen_restore_count++;
+#endif
     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"
-