about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml11
-rw-r--r--README.md3
-rw-r--r--example/asm/shellcode.py2
-rw-r--r--example/jitter/test_x86_32_seh.py56
-rw-r--r--example/samples/x86_32_seh.S76
-rw-r--r--miasm2/analysis/machine.py5
-rw-r--r--miasm2/arch/aarch64/jit.py3
-rw-r--r--miasm2/arch/aarch64/sem.py3
-rw-r--r--miasm2/arch/arm/arch.py59
-rw-r--r--miasm2/arch/arm/jit.py2
-rw-r--r--miasm2/arch/arm/sem.py4
-rw-r--r--miasm2/arch/mips32/jit.py70
-rw-r--r--miasm2/arch/mips32/regs.py2
-rw-r--r--miasm2/arch/msp430/jit.py3
-rw-r--r--miasm2/arch/msp430/regs.py1
-rw-r--r--miasm2/arch/x86/arch.py21
-rw-r--r--miasm2/arch/x86/jit.py32
-rw-r--r--miasm2/arch/x86/sem.py20
-rw-r--r--miasm2/core/bin_stream.py5
-rw-r--r--miasm2/expression/expression.py3
-rw-r--r--miasm2/expression/expression_helper.py2
-rw-r--r--miasm2/expression/simplifications_common.py4
-rw-r--r--miasm2/expression/simplifications_cond.py8
-rw-r--r--miasm2/ir/ir2C.py432
-rw-r--r--miasm2/ir/translators/z3_ir.py2
-rw-r--r--miasm2/jitter/JitCore.c12
-rw-r--r--miasm2/jitter/JitCore.h7
-rw-r--r--miasm2/jitter/Jitgcc.c3
-rw-r--r--miasm2/jitter/Jittcc.c2
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.c133
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.h131
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c114
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h111
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c129
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.h419
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.c112
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.h120
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c202
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h174
-rw-r--r--miasm2/jitter/codegen.py578
-rw-r--r--miasm2/jitter/csts.py3
-rw-r--r--miasm2/jitter/emulatedsymbexec.py5
-rw-r--r--miasm2/jitter/jitcore.py36
-rw-r--r--miasm2/jitter/jitcore_gcc.py28
-rw-r--r--miasm2/jitter/jitcore_python.py21
-rw-r--r--miasm2/jitter/jitcore_tcc.py19
-rw-r--r--miasm2/jitter/jitload.py30
-rw-r--r--miasm2/jitter/loader/pe.py7
-rw-r--r--miasm2/jitter/vm_mngr.c207
-rw-r--r--miasm2/jitter/vm_mngr.h31
-rw-r--r--miasm2/jitter/vm_mngr_py.c92
-rw-r--r--miasm2/os_dep/win_32_structs.py198
-rw-r--r--miasm2/os_dep/win_api_x86_32.py54
-rw-r--r--miasm2/os_dep/win_api_x86_32_seh.py333
-rw-r--r--test/arch/arm/arch.py5
-rw-r--r--test/arch/x86/arch.py8
-rw-r--r--test/expression/simplifications.py8
-rw-r--r--test/test_all.py21
58 files changed, 1815 insertions, 2367 deletions
diff --git a/.travis.yml b/.travis.yml
index c021d97f..a0bf7d06 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,12 +25,15 @@ before_script:
 - "git clone https://github.com/serpilliere/elfesteem elfesteem && cd elfesteem && python setup.py install && cd ..;"
 # install pyparsing
 - "pip install pyparsing"
-# install z3
-- "mkdir z3 && cd z3 && wget -O z3.zip 'http://download-codeplex.sec.s-msft.com/Download/SourceControlFileDownload.ashx?ProjectName=z3&changeSetId=cee7dd39444c9060186df79c2a2c7f8845de415b'"
-- "unzip -q z3.zip && rm z3.zip && python scripts/mk_make.py  --prefix=$(pwd)/../ && cd build && make -j 32 && make install && cd ../.."
+# install z3 with a known to working version
+- "wget https://github.com/serpilliere/z3-prebuild/raw/master/z3.tgz"
+- "tar xzf z3.tgz"
+- "cd z3/build"
+- "make install"
+- "cd ../.."
 # install miasm
 - "cd ..;"
 - "cd miasm;"
 - "python setup.py build build_ext -I$(pwd)/../virtualenv/include -L$(pwd)/../virtualenv/tinycc"
 - "python setup.py install"
-script: "cd test && python test_all.py"
+script: "python -c 'import z3; x = z3.BitVec(chr(0x41), 32)' && cd test && python test_all.py"
diff --git a/README.md b/README.md
index 4ce234cf..09a5d44e 100644
--- a/README.md
+++ b/README.md
@@ -456,6 +456,9 @@ To enable code JIT, one of the following module is mandatory:
 * LLVM v3.2 with python-llvm, see below
 * LibTCC [tinycc (ONLY version 0.9.26)](http://repo.or.cz/w/tinycc.git)
 
+'optional' Miasm can also use:
+* Z3, the [Theorem Prover](https://github.com/Z3Prover/z3)
+
 Configuration
 -------------
 
diff --git a/example/asm/shellcode.py b/example/asm/shellcode.py
index 11cf9a4d..f31c88c2 100644
--- a/example/asm/shellcode.py
+++ b/example/asm/shellcode.py
@@ -71,7 +71,7 @@ symbol_pool.set_offset(symbol_pool.getby_name("main"), addr_main)
 
 if args.PE:
     symbol_pool.set_offset(symbol_pool.getby_name_create("MessageBoxA"),
-                           pe.DirImport.get_funcvirt('MessageBoxA'))
+                           pe.DirImport.get_funcvirt('USER32.dll', 'MessageBoxA'))
 
 # Print and graph firsts blocs before patching it
 for bloc in blocs:
diff --git a/example/jitter/test_x86_32_seh.py b/example/jitter/test_x86_32_seh.py
new file mode 100644
index 00000000..5277807d
--- /dev/null
+++ b/example/jitter/test_x86_32_seh.py
@@ -0,0 +1,56 @@
+import os
+from pdb import pm
+from miasm2.analysis.sandbox import Sandbox_Win_x86_32
+from miasm2.os_dep import win_api_x86_32_seh
+from miasm2.jitter.csts import *
+
+def deal_exception_access_violation(jitter):
+    jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_ACCESS_VIOLATION)
+    return True
+
+def deal_exception_breakpoint(jitter):
+    jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_BREAKPOINT)
+    return True
+
+def deal_exception_div(jitter):
+    jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_INT_DIVIDE_BY_ZERO)
+    return True
+
+def deal_exception_privileged_instruction(jitter):
+    jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_PRIV_INSTRUCTION)
+    return True
+
+def deal_exception_illegal_instruction(jitter):
+    jitter.pc = win_api_x86_32_seh.fake_seh_handler(jitter, win_api_x86_32_seh.EXCEPTION_ILLEGAL_INSTRUCTION)
+    return True
+
+
+def return_from_seh(jitter):
+    win_api_x86_32_seh.return_from_seh(jitter)
+    return True
+
+# Insert here user defined methods
+
+# Parse arguments
+parser = Sandbox_Win_x86_32.parser(description="PE sandboxer")
+parser.add_argument("filename", help="PE Filename")
+options = parser.parse_args()
+options.usesegm = True
+options.use_seh = True
+
+# Create sandbox
+sb = Sandbox_Win_x86_32(options.filename, options, globals())
+
+# Install Windows SEH callbacks
+sb.jitter.add_exception_handler(EXCEPT_ACCESS_VIOL, deal_exception_access_violation)
+sb.jitter.add_exception_handler(EXCEPT_SOFT_BP, deal_exception_breakpoint)
+sb.jitter.add_exception_handler(EXCEPT_DIV_BY_ZERO, deal_exception_div)
+sb.jitter.add_exception_handler(1<<17, deal_exception_privileged_instruction)
+sb.jitter.add_exception_handler(EXCEPT_UNK_MNEMO, deal_exception_illegal_instruction)
+
+sb.jitter.add_breakpoint(win_api_x86_32_seh.return_from_exception, return_from_seh)
+
+# Run
+sb.run()
+
+assert(sb.jitter.run is False)
diff --git a/example/samples/x86_32_seh.S b/example/samples/x86_32_seh.S
new file mode 100644
index 00000000..7bb2c3cd
--- /dev/null
+++ b/example/samples/x86_32_seh.S
@@ -0,0 +1,76 @@
+
+main:
+	PUSH       error
+	PUSH       DWORD PTR FS:[0x0]
+	MOV        DWORD PTR FS:[0x0], ESP
+	XOR        EAX, EAX
+
+;; Access violation
+lbl_err_0:
+	MOV        DWORD PTR [EAX], 0x0
+lbl_err_end0:
+	NOP
+
+
+;; Breakpoint
+lbl_err_1:
+	INT        0x3
+lbl_err_end1:
+	NOP
+
+;; Divide by 0
+	XOR        EAX, EAX
+lbl_err_2:
+	DIV        EAX
+lbl_err_end2:
+	NOP
+
+;; Privileged instruction
+lbl_err_3:
+	STI
+lbl_err_end3:
+	NOP
+
+;; Unknown instruction (Bad LEA encoding)
+lbl_err_4:
+	.byte 0x8D, 0xC0
+lbl_err_end4:
+	NOP
+
+	POP        DWORD PTR FS:[0x0]
+	ADD        ESP, 4
+	RET
+
+error:
+	MOV        ECX, DWORD PTR [ESP+0xC]
+	MOV        EAX, DWORD PTR [ECX+0xB8]
+	MOV        EBX, DWORD PTR [err_num]
+	CMP        EAX, DWORD PTR [labels_err + 4*EBX]
+	JZ         error_address_ok
+	INT        0x3
+error_address_ok:
+	INC        DWORD PTR [err_num]
+	MOV        EAX, DWORD PTR [labels_err_end + 4*EBX]
+	MOV        DWORD PTR [ECX+0xB8], EAX
+	XOR        EAX, EAX
+	RET
+
+
+
+err_num:
+.dword 0
+
+labels_err:
+.dword lbl_err_0
+.dword lbl_err_end1
+.dword lbl_err_2
+.dword lbl_err_3
+.dword lbl_err_4
+
+
+labels_err_end:
+.dword lbl_err_end0
+.dword lbl_err_end1
+.dword lbl_err_end2
+.dword lbl_err_end3
+.dword lbl_err_end4
diff --git a/miasm2/analysis/machine.py b/miasm2/analysis/machine.py
index f963628c..6af403ff 100644
--- a/miasm2/analysis/machine.py
+++ b/miasm2/analysis/machine.py
@@ -134,6 +134,7 @@ class Machine(object):
         self.__log_arch = log_arch
         self.__base_expr = arch.base_expr
         self.__ir = ir
+        self.__name = machine_name
 
     @property
     def dis_engine(self):
@@ -171,6 +172,10 @@ class Machine(object):
     def base_expr(self):
         return self.__base_expr
 
+    @property
+    def name(self):
+        return self.__name
+
     @classmethod
     def available_machine(cls):
         "Return a list of supported machines"
diff --git a/miasm2/arch/aarch64/jit.py b/miasm2/arch/aarch64/jit.py
index 44b0609f..ca8d7b39 100644
--- a/miasm2/arch/aarch64/jit.py
+++ b/miasm2/arch/aarch64/jit.py
@@ -11,7 +11,6 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
 log.setLevel(logging.CRITICAL)
 
-
 class jitter_aarch64l(jitter):
     max_reg_arg = 8
 
@@ -19,7 +18,6 @@ class jitter_aarch64l(jitter):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_aarch64l(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def push_uint64_t(self, v):
         self.cpu.SP -= 8
@@ -70,4 +68,3 @@ class jitter_aarch64b(jitter_aarch64l):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_aarch64b(sp), *args, **kwargs)
         self.vm.set_big_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index b198bc43..02a93dd2 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -793,7 +793,8 @@ class ir_aarch64l(ir):
                 dst = self.expr_fix_regs_for_mode(dst)
                 src = self.expr_fix_regs_for_mode(src)
                 assignblk[dst] = src
-        irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst)
+        if irbloc.dst is not None:
+            irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst)
 
     def mod_pc(self, instr, instr_ir, extra_ir):
         "Replace PC by the instruction's offset"
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 23935dd4..7dc5d959 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -522,7 +522,10 @@ class mn_arm(cls_mn):
         info.lnk = False
         if hasattr(self, "lnk"):
             info.lnk = self.lnk.value != 0
-        info.cond = self.cond.value
+        if hasattr(self, "cond"):
+            info.cond = self.cond.value
+        else:
+            info.cond = None
         return info
 
     @classmethod
@@ -1291,6 +1294,8 @@ imm4 = bs(l=4, cls=(arm_imm, m_arg))
 imm12 = bs(l=12, cls=(arm_imm, m_arg))
 imm16 = bs(l=16, cls=(arm_imm, m_arg))
 
+imm12_off = bs(l=12, fname="imm")
+
 imm4_noarg = bs(l=4, fname="imm4")
 
 imm_4_12 = bs(l=12, cls=(arm_imm_4_12,))
@@ -1405,6 +1410,50 @@ class armt2_rot_rm(m_arg):
 rot_rm = bs(l=2, cls=(armt2_rot_rm,), fname="rot_rm")
 
 
+class arm_mem_rn_imm(m_arg):
+    parser = deref
+    def decode(self, v):
+        value = self.parent.imm.value
+        if self.parent.rw.value == 0:
+            value = -value
+        imm = ExprInt32(value)
+        reg = gpregs.expr[v]
+        if value:
+            expr = ExprMem(reg + imm)
+        else:
+            expr = ExprMem(reg)
+        self.expr = expr
+        return True
+
+    def encode(self):
+        self.parent.add_imm.value = 1
+        self.parent.imm.value = 0
+        expr = self.expr
+        if not isinstance(expr, ExprMem):
+            return False
+        ptr = expr.arg
+        if ptr in gpregs.expr:
+            self.value = gpregs.expr.index(ptr)
+        elif (isinstance(ptr, ExprOp) and
+              len(ptr.args) == 2 and
+              ptr.op == 'preinc'):
+            reg, imm = ptr.args
+            if not reg in gpregs.expr:
+                return False
+            self.value = gpregs.expr.index(reg)
+            if not isinstance(imm, ExprInt):
+                return False
+            value = int(imm.arg)
+            if value & 0x80000000:
+                value = -value
+                self.parent.add_imm.value = 0
+            self.parent.imm.value = value
+        else:
+            return False
+        return True
+
+mem_rn_imm = bs(l=4, cls=(arm_mem_rn_imm,), order=1)
+
 def armop(name, fields, args=None, alias=False):
     dct = {"fields": fields}
     dct["alias"] = alias
@@ -1457,6 +1506,10 @@ bs_ctransfer_name = bs_name(l=1, name=ctransfer_name)
 mr_name = {'MCR': 0, 'MRC': 1}
 bs_mr_name = bs_name(l=1, name=mr_name)
 
+
+bs_addi = bs(l=1, fname="add_imm")
+bs_rw = bs_mod_name(l=1, fname='rw', mn_mod=['W', ''])
+
 armop("mul", [bs('000000'), bs('0'), scc, rd,
       bs('0000'), rs, bs('1001'), rm], [rd, rm, rs])
 armop("umull", [bs('000010'),
@@ -1525,6 +1578,10 @@ armop("sxth", [bs('01101011'), bs('1111'), rd, rot_rm, bs('00'), bs('0111'), rm_
 
 armop("rev", [bs('01101011'), bs('1111'), rd, bs('1111'), bs('0011'), rm])
 
+armop("pld", [bs8(0xF5), bs_addi, bs_rw, bs('01'), mem_rn_imm, bs('1111'), imm12_off])
+
+armop("isb", [bs8(0xF5), bs8(0x7F), bs8(0xF0), bs8(0x6F)])
+
 class arm_widthm1(arm_imm, m_arg):
     def decode(self, v):
         self.expr = ExprInt32(v+1)
diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py
index a9b93f6b..70d16176 100644
--- a/miasm2/arch/arm/jit.py
+++ b/miasm2/arch/arm/jit.py
@@ -17,7 +17,6 @@ class jitter_arml(jitter):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_arml(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def push_uint32_t(self, v):
         self.cpu.SP -= 4
@@ -67,4 +66,3 @@ class jitter_armb(jitter_arml):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_armb(sp), *args, **kwargs)
         self.vm.set_big_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 6838ef66..5bd4db24 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -933,6 +933,9 @@ def rev(ir, instr, a, b):
     e.append(ExprAff(a, c))
     return e
 
+def pld(ir, instr, a):
+    return []
+
 
 
 COND_EQ = 0
@@ -1137,6 +1140,7 @@ mnemo_nocond = {'lsr': lsr,
                 'asrs': asrs,
                 'cbz': cbz,
                 'cbnz': cbnz,
+                'pld': pld,
                 }
 mn_cond_x = [mnemo_condm0,
              mnemo_condm1,
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 93223896..332e8d13 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -1,9 +1,11 @@
+import logging
+
 from miasm2.jitter.jitload import jitter
 from miasm2.core import asmbloc
 from miasm2.core.utils import *
 from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b
-
-import logging
+from miasm2.jitter.codegen import CGen
+import miasm2.expression.expression as m2_expr
 
 log = logging.getLogger('jit_mips32')
 hnd = logging.StreamHandler()
@@ -11,13 +13,73 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
 log.setLevel(logging.CRITICAL)
 
+
+class mipsCGen(CGen):
+    CODE_INIT = CGen.CODE_INIT + r"""
+    unsigned int branch_dst_pc;
+    unsigned int branch_dst_irdst;
+    unsigned int branch_dst_set=0;
+    """
+
+    CODE_RETURN_NO_EXCEPTION = r"""
+    %s:
+    if (branch_dst_set) {
+        %s = %s;
+        BlockDst->address = %s;
+    } else {
+        BlockDst->address = %s;
+    }
+    return JIT_RET_NO_EXCEPTION;
+    """
+
+    def __init__(self, ir_arch):
+        super(mipsCGen, self).__init__(ir_arch)
+        self.delay_slot_dst = m2_expr.ExprId("branch_dst_irdst")
+        self.delay_slot_set = m2_expr.ExprId("branch_dst_set")
+
+    def block2assignblks(self, block):
+        irblocks_list = super(mipsCGen, self).block2assignblks(block)
+        for instr, irblocks in zip(block.lines, irblocks_list):
+            if not instr.breakflow():
+                continue
+            for irblock in irblocks:
+                for i, assignblock in enumerate(irblock.irs):
+                    if self.ir_arch.pc not in assignblock:
+                        continue
+                    # Add internal branch destination
+                    assignblock[self.delay_slot_dst] = assignblock[
+                        self.ir_arch.pc]
+                    assignblock[self.delay_slot_set] = m2_expr.ExprInt(1, 32)
+                    # Replace IRDst with next instruction
+                    assignblock[self.ir_arch.IRDst] = m2_expr.ExprId(
+                        self.ir_arch.get_next_instr(instr))
+                    irblock.dst = m2_expr.ExprId(
+                        self.ir_arch.get_next_instr(instr))
+        return irblocks_list
+
+    def gen_finalize(self, block):
+        """
+        Generate the C code for the final block instruction
+        """
+
+        lbl = self.get_block_post_label(block)
+        out = (self.CODE_RETURN_NO_EXCEPTION % (lbl.name,
+                                                self.C_PC,
+                                                m2_expr.ExprId('branch_dst_irdst'),
+                                                m2_expr.ExprId('branch_dst_irdst'),
+                                                self.id_to_c(m2_expr.ExprInt(lbl.offset, 32)))
+               ).split('\n')
+        return out
+
+
 class jitter_mips32l(jitter):
 
+    C_Gen = mipsCGen
+
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_mips32l(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def push_uint32_t(self, v):
         self.cpu.SP -= 4
@@ -38,8 +100,8 @@ class jitter_mips32l(jitter):
 
 
 class jitter_mips32b(jitter_mips32l):
+
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_mips32b(sp), *args, **kwargs)
         self.vm.set_big_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py
index 6ddcf25b..b64b40d5 100644
--- a/miasm2/arch/mips32/regs.py
+++ b/miasm2/arch/mips32/regs.py
@@ -11,6 +11,8 @@ gen_reg('PC_FETCH', globals())
 gen_reg('R_LO', globals())
 gen_reg('R_HI', globals())
 
+exception_flags = ExprId('exception_flags', 32)
+
 PC_init = ExprId("PC_init")
 PC_FETCH_init = ExprId("PC_FETCH_init")
 
diff --git a/miasm2/arch/msp430/jit.py b/miasm2/arch/msp430/jit.py
index 5a4ff58b..95d34f96 100644
--- a/miasm2/arch/msp430/jit.py
+++ b/miasm2/arch/msp430/jit.py
@@ -1,6 +1,7 @@
 from miasm2.jitter.jitload import jitter
 from miasm2.core import asmbloc
 from miasm2.core.utils import *
+from miasm2.arch.msp430.sem import ir_msp430
 
 import logging
 
@@ -13,11 +14,9 @@ log.setLevel(logging.CRITICAL)
 class jitter_msp430(jitter):
 
     def __init__(self, *args, **kwargs):
-        from miasm2.arch.msp430.sem import ir_msp430
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_msp430(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def push_uint16_t(self, v):
         regs = self.cpu.get_gpreg()
diff --git a/miasm2/arch/msp430/regs.py b/miasm2/arch/msp430/regs.py
index 60638f26..1e35029f 100644
--- a/miasm2/arch/msp430/regs.py
+++ b/miasm2/arch/msp430/regs.py
@@ -7,6 +7,7 @@ from miasm2.core.cpu import reg_info
 regs16_str = ["PC", "SP", "SR"] + ["R%d" % i for i in xrange(3, 16)]
 regs16_expr = [ExprId(x, 16) for x in regs16_str]
 
+exception_flags = ExprId('exception_flags', 32)
 
 gpregs = reg_info(regs16_str, regs16_expr)
 
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 280090aa..ff7dc1ee 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -826,6 +826,13 @@ class mn_x86(cls_mn):
         self.rex_b.value = pre_dis_info['rex_b']
         self.rex_x.value = pre_dis_info['rex_x']
         self.rex_p.value = pre_dis_info['rex_p']
+
+        if hasattr(self, 'no_rex') and\
+           (self.rex_r.value or self.rex_b.value or
+            self.rex_x.value or self.rex_p.value):
+            return False
+
+
         self.g1.value = pre_dis_info['g1']
         self.g2.value = pre_dis_info['g2']
         self.prefix = pre_dis_info['prefix']
@@ -853,6 +860,10 @@ class mn_x86(cls_mn):
             rex |= 0x1
         if rex != 0x40 or self.rex_p.value == 1:
             v = chr(rex) + v
+            if hasattr(self, 'no_rex'):
+                return None
+
+
 
         if hasattr(self, 'prefixed'):
             v = self.prefixed.default + v
@@ -3084,6 +3095,8 @@ pref_f3 = bs(l=0, fname="prefixed", default="\xf3")
 pref_66 = bs(l=0, fname="prefixed", default="\x66")
 no_xmm_pref = bs(l=0, fname="no_xmm_pref")
 
+no_rex = bs(l=0, fname="no_rex")
+
 sib_scale = bs(l=2, cls=(bs_cond_scale,), fname = "sib_scale")
 sib_index = bs(l=3, cls=(bs_cond_index,), fname = "sib_index")
 sib_base = bs(l=3, cls=(bs_cond_index,), fname = "sib_base")
@@ -3723,6 +3736,7 @@ addop("outsw", [bs8(0x6f), bs_opmode16])
 addop("outsd", [bs8(0x6f), bs_opmode32])
 addop("outsd", [bs8(0x6f), bs_opmode64])
 
+addop("setalc", [bs8(0xD6)])
 
 # addop("pause", [bs8(0xf3), bs8(0x90)])
 
@@ -3898,7 +3912,7 @@ addop("wrmsr", [bs8(0x0f), bs8(0x30)])
 addop("xadd", [bs8(0x0f), bs("1100000"), w8]
       + rmmod(rmreg, rm_arg_w8), [rm_arg_w8, rmreg])
 
-addop("nop", [bs8(0x90)], alias=True)
+addop("nop", [bs8(0x90), no_rex], alias=True)
 
 addop("xchg", [bs('10010'), d_eax, reg])
 addop("xchg", [bs('1000011'), w8] +
@@ -4301,10 +4315,7 @@ addop("pextrq", [bs8(0x0f), bs8(0x3a), bs8(0x16), pref_66] +
 
 
 addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), pref_66] +
-      rmmod(xmm_reg, rm_arg_m16) + [u08], [rm_arg_m16, xmm_reg, u08])
-#addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), no_xmm_pref] +
-#      rmmod(mm_reg, rm_arg_m16) + [u08], [rm_arg_m16, mm_reg, u08])
-
+      rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08])
 addop("pextrw", [bs8(0x0f), bs8(0xc5), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, mm_reg, u08])
 addop("pextrw", [bs8(0x0f), bs8(0xc5), pref_66] +
diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py
index 5a9886c5..2e483f2a 100644
--- a/miasm2/arch/x86/jit.py
+++ b/miasm2/arch/x86/jit.py
@@ -4,6 +4,7 @@ from miasm2.jitter.jitload import jitter, named_arguments
 from miasm2.core import asmbloc
 from miasm2.core.utils import *
 from miasm2.arch.x86.sem import ir_x86_16, ir_x86_32, ir_x86_64
+from miasm2.jitter.codegen import CGen
 
 log = logging.getLogger('jit_x86')
 hnd = logging.StreamHandler()
@@ -11,13 +12,34 @@ hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
 log.setLevel(logging.CRITICAL)
 
+
+class x86_32_CGen(CGen):
+    def __init__(self, ir_arch):
+        self.ir_arch = ir_arch
+        self.PC = self.ir_arch.arch.regs.RIP
+        self.init_arch_C()
+
+    def gen_post_code(self, attrib):
+        out = []
+        if attrib.log_regs:
+            out.append('dump_gpregs_32(jitcpu->cpu);')
+        return out
+
+class x86_64_CGen(x86_32_CGen):
+    def gen_post_code(self, attrib):
+        out = []
+        if attrib.log_regs:
+            out.append('dump_gpregs_64(jitcpu->cpu);')
+        return out
+
 class jitter_x86_16(jitter):
 
+    C_Gen = x86_32_CGen
+
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_16(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP
         self.ir_arch.do_stk_segm = False
         self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode
         self.ir_arch.irbloc_fix_regs_for_mode = self.ir_archbloc_fix_regs_for_mode
@@ -45,11 +67,12 @@ class jitter_x86_16(jitter):
 
 class jitter_x86_32(jitter):
 
+    C_Gen = x86_32_CGen
+
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_32(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP
         self.ir_arch.do_stk_segm = False
 
         self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode
@@ -81,7 +104,7 @@ class jitter_x86_32(jitter):
         return ret_ad, args
 
     def func_ret_stdcall(self, ret_addr, ret_value1=None, ret_value2=None):
-        self.cpu.EIP = ret_addr
+        self.pc = self.cpu.EIP = ret_addr
         if ret_value1 is not None:
             self.cpu.EAX = ret_value1
         if ret_value2 is not None:
@@ -105,11 +128,12 @@ class jitter_x86_32(jitter):
 
 class jitter_x86_64(jitter):
 
+    C_Gen = x86_64_CGen
+
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_64(sp), *args, **kwargs)
         self.vm.set_little_endian()
-        self.ir_arch.jit_pc = self.ir_arch.arch.regs.RIP
         self.ir_arch.do_stk_segm = False
 
         self.orig_irbloc_fix_regs_for_mode = self.ir_arch.irbloc_fix_regs_for_mode
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 28e42353..cdc98fba 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3606,19 +3606,25 @@ def ps_rl_ll(ir, instr, a, b, op, size):
     mask = {16: 0xF,
             32: 0x1F,
             64: 0x3F}[size]
-    test = count & m2_expr.ExprInt(((1 << a.size) - 1) ^ mask, a.size)
+    test = expr_simp(count & m2_expr.ExprInt(((1 << a.size) - 1) ^ mask, a.size))
     e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(test,
                                                     lbl_zero,
                                                     lbl_do))]
 
-    e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)),
-              m2_expr.ExprAff(ir.IRDst, lbl_next)]
-
-    e_do = []
     slices = []
     for i in xrange(0, a.size, size):
         slices.append((m2_expr.ExprOp(op, a[i:i + size], count[:size]),
                        i, i + size))
+
+    if isinstance(test, m2_expr.ExprInt):
+        if int(test.arg) == 0:
+            return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))], []
+        else:
+            return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], []
+
+    e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)),
+              m2_expr.ExprAff(ir.IRDst, lbl_next)]
+    e_do = []
     e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices)))
     e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     return e, [irbloc(lbl_do.name, [e_do]), irbloc(lbl_zero.name, [e_zero])]
@@ -4484,7 +4490,6 @@ class ir_x86_16(ir):
 
         instr_ir, extra_ir = mnemo_func[
             instr.name.lower()](self, instr, *args)
-        self.mod_pc(instr, instr_ir, extra_ir)
 
         self.mod_pc(instr, instr_ir, extra_ir)
         instr.additional_info.except_on_instr = False
@@ -4566,7 +4571,8 @@ class ir_x86_16(ir):
                 dst = self.expr_fix_regs_for_mode(dst, mode)
                 src = self.expr_fix_regs_for_mode(src, mode)
                 assignblk[dst] = src
-        irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst, mode)
+        if irbloc.dst is not None:
+            irbloc.dst = self.expr_fix_regs_for_mode(irbloc.dst, mode)
 
 
 class ir_x86_32(ir_x86_16):
diff --git a/miasm2/core/bin_stream.py b/miasm2/core/bin_stream.py
index 67a67de8..f8d491d2 100644
--- a/miasm2/core/bin_stream.py
+++ b/miasm2/core/bin_stream.py
@@ -187,7 +187,10 @@ class bin_stream_container(bin_stream):
         return self.bin.get(self.offset - l, self.offset)
 
     def _getbytes(self, start, l=1):
-        return self.bin.get(start, start + l)
+        try:
+            return self.bin.get(start, start + l)
+        except ValueError:
+            raise IOError("cannot get bytes")
 
     def __str__(self):
         out = self.bin.get(self.offset, self.offset + self.l)
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index de6746ef..c9c2627c 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -217,6 +217,9 @@ class Expr(object):
     def __neg__(self):
         return ExprOp('-', self)
 
+    def __pow__(self, a):
+        return ExprOp("**",self, a)
+
     def __invert__(self):
         s = self.size
         return ExprOp('^', self, ExprInt(mod_size2uint[s](size2mask(s))))
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index 44b4b5af..09feffc2 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -135,7 +135,7 @@ def merge_sliceto_slice(args):
 
 op_propag_cst = ['+', '*', '^', '&', '|', '>>',
                  '<<', "a>>", ">>>", "<<<",
-                 "/", "%", 'idiv', 'imod', 'umod', 'udiv']
+                 "/", "%", 'idiv', 'imod', 'umod', 'udiv','**']
 
 
 def is_pure_int(e):
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index a52debe6..2d5e4e6b 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -30,6 +30,8 @@ def simp_cst_propagation(e_s, e):
                 o = i1.arg + i2.arg
             elif op == '*':
                 o = i1.arg * i2.arg
+            elif op == '**':
+                o =i1.arg ** i2.arg
             elif op == '^':
                 o = i1.arg ^ i2.arg
             elif op == '&':
@@ -194,7 +196,7 @@ def simp_cst_propagation(e_s, e):
             j += 1
         i += 1
 
-    if op in ['|', '&', '%', '/'] and len(args) == 1:
+    if op in ['|', '&', '%', '/', '**'] and len(args) == 1:
         return args[0]
 
     # A <<< A.size => A
diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py
index c6e455b6..a5acdba6 100644
--- a/miasm2/expression/simplifications_cond.py
+++ b/miasm2/expression/simplifications_cond.py
@@ -197,13 +197,13 @@ def __comp_signed(arg1, arg2):
     """Return ExprInt1(1) if arg1 <s arg2 else ExprInt1(0)
     @arg1, @arg2: ExprInt"""
 
-    val1 = arg1.arg
+    val1 = int(arg1.arg)
     if val1 >> (arg1.size - 1) == 1:
-        val1 = - (arg1.mask.arg ^ val1 + 1)
+        val1 = - ((int(arg1.mask.arg) ^ val1) + 1)
 
-    val2 = arg2.arg
+    val2 = int(arg2.arg)
     if val2 >> (arg2.size - 1) == 1:
-        val2 = - (arg2.mask.arg ^ val2 + 1)
+        val2 = - ((int(arg2.mask.arg) ^ val2) + 1)
 
     return m2_expr.ExprInt1(1) if (val1 < val2) else m2_expr.ExprInt1(0)
 
diff --git a/miasm2/ir/ir2C.py b/miasm2/ir/ir2C.py
deleted file mode 100644
index ebc61e27..00000000
--- a/miasm2/ir/ir2C.py
+++ /dev/null
@@ -1,432 +0,0 @@
-import miasm2.expression.expression as m2_expr
-from miasm2.expression.simplifications import expr_simp
-from miasm2.core import asmbloc
-from miasm2.ir.translators import Translator
-import logging
-
-
-log_to_c_h = logging.getLogger("ir_helper")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
-log_to_c_h.addHandler(console_handler)
-log_to_c_h.setLevel(logging.WARN)
-
-# Miasm to C translator
-translator = Translator.to_language("C")
-
-prefetch_id = []
-prefetch_id_size = {}
-for size in [8, 16, 32, 64]:
-    prefetch_id_size[size] = []
-    for i in xrange(20):
-        name = 'pfmem%.2d_%d' % (size, i)
-        c = m2_expr.ExprId(name, size)
-        globals()[name] = c
-        prefetch_id.append(c)
-        prefetch_id_size[size].append(c)
-
-def init_arch_C(arch):
-    arch.id2Cid = {}
-    for x in arch.regs.all_regs_ids + prefetch_id:
-        arch.id2Cid[x] = m2_expr.ExprId('mycpu->' + str(x), x.size)
-
-    arch.id2newCid = {}
-
-    for x in arch.regs.all_regs_ids + prefetch_id:
-        arch.id2newCid[x] = m2_expr.ExprId('mycpu->%s_new' % x, x.size)
-
-
-def patch_c_id(arch, e):
-    return e.replace_expr(arch.id2Cid)
-
-
-def patch_c_new_id(arch, e):
-    return e.replace_expr(arch.id2newCid)
-
-
-mask_int = 0xffffffffffffffff
-
-
-pre_instr_test_exception = r"""
-// pre instruction test exception
-if (VM_exception_flag) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-
-code_exception_fetch_mem_at_instr = r"""
-// except fetch mem at instr
-if (VM_exception_flag & EXCEPT_DO_NOT_UPDATE_PC) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-code_exception_fetch_mem_post_instr = r"""
-// except fetch mem post instr
-if (VM_exception_flag) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-
-code_exception_fetch_mem_at_instr_noautomod = r"""
-// except fetch mem at instr noauto
-if ((VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-code_exception_fetch_mem_post_instr_noautomod = r"""
-// except post instr noauto
-if (VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-
-code_exception_at_instr = r"""
-// except at instr
-if (CPU_exception_flag && CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-code_exception_post_instr = r"""
-// except post instr
-if (CPU_exception_flag) {
-    if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) {
-      %s;
-    }
-    else {
-      %s;
-    }
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-
-code_exception_at_instr_noautomod = r"""
-if ((CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) && (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP)) {
-    %s;
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-code_exception_post_instr_noautomod = r"""
-if (CPU_exception_flag & ~EXCEPT_CODE_AUTOMOD) {
-    if (CPU_exception_flag > EXCEPT_NUM_UPDT_EIP) {
-      %s;
-    }
-    else {
-      %s;
-    }
-    return JIT_RET_EXCEPTION;
-}
-"""
-
-goto_local_code = r"""
-if (BlockDst->is_local) {
-    goto *local_labels[BlockDst->address];
-}
-else {
-    return JIT_RET_NO_EXCEPTION;
-}
-"""
-
-my_size_mask = {1: 1, 2: 3, 3: 7, 7: 0x7f,
-                8: 0xFF,
-                16: 0xFFFF,
-                32: 0xFFFFFFFF,
-                64: 0xFFFFFFFFFFFFFFFFL}
-
-exception_flags = m2_expr.ExprId('exception_flags', 32)
-
-
-def set_pc(ir_arch, src):
-    dst = ir_arch.jit_pc
-    if not isinstance(src, m2_expr.Expr):
-        src = m2_expr.ExprInt_from(dst, src)
-    e = m2_expr.ExprAff(dst, src.zeroExtend(dst.size))
-    return e
-
-
-def gen_resolve_int(ir_arch, e):
-    return 'Resolve_dst(BlockDst, 0x%X, 0)' % (e.arg)
-
-def gen_resolve_id_lbl(ir_arch, e):
-    if e.name.name.startswith("lbl_gen_"):
-        # TODO XXX CLEAN
-        return 'Resolve_dst(BlockDst, 0x%X, 1)'%(e.name.index)
-    else:
-        return 'Resolve_dst(BlockDst, 0x%X, 0)'%(e.name.offset)
-
-def gen_resolve_id(ir_arch, e):
-    return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
-
-def gen_resolve_mem(ir_arch, e):
-    return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
-
-def gen_resolve_other(ir_arch, e):
-    return 'Resolve_dst(BlockDst, %s, 0)'%(translator.from_expr(patch_c_id(ir_arch.arch, e)))
-
-def gen_resolve_dst_simple(ir_arch, e):
-    if isinstance(e, m2_expr.ExprInt):
-        return gen_resolve_int(ir_arch, e)
-    elif isinstance(e, m2_expr.ExprId) and isinstance(e.name,
-                                                      asmbloc.asm_label):
-        return gen_resolve_id_lbl(ir_arch, e)
-    elif isinstance(e, m2_expr.ExprId):
-        return gen_resolve_id(ir_arch, e)
-    elif isinstance(e, m2_expr.ExprMem):
-        return gen_resolve_mem(ir_arch, e)
-    else:
-        return gen_resolve_other(ir_arch, e)
-
-
-def gen_irdst(ir_arch, e):
-    out = []
-    if isinstance(e, m2_expr.ExprCond):
-        dst_cond_c = translator.from_expr(patch_c_id(ir_arch.arch, e.cond))
-        out.append("if (%s)"%dst_cond_c)
-        out.append('    %s;'%(gen_resolve_dst_simple(ir_arch, e.src1)))
-        out.append("else")
-        out.append('    %s;'%(gen_resolve_dst_simple(ir_arch, e.src2)))
-    else:
-        out.append('%s;'%(gen_resolve_dst_simple(ir_arch, e)))
-    return out
-
-def Expr2C(ir_arch, l, assignblk, gen_exception_code=False):
-    id_to_update = []
-    out = ["// %s" % (l)]
-    out_pc = []
-
-    dst_dict = {}
-    src_mem = {}
-
-    prefect_index = {8: 0, 16: 0, 32: 0, 64: 0}
-    new_expr = []
-
-    pc_is_dst = False
-    fetch_mem = False
-    set_exception_flags = False
-    for dst, src in assignblk.iteritems():
-        assert not isinstance(dst, m2_expr.ExprOp)
-        if dst in dst_dict:
-            raise RuntimeError("warning: detected multi dst to same id")
-        new_expr.append((dst, src))
-        # test exception flags
-        ops = m2_expr.get_expr_ops(src)
-        if set(['umod', 'udiv']).intersection(ops):
-            set_exception_flags = True
-        if dst == exception_flags:
-            set_exception_flags = True
-            # TODO XXX test function whose set exception_flags
-
-        # search mem lookup for generate mem read prefetch
-        rs = src.get_r(mem_read=True)
-        for r in rs:
-            if (not isinstance(r, m2_expr.ExprMem)) or r in src_mem:
-                continue
-            fetch_mem = True
-            index = prefect_index[r.size]
-            prefect_index[r.size] += 1
-            pfmem = prefetch_id_size[r.size][index]
-            src_mem[r] = pfmem
-
-    out_mem = []
-
-    # first, generate mem prefetch
-    mem_k = src_mem.keys()
-    mem_k.sort()
-    for k in mem_k:
-        str_src = translator.from_expr(patch_c_id(ir_arch.arch, k))
-        str_dst = translator.from_expr(patch_c_id(ir_arch.arch, src_mem[k]))
-        out.append('%s = %s;' % (str_dst, str_src))
-    src_w_len = {}
-    for k, v in src_mem.items():
-        src_w_len[k] = v
-    for dst, src in new_expr:
-        # reload src using prefetch
-        src = src.replace_expr(src_w_len)
-        if dst is ir_arch.IRDst:
-            out += gen_irdst(ir_arch, src)
-            continue
-
-
-        str_src = translator.from_expr(patch_c_id(ir_arch.arch, src))
-        str_dst = translator.from_expr(patch_c_id(ir_arch.arch, dst))
-
-
-
-        if isinstance(dst, m2_expr.ExprId):
-            id_to_update.append(dst)
-            str_dst = patch_c_new_id(ir_arch.arch, dst)
-            if dst in ir_arch.arch.regs.regs_flt_expr:
-                # dont mask float affectation
-                out.append('%s = (%s);' % (str_dst, str_src))
-            else:
-                out.append('%s = (%s)&0x%X;' % (str_dst, str_src,
-                                                my_size_mask[src.size]))
-        elif isinstance(dst, m2_expr.ExprMem):
-            fetch_mem = True
-            str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE')
-            out_mem.append('%s, %s);' % (str_dst[:-1], str_src))
-
-        if dst == ir_arch.arch.pc[ir_arch.attrib]:
-            pc_is_dst = True
-            out_pc += ["return JIT_RET_NO_EXCEPTION;"]
-
-    # if len(id_to_update) != len(set(id_to_update)):
-    # raise ValueError('Not implemented: multi dst to same id!', str([str(x)
-    # for x in exprs]))
-    out += out_mem
-
-    if gen_exception_code:
-        if fetch_mem:
-            e = set_pc(ir_arch, l.offset & mask_int)
-            s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-            s1 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
-            out.append(code_exception_fetch_mem_at_instr_noautomod % s1)
-        if set_exception_flags:
-            e = set_pc(ir_arch, l.offset & mask_int)
-            s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-            s1 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
-            out.append(code_exception_at_instr_noautomod % s1)
-
-    for i in id_to_update:
-        if i is ir_arch.IRDst:
-            continue
-        out.append('%s = %s;' %
-                   (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i)))
-
-    post_instr = []
-    # test stop exec ####
-    if gen_exception_code:
-        if set_exception_flags:
-            if pc_is_dst:
-                post_instr.append("if (VM_exception_flag) { " +
-                    "/*pc = 0x%X; */return JIT_RET_EXCEPTION; }" % (l.offset))
-            else:
-                e = set_pc(ir_arch, l.offset & mask_int)
-                s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-                s1 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
-                e = set_pc(ir_arch, (l.offset + l.l) & mask_int)
-                s2 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-                s2 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%((l.offset + l.l) & mask_int)
-                post_instr.append(
-                    code_exception_post_instr_noautomod % (s1, s2))
-
-        if fetch_mem:
-            if l.additional_info.except_on_instr:
-                offset = l.offset
-            else:
-                offset = l.offset + l.l
-
-            e = set_pc(ir_arch, offset & mask_int)
-            s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-            s1 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%(offset & mask_int)
-            post_instr.append(
-                code_exception_fetch_mem_post_instr_noautomod % (s1))
-
-    # pc manip after all modifications
-    return out, post_instr, post_instr + out_pc
-
-
-def label2offset(e):
-    if not isinstance(e, m2_expr.ExprId):
-        return e
-    if not isinstance(e.name, asmbloc.asm_label):
-        return e
-    return m2_expr.ExprInt_from(e, e.name.offset)
-
-
-def expr2pyobj(arch, e):
-    if isinstance(e, m2_expr.ExprId):
-        if isinstance(e.name, asmbloc.asm_label):
-            src_c = 'PyString_FromStringAndSize("%s", %d)' % (
-                e.name.name, len(e.name.name))
-        else:
-            src_c = 'PyLong_FromUnsignedLongLong(%s)' % patch_c_id(arch, e)
-    else:
-        raise NotImplementedError('unknown type for e: %s' % type(e))
-    return src_c
-
-
-def ir2C(ir_arch, irbloc, lbl_done,
-    gen_exception_code=False, log_mn=False, log_regs=False):
-    out = []
-    # print "TRANS"
-    # print irbloc
-    out.append(["%s:" % irbloc.label.name])
-    #out.append(['printf("%s:\n");' % irbloc.label.name])
-    assert len(irbloc.irs) == len(irbloc.lines)
-    for l, assignblk in zip(irbloc.lines, irbloc.irs):
-        if l.offset not in lbl_done:
-            e = set_pc(ir_arch, l.offset & mask_int)
-            s1 = "%s" % translator.from_expr(patch_c_id(ir_arch.arch, e))
-            s1 += ';\n    Resolve_dst(BlockDst, 0x%X, 0)'%(l.offset & mask_int)
-            out.append([pre_instr_test_exception % (s1)])
-            lbl_done.add(l.offset)
-
-            if log_regs:
-                out.append([r'dump_gpregs(jitcpu->cpu);'])
-
-            if log_mn:
-                out.append(['printf("%.8X %s\\n");' % (l.offset, str(l))])
-        # print l
-        # gen pc update
-        post_instr = ""
-        c_code, post_instr, _ = Expr2C(ir_arch, l, assignblk, gen_exception_code)
-        out.append(c_code + post_instr)
-    out.append([goto_local_code ] )
-    return out
-
-
-def irblocs2C(ir_arch, resolvers, label, irblocs,
-    gen_exception_code=False, log_mn=False, log_regs=False):
-    out = []
-
-    lbls = [b.label for b in irblocs]
-    lbls_local = []
-    for l in lbls:
-        if l.name.startswith('lbl_gen_'):
-            l.index = int(l.name[8:], 16)
-            lbls_local.append(l)
-    lbl_index_min = 0
-    lbls_index = [l.index for l in lbls if hasattr(l, 'index')]
-    lbls_local.sort(key=lambda x:x.index)
-
-    if lbls_index:
-        lbl_index_min = min(lbls_index)
-        for l in lbls_local:
-            l.index -= lbl_index_min
-
-    out.append("void* local_labels[] = {%s};"%(', '.join(["&&%s"%l.name for l in lbls_local])))
-    out.append("vm_cpu_t* mycpu = (vm_cpu_t*)jitcpu->cpu;")
-
-
-    out.append("goto %s;" % label.name)
-    bloc_labels = [x.label for x in irblocs]
-    assert label in bloc_labels
-
-    lbl_done = set([None])
-
-    for irbloc in irblocs:
-        # XXXX TEST
-        if irbloc.label.offset is None:
-            b_out = ir2C(ir_arch, irbloc, lbl_done, gen_exception_code)
-        else:
-            b_out = ir2C(
-                ir_arch, irbloc, lbl_done, gen_exception_code, log_mn, log_regs)
-        for exprs in b_out:
-            for l in exprs:
-                out.append(l)
-        out.append("")
-
-    return out
-
diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py
index 79099520..e0460cc4 100644
--- a/miasm2/ir/translators/z3_ir.py
+++ b/miasm2/ir/translators/z3_ir.py
@@ -141,7 +141,7 @@ class TranslatorZ3(Translator):
         for subexpr, start, stop in args:
             sube = self.from_expr(subexpr)
             e = z3.Extract(stop-start-1, 0, sube)
-            if res:
+            if res != None:
                 res = z3.Concat(e, res)
             else:
                 res = e
diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c
index a6d29a72..84f835f1 100644
--- a/miasm2/jitter/JitCore.c
+++ b/miasm2/jitter/JitCore.c
@@ -26,7 +26,7 @@ PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure)
 {
 	if (self->pyvm) {
 		Py_INCREF(self->pyvm);
-		return self->pyvm;
+		return (PyObject*)self->pyvm;
 	}
 	Py_INCREF(Py_None);
 	return Py_None;
@@ -34,7 +34,7 @@ PyObject * JitCpu_get_vmmngr(JitCpu *self, void *closure)
 
 PyObject * JitCpu_set_vmmngr(JitCpu *self, PyObject *value, void *closure)
 {
-	self->pyvm = value;
+	self->pyvm = (VmMngr*)value;
 	return 0;
 }
 
@@ -56,22 +56,22 @@ PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure)
 
 uint8_t __attribute__((weak)) MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr)
 {
-	return vm_MEM_LOOKUP_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+	return vm_MEM_LOOKUP_08(&(jitcpu->pyvm->vm_mngr), addr);
 }
 
 uint16_t __attribute__((weak)) MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr)
 {
-	return vm_MEM_LOOKUP_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+	return vm_MEM_LOOKUP_16(&(jitcpu->pyvm->vm_mngr), addr);
 }
 
 uint32_t __attribute__((weak)) MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr)
 {
-	return vm_MEM_LOOKUP_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+	return vm_MEM_LOOKUP_32(&(jitcpu->pyvm->vm_mngr), addr);
 }
 
 uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr)
 {
-	return vm_MEM_LOOKUP_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr);
+	return vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), addr);
 }
 
 void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h
index bae5a417..24feb9c0 100644
--- a/miasm2/jitter/JitCore.h
+++ b/miasm2/jitter/JitCore.h
@@ -92,7 +92,7 @@ typedef struct {
 
 typedef struct {
 	PyObject_HEAD
-	PyObject *pyvm;
+	VmMngr *pyvm;
 	PyObject *jitter;
 	void* cpu;
 } JitCpu;
@@ -129,10 +129,9 @@ PyObject* vm_get_mem(JitCpu *self, PyObject* args);
 
 
 
-
-#define VM_exception_flag (((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags)
+#define VM_exception_flag (jitcpu->pyvm->vm_mngr.exception_flags)
 #define CPU_exception_flag (((vm_cpu_t*)jitcpu->cpu)->exception_flags)
-
+#define CPU_exception_flag_at_instr ((CPU_exception_flag) && ((CPU_exception_flag) > EXCEPT_NUM_UPDT_EIP))
 #define JIT_RET_EXCEPTION 1
 #define JIT_RET_NO_EXCEPTION 0
 
diff --git a/miasm2/jitter/Jitgcc.c b/miasm2/jitter/Jitgcc.c
index 3e7225cb..8b789f70 100644
--- a/miasm2/jitter/Jitgcc.c
+++ b/miasm2/jitter/Jitgcc.c
@@ -35,7 +35,7 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args)
 		// Get the expected jitted function address
 		func_py = PyDict_GetItem(lbl2ptr, retaddr);
 		if (func_py)
-			func = (jitted_func) PyInt_AsLong((PyObject*) func_py);
+			func = (jitted_func) PyLong_AsVoidPtr((PyObject*) func_py);
 		else {
 			if (BlockDst.is_local == 1) {
 				fprintf(stderr, "return on local label!\n");
@@ -44,7 +44,6 @@ PyObject* gcc_exec_bloc(PyObject* self, PyObject* args)
 			// retaddr is not jitted yet
 			return retaddr;
 		}
-
 		// Execute it
 		status = func(&BlockDst, jitcpu);
 		Py_DECREF(retaddr);
diff --git a/miasm2/jitter/Jittcc.c b/miasm2/jitter/Jittcc.c
index 201f9b7f..1acbd56f 100644
--- a/miasm2/jitter/Jittcc.c
+++ b/miasm2/jitter/Jittcc.c
@@ -154,7 +154,7 @@ PyObject* tcc_exec_bloc(PyObject* self, PyObject* args)
 		// Get the expected jitted function address
 		func_py = PyDict_GetItem(lbl2ptr, retaddr);
 		if (func_py)
-			func = (jitted_func) PyInt_AsLong((PyObject*) func_py);
+			func = (jitted_func) PyLong_AsVoidPtr((PyObject*) func_py);
 		else {
 			if (BlockDst.is_local == 1) {
 				fprintf(stderr, "return on local label!\n");
diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c
index 28661bfe..15a3c27c 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.c
+++ b/miasm2/jitter/arch/JitCore_aarch64.c
@@ -1,11 +1,11 @@
 #include <Python.h>
-#include "../JitCore.h"
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../JitCore.h"
 #include "JitCore_aarch64.h"
 
 
@@ -386,7 +386,6 @@ PyObject* get_gpreg_offset_all(void)
     PyObject *o;
 
     get_reg_off(exception_flags);
-    get_reg_off(exception_flags_new);
 
     get_reg_off(X0);
     get_reg_off(X1);
@@ -422,142 +421,12 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(SP);
     get_reg_off(PC);
 
-
-    get_reg_off(X0_new);
-    get_reg_off(X1_new);
-    get_reg_off(X2_new);
-    get_reg_off(X3_new);
-    get_reg_off(X4_new);
-    get_reg_off(X5_new);
-    get_reg_off(X6_new);
-    get_reg_off(X7_new);
-    get_reg_off(X8_new);
-    get_reg_off(X9_new);
-    get_reg_off(X10_new);
-    get_reg_off(X11_new);
-    get_reg_off(X12_new);
-    get_reg_off(X13_new);
-    get_reg_off(X14_new);
-    get_reg_off(X15_new);
-    get_reg_off(X16_new);
-    get_reg_off(X17_new);
-    get_reg_off(X18_new);
-    get_reg_off(X19_new);
-    get_reg_off(X20_new);
-    get_reg_off(X21_new);
-    get_reg_off(X22_new);
-    get_reg_off(X23_new);
-    get_reg_off(X24_new);
-    get_reg_off(X25_new);
-    get_reg_off(X26_new);
-    get_reg_off(X27_new);
-    get_reg_off(X28_new);
-    get_reg_off(X29_new);
-    get_reg_off(LR_new);
-    get_reg_off(SP_new);
-    get_reg_off(PC_new);
-
-
-
     /* eflag */
     get_reg_off(zf);
     get_reg_off(nf);
     get_reg_off(of);
     get_reg_off(cf);
 
-    get_reg_off(zf_new);
-    get_reg_off(nf_new);
-    get_reg_off(of_new);
-    get_reg_off(cf_new);
-
-
-    get_reg_off(pfmem08_0);
-    get_reg_off(pfmem08_1);
-    get_reg_off(pfmem08_2);
-    get_reg_off(pfmem08_3);
-    get_reg_off(pfmem08_4);
-    get_reg_off(pfmem08_5);
-    get_reg_off(pfmem08_6);
-    get_reg_off(pfmem08_7);
-    get_reg_off(pfmem08_8);
-    get_reg_off(pfmem08_9);
-    get_reg_off(pfmem08_10);
-    get_reg_off(pfmem08_11);
-    get_reg_off(pfmem08_12);
-    get_reg_off(pfmem08_13);
-    get_reg_off(pfmem08_14);
-    get_reg_off(pfmem08_15);
-    get_reg_off(pfmem08_16);
-    get_reg_off(pfmem08_17);
-    get_reg_off(pfmem08_18);
-    get_reg_off(pfmem08_19);
-
-
-    get_reg_off(pfmem16_0);
-    get_reg_off(pfmem16_1);
-    get_reg_off(pfmem16_2);
-    get_reg_off(pfmem16_3);
-    get_reg_off(pfmem16_4);
-    get_reg_off(pfmem16_5);
-    get_reg_off(pfmem16_6);
-    get_reg_off(pfmem16_7);
-    get_reg_off(pfmem16_8);
-    get_reg_off(pfmem16_9);
-    get_reg_off(pfmem16_10);
-    get_reg_off(pfmem16_11);
-    get_reg_off(pfmem16_12);
-    get_reg_off(pfmem16_13);
-    get_reg_off(pfmem16_14);
-    get_reg_off(pfmem16_15);
-    get_reg_off(pfmem16_16);
-    get_reg_off(pfmem16_17);
-    get_reg_off(pfmem16_18);
-    get_reg_off(pfmem16_19);
-
-
-    get_reg_off(pfmem32_0);
-    get_reg_off(pfmem32_1);
-    get_reg_off(pfmem32_2);
-    get_reg_off(pfmem32_3);
-    get_reg_off(pfmem32_4);
-    get_reg_off(pfmem32_5);
-    get_reg_off(pfmem32_6);
-    get_reg_off(pfmem32_7);
-    get_reg_off(pfmem32_8);
-    get_reg_off(pfmem32_9);
-    get_reg_off(pfmem32_10);
-    get_reg_off(pfmem32_11);
-    get_reg_off(pfmem32_12);
-    get_reg_off(pfmem32_13);
-    get_reg_off(pfmem32_14);
-    get_reg_off(pfmem32_15);
-    get_reg_off(pfmem32_16);
-    get_reg_off(pfmem32_17);
-    get_reg_off(pfmem32_18);
-    get_reg_off(pfmem32_19);
-
-
-    get_reg_off(pfmem64_0);
-    get_reg_off(pfmem64_1);
-    get_reg_off(pfmem64_2);
-    get_reg_off(pfmem64_3);
-    get_reg_off(pfmem64_4);
-    get_reg_off(pfmem64_5);
-    get_reg_off(pfmem64_6);
-    get_reg_off(pfmem64_7);
-    get_reg_off(pfmem64_8);
-    get_reg_off(pfmem64_9);
-    get_reg_off(pfmem64_10);
-    get_reg_off(pfmem64_11);
-    get_reg_off(pfmem64_12);
-    get_reg_off(pfmem64_13);
-    get_reg_off(pfmem64_14);
-    get_reg_off(pfmem64_15);
-    get_reg_off(pfmem64_16);
-    get_reg_off(pfmem64_17);
-    get_reg_off(pfmem64_18);
-    get_reg_off(pfmem64_19);
-
     return dict;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_aarch64.h b/miasm2/jitter/arch/JitCore_aarch64.h
index e1708541..2203e037 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.h
+++ b/miasm2/jitter/arch/JitCore_aarch64.h
@@ -1,7 +1,6 @@
 
 typedef struct {
 	uint32_t exception_flags;
-	uint32_t exception_flags_new;
 
 	/* gpregs */
 
@@ -40,141 +39,11 @@ typedef struct {
 
 	uint64_t PC;
 
-
-	uint64_t X0_new;
-	uint64_t X1_new;
-	uint64_t X2_new;
-	uint64_t X3_new;
-	uint64_t X4_new;
-	uint64_t X5_new;
-	uint64_t X6_new;
-	uint64_t X7_new;
-	uint64_t X8_new;
-	uint64_t X9_new;
-	uint64_t X10_new;
-	uint64_t X11_new;
-	uint64_t X12_new;
-	uint64_t X13_new;
-	uint64_t X14_new;
-	uint64_t X15_new;
-	uint64_t X16_new;
-	uint64_t X17_new;
-	uint64_t X18_new;
-	uint64_t X19_new;
-	uint64_t X20_new;
-	uint64_t X21_new;
-	uint64_t X22_new;
-	uint64_t X23_new;
-	uint64_t X24_new;
-	uint64_t X25_new;
-	uint64_t X26_new;
-	uint64_t X27_new;
-	uint64_t X28_new;
-	uint64_t X29_new;
-	uint64_t LR_new;
-	uint64_t SP_new;
-
-	uint64_t PC_new;
-
 	/* eflag */
 	uint32_t zf;
 	uint32_t nf;
 	uint32_t of;
 	uint32_t cf;
-
-	uint32_t zf_new;
-	uint32_t nf_new;
-	uint32_t of_new;
-	uint32_t cf_new;
-
-
-	uint8_t pfmem08_0;
-	uint8_t pfmem08_1;
-	uint8_t pfmem08_2;
-	uint8_t pfmem08_3;
-	uint8_t pfmem08_4;
-	uint8_t pfmem08_5;
-	uint8_t pfmem08_6;
-	uint8_t pfmem08_7;
-	uint8_t pfmem08_8;
-	uint8_t pfmem08_9;
-	uint8_t pfmem08_10;
-	uint8_t pfmem08_11;
-	uint8_t pfmem08_12;
-	uint8_t pfmem08_13;
-	uint8_t pfmem08_14;
-	uint8_t pfmem08_15;
-	uint8_t pfmem08_16;
-	uint8_t pfmem08_17;
-	uint8_t pfmem08_18;
-	uint8_t pfmem08_19;
-
-
-	uint16_t pfmem16_0;
-	uint16_t pfmem16_1;
-	uint16_t pfmem16_2;
-	uint16_t pfmem16_3;
-	uint16_t pfmem16_4;
-	uint16_t pfmem16_5;
-	uint16_t pfmem16_6;
-	uint16_t pfmem16_7;
-	uint16_t pfmem16_8;
-	uint16_t pfmem16_9;
-	uint16_t pfmem16_10;
-	uint16_t pfmem16_11;
-	uint16_t pfmem16_12;
-	uint16_t pfmem16_13;
-	uint16_t pfmem16_14;
-	uint16_t pfmem16_15;
-	uint16_t pfmem16_16;
-	uint16_t pfmem16_17;
-	uint16_t pfmem16_18;
-	uint16_t pfmem16_19;
-
-
-	uint32_t pfmem32_0;
-	uint32_t pfmem32_1;
-	uint32_t pfmem32_2;
-	uint32_t pfmem32_3;
-	uint32_t pfmem32_4;
-	uint32_t pfmem32_5;
-	uint32_t pfmem32_6;
-	uint32_t pfmem32_7;
-	uint32_t pfmem32_8;
-	uint32_t pfmem32_9;
-	uint32_t pfmem32_10;
-	uint32_t pfmem32_11;
-	uint32_t pfmem32_12;
-	uint32_t pfmem32_13;
-	uint32_t pfmem32_14;
-	uint32_t pfmem32_15;
-	uint32_t pfmem32_16;
-	uint32_t pfmem32_17;
-	uint32_t pfmem32_18;
-	uint32_t pfmem32_19;
-
-
-	uint64_t pfmem64_0;
-	uint64_t pfmem64_1;
-	uint64_t pfmem64_2;
-	uint64_t pfmem64_3;
-	uint64_t pfmem64_4;
-	uint64_t pfmem64_5;
-	uint64_t pfmem64_6;
-	uint64_t pfmem64_7;
-	uint64_t pfmem64_8;
-	uint64_t pfmem64_9;
-	uint64_t pfmem64_10;
-	uint64_t pfmem64_11;
-	uint64_t pfmem64_12;
-	uint64_t pfmem64_13;
-	uint64_t pfmem64_14;
-	uint64_t pfmem64_15;
-	uint64_t pfmem64_16;
-	uint64_t pfmem64_17;
-	uint64_t pfmem64_18;
-	uint64_t pfmem64_19;
-
 }vm_cpu_t;
 
 
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index b2550194..90e72ea4 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -1,11 +1,11 @@
 #include <Python.h>
-#include "../JitCore.h"
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../JitCore.h"
 #include "JitCore_arm.h"
 
 
@@ -300,8 +300,6 @@ PyObject* get_gpreg_offset_all(void)
     PyObject *o;
 
     get_reg_off(exception_flags);
-    get_reg_off(exception_flags_new);
-
 
     get_reg_off(R0);
     get_reg_off(R1);
@@ -320,122 +318,12 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(LR);
     get_reg_off(PC);
 
-    get_reg_off(R0_new);
-    get_reg_off(R1_new);
-    get_reg_off(R2_new);
-    get_reg_off(R3_new);
-    get_reg_off(R4_new);
-    get_reg_off(R5_new);
-    get_reg_off(R6_new);
-    get_reg_off(R7_new);
-    get_reg_off(R8_new);
-    get_reg_off(R9_new);
-    get_reg_off(R10_new);
-    get_reg_off(R11_new);
-    get_reg_off(R12_new);
-    get_reg_off(SP_new);
-    get_reg_off(LR_new);
-    get_reg_off(PC_new);
-
 	/* eflag */
     get_reg_off(zf);
     get_reg_off(nf);
     get_reg_off(of);
     get_reg_off(cf);
 
-    get_reg_off(zf_new);
-    get_reg_off(nf_new);
-    get_reg_off(of_new);
-    get_reg_off(cf_new);
-
-
-    get_reg_off(pfmem08_0);
-    get_reg_off(pfmem08_1);
-    get_reg_off(pfmem08_2);
-    get_reg_off(pfmem08_3);
-    get_reg_off(pfmem08_4);
-    get_reg_off(pfmem08_5);
-    get_reg_off(pfmem08_6);
-    get_reg_off(pfmem08_7);
-    get_reg_off(pfmem08_8);
-    get_reg_off(pfmem08_9);
-    get_reg_off(pfmem08_10);
-    get_reg_off(pfmem08_11);
-    get_reg_off(pfmem08_12);
-    get_reg_off(pfmem08_13);
-    get_reg_off(pfmem08_14);
-    get_reg_off(pfmem08_15);
-    get_reg_off(pfmem08_16);
-    get_reg_off(pfmem08_17);
-    get_reg_off(pfmem08_18);
-    get_reg_off(pfmem08_19);
-
-
-    get_reg_off(pfmem16_0);
-    get_reg_off(pfmem16_1);
-    get_reg_off(pfmem16_2);
-    get_reg_off(pfmem16_3);
-    get_reg_off(pfmem16_4);
-    get_reg_off(pfmem16_5);
-    get_reg_off(pfmem16_6);
-    get_reg_off(pfmem16_7);
-    get_reg_off(pfmem16_8);
-    get_reg_off(pfmem16_9);
-    get_reg_off(pfmem16_10);
-    get_reg_off(pfmem16_11);
-    get_reg_off(pfmem16_12);
-    get_reg_off(pfmem16_13);
-    get_reg_off(pfmem16_14);
-    get_reg_off(pfmem16_15);
-    get_reg_off(pfmem16_16);
-    get_reg_off(pfmem16_17);
-    get_reg_off(pfmem16_18);
-    get_reg_off(pfmem16_19);
-
-
-    get_reg_off(pfmem32_0);
-    get_reg_off(pfmem32_1);
-    get_reg_off(pfmem32_2);
-    get_reg_off(pfmem32_3);
-    get_reg_off(pfmem32_4);
-    get_reg_off(pfmem32_5);
-    get_reg_off(pfmem32_6);
-    get_reg_off(pfmem32_7);
-    get_reg_off(pfmem32_8);
-    get_reg_off(pfmem32_9);
-    get_reg_off(pfmem32_10);
-    get_reg_off(pfmem32_11);
-    get_reg_off(pfmem32_12);
-    get_reg_off(pfmem32_13);
-    get_reg_off(pfmem32_14);
-    get_reg_off(pfmem32_15);
-    get_reg_off(pfmem32_16);
-    get_reg_off(pfmem32_17);
-    get_reg_off(pfmem32_18);
-    get_reg_off(pfmem32_19);
-
-
-    get_reg_off(pfmem64_0);
-    get_reg_off(pfmem64_1);
-    get_reg_off(pfmem64_2);
-    get_reg_off(pfmem64_3);
-    get_reg_off(pfmem64_4);
-    get_reg_off(pfmem64_5);
-    get_reg_off(pfmem64_6);
-    get_reg_off(pfmem64_7);
-    get_reg_off(pfmem64_8);
-    get_reg_off(pfmem64_9);
-    get_reg_off(pfmem64_10);
-    get_reg_off(pfmem64_11);
-    get_reg_off(pfmem64_12);
-    get_reg_off(pfmem64_13);
-    get_reg_off(pfmem64_14);
-    get_reg_off(pfmem64_15);
-    get_reg_off(pfmem64_16);
-    get_reg_off(pfmem64_17);
-    get_reg_off(pfmem64_18);
-    get_reg_off(pfmem64_19);
-
     return dict;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h
index dde112ef..976ff124 100644
--- a/miasm2/jitter/arch/JitCore_arm.h
+++ b/miasm2/jitter/arch/JitCore_arm.h
@@ -1,7 +1,6 @@
 
 typedef struct {
 	uint32_t exception_flags;
-	uint32_t exception_flags_new;
 
 	/* gpregs */
 	uint32_t R0;
@@ -21,122 +20,12 @@ typedef struct {
 	uint32_t LR;
 	uint32_t PC;
 
-	uint32_t R0_new;
-	uint32_t R1_new;
-	uint32_t R2_new;
-	uint32_t R3_new;
-	uint32_t R4_new;
-	uint32_t R5_new;
-	uint32_t R6_new;
-	uint32_t R7_new;
-	uint32_t R8_new;
-	uint32_t R9_new;
-	uint32_t R10_new;
-	uint32_t R11_new;
-	uint32_t R12_new;
-	uint32_t SP_new;
-	uint32_t LR_new;
-	uint32_t PC_new;
-
 	/* eflag */
 	uint32_t zf;
 	uint32_t nf;
 	uint32_t of;
 	uint32_t cf;
 
-	uint32_t zf_new;
-	uint32_t nf_new;
-	uint32_t of_new;
-	uint32_t cf_new;
-
-
-	uint8_t pfmem08_0;
-	uint8_t pfmem08_1;
-	uint8_t pfmem08_2;
-	uint8_t pfmem08_3;
-	uint8_t pfmem08_4;
-	uint8_t pfmem08_5;
-	uint8_t pfmem08_6;
-	uint8_t pfmem08_7;
-	uint8_t pfmem08_8;
-	uint8_t pfmem08_9;
-	uint8_t pfmem08_10;
-	uint8_t pfmem08_11;
-	uint8_t pfmem08_12;
-	uint8_t pfmem08_13;
-	uint8_t pfmem08_14;
-	uint8_t pfmem08_15;
-	uint8_t pfmem08_16;
-	uint8_t pfmem08_17;
-	uint8_t pfmem08_18;
-	uint8_t pfmem08_19;
-
-
-	uint16_t pfmem16_0;
-	uint16_t pfmem16_1;
-	uint16_t pfmem16_2;
-	uint16_t pfmem16_3;
-	uint16_t pfmem16_4;
-	uint16_t pfmem16_5;
-	uint16_t pfmem16_6;
-	uint16_t pfmem16_7;
-	uint16_t pfmem16_8;
-	uint16_t pfmem16_9;
-	uint16_t pfmem16_10;
-	uint16_t pfmem16_11;
-	uint16_t pfmem16_12;
-	uint16_t pfmem16_13;
-	uint16_t pfmem16_14;
-	uint16_t pfmem16_15;
-	uint16_t pfmem16_16;
-	uint16_t pfmem16_17;
-	uint16_t pfmem16_18;
-	uint16_t pfmem16_19;
-
-
-	uint32_t pfmem32_0;
-	uint32_t pfmem32_1;
-	uint32_t pfmem32_2;
-	uint32_t pfmem32_3;
-	uint32_t pfmem32_4;
-	uint32_t pfmem32_5;
-	uint32_t pfmem32_6;
-	uint32_t pfmem32_7;
-	uint32_t pfmem32_8;
-	uint32_t pfmem32_9;
-	uint32_t pfmem32_10;
-	uint32_t pfmem32_11;
-	uint32_t pfmem32_12;
-	uint32_t pfmem32_13;
-	uint32_t pfmem32_14;
-	uint32_t pfmem32_15;
-	uint32_t pfmem32_16;
-	uint32_t pfmem32_17;
-	uint32_t pfmem32_18;
-	uint32_t pfmem32_19;
-
-
-	uint64_t pfmem64_0;
-	uint64_t pfmem64_1;
-	uint64_t pfmem64_2;
-	uint64_t pfmem64_3;
-	uint64_t pfmem64_4;
-	uint64_t pfmem64_5;
-	uint64_t pfmem64_6;
-	uint64_t pfmem64_7;
-	uint64_t pfmem64_8;
-	uint64_t pfmem64_9;
-	uint64_t pfmem64_10;
-	uint64_t pfmem64_11;
-	uint64_t pfmem64_12;
-	uint64_t pfmem64_13;
-	uint64_t pfmem64_14;
-	uint64_t pfmem64_15;
-	uint64_t pfmem64_16;
-	uint64_t pfmem64_17;
-	uint64_t pfmem64_18;
-	uint64_t pfmem64_19;
-
 }vm_cpu_t;
 
 
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index c8f8fb81..fc5589ff 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -1,11 +1,11 @@
 #include <Python.h>
-#include "../JitCore.h"
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../JitCore.h"
 #include "JitCore_mips32.h"
 
 
@@ -356,7 +356,6 @@ PyObject* get_gpreg_offset_all(void)
     PyObject *o;
 
     get_reg_off(exception_flags);
-    get_reg_off(exception_flags_new);
 
 
     get_reg_off(ZERO);
@@ -396,132 +395,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(R_LO);
     get_reg_off(R_HI);
 
-    get_reg_off(ZERO_new);
-    get_reg_off(AT_new);
-    get_reg_off(V0_new);
-    get_reg_off(V1_new);
-    get_reg_off(A0_new);
-    get_reg_off(A1_new);
-    get_reg_off(A2_new);
-    get_reg_off(A3_new);
-    get_reg_off(T0_new);
-    get_reg_off(T1_new);
-    get_reg_off(T2_new);
-    get_reg_off(T3_new);
-    get_reg_off(T4_new);
-    get_reg_off(T5_new);
-    get_reg_off(T6_new);
-    get_reg_off(T7_new);
-    get_reg_off(S0_new);
-    get_reg_off(S1_new);
-    get_reg_off(S2_new);
-    get_reg_off(S3_new);
-    get_reg_off(S4_new);
-    get_reg_off(S5_new);
-    get_reg_off(S6_new);
-    get_reg_off(S7_new);
-    get_reg_off(T8_new);
-    get_reg_off(T9_new);
-    get_reg_off(K0_new);
-    get_reg_off(K1_new);
-    get_reg_off(GP_new);
-    get_reg_off(SP_new);
-    get_reg_off(FP_new);
-    get_reg_off(RA_new);
-    get_reg_off(PC_new);
-    get_reg_off(PC_FETCH_new);
-    get_reg_off(R_LO_new);
-    get_reg_off(R_HI_new);
-
-
-
-    get_reg_off(pfmem08_0);
-    get_reg_off(pfmem08_1);
-    get_reg_off(pfmem08_2);
-    get_reg_off(pfmem08_3);
-    get_reg_off(pfmem08_4);
-    get_reg_off(pfmem08_5);
-    get_reg_off(pfmem08_6);
-    get_reg_off(pfmem08_7);
-    get_reg_off(pfmem08_8);
-    get_reg_off(pfmem08_9);
-    get_reg_off(pfmem08_10);
-    get_reg_off(pfmem08_11);
-    get_reg_off(pfmem08_12);
-    get_reg_off(pfmem08_13);
-    get_reg_off(pfmem08_14);
-    get_reg_off(pfmem08_15);
-    get_reg_off(pfmem08_16);
-    get_reg_off(pfmem08_17);
-    get_reg_off(pfmem08_18);
-    get_reg_off(pfmem08_19);
-
-
-    get_reg_off(pfmem16_0);
-    get_reg_off(pfmem16_1);
-    get_reg_off(pfmem16_2);
-    get_reg_off(pfmem16_3);
-    get_reg_off(pfmem16_4);
-    get_reg_off(pfmem16_5);
-    get_reg_off(pfmem16_6);
-    get_reg_off(pfmem16_7);
-    get_reg_off(pfmem16_8);
-    get_reg_off(pfmem16_9);
-    get_reg_off(pfmem16_10);
-    get_reg_off(pfmem16_11);
-    get_reg_off(pfmem16_12);
-    get_reg_off(pfmem16_13);
-    get_reg_off(pfmem16_14);
-    get_reg_off(pfmem16_15);
-    get_reg_off(pfmem16_16);
-    get_reg_off(pfmem16_17);
-    get_reg_off(pfmem16_18);
-    get_reg_off(pfmem16_19);
-
-
-    get_reg_off(pfmem32_0);
-    get_reg_off(pfmem32_1);
-    get_reg_off(pfmem32_2);
-    get_reg_off(pfmem32_3);
-    get_reg_off(pfmem32_4);
-    get_reg_off(pfmem32_5);
-    get_reg_off(pfmem32_6);
-    get_reg_off(pfmem32_7);
-    get_reg_off(pfmem32_8);
-    get_reg_off(pfmem32_9);
-    get_reg_off(pfmem32_10);
-    get_reg_off(pfmem32_11);
-    get_reg_off(pfmem32_12);
-    get_reg_off(pfmem32_13);
-    get_reg_off(pfmem32_14);
-    get_reg_off(pfmem32_15);
-    get_reg_off(pfmem32_16);
-    get_reg_off(pfmem32_17);
-    get_reg_off(pfmem32_18);
-    get_reg_off(pfmem32_19);
-
-
-    get_reg_off(pfmem64_0);
-    get_reg_off(pfmem64_1);
-    get_reg_off(pfmem64_2);
-    get_reg_off(pfmem64_3);
-    get_reg_off(pfmem64_4);
-    get_reg_off(pfmem64_5);
-    get_reg_off(pfmem64_6);
-    get_reg_off(pfmem64_7);
-    get_reg_off(pfmem64_8);
-    get_reg_off(pfmem64_9);
-    get_reg_off(pfmem64_10);
-    get_reg_off(pfmem64_11);
-    get_reg_off(pfmem64_12);
-    get_reg_off(pfmem64_13);
-    get_reg_off(pfmem64_14);
-    get_reg_off(pfmem64_15);
-    get_reg_off(pfmem64_16);
-    get_reg_off(pfmem64_17);
-    get_reg_off(pfmem64_18);
-    get_reg_off(pfmem64_19);
-
     return dict;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h
index de98f069..55c63d3b 100644
--- a/miasm2/jitter/arch/JitCore_mips32.h
+++ b/miasm2/jitter/arch/JitCore_mips32.h
@@ -1,7 +1,6 @@
 
 typedef struct {
 	uint32_t exception_flags;
-	uint32_t exception_flags_new;
 
 	/* gpregs */
 
@@ -42,132 +41,6 @@ typedef struct {
 	uint32_t R_LO;
 	uint32_t R_HI;
 
-	uint32_t ZERO_new;
-	uint32_t AT_new;
-	uint32_t V0_new;
-	uint32_t V1_new;
-	uint32_t A0_new;
-	uint32_t A1_new;
-	uint32_t A2_new;
-	uint32_t A3_new;
-	uint32_t T0_new;
-	uint32_t T1_new;
-	uint32_t T2_new;
-	uint32_t T3_new;
-	uint32_t T4_new;
-	uint32_t T5_new;
-	uint32_t T6_new;
-	uint32_t T7_new;
-	uint32_t S0_new;
-	uint32_t S1_new;
-	uint32_t S2_new;
-	uint32_t S3_new;
-	uint32_t S4_new;
-	uint32_t S5_new;
-	uint32_t S6_new;
-	uint32_t S7_new;
-	uint32_t T8_new;
-	uint32_t T9_new;
-	uint32_t K0_new;
-	uint32_t K1_new;
-	uint32_t GP_new;
-	uint32_t SP_new;
-	uint32_t FP_new;
-	uint32_t RA_new;
-	uint32_t PC_new;
-	uint32_t PC_FETCH_new;
-	uint32_t R_LO_new;
-	uint32_t R_HI_new;
-
-
-
-	uint8_t pfmem08_0;
-	uint8_t pfmem08_1;
-	uint8_t pfmem08_2;
-	uint8_t pfmem08_3;
-	uint8_t pfmem08_4;
-	uint8_t pfmem08_5;
-	uint8_t pfmem08_6;
-	uint8_t pfmem08_7;
-	uint8_t pfmem08_8;
-	uint8_t pfmem08_9;
-	uint8_t pfmem08_10;
-	uint8_t pfmem08_11;
-	uint8_t pfmem08_12;
-	uint8_t pfmem08_13;
-	uint8_t pfmem08_14;
-	uint8_t pfmem08_15;
-	uint8_t pfmem08_16;
-	uint8_t pfmem08_17;
-	uint8_t pfmem08_18;
-	uint8_t pfmem08_19;
-
-
-	uint16_t pfmem16_0;
-	uint16_t pfmem16_1;
-	uint16_t pfmem16_2;
-	uint16_t pfmem16_3;
-	uint16_t pfmem16_4;
-	uint16_t pfmem16_5;
-	uint16_t pfmem16_6;
-	uint16_t pfmem16_7;
-	uint16_t pfmem16_8;
-	uint16_t pfmem16_9;
-	uint16_t pfmem16_10;
-	uint16_t pfmem16_11;
-	uint16_t pfmem16_12;
-	uint16_t pfmem16_13;
-	uint16_t pfmem16_14;
-	uint16_t pfmem16_15;
-	uint16_t pfmem16_16;
-	uint16_t pfmem16_17;
-	uint16_t pfmem16_18;
-	uint16_t pfmem16_19;
-
-
-	uint32_t pfmem32_0;
-	uint32_t pfmem32_1;
-	uint32_t pfmem32_2;
-	uint32_t pfmem32_3;
-	uint32_t pfmem32_4;
-	uint32_t pfmem32_5;
-	uint32_t pfmem32_6;
-	uint32_t pfmem32_7;
-	uint32_t pfmem32_8;
-	uint32_t pfmem32_9;
-	uint32_t pfmem32_10;
-	uint32_t pfmem32_11;
-	uint32_t pfmem32_12;
-	uint32_t pfmem32_13;
-	uint32_t pfmem32_14;
-	uint32_t pfmem32_15;
-	uint32_t pfmem32_16;
-	uint32_t pfmem32_17;
-	uint32_t pfmem32_18;
-	uint32_t pfmem32_19;
-
-
-	uint64_t pfmem64_0;
-	uint64_t pfmem64_1;
-	uint64_t pfmem64_2;
-	uint64_t pfmem64_3;
-	uint64_t pfmem64_4;
-	uint64_t pfmem64_5;
-	uint64_t pfmem64_6;
-	uint64_t pfmem64_7;
-	uint64_t pfmem64_8;
-	uint64_t pfmem64_9;
-	uint64_t pfmem64_10;
-	uint64_t pfmem64_11;
-	uint64_t pfmem64_12;
-	uint64_t pfmem64_13;
-	uint64_t pfmem64_14;
-	uint64_t pfmem64_15;
-	uint64_t pfmem64_16;
-	uint64_t pfmem64_17;
-	uint64_t pfmem64_18;
-	uint64_t pfmem64_19;
-
 
 	double F0;
 	double F1;
@@ -202,39 +75,6 @@ typedef struct {
 	double F30;
 	double F31;
 
-	double F0_new;
-	double F1_new;
-	double F2_new;
-	double F3_new;
-	double F4_new;
-	double F5_new;
-	double F6_new;
-	double F7_new;
-	double F8_new;
-	double F9_new;
-	double F10_new;
-	double F11_new;
-	double F12_new;
-	double F13_new;
-	double F14_new;
-	double F15_new;
-	double F16_new;
-	double F17_new;
-	double F18_new;
-	double F19_new;
-	double F20_new;
-	double F21_new;
-	double F22_new;
-	double F23_new;
-	double F24_new;
-	double F25_new;
-	double F26_new;
-	double F27_new;
-	double F28_new;
-	double F29_new;
-	double F30_new;
-	double F31_new;
-
 	uint32_t INDEX;
 	uint32_t CPR0_1;
 	uint32_t CPR0_2;
@@ -491,266 +331,9 @@ typedef struct {
 	uint32_t CPR0_253;
 	uint32_t CPR0_254;
 	uint32_t CPR0_255;
-
-	uint32_t INDEX_new;
-	uint32_t CPR0_1_new;
-	uint32_t CPR0_2_new;
-	uint32_t CPR0_3_new;
-	uint32_t CPR0_4_new;
-	uint32_t CPR0_5_new;
-	uint32_t CPR0_6_new;
-	uint32_t CPR0_7_new;
-	uint32_t CPR0_8_new;
-	uint32_t CPR0_9_new;
-	uint32_t CPR0_10_new;
-	uint32_t CPR0_11_new;
-	uint32_t CPR0_12_new;
-	uint32_t CPR0_13_new;
-	uint32_t CPR0_14_new;
-	uint32_t CPR0_15_new;
-	uint32_t ENTRYLO0_new;
-	uint32_t CPR0_17_new;
-	uint32_t CPR0_18_new;
-	uint32_t CPR0_19_new;
-	uint32_t CPR0_20_new;
-	uint32_t CPR0_21_new;
-	uint32_t CPR0_22_new;
-	uint32_t CPR0_23_new;
-	uint32_t ENTRYLO1_new;
-	uint32_t CPR0_25_new;
-	uint32_t CPR0_26_new;
-	uint32_t CPR0_27_new;
-	uint32_t CPR0_28_new;
-	uint32_t CPR0_29_new;
-	uint32_t CPR0_30_new;
-	uint32_t CPR0_31_new;
-	uint32_t CPR0_32_new;
-	uint32_t CPR0_33_new;
-	uint32_t CPR0_34_new;
-	uint32_t CPR0_35_new;
-	uint32_t CPR0_36_new;
-	uint32_t CPR0_37_new;
-	uint32_t CPR0_38_new;
-	uint32_t CPR0_39_new;
-	uint32_t PAGEMASK_new;
-	uint32_t CPR0_41_new;
-	uint32_t CPR0_42_new;
-	uint32_t CPR0_43_new;
-	uint32_t CPR0_44_new;
-	uint32_t CPR0_45_new;
-	uint32_t CPR0_46_new;
-	uint32_t CPR0_47_new;
-	uint32_t CPR0_48_new;
-	uint32_t CPR0_49_new;
-	uint32_t CPR0_50_new;
-	uint32_t CPR0_51_new;
-	uint32_t CPR0_52_new;
-	uint32_t CPR0_53_new;
-	uint32_t CPR0_54_new;
-	uint32_t CPR0_55_new;
-	uint32_t CPR0_56_new;
-	uint32_t CPR0_57_new;
-	uint32_t CPR0_58_new;
-	uint32_t CPR0_59_new;
-	uint32_t CPR0_60_new;
-	uint32_t CPR0_61_new;
-	uint32_t CPR0_62_new;
-	uint32_t CPR0_63_new;
-	uint32_t CPR0_64_new;
-	uint32_t CPR0_65_new;
-	uint32_t CPR0_66_new;
-	uint32_t CPR0_67_new;
-	uint32_t CPR0_68_new;
-	uint32_t CPR0_69_new;
-	uint32_t CPR0_70_new;
-	uint32_t CPR0_71_new;
-	uint32_t COUNT_new;
-	uint32_t CPR0_73_new;
-	uint32_t CPR0_74_new;
-	uint32_t CPR0_75_new;
-	uint32_t CPR0_76_new;
-	uint32_t CPR0_77_new;
-	uint32_t CPR0_78_new;
-	uint32_t CPR0_79_new;
-	uint32_t ENTRYHI_new;
-	uint32_t CPR0_81_new;
-	uint32_t CPR0_82_new;
-	uint32_t CPR0_83_new;
-	uint32_t CPR0_84_new;
-	uint32_t CPR0_85_new;
-	uint32_t CPR0_86_new;
-	uint32_t CPR0_87_new;
-	uint32_t CPR0_88_new;
-	uint32_t CPR0_89_new;
-	uint32_t CPR0_90_new;
-	uint32_t CPR0_91_new;
-	uint32_t CPR0_92_new;
-	uint32_t CPR0_93_new;
-	uint32_t CPR0_94_new;
-	uint32_t CPR0_95_new;
-	uint32_t CPR0_96_new;
-	uint32_t CPR0_97_new;
-	uint32_t CPR0_98_new;
-	uint32_t CPR0_99_new;
-	uint32_t CPR0_100_new;
-	uint32_t CPR0_101_new;
-	uint32_t CPR0_102_new;
-	uint32_t CPR0_103_new;
-	uint32_t CAUSE_new;
-	uint32_t CPR0_105_new;
-	uint32_t CPR0_106_new;
-	uint32_t CPR0_107_new;
-	uint32_t CPR0_108_new;
-	uint32_t CPR0_109_new;
-	uint32_t CPR0_110_new;
-	uint32_t CPR0_111_new;
-	uint32_t EPC_new;
-	uint32_t CPR0_113_new;
-	uint32_t CPR0_114_new;
-	uint32_t CPR0_115_new;
-	uint32_t CPR0_116_new;
-	uint32_t CPR0_117_new;
-	uint32_t CPR0_118_new;
-	uint32_t CPR0_119_new;
-	uint32_t CPR0_120_new;
-	uint32_t CPR0_121_new;
-	uint32_t CPR0_122_new;
-	uint32_t CPR0_123_new;
-	uint32_t CPR0_124_new;
-	uint32_t CPR0_125_new;
-	uint32_t CPR0_126_new;
-	uint32_t CPR0_127_new;
-	uint32_t CONFIG_new;
-	uint32_t CPR0_129_new;
-	uint32_t CPR0_130_new;
-	uint32_t CPR0_131_new;
-	uint32_t CPR0_132_new;
-	uint32_t CPR0_133_new;
-	uint32_t CPR0_134_new;
-	uint32_t CPR0_135_new;
-	uint32_t CPR0_136_new;
-	uint32_t CPR0_137_new;
-	uint32_t CPR0_138_new;
-	uint32_t CPR0_139_new;
-	uint32_t CPR0_140_new;
-	uint32_t CPR0_141_new;
-	uint32_t CPR0_142_new;
-	uint32_t CPR0_143_new;
-	uint32_t CPR0_144_new;
-	uint32_t CPR0_145_new;
-	uint32_t CPR0_146_new;
-	uint32_t CPR0_147_new;
-	uint32_t CPR0_148_new;
-	uint32_t CPR0_149_new;
-	uint32_t CPR0_150_new;
-	uint32_t CPR0_151_new;
-	uint32_t WATCHHI_new;
-	uint32_t CPR0_153_new;
-	uint32_t CPR0_154_new;
-	uint32_t CPR0_155_new;
-	uint32_t CPR0_156_new;
-	uint32_t CPR0_157_new;
-	uint32_t CPR0_158_new;
-	uint32_t CPR0_159_new;
-	uint32_t CPR0_160_new;
-	uint32_t CPR0_161_new;
-	uint32_t CPR0_162_new;
-	uint32_t CPR0_163_new;
-	uint32_t CPR0_164_new;
-	uint32_t CPR0_165_new;
-	uint32_t CPR0_166_new;
-	uint32_t CPR0_167_new;
-	uint32_t CPR0_168_new;
-	uint32_t CPR0_169_new;
-	uint32_t CPR0_170_new;
-	uint32_t CPR0_171_new;
-	uint32_t CPR0_172_new;
-	uint32_t CPR0_173_new;
-	uint32_t CPR0_174_new;
-	uint32_t CPR0_175_new;
-	uint32_t CPR0_176_new;
-	uint32_t CPR0_177_new;
-	uint32_t CPR0_178_new;
-	uint32_t CPR0_179_new;
-	uint32_t CPR0_180_new;
-	uint32_t CPR0_181_new;
-	uint32_t CPR0_182_new;
-	uint32_t CPR0_183_new;
-	uint32_t CPR0_184_new;
-	uint32_t CPR0_185_new;
-	uint32_t CPR0_186_new;
-	uint32_t CPR0_187_new;
-	uint32_t CPR0_188_new;
-	uint32_t CPR0_189_new;
-	uint32_t CPR0_190_new;
-	uint32_t CPR0_191_new;
-	uint32_t CPR0_192_new;
-	uint32_t CPR0_193_new;
-	uint32_t CPR0_194_new;
-	uint32_t CPR0_195_new;
-	uint32_t CPR0_196_new;
-	uint32_t CPR0_197_new;
-	uint32_t CPR0_198_new;
-	uint32_t CPR0_199_new;
-	uint32_t CPR0_200_new;
-	uint32_t CPR0_201_new;
-	uint32_t CPR0_202_new;
-	uint32_t CPR0_203_new;
-	uint32_t CPR0_204_new;
-	uint32_t CPR0_205_new;
-	uint32_t CPR0_206_new;
-	uint32_t CPR0_207_new;
-	uint32_t CPR0_208_new;
-	uint32_t CPR0_209_new;
-	uint32_t CPR0_210_new;
-	uint32_t CPR0_211_new;
-	uint32_t CPR0_212_new;
-	uint32_t CPR0_213_new;
-	uint32_t CPR0_214_new;
-	uint32_t CPR0_215_new;
-	uint32_t CPR0_216_new;
-	uint32_t CPR0_217_new;
-	uint32_t CPR0_218_new;
-	uint32_t CPR0_219_new;
-	uint32_t CPR0_220_new;
-	uint32_t CPR0_221_new;
-	uint32_t CPR0_222_new;
-	uint32_t CPR0_223_new;
-	uint32_t CPR0_224_new;
-	uint32_t CPR0_225_new;
-	uint32_t CPR0_226_new;
-	uint32_t CPR0_227_new;
-	uint32_t CPR0_228_new;
-	uint32_t CPR0_229_new;
-	uint32_t CPR0_230_new;
-	uint32_t CPR0_231_new;
-	uint32_t CPR0_232_new;
-	uint32_t CPR0_233_new;
-	uint32_t CPR0_234_new;
-	uint32_t CPR0_235_new;
-	uint32_t CPR0_236_new;
-	uint32_t CPR0_237_new;
-	uint32_t CPR0_238_new;
-	uint32_t CPR0_239_new;
-	uint32_t CPR0_240_new;
-	uint32_t CPR0_241_new;
-	uint32_t CPR0_242_new;
-	uint32_t CPR0_243_new;
-	uint32_t CPR0_244_new;
-	uint32_t CPR0_245_new;
-	uint32_t CPR0_246_new;
-	uint32_t CPR0_247_new;
-	uint32_t CPR0_248_new;
-	uint32_t CPR0_249_new;
-	uint32_t CPR0_250_new;
-	uint32_t CPR0_251_new;
-	uint32_t CPR0_252_new;
-	uint32_t CPR0_253_new;
-	uint32_t CPR0_254_new;
-	uint32_t CPR0_255_new;
-
 }vm_cpu_t;
 
+void dump_gpregs(vm_cpu_t* vmcpu);
 
 //#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
 #define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c
index 3a34248a..977b0777 100644
--- a/miasm2/jitter/arch/JitCore_msp430.c
+++ b/miasm2/jitter/arch/JitCore_msp430.c
@@ -1,11 +1,11 @@
 #include <Python.h>
-#include "../JitCore.h"
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../JitCore.h"
 #include "JitCore_msp430.h"
 
 
@@ -317,7 +317,7 @@ PyObject* get_gpreg_offset_all(void)
     PyObject *dict = PyDict_New();
     PyObject *o;
     get_reg_off(exception_flags);
-    get_reg_off(exception_flags_new);
+
     get_reg_off(PC);
     get_reg_off(SP);
     get_reg_off(R3);
@@ -333,22 +333,7 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(R13);
     get_reg_off(R14);
     get_reg_off(R15);
-    get_reg_off(PC_new);
-    get_reg_off(SP_new);
-    get_reg_off(SR_new);
-    get_reg_off(R3_new);
-    get_reg_off(R4_new);
-    get_reg_off(R5_new);
-    get_reg_off(R6_new);
-    get_reg_off(R7_new);
-    get_reg_off(R8_new);
-    get_reg_off(R9_new);
-    get_reg_off(R10_new);
-    get_reg_off(R11_new);
-    get_reg_off(R12_new);
-    get_reg_off(R13_new);
-    get_reg_off(R14_new);
-    get_reg_off(R15_new);
+
     get_reg_off(zf);
     get_reg_off(nf);
     get_reg_off(of);
@@ -359,96 +344,7 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(scg0);
     get_reg_off(scg1);
     get_reg_off(res);
-    get_reg_off(zf_new);
-    get_reg_off(nf_new);
-    get_reg_off(of_new);
-    get_reg_off(cf_new);
-    get_reg_off(cpuoff_new);
-    get_reg_off(gie_new);
-    get_reg_off(osc_new);
-    get_reg_off(scg0_new);
-    get_reg_off(scg1_new);
-    get_reg_off(res_new);
-    get_reg_off(pfmem08_0);
-    get_reg_off(pfmem08_1);
-    get_reg_off(pfmem08_2);
-    get_reg_off(pfmem08_3);
-    get_reg_off(pfmem08_4);
-    get_reg_off(pfmem08_5);
-    get_reg_off(pfmem08_6);
-    get_reg_off(pfmem08_7);
-    get_reg_off(pfmem08_8);
-    get_reg_off(pfmem08_9);
-    get_reg_off(pfmem08_10);
-    get_reg_off(pfmem08_11);
-    get_reg_off(pfmem08_12);
-    get_reg_off(pfmem08_13);
-    get_reg_off(pfmem08_14);
-    get_reg_off(pfmem08_15);
-    get_reg_off(pfmem08_16);
-    get_reg_off(pfmem08_17);
-    get_reg_off(pfmem08_18);
-    get_reg_off(pfmem08_19);
-    get_reg_off(pfmem16_0);
-    get_reg_off(pfmem16_1);
-    get_reg_off(pfmem16_2);
-    get_reg_off(pfmem16_3);
-    get_reg_off(pfmem16_4);
-    get_reg_off(pfmem16_5);
-    get_reg_off(pfmem16_6);
-    get_reg_off(pfmem16_7);
-    get_reg_off(pfmem16_8);
-    get_reg_off(pfmem16_9);
-    get_reg_off(pfmem16_10);
-    get_reg_off(pfmem16_11);
-    get_reg_off(pfmem16_12);
-    get_reg_off(pfmem16_13);
-    get_reg_off(pfmem16_14);
-    get_reg_off(pfmem16_15);
-    get_reg_off(pfmem16_16);
-    get_reg_off(pfmem16_17);
-    get_reg_off(pfmem16_18);
-    get_reg_off(pfmem16_19);
-    get_reg_off(pfmem32_0);
-    get_reg_off(pfmem32_1);
-    get_reg_off(pfmem32_2);
-    get_reg_off(pfmem32_3);
-    get_reg_off(pfmem32_4);
-    get_reg_off(pfmem32_5);
-    get_reg_off(pfmem32_6);
-    get_reg_off(pfmem32_7);
-    get_reg_off(pfmem32_8);
-    get_reg_off(pfmem32_9);
-    get_reg_off(pfmem32_10);
-    get_reg_off(pfmem32_11);
-    get_reg_off(pfmem32_12);
-    get_reg_off(pfmem32_13);
-    get_reg_off(pfmem32_14);
-    get_reg_off(pfmem32_15);
-    get_reg_off(pfmem32_16);
-    get_reg_off(pfmem32_17);
-    get_reg_off(pfmem32_18);
-    get_reg_off(pfmem32_19);
-    get_reg_off(pfmem64_0);
-    get_reg_off(pfmem64_1);
-    get_reg_off(pfmem64_2);
-    get_reg_off(pfmem64_3);
-    get_reg_off(pfmem64_4);
-    get_reg_off(pfmem64_5);
-    get_reg_off(pfmem64_6);
-    get_reg_off(pfmem64_7);
-    get_reg_off(pfmem64_8);
-    get_reg_off(pfmem64_9);
-    get_reg_off(pfmem64_10);
-    get_reg_off(pfmem64_11);
-    get_reg_off(pfmem64_12);
-    get_reg_off(pfmem64_13);
-    get_reg_off(pfmem64_14);
-    get_reg_off(pfmem64_15);
-    get_reg_off(pfmem64_16);
-    get_reg_off(pfmem64_17);
-    get_reg_off(pfmem64_18);
-    get_reg_off(pfmem64_19);
+
     return dict;
 }
 
diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h
index 179554ad..03b0bb25 100644
--- a/miasm2/jitter/arch/JitCore_msp430.h
+++ b/miasm2/jitter/arch/JitCore_msp430.h
@@ -1,7 +1,6 @@
 
 typedef struct {
 	uint32_t exception_flags;
-	uint32_t exception_flags_new;
 
 	/* gpregs */
 	uint32_t PC;
@@ -20,23 +19,6 @@ typedef struct {
 	uint32_t R14;
 	uint32_t R15;
 
-	uint32_t PC_new;
-	uint32_t SP_new;
-	uint32_t SR_new;
-	uint32_t R3_new;
-	uint32_t R4_new;
-	uint32_t R5_new;
-	uint32_t R6_new;
-	uint32_t R7_new;
-	uint32_t R8_new;
-	uint32_t R9_new;
-	uint32_t R10_new;
-	uint32_t R11_new;
-	uint32_t R12_new;
-	uint32_t R13_new;
-	uint32_t R14_new;
-	uint32_t R15_new;
-
 	/* eflag */
 	uint32_t zf;
 	uint32_t nf;
@@ -50,108 +32,6 @@ typedef struct {
 	uint32_t scg1;
 	uint32_t res;
 
-
-	uint32_t zf_new;
-	uint32_t nf_new;
-	uint32_t of_new;
-	uint32_t cf_new;
-
-	uint32_t cpuoff_new;
-	uint32_t gie_new;
-	uint32_t osc_new;
-	uint32_t scg0_new;
-	uint32_t scg1_new;
-	uint32_t res_new;
-
-
-	uint8_t pfmem08_0;
-	uint8_t pfmem08_1;
-	uint8_t pfmem08_2;
-	uint8_t pfmem08_3;
-	uint8_t pfmem08_4;
-	uint8_t pfmem08_5;
-	uint8_t pfmem08_6;
-	uint8_t pfmem08_7;
-	uint8_t pfmem08_8;
-	uint8_t pfmem08_9;
-	uint8_t pfmem08_10;
-	uint8_t pfmem08_11;
-	uint8_t pfmem08_12;
-	uint8_t pfmem08_13;
-	uint8_t pfmem08_14;
-	uint8_t pfmem08_15;
-	uint8_t pfmem08_16;
-	uint8_t pfmem08_17;
-	uint8_t pfmem08_18;
-	uint8_t pfmem08_19;
-
-
-	uint16_t pfmem16_0;
-	uint16_t pfmem16_1;
-	uint16_t pfmem16_2;
-	uint16_t pfmem16_3;
-	uint16_t pfmem16_4;
-	uint16_t pfmem16_5;
-	uint16_t pfmem16_6;
-	uint16_t pfmem16_7;
-	uint16_t pfmem16_8;
-	uint16_t pfmem16_9;
-	uint16_t pfmem16_10;
-	uint16_t pfmem16_11;
-	uint16_t pfmem16_12;
-	uint16_t pfmem16_13;
-	uint16_t pfmem16_14;
-	uint16_t pfmem16_15;
-	uint16_t pfmem16_16;
-	uint16_t pfmem16_17;
-	uint16_t pfmem16_18;
-	uint16_t pfmem16_19;
-
-
-	uint32_t pfmem32_0;
-	uint32_t pfmem32_1;
-	uint32_t pfmem32_2;
-	uint32_t pfmem32_3;
-	uint32_t pfmem32_4;
-	uint32_t pfmem32_5;
-	uint32_t pfmem32_6;
-	uint32_t pfmem32_7;
-	uint32_t pfmem32_8;
-	uint32_t pfmem32_9;
-	uint32_t pfmem32_10;
-	uint32_t pfmem32_11;
-	uint32_t pfmem32_12;
-	uint32_t pfmem32_13;
-	uint32_t pfmem32_14;
-	uint32_t pfmem32_15;
-	uint32_t pfmem32_16;
-	uint32_t pfmem32_17;
-	uint32_t pfmem32_18;
-	uint32_t pfmem32_19;
-
-
-	uint64_t pfmem64_0;
-	uint64_t pfmem64_1;
-	uint64_t pfmem64_2;
-	uint64_t pfmem64_3;
-	uint64_t pfmem64_4;
-	uint64_t pfmem64_5;
-	uint64_t pfmem64_6;
-	uint64_t pfmem64_7;
-	uint64_t pfmem64_8;
-	uint64_t pfmem64_9;
-	uint64_t pfmem64_10;
-	uint64_t pfmem64_11;
-	uint64_t pfmem64_12;
-	uint64_t pfmem64_13;
-	uint64_t pfmem64_14;
-	uint64_t pfmem64_15;
-	uint64_t pfmem64_16;
-	uint64_t pfmem64_17;
-	uint64_t pfmem64_18;
-	uint64_t pfmem64_19;
-
-
 }vm_cpu_t;
 
 //#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index b406e755..0b788071 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -1,11 +1,11 @@
 #include <Python.h>
-#include "../JitCore.h"
 #include "structmember.h"
 #include <stdint.h>
 #include <inttypes.h>
 #include "../queue.h"
 #include "../vm_mngr.h"
 #include "../vm_mngr_py.h"
+#include "../JitCore.h"
 #include "JitCore_x86.h"
 
 
@@ -176,17 +176,46 @@ PyObject * cpu_init_regs(JitCpu* self)
 
 }
 
-void dump_gpregs(vm_cpu_t* vmcpu)
+void dump_gpregs_32(vm_cpu_t* vmcpu)
+{
+
+	printf("EAX %.8"PRIX32" EBX %.8"PRIX32" ECX %.8"PRIX32" EDX %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RAX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RBX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RCX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RDX & 0xFFFFFFFF));
+	printf("ESI %.8"PRIX32" EDI %.8"PRIX32" ESP %.8"PRIX32" EBP %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RSI & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RDI & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RSP & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RBP & 0xFFFFFFFF));
+	printf("EIP %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RIP & 0xFFFFFFFF));
+	printf("zf %.1"PRIX32" nf %.1"PRIX32" of %.1"PRIX32" cf %.1"PRIX32"\n",
+	       (uint32_t)(vmcpu->zf & 0x1),
+	       (uint32_t)(vmcpu->nf & 0x1),
+	       (uint32_t)(vmcpu->of & 0x1),
+	       (uint32_t)(vmcpu->cf & 0x1));
+
+}
+
+void dump_gpregs_64(vm_cpu_t* vmcpu)
 {
 
-	printf("RAX %.16"PRIX64" RBX %.16"PRIX64" RCX %.16"PRIX64" RDX %.16"PRIX64"\n",
+	printf("RAX %.16"PRIX64" RBX %.16"PRIX64" RCX %.16"PRIX64" RDX %.16"PRIX64" ",
 	       vmcpu->RAX, vmcpu->RBX, vmcpu->RCX, vmcpu->RDX);
-	printf("RSI %.16"PRIX64" RDI %.16"PRIX64" RSP %.16"PRIX64" RBP %.16"PRIX64"\n",
+	printf("RSI %.16"PRIX64" RDI %.16"PRIX64" RSP %.16"PRIX64" RBP %.16"PRIX64" ",
 	       vmcpu->RSI, vmcpu->RDI, vmcpu->RSP, vmcpu->RBP);
-	printf("zf %.16"PRIX64" nf %.16"PRIX64" of %.16"PRIX64" cf %.16"PRIX64"\n",
-	       vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf);
 	printf("RIP %.16"PRIX64"\n",
 	       vmcpu->RIP);
+	printf("R8  %.16"PRIX64" R9  %.16"PRIX64" R10 %.16"PRIX64" R11 %.16"PRIX64" ",
+	       vmcpu->R8, vmcpu->R9, vmcpu->R10, vmcpu->R11);
+	printf("R12 %.16"PRIX64" R13 %.16"PRIX64" R14 %.16"PRIX64" R15 %.16"PRIX64" ",
+	       vmcpu->R12, vmcpu->R13, vmcpu->R14, vmcpu->R15);
+
+
+	printf("zf %.1"PRIX64" nf %.1"PRIX64" of %.1"PRIX64" cf %.1"PRIX64"\n",
+	       vmcpu->zf, vmcpu->nf, vmcpu->of, vmcpu->cf);
 
 }
 
@@ -195,7 +224,7 @@ PyObject * cpu_dump_gpregs(JitCpu* self, PyObject* args)
 	vm_cpu_t* vmcpu;
 
 	vmcpu = self->cpu;
-	dump_gpregs(vmcpu);
+	dump_gpregs_64(vmcpu);
 	Py_INCREF(Py_None);
 	return Py_None;
 }
@@ -293,42 +322,24 @@ IMOD(16)
 IMOD(32)
 IMOD(64)
 
-
-
-
-void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
-{
-	PyObject *result;
-
-	if (!(((VmMngr*)jitcpu->pyvm)->vm_mngr.exception_flags & EXCEPT_CODE_AUTOMOD))
-		return;
-	result = PyObject_CallMethod(jitcpu->jitter, "automod_cb", "LL", addr, size);
-	Py_DECREF(result);
-
-}
-
 void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src)
 {
 	vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
-	check_automod(jitcpu, addr, 8);
 }
 
 void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src)
 {
 	vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
-	check_automod(jitcpu, addr, 16);
 }
 
 void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src)
 {
 	vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
-	check_automod(jitcpu, addr, 32);
 }
 
 void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src)
 {
 	vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src);
-	check_automod(jitcpu, addr, 64);
 }
 
 
@@ -358,7 +369,6 @@ PyObject* vm_set_mem(JitCpu *self, PyObject* args)
        ret = vm_write_mem(&(((VmMngr*)self->pyvm)->vm_mngr), addr, buffer, size);
        if (ret < 0)
 	       RAISE(PyExc_TypeError,"arg must be str");
-       check_automod(self, addr, size*8);
 
        Py_INCREF(Py_None);
        return Py_None;
@@ -518,7 +528,6 @@ PyObject* get_gpreg_offset_all(void)
     PyObject *o;
 
     get_reg_off(exception_flags);
-    get_reg_off(exception_flags_new);
 
     get_reg_off(RAX);
     get_reg_off(RBX);
@@ -537,23 +546,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(R14);
     get_reg_off(R15);
     get_reg_off(RIP);
-    get_reg_off(RAX_new);
-    get_reg_off(RBX_new);
-    get_reg_off(RCX_new);
-    get_reg_off(RDX_new);
-    get_reg_off(RSI_new);
-    get_reg_off(RDI_new);
-    get_reg_off(RSP_new);
-    get_reg_off(RBP_new);
-    get_reg_off(R8_new);
-    get_reg_off(R9_new);
-    get_reg_off(R10_new);
-    get_reg_off(R11_new);
-    get_reg_off(R12_new);
-    get_reg_off(R13_new);
-    get_reg_off(R14_new);
-    get_reg_off(R15_new);
-    get_reg_off(RIP_new);
     get_reg_off(zf);
     get_reg_off(nf);
     get_reg_off(pf);
@@ -561,13 +553,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(cf);
     get_reg_off(af);
     get_reg_off(df);
-    get_reg_off(zf_new);
-    get_reg_off(nf_new);
-    get_reg_off(pf_new);
-    get_reg_off(of_new);
-    get_reg_off(cf_new);
-    get_reg_off(af_new);
-    get_reg_off(df_new);
     get_reg_off(tf);
     get_reg_off(i_f);
     get_reg_off(iopl_f);
@@ -578,16 +563,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(vif);
     get_reg_off(vip);
     get_reg_off(i_d);
-    get_reg_off(tf_new);
-    get_reg_off(i_f_new);
-    get_reg_off(iopl_f_new);
-    get_reg_off(nt_new);
-    get_reg_off(rf_new);
-    get_reg_off(vm_new);
-    get_reg_off(ac_new);
-    get_reg_off(vif_new);
-    get_reg_off(vip_new);
-    get_reg_off(i_d_new);
     get_reg_off(my_tick);
     get_reg_off(cond);
 
@@ -599,14 +574,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(float_st5);
     get_reg_off(float_st6);
     get_reg_off(float_st7);
-    get_reg_off(float_st0_new);
-    get_reg_off(float_st1_new);
-    get_reg_off(float_st2_new);
-    get_reg_off(float_st3_new);
-    get_reg_off(float_st4_new);
-    get_reg_off(float_st5_new);
-    get_reg_off(float_st6_new);
-    get_reg_off(float_st7_new);
 
     get_reg_off(ES);
     get_reg_off(CS);
@@ -614,93 +581,6 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(DS);
     get_reg_off(FS);
     get_reg_off(GS);
-    get_reg_off(ES_new);
-    get_reg_off(CS_new);
-    get_reg_off(SS_new);
-    get_reg_off(DS_new);
-    get_reg_off(FS_new);
-    get_reg_off(GS_new);
-
-    get_reg_off(pfmem08_0);
-    get_reg_off(pfmem08_1);
-    get_reg_off(pfmem08_2);
-    get_reg_off(pfmem08_3);
-    get_reg_off(pfmem08_4);
-    get_reg_off(pfmem08_5);
-    get_reg_off(pfmem08_6);
-    get_reg_off(pfmem08_7);
-    get_reg_off(pfmem08_8);
-    get_reg_off(pfmem08_9);
-    get_reg_off(pfmem08_10);
-    get_reg_off(pfmem08_11);
-    get_reg_off(pfmem08_12);
-    get_reg_off(pfmem08_13);
-    get_reg_off(pfmem08_14);
-    get_reg_off(pfmem08_15);
-    get_reg_off(pfmem08_16);
-    get_reg_off(pfmem08_17);
-    get_reg_off(pfmem08_18);
-    get_reg_off(pfmem08_19);
-    get_reg_off(pfmem16_0);
-    get_reg_off(pfmem16_1);
-    get_reg_off(pfmem16_2);
-    get_reg_off(pfmem16_3);
-    get_reg_off(pfmem16_4);
-    get_reg_off(pfmem16_5);
-    get_reg_off(pfmem16_6);
-    get_reg_off(pfmem16_7);
-    get_reg_off(pfmem16_8);
-    get_reg_off(pfmem16_9);
-    get_reg_off(pfmem16_10);
-    get_reg_off(pfmem16_11);
-    get_reg_off(pfmem16_12);
-    get_reg_off(pfmem16_13);
-    get_reg_off(pfmem16_14);
-    get_reg_off(pfmem16_15);
-    get_reg_off(pfmem16_16);
-    get_reg_off(pfmem16_17);
-    get_reg_off(pfmem16_18);
-    get_reg_off(pfmem16_19);
-    get_reg_off(pfmem32_0);
-    get_reg_off(pfmem32_1);
-    get_reg_off(pfmem32_2);
-    get_reg_off(pfmem32_3);
-    get_reg_off(pfmem32_4);
-    get_reg_off(pfmem32_5);
-    get_reg_off(pfmem32_6);
-    get_reg_off(pfmem32_7);
-    get_reg_off(pfmem32_8);
-    get_reg_off(pfmem32_9);
-    get_reg_off(pfmem32_10);
-    get_reg_off(pfmem32_11);
-    get_reg_off(pfmem32_12);
-    get_reg_off(pfmem32_13);
-    get_reg_off(pfmem32_14);
-    get_reg_off(pfmem32_15);
-    get_reg_off(pfmem32_16);
-    get_reg_off(pfmem32_17);
-    get_reg_off(pfmem32_18);
-    get_reg_off(pfmem32_19);
-    get_reg_off(pfmem64_0);
-    get_reg_off(pfmem64_1);
-    get_reg_off(pfmem64_2);
-    get_reg_off(pfmem64_3);
-    get_reg_off(pfmem64_4);
-    get_reg_off(pfmem64_5);
-    get_reg_off(pfmem64_6);
-    get_reg_off(pfmem64_7);
-    get_reg_off(pfmem64_8);
-    get_reg_off(pfmem64_9);
-    get_reg_off(pfmem64_10);
-    get_reg_off(pfmem64_11);
-    get_reg_off(pfmem64_12);
-    get_reg_off(pfmem64_13);
-    get_reg_off(pfmem64_14);
-    get_reg_off(pfmem64_15);
-    get_reg_off(pfmem64_16);
-    get_reg_off(pfmem64_17);
-    get_reg_off(pfmem64_18);
-    get_reg_off(pfmem64_19);
 
     get_reg_off(MM0);
     get_reg_off(MM1);
@@ -710,19 +590,9 @@ PyObject* get_gpreg_offset_all(void)
     get_reg_off(MM5);
     get_reg_off(MM6);
     get_reg_off(MM7);
-    get_reg_off(MM0_new);
-    get_reg_off(MM1_new);
-    get_reg_off(MM2_new);
-    get_reg_off(MM3_new);
-    get_reg_off(MM4_new);
-    get_reg_off(MM5_new);
-    get_reg_off(MM6_new);
-    get_reg_off(MM7_new);
 
     get_reg_off(tsc1);
     get_reg_off(tsc2);
-    get_reg_off(tsc1_new);
-    get_reg_off(tsc2_new);
 
     return dict;
 }
diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h
index ac794d8e..d4282640 100644
--- a/miasm2/jitter/arch/JitCore_x86.h
+++ b/miasm2/jitter/arch/JitCore_x86.h
@@ -1,9 +1,7 @@
 
 typedef struct {
 	uint32_t exception_flags;
-	uint32_t exception_flags_new;
 	uint32_t interrupt_num;
-	uint32_t interrupt_num_new;
 
 
 	/* gpregs */
@@ -26,25 +24,6 @@ typedef struct {
 
 	uint64_t RIP;
 
-	uint64_t RAX_new;
-	uint64_t RBX_new;
-	uint64_t RCX_new;
-	uint64_t RDX_new;
-	uint64_t RSI_new;
-	uint64_t RDI_new;
-	uint64_t RSP_new;
-	uint64_t RBP_new;
-	uint64_t R8_new;
-	uint64_t R9_new;
-	uint64_t R10_new;
-	uint64_t R11_new;
-	uint64_t R12_new;
-	uint64_t R13_new;
-	uint64_t R14_new;
-	uint64_t R15_new;
-
-	uint64_t RIP_new;
-
 	/* eflag */
 	uint64_t zf;
 	uint64_t nf;
@@ -54,14 +33,6 @@ typedef struct {
 	uint64_t af;
 	uint64_t df;
 
-	uint64_t zf_new;
-	uint64_t nf_new;
-	uint64_t pf_new;
-	uint64_t of_new;
-	uint64_t cf_new;
-	uint64_t af_new;
-	uint64_t df_new;
-
 	uint64_t tf;
 	uint64_t i_f;
 	uint64_t iopl_f;
@@ -73,17 +44,6 @@ typedef struct {
 	uint64_t vip;
 	uint64_t i_d;
 
-	uint64_t tf_new;
-	uint64_t i_f_new;
-	uint64_t iopl_f_new;
-	uint64_t nt_new;
-	uint64_t rf_new;
-	uint64_t vm_new;
-	uint64_t ac_new;
-	uint64_t vif_new;
-	uint64_t vip_new;
-	uint64_t i_d_new;
-
 	uint64_t my_tick;
 
 	uint64_t cond;
@@ -97,47 +57,25 @@ typedef struct {
 	double float_st6;
 	double float_st7;
 
-	double float_st0_new;
-	double float_st1_new;
-	double float_st2_new;
-	double float_st3_new;
-	double float_st4_new;
-	double float_st5_new;
-	double float_st6_new;
-	double float_st7_new;
-
 	unsigned int float_c0;
 	unsigned int float_c1;
 	unsigned int float_c2;
 	unsigned int float_c3;
 
-	unsigned int float_c0_new;
-	unsigned int float_c1_new;
-	unsigned int float_c2_new;
-	unsigned int float_c3_new;
 
 	unsigned int float_stack_ptr;
-	unsigned int float_stack_ptr_new;
 
 	unsigned int reg_float_control;
-	unsigned int reg_float_control_new;
 
 	unsigned int reg_float_eip;
-	unsigned int reg_float_eip_new;
 	unsigned int reg_float_cs;
-	unsigned int reg_float_cs_new;
 	unsigned int reg_float_address;
-	unsigned int reg_float_address_new;
 	unsigned int reg_float_ds;
-	unsigned int reg_float_ds_new;
 
 
 	uint64_t tsc1;
 	uint64_t tsc2;
 
-	uint64_t tsc1_new;
-	uint64_t tsc2_new;
-
 
 	uint64_t ES;
 	uint64_t CS;
@@ -146,108 +84,8 @@ typedef struct {
 	uint64_t FS;
 	uint64_t GS;
 
-	uint64_t ES_new;
-	uint64_t CS_new;
-	uint64_t SS_new;
-	uint64_t DS_new;
-	uint64_t FS_new;
-	uint64_t GS_new;
-
 	unsigned int cr0;
-	unsigned int cr0_new;
-
 	unsigned int cr3;
-	unsigned int cr3_new;
-
-
-
-	uint8_t pfmem08_0;
-	uint8_t pfmem08_1;
-	uint8_t pfmem08_2;
-	uint8_t pfmem08_3;
-	uint8_t pfmem08_4;
-	uint8_t pfmem08_5;
-	uint8_t pfmem08_6;
-	uint8_t pfmem08_7;
-	uint8_t pfmem08_8;
-	uint8_t pfmem08_9;
-	uint8_t pfmem08_10;
-	uint8_t pfmem08_11;
-	uint8_t pfmem08_12;
-	uint8_t pfmem08_13;
-	uint8_t pfmem08_14;
-	uint8_t pfmem08_15;
-	uint8_t pfmem08_16;
-	uint8_t pfmem08_17;
-	uint8_t pfmem08_18;
-	uint8_t pfmem08_19;
-
-
-	uint16_t pfmem16_0;
-	uint16_t pfmem16_1;
-	uint16_t pfmem16_2;
-	uint16_t pfmem16_3;
-	uint16_t pfmem16_4;
-	uint16_t pfmem16_5;
-	uint16_t pfmem16_6;
-	uint16_t pfmem16_7;
-	uint16_t pfmem16_8;
-	uint16_t pfmem16_9;
-	uint16_t pfmem16_10;
-	uint16_t pfmem16_11;
-	uint16_t pfmem16_12;
-	uint16_t pfmem16_13;
-	uint16_t pfmem16_14;
-	uint16_t pfmem16_15;
-	uint16_t pfmem16_16;
-	uint16_t pfmem16_17;
-	uint16_t pfmem16_18;
-	uint16_t pfmem16_19;
-
-
-	uint32_t pfmem32_0;
-	uint32_t pfmem32_1;
-	uint32_t pfmem32_2;
-	uint32_t pfmem32_3;
-	uint32_t pfmem32_4;
-	uint32_t pfmem32_5;
-	uint32_t pfmem32_6;
-	uint32_t pfmem32_7;
-	uint32_t pfmem32_8;
-	uint32_t pfmem32_9;
-	uint32_t pfmem32_10;
-	uint32_t pfmem32_11;
-	uint32_t pfmem32_12;
-	uint32_t pfmem32_13;
-	uint32_t pfmem32_14;
-	uint32_t pfmem32_15;
-	uint32_t pfmem32_16;
-	uint32_t pfmem32_17;
-	uint32_t pfmem32_18;
-	uint32_t pfmem32_19;
-
-
-	uint64_t pfmem64_0;
-	uint64_t pfmem64_1;
-	uint64_t pfmem64_2;
-	uint64_t pfmem64_3;
-	uint64_t pfmem64_4;
-	uint64_t pfmem64_5;
-	uint64_t pfmem64_6;
-	uint64_t pfmem64_7;
-	uint64_t pfmem64_8;
-	uint64_t pfmem64_9;
-	uint64_t pfmem64_10;
-	uint64_t pfmem64_11;
-	uint64_t pfmem64_12;
-	uint64_t pfmem64_13;
-	uint64_t pfmem64_14;
-	uint64_t pfmem64_15;
-	uint64_t pfmem64_16;
-	uint64_t pfmem64_17;
-	uint64_t pfmem64_18;
-	uint64_t pfmem64_19;
-
 
 	uint64_t MM0;
 	uint64_t MM1;
@@ -258,15 +96,6 @@ typedef struct {
 	uint64_t MM6;
 	uint64_t MM7;
 
-	uint64_t MM0_new;
-	uint64_t MM1_new;
-	uint64_t MM2_new;
-	uint64_t MM3_new;
-	uint64_t MM4_new;
-	uint64_t MM5_new;
-	uint64_t MM6_new;
-	uint64_t MM7_new;
-
 	uint32_t segm_base[0x10000];
 
 }vm_cpu_t;
@@ -274,7 +103,8 @@ typedef struct {
 
 
 
-void dump_gpregs(vm_cpu_t* vmcpu);
+void dump_gpregs_32(vm_cpu_t* vmcpu);
+void dump_gpregs_64(vm_cpu_t* vmcpu);
 uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr);
 
 
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
new file mode 100644
index 00000000..7630a2ef
--- /dev/null
+++ b/miasm2/jitter/codegen.py
@@ -0,0 +1,578 @@
+import miasm2.expression.expression as m2_expr
+from miasm2.ir.ir import irbloc
+from miasm2.ir.translators import Translator
+from miasm2.core.asmbloc import expr_is_label, asm_block_bad, asm_label
+
+# Miasm to C translator
+translator = Translator.to_language("C")
+
+SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)}
+
+MASK_INT = 0xffffffffffffffff
+
+
+class Attributes(object):
+
+    """
+    Store an irblock attributes
+    """
+
+    def __init__(self, log_mn=False, log_regs=False):
+        self.mem_read = False
+        self.mem_write = False
+        self.set_exception = False
+        self.op_set_exception = False
+        self.log_mn = log_mn
+        self.log_regs = log_regs
+        self.instr = None
+
+
+class CGen(object):
+
+    IMPLICIT_EXCEPTION_OP = set(['umod', 'udiv'])
+
+    """
+    Translate native assembly block to C
+    """
+
+    CODE_EXCEPTION_MEM_AT_INSTR = r"""
+    // except fetch mem at instr noauto
+    if ((VM_exception_flag & ~EXCEPT_CODE_AUTOMOD) & EXCEPT_DO_NOT_UPDATE_PC) {
+        %s = %s;
+        BlockDst->address = %s;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_EXCEPTION_MEM_POST_INSTR = r"""
+    // except fetch mem post instr
+    if (VM_exception_flag) {
+        %s = %s;
+        BlockDst->address = %s;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_EXCEPTION_AT_INSTR = r"""
+    if (CPU_exception_flag_at_instr) {
+        %s = %s;
+        BlockDst->address = %s;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_EXCEPTION_POST_INSTR = r"""
+    if (CPU_exception_flag) {
+        %s = %s;
+        BlockDst->address = %s;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_RETURN_EXCEPTION = r"""
+    return JIT_RET_EXCEPTION;
+    """
+
+    CODE_RETURN_NO_EXCEPTION = r"""
+    %s:
+    %s = %s;
+    BlockDst->address = %s;
+    return JIT_RET_NO_EXCEPTION;
+    """
+
+    CODE_CPU_EXCEPTION_POST_INSTR = r"""
+    if (CPU_exception_flag) {
+        %s = %s;
+        BlockDst->address = DST_value;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_VM_EXCEPTION_POST_INSTR = r"""
+    check_memory_breakpoint(&(jitcpu->pyvm->vm_mngr));
+    check_invalid_code_blocs(&(jitcpu->pyvm->vm_mngr));
+    if (VM_exception_flag) {
+        %s = %s;
+        BlockDst->address = DST_value;
+        return JIT_RET_EXCEPTION;
+    }
+    """
+
+    CODE_INIT = r"""
+    int DST_case;
+    unsigned long long DST_value;
+    vm_cpu_t* mycpu = (vm_cpu_t*)jitcpu->cpu;
+
+    goto %s;
+    """
+
+    CODE_BAD_BLOCK = r"""
+    // Unknown mnemonic
+    CPU_exception_flag = EXCEPT_UNK_MNEMO;
+    """ + CODE_RETURN_EXCEPTION
+
+    def __init__(self, ir_arch):
+        self.ir_arch = ir_arch
+        self.PC = self.ir_arch.pc
+        self.init_arch_C()
+
+    def init_arch_C(self):
+        self.id_to_c_id = {}
+        for reg in self.ir_arch.arch.regs.all_regs_ids:
+            self.id_to_c_id[reg] = m2_expr.ExprId('mycpu->%s' % reg, reg.size)
+
+        self.C_PC = self.id_to_c(self.PC)
+
+    def dst_to_c(self, src):
+        if not isinstance(src, m2_expr.Expr):
+            src = m2_expr.ExprInt(src, self.PC.size)
+        return self.id_to_c(src)
+
+    def patch_c_id(self, expr):
+        return expr.replace_expr(self.id_to_c_id)
+
+    def id_to_c(self, expr):
+        return translator.from_expr(self.patch_c_id(expr))
+
+    def get_post_instr_label(self, offset):
+        return self.ir_arch.symbol_pool.getby_name_create("lbl_gen_post_instr_%.8X" % (offset))
+
+    def add_label_index(self, dst2index, lbl):
+        dst2index[lbl] = len(dst2index)
+
+    def assignblk_to_irbloc(self, instr, assignblk):
+        """
+        Ensure IRDst is always set in the head @assignblk of the @instr
+        @assignblk: Assignblk instance
+        @instr: an instruction instance
+        """
+        if self.ir_arch.IRDst not in assignblk:
+            assignblk[self.ir_arch.IRDst] = m2_expr.ExprInt(
+                instr.offset + instr.l,
+                self.ir_arch.IRDst.size)
+
+        return irbloc(self.ir_arch.get_instr_label(instr), [assignblk])
+
+    def block2assignblks(self, block):
+        irblocks_list = []
+        for instr in block.lines:
+            assignblk_head, assignblks_extra = self.ir_arch.instr2ir(instr)
+            # Keep result in ordered list as first element is the assignblk head
+            # The remainings order is not really important
+            irblock_head = self.assignblk_to_irbloc(instr, assignblk_head)
+            irblocks = [irblock_head] + assignblks_extra
+
+            for irblock in irblocks:
+                assert irblock.dst is not None
+            irblocks_list.append(irblocks)
+        return irblocks_list
+
+    def gen_mem_prefetch(self, assignblk, mems_to_prefetch):
+        out = []
+        for expr, prefetcher in sorted(mems_to_prefetch.iteritems()):
+            str_src = self.id_to_c(expr)
+            str_dst = self.id_to_c(prefetcher)
+            out.append('%s = %s;' % (str_dst, str_src))
+        assignblk.C_prefetch = out
+        return out
+
+    def add_local_var(self, dst_var, dst_index, expr):
+        size = expr.size
+        if size < 8:
+            size = 8
+        if size not in dst_index:
+            raise RuntimeError("Unsupported operand size %s", size)
+        var_num = dst_index[size]
+        dst = m2_expr.ExprId("var_%.2d_%.2d" % (size, var_num), size)
+        dst_index[size] += 1
+        dst_var[expr] = dst
+        return dst
+
+    def gen_assignments(self, assignblk, prefetchers):
+        out_var = []
+        out_main = []
+        out_mem = []
+        out_updt = []
+
+        dst_index = {8: 0, 16: 0, 32: 0, 64: 0}
+        dst_var = {}
+
+        for var in prefetchers.itervalues():
+            out_var.append("uint%d_t %s;" % (var.size, var))
+
+        for dst, src in sorted(assignblk.iteritems()):
+            src = src.replace_expr(prefetchers)
+            if dst is self.ir_arch.IRDst:
+                pass
+            elif isinstance(dst, m2_expr.ExprId):
+                new_dst = self.add_local_var(dst_var, dst_index, dst)
+                if dst in self.ir_arch.arch.regs.regs_flt_expr:
+                    # Dont mask float affectation
+                    out_main.append(
+                        '%s = (%s);' % (self.id_to_c(new_dst), self.id_to_c(src)))
+                else:
+                    out_main.append(
+                        '%s = (%s)&0x%X;' % (self.id_to_c(new_dst),
+                                             self.id_to_c(src),
+                                             SIZE_TO_MASK[src.size]))
+            elif isinstance(dst, m2_expr.ExprMem):
+                ptr = dst.arg.replace_expr(prefetchers)
+                new_dst = m2_expr.ExprMem(ptr, dst.size)
+                str_dst = self.id_to_c(new_dst).replace('MEM_LOOKUP', 'MEM_WRITE')
+                out_mem.append('%s, %s);' % (str_dst[:-1], self.id_to_c(src)))
+            else:
+                raise ValueError("Unknown dst")
+
+        for dst, new_dst in dst_var.iteritems():
+            if dst is self.ir_arch.IRDst:
+                continue
+            out_updt.append('%s = %s;' % (self.id_to_c(dst), self.id_to_c(new_dst)))
+            out_var.append("uint%d_t %s;" % (new_dst.size, new_dst))
+
+        assignblk.C_var = out_var
+        assignblk.C_main = out_main
+        assignblk.C_mem = out_mem
+        assignblk.C_updt = out_updt
+
+    def gen_c_assignblk(self, assignblk):
+        mem_read, mem_write = False, False
+
+        mem_index = {8: 0, 16: 0, 32: 0, 64: 0}
+        mem_var = {}
+        prefetch_index = {8: 0, 16: 0, 32: 0, 64: 0}
+
+        # Prefetch memory read
+        for expr in assignblk.get_r(mem_read=True):
+            if not isinstance(expr, m2_expr.ExprMem):
+                continue
+            mem_read = True
+            var_num = mem_index[expr.size]
+            mem_index[expr.size] += 1
+            var = m2_expr.ExprId(
+                "prefetch_%.2d_%.2d" % (expr.size, var_num), expr.size)
+            mem_var[expr] = var
+
+        # Check if assignblk can write mem
+        mem_write = any(isinstance(expr, m2_expr.ExprMem)
+                        for expr in assignblk.get_w())
+
+        assignblk.mem_write = mem_write
+        assignblk.mem_read = mem_read
+
+        # Generate memory prefetch
+        return mem_var
+
+    def gen_check_memory_exception(self, address):
+        dst = self.dst_to_c(address)
+        return (self.CODE_EXCEPTION_MEM_AT_INSTR % (self.C_PC, dst, dst)).split('\n')
+
+    def gen_check_memory_exception_post(self, address):
+        dst = self.dst_to_c(address)
+        return (self.CODE_EXCEPTION_MEM_POST_INSTR % (self.C_PC, dst, dst)).split('\n')
+
+    def gen_check_cpu_exception(self, address):
+        dst = self.dst_to_c(address)
+        return (self.CODE_EXCEPTION_AT_INSTR % (self.C_PC, dst, dst)).split('\n')
+
+    def gen_check_cpu_exception_post(self, address):
+        dst = self.dst_to_c(address)
+        return (self.CODE_EXCEPTION_POST_INSTR % (self.C_PC, dst, dst)).split('\n')
+
+    def traverse_expr_dst(self, expr, dst2index):
+        """
+        Generate the index of the destination label for the @expr
+        @dst2index: dictionnary to link label to its index
+        """
+
+        if isinstance(expr, m2_expr.ExprCond):
+            cond = self.id_to_c(expr.cond)
+            src1, src1b = self.traverse_expr_dst(expr.src1, dst2index)
+            src2, src2b = self.traverse_expr_dst(expr.src2, dst2index)
+            return ("((%s)?(%s):(%s))" % (cond, src1, src2),
+                    "((%s)?(%s):(%s))" % (cond, src1b, src2b))
+        elif isinstance(expr, m2_expr.ExprInt):
+            offset = int(expr.arg)
+            self.add_label_index(dst2index, offset)
+            return ("%s" % dst2index[offset],
+                    hex(offset))
+        elif expr_is_label(expr):
+            label = expr.name
+            if label.offset != None:
+                offset = label.offset
+                self.add_label_index(dst2index, offset)
+                return ("%s" % dst2index[offset],
+                        hex(offset))
+            else:
+                self.add_label_index(dst2index, label)
+                return ("%s" % dst2index[label],
+                        "0")
+
+        elif (isinstance(expr, m2_expr.ExprId) or
+              isinstance(expr, m2_expr.ExprMem) or
+              isinstance(expr, m2_expr.ExprSlice)):
+            dst2index[expr] = -1
+            return ("-1",
+                    self.id_to_c(expr))
+        else:
+            raise RuntimeError("Unsupported IRDst type %s" % expr)
+
+    def gen_assignblk_dst(self, dst):
+        dst2index = {}
+        (ret, retb) = self.traverse_expr_dst(dst, dst2index)
+        ret = "DST_case = %s;" % ret
+        retb = "DST_value = %s;" % retb
+        return ['// %s' % dst2index,
+                '%s' % ret,
+                '%s' % retb], dst2index
+
+    def gen_post_instr_checks(self, attrib, dst):
+        out = []
+        dst = self.dst_to_c(dst)
+        if attrib.mem_read | attrib.mem_write:
+            out += (self.CODE_VM_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n')
+        if attrib.set_exception or attrib.op_set_exception:
+            out += (self.CODE_CPU_EXCEPTION_POST_INSTR % (self.C_PC, dst)).split('\n')
+
+        if attrib.mem_read | attrib.mem_write:
+            out.append("reset_memory_access(&(jitcpu->pyvm->vm_mngr));")
+
+        return out
+
+    def gen_pre_code(self, attrib):
+        out = []
+
+        if attrib.log_mn:
+            out.append('printf("%.8X %s\\n");' % (attrib.instr.offset,
+                                                  attrib.instr))
+        return out
+
+    def gen_post_code(self, attrib):
+        out = []
+        if attrib.log_regs:
+            out.append('dump_gpregs(jitcpu->cpu);')
+        return out
+
+    def gen_goto_code(self, attrib, instr_offsets, dst):
+        out = []
+        if isinstance(dst, asm_label):
+            out.append('goto %s;' % dst.name)
+        elif dst in instr_offsets:
+            lbl = self.ir_arch.symbol_pool.getby_offset_create(dst)
+            out += self.gen_post_code(attrib)
+            out += self.gen_post_instr_checks(attrib, dst)
+            out.append('goto %s;' % lbl.name)
+        else:
+            out += self.gen_post_code(attrib)
+            out.append('BlockDst->address = DST_value;')
+            out += self.gen_post_instr_checks(attrib, dst)
+            out.append('\t\treturn JIT_RET_NO_EXCEPTION;')
+        return out
+
+    def gen_dst_goto(self, attrib, instr_offsets, dst2index):
+        """
+        Generate code for possible @dst2index.
+
+        @attrib: an Attributs instance
+        @instr_offsets: list of instructions offsets
+        @dst2index: link from dstination to index
+        """
+
+        if not dst2index:
+            return []
+        out = []
+        out.append('switch(DST_case) {')
+        for dst, index in sorted(dst2index.iteritems(), key=lambda lblindex: lblindex[1]):
+            out.append('\tcase %d:' % index)
+            out += self.gen_goto_code(attrib, instr_offsets, dst)
+            out.append('\t\tbreak;')
+        out.append('};')
+        return out
+
+    def gen_c_code(self, assignblk, c_dst):
+        """
+        Generate the C code for @assignblk.
+        @assignblk: an Assignblk instance
+        @c_dst: irdst C code
+        """
+        out = []
+        out.append("{")
+        out.append("// var")
+        out += assignblk.C_var
+        out.append("// Prefetch")
+        out += assignblk.C_prefetch
+        out.append("// Dst")
+        out += c_dst
+        out.append("// Main")
+        out += assignblk.C_main
+
+        out.append("// Check op/mem exceptions")
+
+        # Check memory access if assignblk has memory read
+        if assignblk.C_prefetch:
+            out += self.gen_check_memory_exception(assignblk.instr_addr)
+
+        # Check if operator raised exception flags
+        if assignblk.op_set_exception:
+            out += self.gen_check_cpu_exception(assignblk.instr_addr)
+
+        out.append("// Mem updt")
+        out += assignblk.C_mem
+
+        out.append("// Check exception Mem write")
+        # Check memory write exceptions
+        if assignblk.mem_write:
+            out += self.gen_check_memory_exception(assignblk.instr_addr)
+
+        out.append("// Updt")
+        out += assignblk.C_updt
+
+        out.append("// Checks exception")
+
+        # Check post assignblk exception flags
+        if assignblk.set_exception:
+            out += self.gen_check_cpu_exception(assignblk.instr_addr)
+
+        out.append("}")
+
+        return out
+
+    def is_exception_operator(self, operator):
+        """Return True if the @op operator can raise a runtime exception"""
+
+        return any(operator.startswith(except_op)
+                   for except_op in self.IMPLICIT_EXCEPTION_OP)
+
+    def get_caracteristics(self, irblock):
+        """
+        Get the carateristics of each assignblk in the @irblock
+        @irblock: an irbloc instance
+        """
+
+        for assignblk in irblock.irs:
+            assignblk.mem_read, assignblk.mem_write = False, False
+            assignblk.op_set_exception = False
+            # Check explicit exception raising
+            assignblk.set_exception = self.ir_arch.arch.regs.exception_flags in assignblk
+
+            element_read = assignblk.get_r(mem_read=True)
+            # Check implicit exception raising
+            assignblk.op_set_exception = any(self.is_exception_operator(operator)
+                                             for elem in assignblk.values()
+                                             for operator in m2_expr.get_expr_ops(elem))
+            # Check mem read
+            assignblk.mem_read = any(isinstance(expr, m2_expr.ExprMem)
+                                     for expr in element_read)
+            # Check mem write
+            assignblk.mem_write = any(isinstance(dst, m2_expr.ExprMem)
+                                      for dst in assignblk)
+
+    def get_attributes(self, instr, irblocks, log_mn=False, log_regs=False):
+        """
+        Get the carateristics of each @irblocks. Returns the corresponding
+        attributes object.
+        @irblock: a list of irbloc instance
+        @log_mn: generate code to log instructions
+        @log_regs: generate code to log registers states
+        """
+
+        attrib = Attributes(log_mn, log_regs)
+
+        for irblock in irblocks:
+            for assignblk in irblock.irs:
+                self.get_caracteristics(irblock)
+                attrib.mem_read |= assignblk.mem_read
+                attrib.mem_write |= assignblk.mem_write
+                attrib.set_exception |= assignblk.set_exception
+                attrib.op_set_exception |= assignblk.op_set_exception
+        attrib.instr = instr
+        return attrib
+
+    def gen_bad_block(self):
+        """
+        Generate the C code for a bad_block instance
+        """
+        return self.CODE_BAD_BLOCK.split("\n")
+
+    def get_block_post_label(self, block):
+        last_instr = block.lines[-1]
+        offset = last_instr.offset + last_instr.l
+        return self.ir_arch.symbol_pool.getby_offset_create(offset)
+
+    def gen_init(self, block):
+        """
+        Generate the init C code for a @block
+        @block: an asm_bloc instance
+        """
+
+        instr_offsets = [line.offset for line in block.lines]
+        instr_offsets.append(self.get_block_post_label(block).offset)
+        lbl_start = self.ir_arch.symbol_pool.getby_offset_create(instr_offsets[0])
+        return (self.CODE_INIT % lbl_start.name).split("\n"), instr_offsets
+
+    def gen_irblock(self, attrib, instr_offsets, instr, irblock):
+        """
+        Generate the C code for an @irblock
+        @instr: the current instruction to translate
+        @irblock: an irbloc instance
+        @attrib: an Attributs instance
+        """
+
+        out = []
+        dst2index = None
+        for index, assignblk in enumerate(irblock.irs):
+            if index == irblock.dst_linenb:
+                c_dst, dst2index = self.gen_assignblk_dst(irblock.dst)
+            else:
+                c_dst = []
+            assignblk.instr_addr = instr.offset
+            prefetchers = self.gen_c_assignblk(assignblk)
+            self.gen_mem_prefetch(assignblk, prefetchers)
+            self.gen_assignments(assignblk, prefetchers)
+
+            out += self.gen_c_code(assignblk, c_dst)
+
+        if dst2index:
+            out.append("// Set irdst")
+            # Gen goto on irdst set
+            out += self.gen_dst_goto(attrib, instr_offsets, dst2index)
+
+        return out
+
+    def gen_finalize(self, block):
+        """
+        Generate the C code for the final block instruction
+        """
+
+        lbl = self.get_block_post_label(block)
+        dst = self.dst_to_c(lbl.offset)
+        code = self.CODE_RETURN_NO_EXCEPTION % (lbl.name, self.C_PC, dst, dst)
+        return code.split('\n')
+
+    def gen_c(self, block, log_mn=False, log_regs=False):
+        """
+        Generate the C code for the @block and return it as a list of lines
+        @log_mn: log mnemonics
+        @log_regs: log registers
+        """
+
+        if isinstance(block, asm_block_bad):
+            return self.gen_bad_block()
+        irblocks_list = self.block2assignblks(block)
+
+        out, instr_offsets = self.gen_init(block)
+
+        for instr, irblocks in zip(block.lines, irblocks_list):
+            attrib = self.get_attributes(instr, irblocks, log_mn, log_regs)
+
+            for index, irblock in enumerate(irblocks):
+                self.ir_arch.irbloc_fix_regs_for_mode(
+                    irblock, self.ir_arch.attrib)
+
+                out.append("%-40s // %.16X %s" %
+                           (str(irblock.label.name) + ":", instr.offset, instr))
+                if index == 0:
+                    out += self.gen_pre_code(attrib)
+                out += self.gen_irblock(attrib, instr_offsets, instr, irblock)
+
+        out += self.gen_finalize(block)
+        return ['\t' + line for line in out]
diff --git a/miasm2/jitter/csts.py b/miasm2/jitter/csts.py
index b71e9463..7af2435f 100644
--- a/miasm2/jitter/csts.py
+++ b/miasm2/jitter/csts.py
@@ -13,6 +13,9 @@ EXCEPT_BREAKPOINT_INTERN = (1 << 10)
 EXCEPT_ACCESS_VIOL = ((1 << 14) | EXCEPT_DO_NOT_UPDATE_PC)
 EXCEPT_DIV_BY_ZERO = ((1 << 16) | EXCEPT_DO_NOT_UPDATE_PC)
 EXCEPT_PRIV_INSN = ((1 << 17) | EXCEPT_DO_NOT_UPDATE_PC)
+EXCEPT_ILLEGAL_INSN = ((1 << 18) | EXCEPT_DO_NOT_UPDATE_PC)
+EXCEPT_UNK_MNEMO = ((1 << 19) | EXCEPT_DO_NOT_UPDATE_PC)
+
 # VM Mngr constants
 
 PAGE_READ = 1
diff --git a/miasm2/jitter/emulatedsymbexec.py b/miasm2/jitter/emulatedsymbexec.py
index f7c48227..d72de771 100644
--- a/miasm2/jitter/emulatedsymbexec.py
+++ b/miasm2/jitter/emulatedsymbexec.py
@@ -5,13 +5,14 @@ from miasm2.ir.symbexec import symbexec
 class EmulatedSymbExec(symbexec):
     """Symbolic exec instance linked with a jitter"""
 
-    def __init__(self, cpu, *args, **kwargs):
+    def __init__(self, cpu, vm, *args, **kwargs):
         """Instanciate an EmulatedSymbExec, associated to CPU @cpu and bind
         memory accesses.
         @cpu: JitCpu instance
         """
         super(EmulatedSymbExec, self).__init__(*args, **kwargs)
         self.cpu = cpu
+        self.vm = vm
         self.func_read = self._func_read
         self.func_write = self._func_write
 
@@ -28,6 +29,7 @@ class EmulatedSymbExec(symbexec):
         addr = expr_mem.arg.arg.arg
         size = expr_mem.size / 8
         value = self.cpu.get_mem(addr, size)
+        self.vm.add_mem_read(addr, size)
 
         return m2_expr.ExprInt(int(value[::-1].encode("hex"), 16),
                                expr_mem.size)
@@ -53,6 +55,7 @@ class EmulatedSymbExec(symbexec):
 
         # Write in VmMngr context
         self.cpu.set_mem(addr, content)
+        self.vm.add_mem_write(addr, len(content))
 
     # Interaction symbexec <-> jitter
     def update_cpu_from_engine(self):
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 74c438a7..04bd707a 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -51,8 +51,6 @@ class JitCore(object):
         self.blocs_mem_interval = interval()
         self.disasm_cb = None
         self.split_dis = set()
-        self.addr_mod = interval()
-
         self.options = {"jit_maxline": 50  # Maximum number of line jitted
                         }
 
@@ -95,6 +93,11 @@ class JitCore(object):
         if cur_bloc.lines:
             cur_bloc.ad_min = cur_bloc.lines[0].offset
             cur_bloc.ad_max = cur_bloc.lines[-1].offset + cur_bloc.lines[-1].l
+        else:
+            # 1 byte block for unknown mnemonic
+            cur_bloc.ad_min = cur_bloc.label.offset
+            cur_bloc.ad_max = cur_bloc.label.offset+1
+
 
     def add_bloc_to_mem_interval(self, vm, bloc):
         "Update vm to include bloc addresses in its memory range"
@@ -142,16 +145,13 @@ class JitCore(object):
             cur_bloc = self.mdis.dis_bloc(addr)
         except IOError:
             # vm_exception_flag is set
-            cur_bloc = asmbloc.asm_bloc(label)
+            label = self.ir_arch.symbol_pool.getby_offset_create(addr)
+            cur_bloc = asmbloc.asm_block_bad(label)
 
         # Logging
         if self.log_newbloc:
             print cur_bloc
 
-        # Check for empty blocks
-        if not cur_bloc.lines:
-            raise ValueError("Cannot JIT a block without any assembly line")
-
         # Update label -> bloc
         self.lbl2bloc[cur_bloc.label] = cur_bloc
 
@@ -259,15 +259,21 @@ class JitCore(object):
 
         return modified_blocs
 
-    def updt_automod_code(self, vm):
-        """Remove code jitted in range self.addr_mod
+    def updt_automod_code_range(self, vm, mem_range):
+        """Remove jitted code in range @mem_range
         @vm: VmMngr instance
+        @mem_range: list of start/stop addresses
         """
-        for addr_start, addr_stop in self.addr_mod:
-            self.del_bloc_in_range(addr_start, addr_stop + 1)
+        for addr_start, addr_stop in mem_range:
+            self.del_bloc_in_range(addr_start, addr_stop)
         self.__updt_jitcode_mem_range(vm)
-        self.addr_mod = interval()
+        vm.reset_memory_access()
 
-    def automod_cb(self, addr=0, size=0):
-        self.addr_mod += interval([(addr, addr + size / 8 - 1)])
-        return None
+    def updt_automod_code(self, vm):
+        """Remove jitted code updated by memory write
+        @vm: VmMngr instance
+        """
+        mem_range = []
+        for addr_start, addr_stop in vm.get_memory_write():
+            mem_range.append((addr_start, addr_stop))
+        self.updt_automod_code_range(vm, mem_range)
diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py
index db0b7880..7f72d8e7 100644
--- a/miasm2/jitter/jitcore_gcc.py
+++ b/miasm2/jitter/jitcore_gcc.py
@@ -4,11 +4,11 @@
 import os
 import tempfile
 import ctypes
+import _ctypes
 from distutils.sysconfig import get_python_inc
 from subprocess import check_call
 from hashlib import md5
 
-from miasm2.ir.ir2C import irblocs2C
 from miasm2.jitter import jitcore, Jitgcc
 from miasm2.core.utils import keydefaultdict
 
@@ -79,7 +79,11 @@ class JitCore_Gcc(jitcore.JitCore):
         self.include_files = None
 
     def deleteCB(self, offset):
-        pass
+        """Free the state associated to @offset and delete it
+        @offset: gcc state offset
+        """
+        _ctypes.dlclose(self.gcc_states[offset]._handle)
+        del self.gcc_states[offset]
 
     def load(self):
         lib_dir = os.path.dirname(os.path.realpath(__file__))
@@ -92,6 +96,13 @@ class JitCore_Gcc(jitcore.JitCore):
         self.include_files = include_files
         self.libs = libs
 
+    def init_codegen(self, codegen):
+        """
+        Get the code generator @codegen
+        @codegen: an CGen instance
+        """
+        self.codegen = codegen
+
     def label2fname(self, label):
         """
         Generate function name from @label
@@ -105,9 +116,10 @@ class JitCore_Gcc(jitcore.JitCore):
         func = getattr(lib, f_name)
         addr = ctypes.cast(func, ctypes.c_void_p).value
         self.lbl2jitbloc[label.offset] = addr
-        self.gcc_states[label.offset] = None
+        self.gcc_states[label.offset] = lib
+
 
-    def gen_c_code(self, label, irblocks):
+    def gen_c_code(self, label, block):
         """
         Return the C code corresponding to the @irblocks
         @label: asm_label of the block to jit
@@ -115,10 +127,7 @@ class JitCore_Gcc(jitcore.JitCore):
         """
         f_name = self.label2fname(label)
         f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name
-        out = irblocs2C(self.ir_arch, self.resolver, label, irblocks,
-                        gen_exception_code=True,
-                        log_mn=self.log_mn,
-                        log_regs=self.log_regs)
+        out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs)
         out = [f_declaration + '{'] + out + ['}\n']
         c_code = out
 
@@ -136,8 +145,7 @@ class JitCore_Gcc(jitcore.JitCore):
         fname_out = os.path.join(self.tempdir, "%s.so" % block_hash)
 
         if not os.access(fname_out, os.R_OK | os.X_OK):
-            irblocks = self.ir_arch.add_bloc(block, gen_pc_updt=True)
-            func_code = self.gen_c_code(block.label, irblocks)
+            func_code = self.gen_c_code(block.label, block)
 
             # Create unique C file
             fdesc, fname_in = tempfile.mkstemp(suffix=".c")
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index e1e62816..ae72b307 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -17,10 +17,14 @@ class JitCore_Python(jitcore.JitCore):
         super(JitCore_Python, self).__init__(ir_arch, bs)
         self.ir_arch = ir_arch
 
-        # CPU (None for now) will be set by the "jitted" Python function
-        self.symbexec = EmulatedSymbExec(None, self.ir_arch, {})
+        # CPU & VM (None for now) will be set by the "jitted" Python function
+        self.symbexec = EmulatedSymbExec(None, None, self.ir_arch, {})
         self.symbexec.enable_emulated_simplifications()
 
+    def set_cpu_vm(self, cpu, vm):
+        self.symbexec.cpu = cpu
+        self.symbexec.vm = vm
+
     def load(self):
         "Preload symbols according to current architecture"
         self.symbexec.reset_regs()
@@ -45,7 +49,6 @@ class JitCore_Python(jitcore.JitCore):
 
             # Get exec engine
             exec_engine = self.symbexec
-            exec_engine.cpu = cpu
 
             # For each irbloc inside irblocs
             while True:
@@ -66,12 +69,19 @@ class JitCore_Python(jitcore.JitCore):
 
                     # For each new instruction (in assembly)
                     if line.offset not in offsets_jitted:
+                        # Test exceptions
+                        vmmngr.check_invalid_code_blocs()
+                        vmmngr.check_memory_breakpoint()
+                        if vmmngr.get_exception():
+                            exec_engine.update_cpu_from_engine()
+                            return line.offset
+
                         offsets_jitted.add(line.offset)
 
                         # Log registers values
                         if self.log_regs:
                             exec_engine.update_cpu_from_engine()
-                            cpu.dump_gpregs()
+                            exec_engine.cpu.dump_gpregs()
 
                         # Log instruction
                         if self.log_mn:
@@ -90,6 +100,9 @@ class JitCore_Python(jitcore.JitCore):
                         exec_engine.update_cpu_from_engine()
                         return line.offset
 
+                vmmngr.check_invalid_code_blocs()
+                vmmngr.check_memory_breakpoint()
+
                 # Get next bloc address
                 ad = expr_simp(exec_engine.eval_expr(self.ir_arch.IRDst))
 
diff --git a/miasm2/jitter/jitcore_tcc.py b/miasm2/jitter/jitcore_tcc.py
index 151fab7d..d3e90f85 100644
--- a/miasm2/jitter/jitcore_tcc.py
+++ b/miasm2/jitter/jitcore_tcc.py
@@ -7,7 +7,6 @@ from subprocess import Popen, PIPE
 from hashlib import md5
 import tempfile
 
-from miasm2.ir.ir2C import irblocs2C
 from miasm2.jitter import jitcore, Jittcc
 
 
@@ -141,6 +140,13 @@ class JitCore_Tcc(jitcore.JitCore):
         include_files = ";".join(include_files)
         Jittcc.tcc_set_emul_lib_path(include_files, libs)
 
+    def init_codegen(self, codegen):
+        """
+        Get the code generator @codegen
+        @codegen: an CGen instance
+        """
+        self.codegen = codegen
+
     def __del__(self):
         for tcc_state in self.tcc_states.values():
             Jittcc.tcc_end(tcc_state)
@@ -164,7 +170,7 @@ class JitCore_Tcc(jitcore.JitCore):
         self.lbl2jitbloc[label.offset] = mcode
         self.tcc_states[label.offset] = tcc_state
 
-    def gen_c_code(self, label, irblocks):
+    def gen_c_code(self, label, block):
         """
         Return the C code corresponding to the @irblocks
         @label: asm_label of the block to jit
@@ -172,10 +178,7 @@ class JitCore_Tcc(jitcore.JitCore):
         """
         f_name = self.label2fname(label)
         f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % f_name
-        out = irblocs2C(self.ir_arch, self.resolver, label, irblocks,
-                        gen_exception_code=True,
-                        log_mn=self.log_mn,
-                        log_regs=self.log_regs)
+        out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs)
         out = [f_declaration + '{'] + out + ['}\n']
         c_code = out
 
@@ -194,9 +197,7 @@ class JitCore_Tcc(jitcore.JitCore):
         if os.access(fname_out, os.R_OK):
             func_code = open(fname_out).read()
         else:
-            irblocks = self.ir_arch.add_bloc(block, gen_pc_updt=True)
-            block.irblocs = irblocks
-            func_code = self.gen_c_code(block.label, irblocks)
+            func_code = self.gen_c_code(block.label, block)
 
             # Create unique C file
             fdesc, fname_tmp = tempfile.mkstemp(suffix=".c")
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index cc92b0cf..d8393230 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -2,14 +2,14 @@
 
 import logging
 from functools import wraps
-from collections import Sequence, namedtuple
+from collections import Sequence, namedtuple, Iterator
 
 from miasm2.jitter.csts import *
 from miasm2.core.utils import *
 from miasm2.core.bin_stream import bin_stream_vm
-from miasm2.ir.ir2C import init_arch_C
 from miasm2.core.interval import interval
 from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec
+from miasm2.jitter.codegen import CGen
 
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
@@ -161,11 +161,14 @@ class jitter:
 
     "Main class for JIT handling"
 
+    C_Gen = CGen
+
     def __init__(self, ir_arch, jit_type="tcc"):
         """Init an instance of jitter.
         @ir_arch: ir instance for this architecture
         @jit_type: JiT backend to use. Available options are:
             - "tcc"
+            - "gcc"
             - "llvm"
             - "python"
         """
@@ -194,9 +197,8 @@ class jitter:
         self.cpu = jcore.JitCpu()
         self.ir_arch = ir_arch
         self.bs = bin_stream_vm(self.vm)
-        init_arch_C(self.arch)
 
-        self.symbexec = EmulatedSymbExec(self.cpu, self.ir_arch, {})
+        self.symbexec = EmulatedSymbExec(self.cpu, self.vm, self.ir_arch, {})
         self.symbexec.reset_regs()
 
         try:
@@ -214,6 +216,10 @@ class jitter:
             raise RuntimeError('Unsupported jitter: %s' % jit_type)
 
         self.jit = JitCore(self.ir_arch, self.bs)
+        if jit_type in ['tcc', 'gcc']:
+            self.jit.init_codegen(self.C_Gen(self.ir_arch))
+        elif jit_type == "python":
+            self.jit.set_cpu_vm(self.cpu, self.vm)
 
         self.cpu.init_regs()
         self.vm.init_memory_page_pool()
@@ -261,8 +267,7 @@ class jitter:
         self.breakpoints_handler.add_callback(addr, callback)
         self.jit.add_disassembly_splits(addr)
         # De-jit previously jitted blocks
-        self.jit.addr_mod = interval([(addr, addr)])
-        self.jit.updt_automod_code(self.vm)
+        self.jit.updt_automod_code_range(self.vm, [(addr, addr)])
 
     def set_breakpoint(self, addr, *args):
         """Set callbacks associated with addr.
@@ -309,6 +314,17 @@ class jitter:
         old_pc = self.pc
         for res in self.breakpoints_handler.call_callbacks(self.pc, self):
             if res is not True:
+                if isinstance(res, collections.Iterator):
+                    # If the breakpoint is a generator, yield it step by step
+                    for tmp in res:
+                        yield tmp
+                else:
+                    yield res
+
+        # Check exceptions (raised by breakpoints)
+        exception_flag = self.get_exception()
+        for res in self.exceptions_handler(exception_flag, self):
+            if res is not True:
                 yield res
 
         # If a callback changed pc, re call every callback
@@ -321,7 +337,7 @@ class jitter:
         # Run the bloc at PC
         self.pc = self.runbloc(self.pc)
 
-        # Check exceptions
+        # Check exceptions (raised by the execution of the block)
         exception_flag = self.get_exception()
         for res in self.exceptions_handler(exception_flag, self):
             if res is not True:
diff --git a/miasm2/jitter/loader/pe.py b/miasm2/jitter/loader/pe.py
index bb6740af..e8dacb55 100644
--- a/miasm2/jitter/loader/pe.py
+++ b/miasm2/jitter/loader/pe.py
@@ -98,6 +98,12 @@ def get_export_name_addr_list(e):
         # hex(e.rva2virt(addr.rva))))
         out.append(
             (o.ordinal + e.DirExport.expdesc.base, e.rva2virt(addr.rva)))
+
+    for i, s in enumerate(e.DirExport.f_address):
+        if not s.rva:
+            continue
+        out.append((i + e.DirExport.expdesc.base, e.rva2virt(s.rva)))
+
     return out
 
 
@@ -396,6 +402,7 @@ class libimp_pe(libimp):
                 c_name = canon_libname_libfunc(
                     name_inv[libad], imp_ord_or_name)
                 self.fad2cname[ad] = c_name
+                log.debug("Add func %s %s", hex(ad), c_name)
                 self.fad2info[ad] = libad, imp_ord_or_name
 
     def gen_new_lib(self, target_pe, filter_import=lambda peobj, ad: True, **kwargs):
diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c
index f5c83b8b..df8326d9 100644
--- a/miasm2/jitter/vm_mngr.c
+++ b/miasm2/jitter/vm_mngr.c
@@ -76,7 +76,38 @@ const uint8_t parity_table[256] = {
     0, CC_P, CC_P, 0, CC_P, 0, 0, CC_P,
 };
 
-//#define DEBUG_MIASM_AUTOMOD_CODE
+// #define DEBUG_MIASM_AUTOMOD_CODE
+
+void memory_access_list_init(struct memory_access_list * access)
+{
+	access->array = NULL;
+	access->allocated = 0;
+	access->num = 0;
+}
+
+void memory_access_list_reset(struct memory_access_list * access)
+{
+	if (access->array) {
+		free(access->array);
+		access->array = NULL;
+	}
+	access->allocated = 0;
+	access->num = 0;
+}
+
+void memory_access_list_add(struct memory_access_list * access, uint64_t start, uint64_t stop)
+{
+	if (access->num >= access->allocated) {
+		if (access->allocated == 0)
+			access->allocated = 1;
+		else
+			access->allocated *= 2;
+		access->array = realloc(access->array, access->allocated * sizeof(struct memory_access));
+	}
+	access->array[access->num].start = start;
+	access->array[access->num].stop = stop;
+	access->num += 1;
+}
 
 
 
@@ -119,9 +150,6 @@ inline int midpoint(int imin, int imax)
 
 int find_page_node(struct memory_page_node * array, uint64_t key, int imin, int imax)
 {
-	if (imax < 1)
-		return -1;
-	imax--;
 	// continue searching while [imin,imax] is not empty
 	while (imin <= imax) {
 		// calculate the midpoint for roughly equal partition
@@ -149,7 +177,7 @@ struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint6
 	i = find_page_node(vm_mngr->memory_pages_array,
 			   ad,
 			   0,
-			   vm_mngr->memory_pages_number);
+			   vm_mngr->memory_pages_number - 1);
 	if (i >= 0) {
 		mpn = &vm_mngr->memory_pages_array[i];
 		if ((mpn->ad <= ad) && (ad < mpn->ad + mpn->size))
@@ -226,7 +254,7 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 			if (!mpn)
 				return 0;
 			addr = &((unsigned char*)mpn->ad_hp)[ad - mpn->ad];
-			ret |= (*((unsigned char*)addr)&0xFF)<<(index);
+			ret |= ((uint64_t)(*((unsigned char*)addr)&0xFF))<<(index);
 			index +=8;
 			new_size -= 8;
 			ad ++;
@@ -396,29 +424,123 @@ void dump_code_bloc(vm_mngr_t* vm_mngr)
 
 }
 
-void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr)
+void add_range_to_list(struct memory_access_list * access, uint64_t addr1, uint64_t addr2)
+{
+	if (access->num > 0) {
+		/* Check match on upper bound */
+		 if (access->array[access->num-1].stop == addr1) {
+			 access->array[access->num-1].stop = addr2;
+			 return;
+		 }
+
+		/* Check match on lower bound */
+		 if (access->array[0].start == addr2) {
+			 access->array[0].start = addr1;
+			 return;
+		 }
+	}
+
+	/* No merge, add to the list */
+	memory_access_list_add(access, addr1, addr2);
+}
+
+
+void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size)
 {
+	add_range_to_list(&(vm_mngr->memory_r), addr, addr + size);
+}
+
+void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size)
+{
+	add_range_to_list(&(vm_mngr->memory_w), addr, addr + size);
+}
+
+void check_invalid_code_blocs(vm_mngr_t* vm_mngr)
+{
+	int i;
 	struct code_bloc_node * cbp;
+	for (i=0;i<vm_mngr->memory_w.num; i++) {
+		if (vm_mngr->exception_flags & EXCEPT_CODE_AUTOMOD)
+			break;
+		if (vm_mngr->memory_w.array[i].stop <= vm_mngr->code_bloc_pool_ad_min ||
+		    vm_mngr->memory_w.array[i].start >=vm_mngr->code_bloc_pool_ad_max)
+			continue;
 
-	if (!(addr + my_size/8 <= vm_mngr->code_bloc_pool_ad_min ||
-	      addr >=vm_mngr->code_bloc_pool_ad_max)){
 		LIST_FOREACH(cbp, &vm_mngr->code_bloc_pool, next){
-			if ((cbp->ad_start < addr + my_size/8) &&
-			    (addr < cbp->ad_stop)){
+			if ((cbp->ad_start < vm_mngr->memory_w.array[i].stop) &&
+			    (vm_mngr->memory_w.array[i].start < cbp->ad_stop)){
 #ifdef DEBUG_MIASM_AUTOMOD_CODE
 				fprintf(stderr, "**********************************\n");
-				fprintf(stderr, "self modifying code %"PRIX64" %.8X\n",
-				       addr, my_size);
+				fprintf(stderr, "self modifying code %"PRIX64" %"PRIX64"\n",
+					vm_mngr->memory_w.array[i].start,
+					vm_mngr->memory_w.array[i].stop);
 				fprintf(stderr, "**********************************\n");
 #endif
 				vm_mngr->exception_flags |= EXCEPT_CODE_AUTOMOD;
-
 				break;
 			}
 		}
 	}
 }
 
+
+void check_memory_breakpoint(vm_mngr_t* vm_mngr)
+{
+	int i;
+	struct memory_breakpoint_info * memory_bp;
+
+	/* Check memory breakpoints */
+	LIST_FOREACH(memory_bp, &vm_mngr->memory_breakpoint_pool, next) {
+		if (vm_mngr->exception_flags & EXCEPT_BREAKPOINT_INTERN)
+			break;
+		if (memory_bp->access & BREAKPOINT_READ) {
+			for (i=0;i<vm_mngr->memory_r.num; i++) {
+				if ((memory_bp->ad < vm_mngr->memory_r.array[i].stop) &&
+				    (vm_mngr->memory_r.array[i].start < memory_bp->ad + memory_bp->size)) {
+					vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN;
+					break;
+				}
+			}
+		}
+		if (memory_bp->access & BREAKPOINT_WRITE) {
+			for (i=0;i<vm_mngr->memory_w.num; i++) {
+				if ((memory_bp->ad < vm_mngr->memory_w.array[i].stop) &&
+				    (vm_mngr->memory_w.array[i].start < memory_bp->ad + memory_bp->size)) {
+					vm_mngr->exception_flags |= EXCEPT_BREAKPOINT_INTERN;
+					break;
+				}
+			}
+		}
+	}
+}
+
+
+PyObject* get_memory_pylist(vm_mngr_t* vm_mngr, struct memory_access_list* memory_list)
+{
+	int i;
+	PyObject *pylist;
+	PyObject *range;
+	pylist = PyList_New(memory_list->num);
+	for (i=0;i<memory_list->num;i++) {
+		range = PyTuple_New(2);
+		PyTuple_SetItem(range, 0, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].start));
+		PyTuple_SetItem(range, 1, PyLong_FromUnsignedLongLong((uint64_t)memory_list->array[i].stop));
+		PyList_SetItem(pylist, i, range);
+	}
+	return pylist;
+
+}
+
+PyObject* get_memory_read(vm_mngr_t* vm_mngr)
+{
+	return get_memory_pylist(vm_mngr, &vm_mngr->memory_r);
+}
+
+PyObject* get_memory_write(vm_mngr_t* vm_mngr)
+{
+	return get_memory_pylist(vm_mngr, &vm_mngr->memory_w);
+}
+
 PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr)
 {
 	PyObject* pyaddr;
@@ -438,49 +560,53 @@ PyObject* addr2BlocObj(vm_mngr_t* vm_mngr, uint64_t addr)
 
 void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src)
 {
-	check_write_code_bloc(vm_mngr, 8, addr);
+	add_mem_write(vm_mngr, addr, 1);
 	memory_page_write(vm_mngr, 8, addr, src);
 }
 
 void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src)
 {
-	check_write_code_bloc(vm_mngr, 16, addr);
+	add_mem_write(vm_mngr, addr, 2);
 	memory_page_write(vm_mngr, 16, addr, src);
 }
 void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src)
 {
-	check_write_code_bloc(vm_mngr, 32, addr);
+	add_mem_write(vm_mngr, addr, 4);
 	memory_page_write(vm_mngr, 32, addr, src);
 }
 void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src)
 {
-	check_write_code_bloc(vm_mngr, 64, addr);
+	add_mem_write(vm_mngr, addr, 8);
 	memory_page_write(vm_mngr, 64, addr, src);
 }
 
 unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr)
 {
-    unsigned char ret;
-    ret = memory_page_read(vm_mngr, 8, addr);
-    return ret;
+	unsigned char ret;
+	add_mem_read(vm_mngr, addr, 1);
+	ret = memory_page_read(vm_mngr, 8, addr);
+	return ret;
 }
 unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr)
 {
-    unsigned short ret;
-    ret = memory_page_read(vm_mngr, 16, addr);
-    return ret;
+	unsigned short ret;
+	add_mem_read(vm_mngr, addr, 2);
+	ret = memory_page_read(vm_mngr, 16, addr);
+	return ret;
 }
 unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr)
 {
-    unsigned int ret;
-    ret = memory_page_read(vm_mngr, 32, addr);
-    return ret;
+	unsigned int ret;
+	add_mem_read(vm_mngr, addr, 4);
+	ret = memory_page_read(vm_mngr, 32, addr);
+	return ret;
 }
 uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr)
 {
-    uint64_t ret;
-    ret = memory_page_read(vm_mngr, 64, addr);
-    return ret;
+	uint64_t ret;
+	add_mem_read(vm_mngr, addr, 8);
+	ret = memory_page_read(vm_mngr, 64, addr);
+	return ret;
 }
 
 
@@ -521,8 +647,6 @@ int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, uint64_t size)
        uint64_t len;
        struct memory_page_node * mpn;
 
-       check_write_code_bloc(vm_mngr, size * 8, addr);
-
        /* write is multiple page wide */
        while (size){
 	      mpn = get_memory_page_from_address(vm_mngr, addr, 1);
@@ -1393,6 +1517,11 @@ void init_code_bloc_pool(vm_mngr_t* vm_mngr)
 	LIST_INIT(&vm_mngr->code_bloc_pool);
 	vm_mngr->code_bloc_pool_ad_min = 0xffffffff;
 	vm_mngr->code_bloc_pool_ad_max = 0;
+
+	memory_access_list_init(&(vm_mngr->memory_r));
+	memory_access_list_init(&(vm_mngr->memory_w));
+
+
 }
 
 void init_memory_breakpoint(vm_mngr_t* vm_mngr)
@@ -1403,6 +1532,13 @@ void init_memory_breakpoint(vm_mngr_t* vm_mngr)
 
 void reset_memory_page_pool(vm_mngr_t* vm_mngr)
 {
+	struct memory_page_node * mpn;
+	int i;
+	for (i=0;i<vm_mngr->memory_pages_number; i++) {
+		mpn = &vm_mngr->memory_pages_array[i];
+		free(mpn->ad_hp);
+		free(mpn->name);
+	}
 	free(vm_mngr->memory_pages_array);
 	vm_mngr->memory_pages_array = NULL;
 	vm_mngr->memory_pages_number = 0;
@@ -1423,6 +1559,11 @@ void reset_code_bloc_pool(vm_mngr_t* vm_mngr)
 	vm_mngr->code_bloc_pool_ad_max = 0;
 }
 
+void reset_memory_access(vm_mngr_t* vm_mngr)
+{
+	memory_access_list_reset(&(vm_mngr->memory_r));
+	memory_access_list_reset(&(vm_mngr->memory_w));
+}
 
 void reset_memory_breakpoint(vm_mngr_t* vm_mngr)
 {
@@ -1436,6 +1577,8 @@ void reset_memory_breakpoint(vm_mngr_t* vm_mngr)
 
 }
 
+
+
 /* We don't use dichotomy here for the insertion */
 int is_mpn_in_tab(vm_mngr_t* vm_mngr, struct memory_page_node* mpn_a)
 {
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index 76b1c0dd..13ec065a 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -73,7 +73,16 @@ struct memory_page_node {
 	char* name;
 };
 
+struct memory_access {
+	uint64_t start;
+	uint64_t stop;
+};
 
+struct memory_access_list {
+	struct memory_access *array;
+	uint64_t allocated;
+	uint64_t num;
+};
 
 typedef struct {
 	int sex;
@@ -90,6 +99,14 @@ typedef struct {
 	uint64_t exception_flags;
 	uint64_t exception_flags_new;
 	PyObject *addr2obj;
+
+
+	struct memory_access_list memory_r;
+	struct memory_access_list memory_w;
+
+
+	int write_num;
+
 }vm_mngr_t;
 
 
@@ -205,6 +222,7 @@ unsigned int umul16_hi(unsigned short a, unsigned short b);
 uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b);
 uint64_t rot_right(uint64_t size, uint64_t a, uint64_t b);
 unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf);
+unsigned int rcr_rez_op(unsigned int size, unsigned int a, unsigned int b, unsigned int cf);
 
 
 #define UDIV(sizeA)						\
@@ -259,6 +277,11 @@ unsigned int rcl_rez_op(unsigned int size, unsigned int a, unsigned int b, unsig
 	    }
 
 
+void memory_access_list_init(struct memory_access_list * access);
+void memory_access_list_reset(struct memory_access_list * access);
+void memory_access_list_add(struct memory_access_list * access, uint64_t start, uint64_t stop);
+
+
 void hexdump(char* m, unsigned int l);
 
 struct code_bloc_node * create_code_bloc_node(uint64_t ad_start, uint64_t ad_stop);
@@ -280,7 +303,13 @@ void remove_memory_breakpoint(vm_mngr_t* vm_mngr, uint64_t ad, unsigned int acce
 
 void add_memory_page(vm_mngr_t* vm_mngr, struct memory_page_node* mpn);
 
-void check_write_code_bloc(vm_mngr_t* vm_mngr, uint64_t my_size, uint64_t addr);
+void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size);
+void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size);
+void check_invalid_code_blocs(vm_mngr_t* vm_mngr);
+void check_memory_breakpoint(vm_mngr_t* vm_mngr);
+void reset_memory_access(vm_mngr_t* vm_mngr);
+PyObject* get_memory_read(vm_mngr_t* vm_mngr);
+PyObject* get_memory_write(vm_mngr_t* vm_mngr);
 
 
 char* dump(vm_mngr_t* vm_mngr);
diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c
index 215517ee..5aece270 100644
--- a/miasm2/jitter/vm_mngr_py.c
+++ b/miasm2/jitter/vm_mngr_py.c
@@ -186,7 +186,8 @@ PyObject* vm_set_mem(VmMngr* self, PyObject* args)
        if (ret < 0)
 	      RAISE(PyExc_TypeError, "Error in set_mem");
 
-       check_write_code_bloc(&self->vm_mngr, size*8, addr);
+       add_mem_write(&self->vm_mngr, addr, size);
+       check_invalid_code_blocs(&self->vm_mngr);
 
        Py_INCREF(Py_None);
        return Py_None;
@@ -320,6 +321,63 @@ PyObject* vm_reset_memory_breakpoint(VmMngr* self, PyObject* args)
 
 }
 
+PyObject* vm_reset_memory_access(VmMngr* self, PyObject* args)
+{
+    reset_memory_access(&self->vm_mngr);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyObject* py_add_mem_read(VmMngr* self, PyObject* args)
+{
+	PyObject *py_addr;
+	PyObject *py_size;
+	uint64_t addr;
+	uint64_t size;
+
+	if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_size))
+		return NULL;
+
+	PyGetInt(py_addr, addr);
+	PyGetInt(py_size, size);
+	add_mem_read(&self->vm_mngr, addr, size);
+	Py_INCREF(Py_None);
+	return Py_None;
+
+}
+
+PyObject* py_add_mem_write(VmMngr* self, PyObject* args)
+{
+	PyObject *py_addr;
+	PyObject *py_size;
+	uint64_t addr;
+	uint64_t size;
+
+	if (!PyArg_ParseTuple(args, "OO", &py_addr, &py_size))
+		return NULL;
+
+	PyGetInt(py_addr, addr);
+	PyGetInt(py_size, size);
+	add_mem_write(&self->vm_mngr, addr, size);
+	Py_INCREF(Py_None);
+	return Py_None;
+
+}
+
+PyObject* vm_check_invalid_code_blocs(VmMngr* self, PyObject* args)
+{
+    check_invalid_code_blocs(&self->vm_mngr);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+PyObject* vm_check_memory_breakpoint(VmMngr* self, PyObject* args)
+{
+    check_memory_breakpoint(&self->vm_mngr);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 PyObject *vm_dump(PyObject* self)
 {
 	char* buf_final;
@@ -460,6 +518,23 @@ PyObject* vm_is_mapped(VmMngr* self, PyObject* args)
 	return PyLong_FromUnsignedLongLong((uint64_t)ret);
 }
 
+PyObject* vm_get_memory_read(VmMngr* self, PyObject* args)
+{
+	PyObject* result;
+	result = get_memory_read(&self->vm_mngr);
+	Py_INCREF(result);
+	return result;
+}
+
+PyObject* vm_get_memory_write(VmMngr* self, PyObject* args)
+{
+	PyObject* result;
+	result = get_memory_write(&self->vm_mngr);
+	Py_INCREF(result);
+	return result;
+}
+
+
 
 static PyObject *
 vm_set_big_endian(VmMngr *self, PyObject *value, void *closure)
@@ -557,11 +632,24 @@ static PyMethodDef VmMngr_methods[] = {
 	 "X"},
 	{"get_exception",(PyCFunction)vm_get_exception, METH_VARARGS,
 	 "X"},
-
 	{"set_big_endian",(PyCFunction)vm_set_big_endian, METH_VARARGS,
 	 "X"},
 	{"set_little_endian",(PyCFunction)vm_set_little_endian, METH_VARARGS,
 	 "X"},
+	{"get_memory_read",(PyCFunction)vm_get_memory_read, METH_VARARGS,
+	 "X"},
+	{"get_memory_write",(PyCFunction)vm_get_memory_write, METH_VARARGS,
+	 "X"},
+	{"reset_memory_access",(PyCFunction)vm_reset_memory_access, METH_VARARGS,
+	 "X"},
+	{"add_mem_read",(PyCFunction)py_add_mem_read, METH_VARARGS,
+	 "X"},
+	{"add_mem_write",(PyCFunction)py_add_mem_write, METH_VARARGS,
+	 "X"},
+	{"check_invalid_code_blocs",(PyCFunction)vm_check_invalid_code_blocs, METH_VARARGS,
+	 "X"},
+	{"check_memory_breakpoint",(PyCFunction)vm_check_memory_breakpoint, METH_VARARGS,
+	 "X"},
 
 	{NULL}  /* Sentinel */
 };
diff --git a/miasm2/os_dep/win_32_structs.py b/miasm2/os_dep/win_32_structs.py
new file mode 100644
index 00000000..993fc79c
--- /dev/null
+++ b/miasm2/os_dep/win_32_structs.py
@@ -0,0 +1,198 @@
+from miasm2.core.types import MemStruct, Num, Ptr, Str, \
+    Array, RawStruct, Union, \
+    BitField, Self, Void, Bits, \
+    set_allocator, MemUnion, Struct
+
+
+class UnicodeString(MemStruct):
+    fields = [
+        ("length", Num("H")),
+        ("maxlength", Num("H")),
+        ("data", Ptr("<I", Str("utf16"))),
+    ]
+
+
+class ListEntry(MemStruct):
+    fields = [
+        ("flink", Ptr("<I", Void())),
+        ("blink", Ptr("<I", Void())),
+    ]
+
+
+class LdrDataEntry(MemStruct):
+
+    """
+    +0x000 InLoadOrderLinks : _LIST_ENTRY
+    +0x008 InMemoryOrderLinks : _LIST_ENTRY
+    +0x010 InInitializationOrderLinks : _LIST_ENTRY
+    +0x018 DllBase : Ptr32 Void
+    +0x01c EntryPoint : Ptr32 Void
+    +0x020 SizeOfImage : Uint4B
+    +0x024 FullDllName : _UNICODE_STRING
+    +0x02c BaseDllName : _UNICODE_STRING
+    +0x034 Flags : Uint4B
+    +0x038 LoadCount : Uint2B
+    +0x03a TlsIndex : Uint2B
+    +0x03c HashLinks : _LIST_ENTRY
+    +0x03c SectionPointer : Ptr32 Void
+    +0x040 CheckSum : Uint4B
+    +0x044 TimeDateStamp : Uint4B
+    +0x044 LoadedImports : Ptr32 Void
+    +0x048 EntryPointActivationContext : Ptr32 Void
+    +0x04c PatchInformation : Ptr32 Void
+    """
+
+    fields = [
+        ("InLoadOrderLinks", ListEntry),
+        ("InMemoryOrderLinks", ListEntry),
+        ("InInitializationOrderLinks", ListEntry),
+        ("DllBase", Ptr("<I", Void())),
+        ("EntryPoint", Ptr("<I", Void())),
+        ("SizeOfImage", Num("<I")),
+        ("FullDllName", UnicodeString),
+        ("BaseDllName", UnicodeString),
+        ("Flags", Array(Num("B"), 4)),
+        ("LoadCount", Num("H")),
+        ("TlsIndex", Num("H")),
+        ("union1", Union([
+            ("HashLinks", Ptr("<I", Void())),
+            ("SectionPointer", Ptr("<I", Void())),
+        ])),
+        ("CheckSum", Num("<I")),
+        ("union2", Union([
+            ("TimeDateStamp", Num("<I")),
+            ("LoadedImports", Ptr("<I", Void())),
+        ])),
+        ("EntryPointActivationContext", Ptr("<I", Void())),
+        ("PatchInformation", Ptr("<I", Void())),
+
+    ]
+
+
+class PEB_LDR_DATA(MemStruct):
+
+    """
+    +0x000 Length                          : Uint4B
+    +0x004 Initialized                     : UChar
+    +0x008 SsHandle                        : Ptr32 Void
+    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
+    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
+    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
+    """
+
+    fields = [
+        ("Length", Num("<I")),
+        ("Initialized", Num("<I")),
+        ("SsHandle", Ptr("<I", Void())),
+        ("InLoadOrderModuleList", ListEntry),
+        ("InMemoryOrderModuleList", ListEntry),
+        ("InInitializationOrderModuleList", ListEntry)
+    ]
+
+
+class PEB(MemStruct):
+
+    """
+    +0x000 InheritedAddressSpace    : UChar
+    +0x001 ReadImageFileExecOptions : UChar
+    +0x002 BeingDebugged            : UChar
+    +0x003 SpareBool                : UChar
+    +0x004 Mutant                   : Ptr32 Void
+    +0x008 ImageBaseAddress         : Ptr32 Void
+    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
+    +0x010 processparameter
+    """
+
+    fields = [
+        ("InheritedAddressSpace", Num("B")),
+        ("ReadImageFileExecOptions", Num("B")),
+        ("BeingDebugged", Num("B")),
+        ("SpareBool", Num("B")),
+        ("Mutant", Ptr("<I", Void())),
+        ("ImageBaseAddress", Num("<I")),
+        ("Ldr", Ptr("<I", PEB_LDR_DATA)),
+    ]
+
+
+class NT_TIB(MemStruct):
+
+    """
+    +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList
+    +04 void *StackBase
+    +08 void *StackLimit
+    +0c void *SubSystemTib
+    +10 void *FiberData
+    +10 uint32 Version
+    +14 void *ArbitraryUserPointer
+    +18 struct _NT_TIB *Self
+    """
+
+    fields = [
+        ("ExceptionList", Ptr("<I", Void())),
+        ("StackBase", Ptr("<I", Void())),
+        ("StackLimit", Ptr("<I", Void())),
+        ("SubSystemTib", Ptr("<I", Void())),
+        (None, Union([
+            ("FiberData", Ptr("<I", Void())),
+            ("Version", Num("<I"))
+        ])),
+        ("ArbitraryUserPointer", Ptr("<I", Void())),
+        ("Self", Ptr("<I", Self())),
+    ]
+
+
+class TEB(MemStruct):
+
+    """
+    +0x000 NtTib                     : _NT_TIB
+    +0x01c EnvironmentPointer        : Ptr32 Void
+    +0x020 ClientId                  : _CLIENT_ID
+    +0x028 ActiveRpcHandle           : Ptr32 Void
+    +0x02c ThreadLocalStoragePointer : Ptr32 Void
+    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
+    +0x034 LastErrorValue            : Uint4B
+    ...
+    """
+
+    fields = [
+        ("NtTib", NT_TIB),
+        ("EnvironmentPointer", Ptr("<I", Void())),
+        ("ClientId", Array(Num("B"), 0x8)),
+        ("ActiveRpcHandle", Ptr("<I", Void())),
+        ("ThreadLocalStoragePointer", Ptr("<I", Void())),
+        ("ProcessEnvironmentBlock", Ptr("<I", PEB)),
+        ("LastErrorValue", Num("<I")),
+    ]
+
+
+class ContextException(MemStruct):
+    fields = [
+        ("ContectFlags", Num("<I")),
+        ("dr0", Num("<I")),
+        ("dr1", Num("<I")),
+        ("dr2", Num("<I")),
+        ("dr3", Num("<I")),
+        ("dr4", Num("<I")),
+        ("dr5", Num("<I")),
+
+        ("Float", Array(Num("B"), 112)),
+
+        ("gs", Num("<I")),
+        ("fs", Num("<I")),
+        ("es", Num("<I")),
+        ("ds", Num("<I")),
+
+        ("edi", Num("<I")),
+        ("esi", Num("<I")),
+        ("ebx", Num("<I")),
+        ("edx", Num("<I")),
+        ("ecx", Num("<I")),
+        ("eax", Num("<I")),
+        ("ebp", Num("<I")),
+        ("eip", Num("<I")),
+
+        ("cs", Num("<I")),
+        ("eflags", Num("<I")),
+        ("esp", Num("<I")),
+        ("ss", Num("<I")),
+    ]
diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py
index a6041b15..029af8b5 100644
--- a/miasm2/os_dep/win_api_x86_32.py
+++ b/miasm2/os_dep/win_api_x86_32.py
@@ -383,10 +383,10 @@ def user32_FindWindowA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pclassname", "pwindowname"])
     if args.pclassname:
         classname = jitter.get_str_ansi(args.pclassname)
-        log.info("classname %s", classname)
+        log.info("FindWindowA classname %s", classname)
     if args.pwindowname:
         windowname = jitter.get_str_ansi(args.pwindowname)
-        log.info("windowname %s", windowname)
+        log.info("FindWindowA windowname %s", windowname)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -526,7 +526,7 @@ def kernel32_CreateFile(jitter, funcname, get_str):
         return
 
     fname = get_str(jitter, args.lpfilename)
-    log.debug('fname %s', fname)
+    log.info('CreateFile fname %s', fname)
     ret = 0xffffffff
 
     log.debug("%r %r", fname.lower(), winobjs.module_path.lower())
@@ -617,7 +617,7 @@ def kernel32_CreateFile(jitter, funcname, get_str):
 
         # h = open(sb_fname, 'rb+')
         # ret = winobjs.handle_pool.add(sb_fname, h)
-    log.debug('ret %x', ret)
+    log.debug('CreateFile ret %x', ret)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -752,7 +752,7 @@ def kernel32_VirtualAlloc(jitter):
                 alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize,
                 "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
 
-    log.debug('Memory addr: %x', alloc_addr)
+    log.info('VirtualAlloc addr: 0x%x', alloc_addr)
     jitter.func_ret_stdcall(ret_ad, alloc_addr)
 
 
@@ -814,7 +814,7 @@ def kernel32_CreateMutex(jitter, funcname, get_str):
 
     if args.lpname:
         name = get_str(jitter, args.lpname)
-        log.debug(name)
+        log.info("CreateMutex %r", name)
     else:
         name = None
     if args.initowner:
@@ -890,10 +890,8 @@ def kernel32_LoadLibraryA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["dllname"])
 
     libname = get_str_ansi(jitter, args.dllname, 0x100)
-    log.info(libname)
-
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("ret %x", ret)
+    log.info("Loading %r ret 0x%x", libname, ret)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -903,10 +901,8 @@ def kernel32_LoadLibraryExA(jitter):
     if args.hfile != 0:
         raise NotImplementedError("Untested case")
     libname = get_str_ansi(jitter, args.dllname, 0x100)
-    log.info(libname)
-
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("ret %x", ret)
+    log.info("Loading %r ret 0x%x", libname, ret)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -919,12 +915,11 @@ def kernel32_GetProcAddress(jitter):
         fname = get_str_ansi(jitter, fname, 0x100)
         if not fname:
             fname = None
-    log.info(fname)
     if fname is not None:
         ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
     else:
         ad = 0
-    ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
+    log.info("GetProcAddress %r %r ret 0x%x", args.libbase, fname, ad)
     jitter.add_breakpoint(ad, jitter.handle_lib)
     jitter.func_ret_stdcall(ret_ad, ad)
 
@@ -933,10 +928,8 @@ def kernel32_LoadLibraryW(jitter):
     ret_ad, args = jitter.func_args_stdcall(["dllname"])
 
     libname = get_str_unic(jitter, args.dllname, 0x100)
-    log.info(libname)
-
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("ret %x", ret)
+    log.info("Loading %r ret 0x%x", libname, ret)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -945,15 +938,15 @@ def kernel32_GetModuleHandle(jitter, funcname, get_str):
 
     if args.dllname:
         libname = get_str(jitter, args.dllname)
-        log.info(libname)
         if libname:
             ret = winobjs.runtime_dll.lib_get_add_base(libname)
         else:
             log.warning('unknown module!')
             ret = 0
+        log.info("GetModuleHandle %r ret 0x%x", libname, ret)
     else:
         ret = winobjs.current_pe.NThdr.ImageBase
-        log.debug("default img base %x", ret)
+        log.info("GetModuleHandle default ret 0x%x", ret)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -1030,7 +1023,7 @@ def kernel32_GetCommandLineW(jitter):
 def shell32_CommandLineToArgvW(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"])
     cmd = get_str_unic(jitter, args.pcmd)
-    log.debug(cmd)
+    log.info("CommandLineToArgv %r", cmd)
     tks = cmd.split(' ')
     addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks))
     addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1))
@@ -1525,7 +1518,7 @@ def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
     s = get_str(jitter, args.lpname)
     if get_str == get_str_unic:
         s = s
-    log.debug('variable %r', s)
+    log.info('GetEnvironmentVariable %r', s)
     if s in winobjs.env_variables:
         v = set_str(winobjs.env_variables[s])
     else:
@@ -2018,9 +2011,9 @@ def advapi32_RegSetValue(jitter, funcname, get_str):
                                              "valuetype", "pvalue",
                                              "vlen"])
     if args.psubkey:
-        log.debug("Subkey %s", get_str(jitter, args.psubkey))
+        log.info("Subkey %s", get_str(jitter, args.psubkey))
     if args.pvalue:
-        log.debug("Value %s", get_str(jitter, args.pvalue))
+        log.info("Value %s", get_str(jitter, args.pvalue))
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -2224,7 +2217,7 @@ def kernel32_MapViewOfFile(jitter):
     data = fd.read(args.length) if args.length else fd.read()
     length = len(data)
 
-    log.debug('mapp total: %x', len(data))
+    log.debug('MapViewOfFile len: %x', len(data))
     access_dict = {
         0x0: 0,
         0x1: 0,
@@ -2271,6 +2264,8 @@ def kernel32_GetDriveType(jitter, funcname, get_str):
     p = get_str(jitter, args.pathname)
     p = p.upper()
 
+    log.debug('Drive: %r', p)
+
     ret = 0
     if p[0] == "C":
         ret = 3
@@ -2375,10 +2370,10 @@ def kernel32_SetFilePointer(jitter):
 
     # data = None
     if args.hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance)
+        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance, args.movemethod)
     elif args.hwnd in winobjs.handle_pool:
         wh = winobjs.handle_pool[args.hwnd]
-        data = wh.info.seek(args.distance)
+        wh.info.seek(args.distance, args.movemethod)
     else:
         raise ValueError('unknown filename')
     jitter.func_ret_stdcall(ret_ad, args.distance)
@@ -2403,10 +2398,10 @@ def kernel32_SetFilePointerEx(jitter):
 
     # data = None
     if args.hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance)
+        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance, args.movemethod)
     elif args.hwnd in winobjs.handle_pool:
         wh = winobjs.handle_pool[args.hwnd]
-        # data = wh.info.seek(distance)
+        wh.info.seek(distance, args.movemethod)
     else:
         raise ValueError('unknown filename')
     jitter.func_ret_stdcall(ret_ad, 1)
@@ -2733,8 +2728,7 @@ def msvcrt_myfopen(jitter, func):
 
     fname = func(jitter, args.pfname)
     rw = func(jitter, args.pmode)
-    log.debug(fname)
-    log.debug(rw)
+    log.info("fopen %r, %r", fname, rw)
 
     if rw in ['r', 'rb', 'wb+']:
         sb_fname = windows_to_sbpath(fname)
diff --git a/miasm2/os_dep/win_api_x86_32_seh.py b/miasm2/os_dep/win_api_x86_32_seh.py
index 6bf491bf..da8df7d7 100644
--- a/miasm2/os_dep/win_api_x86_32_seh.py
+++ b/miasm2/os_dep/win_api_x86_32_seh.py
@@ -28,6 +28,8 @@ from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm2.core.utils import pck32, upck32
 import miasm2.arch.x86.regs as x86_regs
 
+from miasm2.os_dep.win_32_structs import LdrDataEntry, ListEntry, \
+    TEB, NT_TIB, PEB, PEB_LDR_DATA, ContextException
 
 # Constants Windows
 EXCEPTION_BREAKPOINT = 0x80000003
@@ -46,6 +48,7 @@ log.setLevel(logging.INFO)
 FS_0_AD = 0x7ff70000
 PEB_AD = 0x7ffdf000
 LDR_AD = 0x340000
+DEFAULT_SEH = 0x7ffff000
 
 MAX_MODULES = 0x40
 
@@ -67,7 +70,6 @@ InLoadOrderModuleList_offset = 0x1ee0 + \
 InLoadOrderModuleList_address = LDR_AD + \
     InLoadOrderModuleList_offset
 
-default_seh = PEB_AD + 0x20000
 
 process_environment_address = 0x10000
 process_parameters_address = 0x200000
@@ -86,56 +88,50 @@ def build_teb(jitter, teb_address):
     """
     Build TEB informations using following structure:
 
-    +0x000 NtTib                     : _NT_TIB
-    +0x01c EnvironmentPointer        : Ptr32 Void
-    +0x020 ClientId                  : _CLIENT_ID
-    +0x028 ActiveRpcHandle           : Ptr32 Void
-    +0x02c ThreadLocalStoragePointer : Ptr32 Void
-    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
-    +0x034 LastErrorValue            : Uint4B
-    ...
     @jitter: jitter instance
     @teb_address: the TEB address
     """
 
-    o = ""
-    o += pck32(default_seh)
-    o += (0x18 - len(o)) * "\x00"
-    o += pck32(tib_address)
-
-    o += (0x30 - len(o)) * "\x00"
-    o += pck32(peb_address)
-    o += pck32(0x11223344)
-
-    jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE, o, "TEB")
-
+    # Only allocate space for ExceptionList/ProcessEnvironmentBlock/Self
+    jitter.vm.add_memory_page(teb_address, PAGE_READ | PAGE_WRITE,
+                              "\x00" * NT_TIB.get_offset("StackBase"),
+                              "TEB.NtTib.ExceptionList")
+    jitter.vm.add_memory_page(teb_address + NT_TIB.get_offset("Self"),
+                              PAGE_READ | PAGE_WRITE,
+                              "\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")),
+                              "TEB.NtTib.Self")
+    jitter.vm.add_memory_page(teb_address + TEB.get_offset("ProcessEnvironmentBlock"),
+                              PAGE_READ | PAGE_WRITE,
+                              "\x00" * (TEB.get_offset("LastErrorValue") -
+                                        TEB.get_offset("ProcessEnvironmentBlock")),
+                              "TEB.ProcessEnvironmentBlock")
+    Teb = TEB(jitter.vm, teb_address)
+    Teb.NtTib.ExceptionList = DEFAULT_SEH
+    Teb.NtTib.Self = teb_address
+    Teb.ProcessEnvironmentBlock = peb_address
 
 def build_peb(jitter, peb_address):
     """
     Build PEB informations using following structure:
 
-    +0x000 InheritedAddressSpace    : UChar
-    +0x001 ReadImageFileExecOptions : UChar
-    +0x002 BeingDebugged            : UChar
-    +0x003 SpareBool                : UChar
-    +0x004 Mutant                   : Ptr32 Void
-    +0x008 ImageBaseAddress         : Ptr32 Void
-    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
-    +0x010 processparameter
-
     @jitter: jitter instance
     @peb_address: the PEB address
     """
 
-    offset = peb_address + 8
-    o = ""
     if main_pe:
-        o += pck32(main_pe.NThdr.ImageBase)
+        offset, length = peb_address + 8, 4
     else:
-        offset += 4
-    o += pck32(peb_ldr_data_address)
-    o += pck32(process_parameters_address)
-    jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, o, "PEB")
+        offset, length = peb_address + 0xC, 0
+    length += 4
+
+    jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE,
+                              "\x00" * length,
+                              "PEB")
+
+    Peb = PEB(jitter.vm, peb_address)
+    if main_pe:
+        Peb.ImageBaseAddress = main_pe.NThdr.ImageBase
+    Peb.Ldr = peb_ldr_data_address
 
 
 def build_ldr_data(jitter, modules_info):
@@ -156,8 +152,42 @@ def build_ldr_data(jitter, modules_info):
 
     """
     # ldr offset pad
-    offset = peb_ldr_data_address + 0xC
+    offset = 0xC
+    addr = LDR_AD + peb_ldr_data_offset
+    ldrdata = PEB_LDR_DATA(jitter.vm, addr)
+
+    main_pe = modules_info.name2module.get(main_pe_name, None)
+    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
 
+
+    size = 0
+    if main_pe:
+        size += ListEntry.sizeof() * 2
+        main_addr_entry = modules_info.module2entry[main_pe]
+    if ntdll_pe:
+        size += ListEntry.sizeof()
+        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
+
+    jitter.vm.add_memory_page(addr + offset, PAGE_READ | PAGE_WRITE,
+                              "\x00" * size,
+                              "Loader struct")  # (ldrdata.get_size() - offset))
+
+    if main_pe:
+        ldrdata.InLoadOrderModuleList.flink = main_addr_entry
+        ldrdata.InLoadOrderModuleList.blink = 0
+
+        ldrdata.InMemoryOrderModuleList.flink = main_addr_entry + \
+            LdrDataEntry.get_type().get_offset("InMemoryOrderLinks")
+        ldrdata.InMemoryOrderModuleList.blink = 0
+
+    if ntdll_pe:
+        ldrdata.InInitializationOrderModuleList.flink = ntdll_addr_entry + \
+            LdrDataEntry.get_type().get_offset("InInitializationOrderLinks")
+        ldrdata.InInitializationOrderModuleList.blink = 0
+
+    # data += pck32(ntdll_addr_entry + 0x10) + pck32(0)  # XXX TODO fix blink
+
+    """
     # get main pe info
     main_pe = modules_info.name2module.get(main_pe_name, None)
     if not main_pe:
@@ -167,18 +197,20 @@ def build_ldr_data(jitter, modules_info):
         main_addr_entry = modules_info.module2entry[main_pe]
         log.info('Ldr %x', main_addr_entry)
         data = pck32(main_addr_entry) + pck32(0)
-        data += pck32(main_addr_entry + 0x8) + pck32(0)  # XXX TODO fix prev
+        data += pck32(main_addr_entry + 0x8) + pck32(0)  # XXX TODO fix blink
 
     ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
     if not ntdll_pe:
         log.warn('No ntdll, ldr data will be unconsistant')
     else:
         ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
-        data += pck32(ntdll_addr_entry + 0x10) + pck32(0)  # XXX TODO fix prev
+        data += pck32(ntdll_addr_entry + 0x10) + pck32(0)  # XXX TODO fix blink
 
     if data:
-        jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE, data,
+        jitter.vm.add_memory_page(offset, PAGE_READ | PAGE_WRITE,
+                                  data,
                                   "Loader struct")
+    """
 
     # Add dummy dll base
     jitter.vm.add_memory_page(peb_ldr_data_address + 0x24,
@@ -216,26 +248,6 @@ def create_modules_chain(jitter, name2module):
     """
     Create the modules entries. Those modules are not linked in this function.
 
-    kd> dt nt!_LDR_DATA_TABLE_ENTRY
-    +0x000 InLoadOrderLinks : _LIST_ENTRY
-    +0x008 InMemoryOrderLinks : _LIST_ENTRY
-    +0x010 InInitializationOrderLinks : _LIST_ENTRY
-    +0x018 DllBase : Ptr32 Void
-    +0x01c EntryPoint : Ptr32 Void
-    +0x020 SizeOfImage : Uint4B
-    +0x024 FullDllName : _UNICODE_STRING
-    +0x02c BaseDllName : _UNICODE_STRING
-    +0x034 Flags : Uint4B
-    +0x038 LoadCount : Uint2B
-    +0x03a TlsIndex : Uint2B
-    +0x03c HashLinks : _LIST_ENTRY
-    +0x03c SectionPointer : Ptr32 Void
-    +0x040 CheckSum : Uint4B
-    +0x044 TimeDateStamp : Uint4B
-    +0x044 LoadedImports : Ptr32 Void
-    +0x048 EntryPointActivationContext : Ptr32 Void
-    +0x04c PatchInformation : Ptr32 Void
-
     @jitter: jitter instance
     @name2module: dict containing association between name and its pe instance
     """
@@ -259,36 +271,30 @@ def create_modules_chain(jitter, name2module):
 
         modules_info.add(bname_str, pe_obj, addr)
 
-        m_o = ""
-        m_o += pck32(0)
-        m_o += pck32(0)
-        m_o += pck32(0)
-        m_o += pck32(0)
-        m_o += pck32(0)
-        m_o += pck32(0)
-        m_o += pck32(pe_obj.NThdr.ImageBase)
-        m_o += pck32(pe_obj.rva2virt(pe_obj.Opthdr.AddressOfEntryPoint))
-        m_o += pck32(pe_obj.NThdr.sizeofimage)
-        m_o += struct.pack('HH', len(bname), len(bname) + 2)
-        m_o += pck32(addr + offset_path)
-        m_o += struct.pack('HH', len(bname), len(bname) + 2)
-        m_o += pck32(addr + offset_name)
-        jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, m_o,
+        # Allocate a partial LdrDataEntry (0-Flags)
+        jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE,
+                                  "\x00" * LdrDataEntry.get_offset("Flags"),
                                   "Module info %r" % bname_str)
 
-        m_o = ""
-        m_o += bname
-        m_o += "\x00" * 3
-        jitter.vm.add_memory_page(
-            addr + offset_name, PAGE_READ | PAGE_WRITE, m_o,
-            "Module name %r" % bname_str)
+        LdrEntry = LdrDataEntry(jitter.vm, addr)
 
-        m_o = ""
-        m_o += "\x00".join(bpath) + "\x00"
-        m_o += "\x00" * 3
-        jitter.vm.add_memory_page(
-            addr + offset_path, PAGE_READ | PAGE_WRITE, m_o,
-            "Module path %r" % bname_str)
+        LdrEntry.DllBase = pe_obj.NThdr.ImageBase
+        LdrEntry.EntryPoint = pe_obj.Opthdr.AddressOfEntryPoint
+        LdrEntry.SizeOfImage = pe_obj.NThdr.sizeofimage
+        LdrEntry.FullDllName.length = len(bname)
+        LdrEntry.FullDllName.maxlength = len(bname) + 2
+        LdrEntry.FullDllName.data = addr + offset_path
+        LdrEntry.BaseDllName.length = len(bname)
+        LdrEntry.BaseDllName.maxlength = len(bname) + 2
+        LdrEntry.BaseDllName.data = addr + offset_name
+
+        jitter.vm.add_memory_page(addr + offset_name, PAGE_READ | PAGE_WRITE,
+                                  bname + "\x00" * 3,
+                                  "Module name %r" % bname_str)
+
+        jitter.vm.add_memory_page(addr + offset_path, PAGE_READ | PAGE_WRITE,
+                                  "\x00".join(bpath) + "\x00" + "\x00" * 3,
+                                  "Module path %r" % bname_str)
 
     return modules_info
 
@@ -443,100 +449,94 @@ def init_seh(jitter):
     add_process_env(jitter)
     add_process_parameters(jitter)
 
-    jitter.vm.add_memory_page(default_seh, PAGE_READ | PAGE_WRITE, pck32(
-        0xffffffff) + pck32(0x41414141) + pck32(0x42424242),
-        "Default seh handler")
-
-
-# http://www.codeproject.com/KB/system/inject2exe.aspx#RestorethefirstRegistersContext5_1
 
 
-def regs2ctxt(jitter):
+def regs2ctxt(jitter, context_address):
     """
     Build x86_32 cpu context for exception handling
     @jitter: jitload instance
     """
 
-    ctxt = []
+    ctxt = ContextException(jitter.vm, context_address)
+    ctxt.memset("\x00")
     # ContextFlags
-    ctxt += [pck32(0x0)]
+    # XXX
+
     # DRX
-    ctxt += [pck32(0x0)] * 6
+    ctxt.dr0 = 0
+    ctxt.dr1 = 0
+    ctxt.dr2 = 0
+    ctxt.dr3 = 0
+    ctxt.dr4 = 0
+    ctxt.dr5 = 0
+
     # Float context
-    ctxt += ['\x00' * 112]
+    # XXX
+
     # Segment selectors
-    ctxt += [pck32(reg) for reg in (jitter.cpu.GS, jitter.cpu.FS,
-                                    jitter.cpu.ES, jitter.cpu.DS)]
+    ctxt.gs = jitter.cpu.GS
+    ctxt.fs = jitter.cpu.FS
+    ctxt.es = jitter.cpu.ES
+    ctxt.ds = jitter.cpu.DS
+
     # Gpregs
-    ctxt += [pck32(reg) for reg in (jitter.cpu.EDI, jitter.cpu.ESI,
-                                    jitter.cpu.EBX, jitter.cpu.EDX,
-                                    jitter.cpu.ECX, jitter.cpu.EAX,
-                                    jitter.cpu.EBP, jitter.cpu.EIP)]
+    ctxt.edi = jitter.cpu.EDI
+    ctxt.esi = jitter.cpu.ESI
+    ctxt.ebx = jitter.cpu.EBX
+    ctxt.edx = jitter.cpu.EDX
+    ctxt.ecx = jitter.cpu.ECX
+    ctxt.eax = jitter.cpu.EAX
+    ctxt.ebp = jitter.cpu.EBP
+    ctxt.eip = jitter.cpu.EIP
+
     # CS
-    ctxt += [pck32(jitter.cpu.CS)]
+    ctxt.cs = jitter.cpu.CS
+
     # Eflags
     # XXX TODO real eflag
-    ctxt += [pck32(0x0)]
+
     # ESP
-    ctxt += [pck32(jitter.cpu.ESP)]
+    ctxt.esp = jitter.cpu.ESP
+
     # SS
-    ctxt += [pck32(jitter.cpu.SS)]
-    return "".join(ctxt)
+    ctxt.ss = jitter.cpu.SS
 
 
-def ctxt2regs(ctxt, jitter):
+def ctxt2regs(jitter, ctxt_ptr):
     """
     Restore x86_32 registers from an exception context
     @ctxt: the serialized context
     @jitter: jitload instance
     """
 
-    ctxt = ctxt[:]
-    # ContextFlags
-    ctxt = ctxt[4:]
-    # DRX XXX TODO
-    ctxt = ctxt[4 * 6:]
-    # Float context XXX TODO
-    ctxt = ctxt[112:]
-    # gs
-    jitter.cpu.GS = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    # fs
-    jitter.cpu.FS = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    # es
-    jitter.cpu.ES = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    # ds
-    jitter.cpu.DS = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
+    ctxt = ContextException(jitter.vm, ctxt_ptr)
+
+    # Selectors
+    jitter.cpu.GS = ctxt.gs
+    jitter.cpu.FS = ctxt.fs
+    jitter.cpu.ES = ctxt.es
+    jitter.cpu.DS = ctxt.ds
 
     # Gpregs
-    jitter.cpu.EDI = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.ESI = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.EBX = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.EDX = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.ECX = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.EAX = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.EBP = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    jitter.cpu.EIP = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
+    jitter.cpu.EDI = ctxt.edi
+    jitter.cpu.ESI = ctxt.esi
+    jitter.cpu.EBX = ctxt.ebx
+    jitter.cpu.EDX = ctxt.edx
+    jitter.cpu.ECX = ctxt.ecx
+    jitter.cpu.EAX = ctxt.eax
+    jitter.cpu.EBP = ctxt.ebp
+    jitter.cpu.EIP = ctxt.eip
 
     # CS
-    jitter.cpu.CS = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
-    # Eflag XXX TODO
-    ctxt = ctxt[4:]
+    jitter.cpu.CS = ctxt.cs
+
+    # Eflag
+    # XXX TODO
+
     # ESP
-    jitter.cpu.ESP = upck32(ctxt[:4])
-    ctxt = ctxt[4:]
+    jitter.cpu.ESP = ctxt.esp
+    # SS
+    jitter.cpu.SS = ctxt.ss
 
 
 def fake_seh_handler(jitter, except_code):
@@ -551,11 +551,15 @@ def fake_seh_handler(jitter, except_code):
     log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count)
     seh_count += 1
 
-    # Help lambda
-    p = lambda s: struct.pack('I', s)
+    # Get space on stack for exception handling
+    new_ESP = jitter.cpu.ESP - 0x3c8
+    exception_base_address = new_ESP
+    exception_record_address = exception_base_address + 0xe8
+    context_address = exception_base_address + 0xfc
+    fake_seh_address = exception_base_address + 0x14
 
-    # Forge a CONTEXT
-    ctxt = regs2ctxt(jitter)
+    # Save a CONTEXT
+    regs2ctxt(jitter, context_address)
 
     # Get current seh (fs:[0])
     seh_ptr = upck32(jitter.vm.get_mem(tib_address, 4))
@@ -564,19 +568,10 @@ def fake_seh_handler(jitter, except_code):
     old_seh, eh, safe_place = struct.unpack(
         'III', jitter.vm.get_mem(seh_ptr, 0xc))
 
-    # Get space on stack for exception handling
-    jitter.cpu.ESP -= 0x3c8
-    exception_base_address = jitter.cpu.ESP
-    exception_record_address = exception_base_address + 0xe8
-    context_address = exception_base_address + 0xfc
-    fake_seh_address = exception_base_address + 0x14
-
     log.info('seh_ptr %x { old_seh %x eh %x safe_place %x} ctx_addr %x',
              seh_ptr, old_seh, eh, safe_place, context_address)
 
-    # Write context
-    jitter.vm.set_mem(context_address, ctxt)
-
+    jitter.cpu.ESP = new_ESP
     # Write exception_record
 
     """
@@ -634,10 +629,12 @@ def dump_seh(jitter):
         if loop > MAX_SEH:
             log.warn("Too many seh, quit")
             return
+        if not jitter.vm.is_mapped(cur_seh_ptr, 8):
+            break
         prev_seh, eh = struct.unpack('II', jitter.vm.get_mem(cur_seh_ptr, 8))
         log.info('\t' * indent + 'seh_ptr: %x { prev_seh: %x eh %x }',
                  cur_seh_ptr, prev_seh, eh)
-        if prev_seh in [0xFFFFFFFF, 0]:
+        if prev_seh == 0:
             break
         cur_seh_ptr = prev_seh
         indent += 1
@@ -683,8 +680,8 @@ def return_from_seh(jitter):
         log.info('Seh continues Context: %x', ctxt_ptr)
 
         # Get registers changes
-        ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc)
-        ctxt2regs(ctxt_str, jitter)
+        # ctxt_str = jitter.vm.get_mem(ctxt_ptr, 0x2cc)
+        ctxt2regs(jitter, ctxt_ptr)
         jitter.pc = jitter.cpu.EIP
         log.info('Context::Eip: %x', jitter.pc)
 
diff --git a/test/arch/arm/arch.py b/test/arch/arm/arch.py
index 2ffbd3b1..a00fe3d6 100644
--- a/test/arch/arm/arch.py
+++ b/test/arch/arm/arch.py
@@ -245,6 +245,11 @@ reg_tests_arm = [
     ("XXXXXXXX    REV        R0, R2",
      "320FBFE6"),
 
+    ('XXXXXXXX    PLD        [R1]',
+     '00F0D1F5'),
+    ('XXXXXXXX    PLD        [R1, 0x1C]',
+     '1CF0D1F5'),
+
 
 ]
 ts = time.time()
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 9a7f3d8a..80a8563d 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -72,6 +72,8 @@ reg_tests = [
     (m64, "XXXXXXXX    CPUID",
     "0fa2"),
 
+    (m32, "XXXXXXXX    SETALC",
+    "D6"),
 
     (m32, "XXXXXXXX    PMINSW     MM0, QWORD PTR [EAX]",
     "0fea00"),
@@ -2224,6 +2226,9 @@ reg_tests = [
     (m32, "00000000    NOP",
      "90"),
 
+    (m64, "00000000    XCHG       RAX, R8",
+     "4990"),
+
 
     (m32, "00000000    XCHG       BYTE PTR [EAX], AL",
      "8600"),
@@ -2882,6 +2887,9 @@ reg_tests = [
     (m64, "00000000    PEXTRQ     QWORD PTR [RDX], XMM2, 0x5",
     "66480F3A161205"),
 
+    (m64, "00000000    PEXTRW     RCX, XMM14, 0x5",
+    "664C0F3A15F105"),
+
 
     (m32, "00000000    UNPCKHPS   XMM2, XMMWORD PTR [EDX]",
      "0f1512"),
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index acef0904..99cc7c35 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -144,6 +144,8 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
      ExprOp('*', a, b, c, ExprInt32(0x12))),
     (ExprOp('*', -a, -b, -c, ExprInt32(0x12)),
      - ExprOp('*', a, b, c, ExprInt32(0x12))),
+     (ExprOp('**', ExprInt32(2), ExprInt32(8)), ExprInt32(0x100)),
+     (ExprInt32(2)**ExprInt32(8), ExprInt32(256)),
     (a | ExprInt32(0xffffffff),
      ExprInt32(0xffffffff)),
     (ExprCond(a, ExprInt32(1), ExprInt32(2)) * ExprInt32(4),
@@ -349,6 +351,12 @@ to_test = [
     (ExprOp_equal(ExprInt32(12), ExprInt32(-12)), ExprInt1(0)),
     (ExprCond(a - b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, b)),
     (ExprCond(a + b, ExprInt1(0), ExprInt1(1)), ExprOp_equal(a, -b)),
+    (ExprOp_inf_signed(ExprInt32(-2), ExprInt32(3)), ExprInt1(1)),
+    (ExprOp_inf_signed(ExprInt32(3), ExprInt32(-3)), ExprInt1(0)),
+    (ExprOp_inf_signed(ExprInt32(2), ExprInt32(3)), ExprInt1(1)),
+    (ExprOp_inf_signed(ExprInt32(-3), ExprInt32(-2)), ExprInt1(1)),
+    (ExprOp_inf_signed(ExprInt32(0), ExprInt32(2)), ExprInt1(1)),
+    (ExprOp_inf_signed(ExprInt32(-3), ExprInt32(0)), ExprInt1(1)),
 ]
 
 expr_simp_cond = ExpressionSimplifier()
diff --git a/test/test_all.py b/test/test_all.py
index 35f081de..c9401552 100644
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -232,8 +232,7 @@ for script in ["modint.py",
                ]:
     testset += RegressionTest([script], base_dir="expression")
 ## IR
-for script in ["ir2C.py",
-               "symbexec.py",
+for script in ["symbexec.py",
                ]:
     testset += RegressionTest([script], base_dir="ir")
 testset += RegressionTest(["analysis.py"], base_dir="ir",
@@ -399,6 +398,8 @@ test_mips32l = ExampleShellcode(["mips32l", "mips32.S", "mips32_sc_l.bin"])
 test_x86_64 = ExampleShellcode(["x86_64", "x86_64.S", "demo_x86_64.bin",
                                 "--PE"])
 test_x86_32_if_reg = ExampleShellcode(['x86_32', 'x86_32_if_reg.S', "x86_32_if_reg.bin"])
+test_x86_32_seh = ExampleShellcode(["x86_32", "x86_32_seh.S", "x86_32_seh.bin",
+                                    "--PE"])
 
 testset += test_armb
 testset += test_arml
@@ -413,6 +414,7 @@ testset += test_mips32b
 testset += test_mips32l
 testset += test_x86_64
 testset += test_x86_32_if_reg
+testset += test_x86_32_seh
 
 class ExampleDisassembler(Example):
     """Disassembler examples specificities:
@@ -554,6 +556,14 @@ class ExampleJitter(Example):
     jitter_engines = ["tcc", "llvm", "python", "gcc"]
 
 
+class ExampleJitterNoPython(ExampleJitter):
+    """Jitter examples specificities:
+    - script path begins with "jitter/"
+    Run jitting script without python support
+    """
+    jitter_engines = ["tcc", "llvm", "gcc"]
+
+
 for jitter in ExampleJitter.jitter_engines:
     # Take 5 min on a Core i5
     tags = {"python": [TAGS["long"]],
@@ -588,6 +598,13 @@ for script, dep in [(["x86_32.py", Example.get_sample("x86_32_sc.bin")], []),
         testset += ExampleJitter(script + ["--jitter", jitter], depends=dep,
                                  tags=tags)
 
+
+for jitter in ExampleJitterNoPython.jitter_engines:
+    tags = [TAGS[jitter]] if jitter in TAGS else []
+    testset += ExampleJitterNoPython(["test_x86_32_seh.py", Example.get_sample("x86_32_seh.bin")] + ["--jitter", jitter],
+                                     depends=[test_x86_32_seh],
+                                     tags=tags)
+
 testset += ExampleJitter(["example_types.py"])