about summary refs log tree commit diff stats
path: root/miasm2
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2')
-rw-r--r--miasm2/analysis/binary.py1
-rw-r--r--miasm2/analysis/data_analysis.py65
-rw-r--r--miasm2/analysis/debugging.py2
-rw-r--r--miasm2/analysis/disasm_cb.py16
-rw-r--r--miasm2/arch/arm/ira.py3
-rw-r--r--miasm2/arch/arm/jit.py2
-rw-r--r--miasm2/arch/arm/sem.py288
-rw-r--r--miasm2/arch/mips32/ira.py6
-rw-r--r--miasm2/arch/mips32/jit.py4
-rw-r--r--miasm2/arch/mips32/regs.py1
-rw-r--r--miasm2/arch/mips32/sem.py185
-rw-r--r--miasm2/arch/msp430/ira.py3
-rw-r--r--miasm2/arch/msp430/jit.py2
-rw-r--r--miasm2/arch/msp430/sem.py71
-rw-r--r--miasm2/arch/x86/ira.py4
-rw-r--r--miasm2/arch/x86/jit.py50
-rw-r--r--miasm2/arch/x86/sem.py628
-rw-r--r--miasm2/core/asmbloc.py3
-rw-r--r--miasm2/ir/analysis.py3
-rw-r--r--miasm2/ir/ir.py53
-rw-r--r--miasm2/ir/ir2C.py202
-rw-r--r--miasm2/ir/symbexec.py22
-rw-r--r--miasm2/jitter/Jittcc.c26
-rw-r--r--miasm2/jitter/arch/JitCore.c10
-rw-r--r--miasm2/jitter/arch/JitCore.h7
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h3
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.h4
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.h3
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h3
-rw-r--r--miasm2/jitter/jitcore.py18
-rw-r--r--miasm2/jitter/jitcore_llvm.py15
-rw-r--r--miasm2/jitter/jitcore_python.py15
-rw-r--r--miasm2/jitter/jitcore_tcc.py27
-rw-r--r--miasm2/jitter/jitload.py20
-rw-r--r--miasm2/jitter/vm_mngr.h1
35 files changed, 1036 insertions, 730 deletions
diff --git a/miasm2/analysis/binary.py b/miasm2/analysis/binary.py
index b755aae4..c14078e3 100644
--- a/miasm2/analysis/binary.py
+++ b/miasm2/analysis/binary.py
@@ -1,6 +1,7 @@
 from miasm2.core.bin_stream import *
 import logging
 from miasm2.jitter.jitload import vm_load_pe, vm_load_elf
+from miasm2.jitter.csts import PAGE_READ
 
 log = logging.getLogger("binary")
 console_handler = logging.StreamHandler()
diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py
index cb953399..06d28351 100644
--- a/miasm2/analysis/data_analysis.py
+++ b/miasm2/analysis/data_analysis.py
@@ -8,7 +8,7 @@ def get_node_name(label, i, n):
     return n_name
 
 
-def intra_bloc_flow_raw(my_ir, flow_graph, irb):
+def intra_bloc_flow_raw(ir_arch, flow_graph, irb):
     """
     Create data flow for an irbloc using raw IR expressions
     """
@@ -64,7 +64,7 @@ def intra_bloc_flow_raw(my_ir, flow_graph, irb):
     irb.out_nodes = out_nodes
 
 
-def intra_bloc_flow_symbexec(my_ir, flow_graph, irb):
+def intra_bloc_flow_symbexec(ir_arch, flow_graph, irb):
     """
     Create data flow for an irbloc using symbolic execution
     """
@@ -73,13 +73,13 @@ def intra_bloc_flow_symbexec(my_ir, flow_graph, irb):
     current_nodes = {}
 
     symbols_init = {}
-    for r in my_ir.arch.regs.all_regs_ids:
-        # symbols_init[r] = my_ir.arch.regs.all_regs_ids_init[i]
+    for r in ir_arch.arch.regs.all_regs_ids:
+        # symbols_init[r] = ir_arch.arch.regs.all_regs_ids_init[i]
         x = ExprId(r.name, r.size)
         x.is_term = True
         symbols_init[r] = x
 
-    sb = symbexec(my_ir.arch, dict(symbols_init))
+    sb = symbexec(ir_arch, dict(symbols_init))
     sb.emulbloc(irb)
     # print "*"*40
     # print irb
@@ -110,7 +110,7 @@ def intra_bloc_flow_symbexec(my_ir, flow_graph, irb):
     irb.out_nodes = out_nodes
 
 
-def inter_bloc_flow_link(my_ir, flow_graph, todo, link_exec_to_data):
+def inter_bloc_flow_link(ir_arch, flow_graph, todo, link_exec_to_data):
     lbl, current_nodes, exec_nodes = todo
     # print 'TODO'
     # print lbl
@@ -118,10 +118,10 @@ def inter_bloc_flow_link(my_ir, flow_graph, todo, link_exec_to_data):
     current_nodes = dict(current_nodes)
 
     # link current nodes to bloc in_nodes
-    if not lbl in my_ir.blocs:
+    if not lbl in ir_arch.blocs:
         print "cannot find bloc!!", lbl
         return set()
-    irb = my_ir.blocs[lbl]
+    irb = ir_arch.blocs[lbl]
     # pp(('IN', lbl, [(str(x[0]), str(x[1])) for x in current_nodes.items()]))
     to_del = set()
     for n_r, node_n_r in irb.in_nodes.items():
@@ -149,7 +149,7 @@ def inter_bloc_flow_link(my_ir, flow_graph, todo, link_exec_to_data):
     x_nodes = tuple(sorted(list(irb.dst.get_r())))
 
     todo = set()
-    for lbl_dst in my_ir.g.successors(irb.label):
+    for lbl_dst in ir_arch.g.successors(irb.label):
         todo.add((lbl_dst, tuple(current_nodes.items()), x_nodes))
 
     # pp(('OUT', lbl, [(str(x[0]), str(x[1])) for x in current_nodes.items()]))
@@ -157,19 +157,19 @@ def inter_bloc_flow_link(my_ir, flow_graph, todo, link_exec_to_data):
     return todo
 
 
-def create_implicit_flow(my_ir, flow_graph):
+def create_implicit_flow(ir_arch, flow_graph):
 
     # first fix IN/OUT
     # If a son read a node which in not in OUT, add it
-    todo = set(my_ir.blocs.keys())
+    todo = set(ir_arch.blocs.keys())
     while todo:
         lbl = todo.pop()
-        irb = my_ir.blocs[lbl]
-        for lbl_son in my_ir.g.successors(irb.label):
-            if not lbl_son in my_ir.blocs:
+        irb = ir_arch.blocs[lbl]
+        for lbl_son in ir_arch.g.successors(irb.label):
+            if not lbl_son in ir_arch.blocs:
                 print "cannot find bloc!!", lbl
                 continue
-            irb_son = my_ir.blocs[lbl_son]
+            irb_son = ir_arch.blocs[lbl_son]
             for n_r in irb_son.in_nodes:
                 if n_r in irb.out_nodes:
                     continue
@@ -188,13 +188,13 @@ def create_implicit_flow(my_ir, flow_graph):
                     irb.in_nodes[n_r] = irb.label, 0, n_r
                 node_n_r = irb.in_nodes[n_r]
                 # print "###", node_n_r
-                for lbl_p in my_ir.g.predecessors(irb.label):
+                for lbl_p in ir_arch.g.predecessors(irb.label):
                     todo.add(lbl_p)
 
                 flow_graph.add_uniq_edge(node_n_r, node_n_w)
 
 
-def inter_bloc_flow(my_ir, flow_graph, irb_0, link_exec_to_data=True):
+def inter_bloc_flow(ir_arch, flow_graph, irb_0, link_exec_to_data=True):
 
     todo = set()
     done = set()
@@ -205,7 +205,7 @@ def inter_bloc_flow(my_ir, flow_graph, irb_0, link_exec_to_data=True):
         if state in done:
             continue
         done.add(state)
-        out = inter_bloc_flow_link(my_ir, flow_graph, state, link_exec_to_data)
+        out = inter_bloc_flow_link(ir_arch, flow_graph, state, link_exec_to_data)
         todo.update(out)
 
 
@@ -219,20 +219,20 @@ class symb_exec_func:
     There is no real magic here, loops and complex merging will certainly fail.
     """
 
-    def __init__(self, my_ir):
+    def __init__(self, ir_arch):
         self.todo = set()
         self.stateby_ad = {}
         self.cpt = {}
         self.states_var_done = set()
         self.states_done = set()
         self.total_done = 0
-        self.my_ir = my_ir
+        self.ir_arch = ir_arch
 
     def add_state(self, parent, ad, state):
         variables = dict(state.symbols.items())
 
         # get bloc dead, and remove from state
-        b = self.my_ir.get_bloc(ad)
+        b = self.ir_arch.get_bloc(ad)
         if b is None:
             raise ValueError("unknown bloc! %s" % ad)
         """
@@ -299,28 +299,7 @@ class symb_exec_func:
             #    print "state done"
             #    continue
 
-            sb = symbexec(self.my_ir.arch, dict(s))
-            """
-            if (not is_dispatcher(ad)) and len(self.stateby_ad[ad]) > 10:
-                print "DROP", ad
-                continue
+            sb = symbexec(self.ir_arch, dict(s))
 
-            if (not is_dispatcher(ad)) and len(self.stateby_ad[ad]) > 5:
-                print ad
-                big_keys = diff_states(*self.stateby_ad[ad])
-                print big_keys
-                print "MERGE", ad
-
-                if not big_keys:
-                    return parent, sb
-                #assert(len(big_keys) == 1)
-                s_out = []
-                for k, v in s:
-                    if k not in big_keys :
-                        s_out.append((k, v))
-                sb = symbexec(mn, dict(s_out))
-                return parent, ad, sb
-                #diff_states(*self.stateby_ad[ad])
-            """
             return parent, ad, sb
         return None
diff --git a/miasm2/analysis/debugging.py b/miasm2/analysis/debugging.py
index 28e5ab3c..82710b6a 100644
--- a/miasm2/analysis/debugging.py
+++ b/miasm2/analysis/debugging.py
@@ -190,7 +190,7 @@ class Debugguer(object):
     def set_reg_value(self, reg_name, value):
 
         # Handle PC case
-        if reg_name == self.myjit.my_ir.pc.name:
+        if reg_name == self.myjit.ir_arch.pc.name:
             self.init_run(value)
 
         setattr(self.myjit.cpu, reg_name, value)
diff --git a/miasm2/analysis/disasm_cb.py b/miasm2/analysis/disasm_cb.py
index 4b4832f8..d205d4eb 100644
--- a/miasm2/analysis/disasm_cb.py
+++ b/miasm2/analysis/disasm_cb.py
@@ -26,12 +26,12 @@ def arm_guess_subcall(
     ira = get_ira(mnemo, attrib)
 
     sp = asm_symbol_pool()
-    my_ir = ira(sp)
+    ir_arch = ira(sp)
     print '###'
     print cur_bloc
-    my_ir.add_bloc(cur_bloc)
+    ir_arch.add_bloc(cur_bloc)
 
-    ir_blocs = my_ir.blocs.values()
+    ir_blocs = ir_arch.blocs.values()
     # flow_graph = DiGraph()
     to_add = set()
     for irb in ir_blocs:
@@ -41,7 +41,7 @@ def arm_guess_subcall(
         lr_val = None
         for exprs in irb.irs:
             for e in exprs:
-                if e.dst == my_ir.pc:
+                if e.dst == ir_arch.pc:
                     pc_val = e.src
                 if e.dst == mnemo.regs.LR:
                     lr_val = e.src
@@ -75,10 +75,10 @@ def arm_guess_jump_table(
     jrb = ExprId('jrb')
 
     sp = asm_symbol_pool()
-    my_ir = ira(sp)
-    my_ir.add_bloc(cur_bloc)
+    ir_arch = ira(sp)
+    ir_arch.add_bloc(cur_bloc)
 
-    ir_blocs = my_ir.blocs.values()
+    ir_blocs = ir_arch.blocs.values()
     for irb in ir_blocs:
         # print 'X'*40
         # print irb
@@ -86,7 +86,7 @@ def arm_guess_jump_table(
         # lr_val = None
         for exprs in irb.irs:
             for e in exprs:
-                if e.dst == my_ir.pc:
+                if e.dst == ir_arch.pc:
                     pc_val = e.src
                 # if e.dst == mnemo.regs.LR:
                 #    lr_val = e.src
diff --git a/miasm2/arch/arm/ira.py b/miasm2/arch/arm/ira.py
index 81d3bbbb..b92800e7 100644
--- a/miasm2/arch/arm/ira.py
+++ b/miasm2/arch/arm/ira.py
@@ -61,7 +61,8 @@ class ir_a_arm(ir_a_arm_base):
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
             irs = self.call_effects(pc_val)
-            nbloc = irbloc(new_lbl, ExprId(lbl, size=self.pc.size), irs)
+            irs.append([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))])
+            nbloc = irbloc(new_lbl, irs)
             nbloc.lines = [l]
             self.blocs[new_lbl] = nbloc
             irb.dst = ExprId(new_lbl, size=self.pc.size)
diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py
index d491671c..c2c21924 100644
--- a/miasm2/arch/arm/jit.py
+++ b/miasm2/arch/arm/jit.py
@@ -16,7 +16,7 @@ class jitter_arm(jitter):
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_arm(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.PC
+        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def vm_push_uint32_t(self, v):
         self.cpu.SP -= 4
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 2f00c56e..8f176947 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -117,7 +117,9 @@ def adc(ir, instr, a, b, c=None):
         e += update_flag_add(b, c, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def add(ir, instr, a, b, c=None):
@@ -130,7 +132,9 @@ def add(ir, instr, a, b, c=None):
         e += update_flag_add(b, c, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def l_and(ir, instr, a, b, c=None):
@@ -142,7 +146,9 @@ def l_and(ir, instr, a, b, c=None):
         e += update_flag_logic(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def sub(ir, instr, a, b, c=None):
@@ -152,7 +158,9 @@ def sub(ir, instr, a, b, c=None):
     r = b - c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def subs(ir, instr, a, b, c=None):
@@ -164,7 +172,9 @@ def subs(ir, instr, a, b, c=None):
     e += update_flag_sub(b, c, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def eor(ir, instr, a, b, c=None):
@@ -174,7 +184,9 @@ def eor(ir, instr, a, b, c=None):
     r = b ^ c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def eors(ir, instr, a, b, c=None):
@@ -185,7 +197,9 @@ def eors(ir, instr, a, b, c=None):
     e += update_flag_logic(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def rsb(ir, instr, a, b, c=None):
@@ -195,7 +209,9 @@ def rsb(ir, instr, a, b, c=None):
     r = c - b
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def rsbs(ir, instr, a, b, c=None):
@@ -207,7 +223,9 @@ def rsbs(ir, instr, a, b, c=None):
     e += update_flag_sub(b, c, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def sbc(ir, instr, a, b, c=None):
@@ -217,7 +235,9 @@ def sbc(ir, instr, a, b, c=None):
     r = (b + cf.zeroExtend(32)) - (c + ExprInt32(1))
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def sbcs(ir, instr, a, b, c=None):
@@ -229,7 +249,9 @@ def sbcs(ir, instr, a, b, c=None):
     e += update_flag_sub(b, c, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def rsc(ir, instr, a, b, c=None):
@@ -239,7 +261,9 @@ def rsc(ir, instr, a, b, c=None):
     r = (c + cf.zeroExtend(32)) - (b + ExprInt32(1))
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def rscs(ir, instr, a, b, c=None):
@@ -252,7 +276,9 @@ def rscs(ir, instr, a, b, c=None):
     e += update_flag_sub(c, b, r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def tst(ir, instr, a, b, c=None):
@@ -261,7 +287,7 @@ def tst(ir, instr, a, b, c=None):
         b, c = a, b
     r = b & c
     e += update_flag_logic(r)
-    return None, e
+    return e
 
 
 def teq(ir, instr, a, b, c=None):
@@ -270,7 +296,7 @@ def teq(ir, instr, a, b, c=None):
         b, c = a, b
     r = b ^ c
     e += update_flag_logic(r)
-    return None, e
+    return e
 
 
 def l_cmp(ir, instr, a, b, c=None):
@@ -280,7 +306,7 @@ def l_cmp(ir, instr, a, b, c=None):
     r = b - c
     e += update_flag_arith(r)
     e += update_flag_sub(c, b, r)
-    return None, e
+    return e
 
 
 def cmn(ir, instr, a, b, c=None):
@@ -290,7 +316,7 @@ def cmn(ir, instr, a, b, c=None):
     r = b + c
     e += update_flag_arith(r)
     e += update_flag_add(b, c, r)
-    return None, e
+    return e
 
 
 def orr(ir, instr, a, b, c=None):
@@ -300,7 +326,9 @@ def orr(ir, instr, a, b, c=None):
     r = b | c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def orrs(ir, instr, a, b, c=None):
@@ -311,19 +339,26 @@ def orrs(ir, instr, a, b, c=None):
     e += update_flag_logic(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def mov(ir, instr, a, b):
     e = [ExprAff(a, b)]
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, b))
+    return e
 
 
 def movt(ir, instr, a, b):
-    e = [ExprAff(a, a | b << ExprInt32(16))]
+    r = a | b << ExprInt32(16)
+    e = [ExprAff(a, r)]
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def movs(ir, instr, a, b):
@@ -332,13 +367,18 @@ def movs(ir, instr, a, b):
     # XXX TODO check
     e += update_flag_logic(b)
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, b))
+    return e
 
 
 def mvn(ir, instr, a, b):
-    e = [ExprAff(a, b ^ ExprInt32(-1))]
+    r = b ^ ExprInt32(-1)
+    e = [ExprAff(a, r)]
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def mvns(ir, instr, a, b):
@@ -348,7 +388,9 @@ def mvns(ir, instr, a, b):
     # XXX TODO check
     e += update_flag_logic(r)
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def neg(ir, instr, a, b):
@@ -356,11 +398,13 @@ def neg(ir, instr, a, b):
     r = - b
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def negs(ir, instr, a, b):
-    dst, e = subs(ir, instr, a, ExprInt_from(b, 0), b)
-    return dst, e
+    e = subs(ir, instr, a, ExprInt_from(b, 0), b)
+    return e
 
 def bic(ir, instr, a, b, c=None):
     e = []
@@ -369,7 +413,9 @@ def bic(ir, instr, a, b, c=None):
     r = b & (c ^ ExprInt(uint32(-1)))
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def bics(ir, instr, a, b, c=None):
@@ -380,7 +426,9 @@ def bics(ir, instr, a, b, c=None):
     e += update_flag_logic(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def mla(ir, instr, a, b, c, d):
@@ -388,7 +436,9 @@ def mla(ir, instr, a, b, c, d):
     r = (b * c) + d
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def mlas(ir, instr, a, b, c, d):
@@ -397,7 +447,9 @@ def mlas(ir, instr, a, b, c, d):
     e += update_flag_zn(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def mul(ir, instr, a, b, c = None):
@@ -407,7 +459,9 @@ def mul(ir, instr, a, b, c = None):
     r = b * c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def muls(ir, instr, a, b, c = None):
@@ -418,35 +472,41 @@ def muls(ir, instr, a, b, c = None):
     e += update_flag_zn(r)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def b(ir, instr, a):
     e = []
     e.append(ExprAff(PC, a))
-    return a, e
+    e.append(ExprAff(ir.IRDst, a))
+    return e
 
 
 def bl(ir, instr, a):
     e = []
     l = ExprInt32(instr.offset + instr.l)
     e.append(ExprAff(PC, a))
+    e.append(ExprAff(ir.IRDst, a))
     e.append(ExprAff(LR, l))
-    return a, e
+    return e
 
 
 def bx(ir, instr, a):
     e = []
     e.append(ExprAff(PC, a))
-    return a, e
+    e.append(ExprAff(ir.IRDst, a))
+    return e
 
 
 def blx(ir, instr, a):
     e = []
     l = ExprInt32(instr.offset + instr.l)
     e.append(ExprAff(PC, a))
+    e.append(ExprAff(ir.IRDst, a))
     e.append(ExprAff(LR, l))
-    return a, e
+    return e
 
 
 def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False):
@@ -502,6 +562,7 @@ def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False):
     else:
         if a == PC:
             dst = PC
+            e.append(ExprAff(ir.IRDst, m))
         e.append(ExprAff(a, m))
         if dmem:
             e.append(ExprAff(a2, ExprMem(ad + ExprInt32(4), size=size)))
@@ -509,7 +570,7 @@ def st_ld_r(ir, instr, a, b, store=False, size=32, s_ext=False, z_ext=False):
     # XXX TODO check multiple write cause by wb
     if wb or postinc:
         e.append(ExprAff(base, base + off))
-    return dst, e
+    return e
 
 
 def ldr(ir, instr, a, b):
@@ -517,8 +578,8 @@ def ldr(ir, instr, a, b):
 
 
 def ldrd(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=False, size=64)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=False, size=64)
+    return e
 
 
 def l_str(ir, instr, a, b):
@@ -526,38 +587,38 @@ def l_str(ir, instr, a, b):
 
 
 def l_strd(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=True, size=64)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=True, size=64)
+    return e
 
 
 def ldrb(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=False, size=8, z_ext=True)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=False, size=8, z_ext=True)
+    return e
 
 def ldrsb(ir, instr, a, b):
-    dst, e = st_ld_r(
+    e = st_ld_r(
         ir, instr, a, b, store=False, size=8, s_ext=True, z_ext=False)
-    return dst, e
+    return e
 
 def strb(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=True, size=8)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=True, size=8)
+    return e
 
 
 def ldrh(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=False, size=16, z_ext=True)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=False, size=16, z_ext=True)
+    return e
 
 
 def strh(ir, instr, a, b):
-    dst, e = st_ld_r(ir, instr, a, b, store=True, size=16, z_ext=True)
-    return dst, e
+    e = st_ld_r(ir, instr, a, b, store=True, size=16, z_ext=True)
+    return e
 
 
 def ldrsh(ir, instr, a, b):
-    dst, e = st_ld_r(
+    e = st_ld_r(
         ir, instr, a, b, store=False, size=16, s_ext=True, z_ext=False)
-    return dst, e
+    return e
 
 
 def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False):
@@ -588,6 +649,8 @@ def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False):
             e.append(ExprAff(ExprMem(ad), r))
         else:
             e.append(ExprAff(r, ExprMem(ad)))
+            if r == PC:
+                e.append(ExprAff(ir.IRDst, ExprMem(ad)))
     # XXX TODO check multiple write cause by wb
     if wb:
         if postinc:
@@ -598,10 +661,8 @@ def st_ld_m(ir, instr, a, b, store=False, postinc=False, updown=False):
         pass
     else:
         assert(isinstance(b, ExprOp) and b.op == "reglist")
-        if PC in b.args:
-            dst = PC
 
-    return dst, e
+    return e
 
 
 def ldmia(ir, instr, a, b):
@@ -640,13 +701,13 @@ def svc(ir, instr, a):
     # XXX TODO implement
     e = [
         ExprAff(exception_flags, ExprInt32(EXCEPT_PRIV_INSN))]
-    return None, e
+    return e
 
 
 def und(ir, instr, a, b):
     # XXX TODO implement
     e = []
-    return None, e
+    return e
 
 # TODO XXX implement correct CF for shifters
 def lsr(ir, instr, a, b, c = None):
@@ -656,7 +717,9 @@ def lsr(ir, instr, a, b, c = None):
     r = b >> c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def lsrs(ir, instr, a, b, c = None):
@@ -667,7 +730,9 @@ def lsrs(ir, instr, a, b, c = None):
     e.append(ExprAff(a, r))
     e += update_flag_logic(r)
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def asr(ir, instr, a, b, c=None):
     e = []
@@ -676,7 +741,9 @@ def asr(ir, instr, a, b, c=None):
     r = ExprOp("a>>", b, c)
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def asrs(ir, instr, a, b, c):
     e = []
@@ -686,7 +753,9 @@ def asrs(ir, instr, a, b, c):
     e.append(ExprAff(a, r))
     e += update_flag_logic(r)
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def lsl(ir, instr, a, b, c = None):
     e = []
@@ -695,7 +764,9 @@ def lsl(ir, instr, a, b, c = None):
     r = b << c
     e.append(ExprAff(a, r))
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def lsls(ir, instr, a, b, c = None):
@@ -706,7 +777,9 @@ def lsls(ir, instr, a, b, c = None):
     e.append(ExprAff(a, r))
     e += update_flag_logic(r)
     dst = get_dst(a)
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def push(ir, instr, a):
@@ -717,80 +790,92 @@ def push(ir, instr, a):
         e.append(ExprAff(regs[i], ExprMem(r)))
     r = SP + ExprInt32(-4 * len(regs))
     e.append(ExprAff(SP, r))
-    return None, e
+    return e
 
 
 def pop(ir, instr, a):
     e = []
     regs = list(a.args)
+    dst = None
     for i in xrange(len(regs)):
         r = SP + ExprInt32(4 * i)
         e.append(ExprAff(regs[i], ExprMem(r)))
+        if regs[i] == ir.pc:
+            dst = ExprMem(r)
     r = SP + ExprInt32(4 * len(regs))
     e.append(ExprAff(SP, r))
-    dst = None
-    if PC in a.get_r():
-        dst = PC
-    return dst, e
+    if dst is not None:
+        e.append(ExprAff(ir.IRDst, dst))
+    return e
 
 
 def cbz(ir, instr, a, b):
     e = []
     lbl_next = ExprId(ir.get_next_label(instr), 32)
-    dst = ExprCond(a, lbl_next, b)
-    return dst, e
+    e.append(ExprAff(ir.IRDst, ExprCond(a, lbl_next, b)))
+    return e
 
 
 def cbnz(ir, instr, a, b):
     e = []
     lbl_next = ExprId(ir.get_next_label(instr), 32)
-    dst = ExprCond(a, b, lbl_next)
-    return dst, e
+    e.append(ir.IRDst, ExprCond(a, b, lbl_next))
+    return e
 
 
 
 def uxtb(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, b[:8].zeroExtend(32)))
+    r = b[:8].zeroExtend(32)
+    e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
         dst = PC
-    return dst, e
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def uxth(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, b[:16].zeroExtend(32)))
+    r = b[:16].zeroExtend(32)
+    e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
         dst = PC
-    return dst, e
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def sxtb(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, b[:8].signExtend(32)))
+    r = b[:8].signExtend(32)
+    e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
         dst = PC
-    return dst, e
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 def sxth(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, b[:16].signExtend(32)))
+    r = b[:16].signExtend(32)
+    e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
         dst = PC
-    return dst, e
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 def ubfx(ir, instr, a, b, c, d):
     e = []
     c = int(c.arg)
     d = int(d.arg)
-    e.append(ExprAff(a, b[c:c+d].zeroExtend(32)))
+    r = b[c:c+d].zeroExtend(32)
+    e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
         dst = PC
-    return dst, e
+        e.append(ExprAff(ir.IRDst, r))
+    return e
 
 
 
@@ -864,10 +949,9 @@ def is_pc_written(ir, instr_ir):
     return False, None
 
 
-def add_condition_expr(ir, instr, cond, instr_ir, dst):
-    # print "XXX", hex(instr.offset), instr
+def add_condition_expr(ir, instr, cond, instr_ir):
     if cond == COND_AL:
-        return dst, instr_ir, []
+        return instr_ir, []
     if not cond in tab_cond:
         raise ValueError('unknown condition %r' % cond)
     cond = tab_cond[cond]
@@ -878,10 +962,16 @@ def add_condition_expr(ir, instr, cond, instr_ir, dst):
     dst_cond = ExprCond(cond, lbl_do, lbl_next)
     assert(isinstance(instr_ir, list))
 
-    if dst is None:
-        dst = lbl_next
-    e_do = irbloc(lbl_do.name, dst, [instr_ir])
-    return dst_cond, [], [e_do]
+    has_irdst = False
+    for e in instr_ir:
+        if e.dst == ir.IRDst:
+            has_irdst = True
+            break
+    if not has_irdst:
+        instr_ir.append(ExprAff(ir.IRDst, lbl_next))
+    e_do = irbloc(lbl_do.name, [instr_ir])
+    e = [ExprAff(ir.IRDst, dst_cond)]
+    return e, [e_do]
 
 mnemo_func = {}
 mnemo_func_cond = {}
@@ -1023,9 +1113,9 @@ def get_mnemo_expr(ir, instr, *args):
     if not instr.name.lower() in mnemo_func_cond:
         raise ValueError('unknown mnemo %s' % instr)
     cond, mf = mnemo_func_cond[instr.name.lower()]
-    dst, instr_ir = mf(ir, instr, *args)
-    dst, instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir, dst)
-    return dst, instr, extra_ir
+    instr_ir = mf(ir, instr, *args)
+    instr, extra_ir = add_condition_expr(ir, instr, cond, instr_ir)
+    return instr, extra_ir
 
 get_arm_instr_expr = get_mnemo_expr
 
@@ -1041,6 +1131,7 @@ class ir_arm(ir):
         ir.__init__(self, mn_arm, "arm", symbol_pool)
         self.pc = PC
         self.sp = SP
+        self.IRDst = ExprId('IRDst', 32)
 
     def get_ir(self, instr):
         args = instr.args
@@ -1053,7 +1144,7 @@ class ir_arm(ir):
                   isinstance(args[-1].args[-1], ExprId)):
                 args[-1].args = args[-1].args[:-1] + (
                     args[-1].args[-1][:8].zeroExtend(32),)
-        dst, instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
+        instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
         # if self.name.startswith('B'):
         #    return instr_ir, extra_ir
         for i, x in enumerate(instr_ir):
@@ -1067,7 +1158,7 @@ class ir_arm(ir):
                         {self.pc: ExprInt32(instr.offset + 8)}))
                     irs[i] = x
         # return out_ir, extra_ir
-        return dst, instr_ir, extra_ir
+        return instr_ir, extra_ir
 
 
 class ir_armt(ir):
@@ -1076,6 +1167,7 @@ class ir_armt(ir):
         ir.__init__(self, mn_armt, "armt", symbol_pool)
         self.pc = PC
         self.sp = SP
+        self.IRDst = ExprId('IRDst', 32)
 
     def get_ir(self, instr):
         return get_mnemo_expr(self, instr, *instr.args)
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index 82af9acc..bc9e2439 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -13,9 +13,6 @@ class ir_a_mips32(ir_mips32, ira):
         ir_mips32.__init__(self, symbol_pool)
         self.ret_reg = self.arch.regs.V0
 
-    def get_next_break_label(self, instr):
-        l = self.symbol_pool.getby_offset_create(instr.offset  + 8)
-        return l
 
     # for test XXX TODO
     def set_dead_regs(self, b):
@@ -58,7 +55,8 @@ class ir_a_mips32(ir_mips32, ira):
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
             irs = self.call_effects(pc_val)
-            nbloc = irbloc(new_lbl, ExprId(lbl, size=self.pc.size), irs)
+            irs.append([ExprAff(IRDst, ExprId(lbl, size=self.pc.size))])
+            nbloc = irbloc(new_lbl, irs)
             nbloc.lines = [l]
             self.blocs[new_lbl] = nbloc
             irb.dst = ExprId(new_lbl, size=self.pc.size)
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 70e05380..132e5da5 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -16,8 +16,8 @@ class jitter_mips32(jitter):
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_mips32(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.PC
-        self.my_ir.attrib = 'l'
+        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
+        self.ir_arch.attrib = 'l'
 
     def vm_push_uint32_t(self, v):
         self.cpu.SP -= 4
diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py
index ef5e380c..64df4b98 100644
--- a/miasm2/arch/mips32/regs.py
+++ b/miasm2/arch/mips32/regs.py
@@ -4,6 +4,7 @@
 from miasm2.expression.expression import *
 from miasm2.core.cpu import gen_reg, gen_regs
 
+
 gen_reg('PC', globals())
 gen_reg('PC_FETCH', globals())
 
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index 3d895cda..9bee8775 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -6,295 +6,318 @@ from miasm2.arch.mips32.regs import *
 def addiu(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b+c))
-    return None, e, []
+    return e, []
 
 def lw(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 def sw(ir, instr, a, b):
     e = []
     e.append(ExprAff(b, a))
-    return None, e, []
+    return e, []
 
 def jal(ir, instr, a):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     e.append(ExprAff(PC, a))
+    e.append(ExprAff(ir.IRDst, a))
     e.append(ExprAff(RA, n))
-    return a, e, []
+    return e, []
 
 def jalr(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     e.append(ExprAff(PC, a))
+    e.append(ExprAff(ir.IRDst, a))
     e.append(ExprAff(b, n))
-    return a, e, []
+    return e, []
 
 def bal(ir, instr, a):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     e.append(ExprAff(PC, a))
+    e.append(ExprAff(ir.IRDst, a))
     e.append(ExprAff(RA, n))
-    return a, e, []
+    return e, []
 
 def l_b(ir, instr, a):
     e = []
     e.append(ExprAff(PC, a))
-    return a, e, []
+    e.append(ExprAff(ir.IRDst, a))
+    return e, []
 
 def lbu(ir, instr, a, b):
     e = []
     b = ExprMem(b.arg, 8)
     e.append(ExprAff(a, b.zeroExtend(32)))
-    return None, e, []
+    return e, []
 
 def lhu(ir, instr, a, b):
     e = []
     b = ExprMem(b.arg, 16)
     e.append(ExprAff(a, b.zeroExtend(32)))
-    return None, e, []
+    return e, []
 
 def beq(ir, instr, a, b, c):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a-b, n, c)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+     ]
+    return e, []
 
 def bgez(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a.msb(), n, b)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+     ]
+    return e, []
 
 def bne(ir, instr, a, b, c):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a-b, c, n)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+    ]
+    return e, []
 
 def lui(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprCompose([(ExprInt16(0), 0, 16),
                                      (b[:16], 16, 32)])))
-    return None, e, []
+    return e, []
 
 def nop(ir, instr):
-    return None, [], []
+    return [], []
 
 def j(ir, instr, a):
     e = []
     e.append(ExprAff(PC, a))
-    return a, e, []
+    e.append(ExprAff(ir.IRDst, a))
+    return e, []
 
 def l_or(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b|c))
-    return None, e, []
+    return e, []
 
 def nor(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, (b|c)^ExprInt32(0xFFFFFFFF)))
-    return None, e, []
+    return e, []
 
 def l_and(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b&c))
-    return None, e, []
+    return e, []
 
 def ext(ir, instr, a, b, c, d):
     e = []
     pos = int(c.arg)
     size = int(d.arg)
     e.append(ExprAff(a, b[pos:pos+size].zeroExtend(32)))
-    return None, e, []
+    return e, []
 
 def mul(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('imul', b, c)))
-    return None, e, []
+    return e, []
 
 def sltu(ir, instr, a, x, y):
     e = []
     e.append(ExprAff(a, (((x - y) ^ ((x ^ y) & ((x - y) ^ x))) ^ x ^ y).msb().zeroExtend(32)))
-    return None, e, []
+    return e, []
 
 def slt(ir, instr, a, x, y):
     e = []
     e.append(ExprAff(a, ((x - y) ^ ((x ^ y) & ((x - y) ^ x))).zeroExtend(32)))
-    return None, e, []
+    return e, []
 
 def l_sub(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b-c))
-    return None, e, []
+    return e, []
 
 def sb(ir, instr, a, b):
     e = []
     b = ExprMem(b.arg, 8)
     e.append(ExprAff(b, a[:8]))
-    return None, e, []
+    return e, []
 
 def sh(ir, instr, a, b):
     e = []
     b = ExprMem(b.arg, 16)
     e.append(ExprAff(b, a[:16]))
-    return None, e, []
+    return e, []
 
 def movn(ir, instr, a, b, c):
     lbl_do = ExprId(ir.gen_label(), 32)
-    lbl_skip = ExprId(ir.get_next_label(instr), 32)
+    lbl_skip = ExprId(ir.get_next_instr(instr), 32)
     e_do = []
     e_do.append(ExprAff(a, b))
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e = []
+    e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_do, lbl_skip)))
 
-    return ExprCond(c, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    return e, [irbloc(lbl_do.name, [e_do], [])]
 
 def movz(ir, instr, a, b, c):
     lbl_do = ExprId(ir.gen_label(), 32)
-    lbl_skip = ExprId(ir.get_next_label(instr), 32)
+    lbl_skip = ExprId(ir.get_next_instr(instr), 32)
     e_do = []
     e_do.append(ExprAff(a, b))
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e = []
+    e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_skip, lbl_do)))
 
-    return ExprCond(c, lbl_skip, lbl_do), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    return e, [irbloc(lbl_do.name, [e_do], [])]
 
 def srl(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b >> c))
-    return None, e, []
+    return e, []
 
 def sra(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('a>>', b, c)))
-    return None, e, []
+    return e, []
 
 def srav(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('a>>', b, c&ExprInt32(0x1F))))
-    return None, e, []
+    return e, []
 
 def sll(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b<<c))
-    return None, e, []
+    return e, []
 
 def srlv(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b >> (c & ExprInt32(0x1F))))
-    return None, e, []
+    return e, []
 
 def sllv(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b << (c & ExprInt32(0x1F))))
-    return None, e, []
+    return e, []
 
 def l_xor(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, b^c))
-    return None, e, []
+    return e, []
 
 def seb(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, b[:8].signExtend(32)))
-    return None, e, []
+    return e, []
 
 def bltz(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a.msb(), b, n)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+    ]
+    return e, []
 
 def blez(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb()
     dst_o = ExprCond(cond, b, n)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+    ]
+    return e, []
 
 def bgtz(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     cond = ExprCond(a, ExprInt1(1), ExprInt1(0)) | a.msb()
     dst_o = ExprCond(cond, n, b)
-    e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(PC, dst_o),
+         ExprAff(ir.IRDst, dst_o)
+     ]
+    return e, []
 
 def wsbh(ir, instr, a, b):
     e = [ExprAff(a, ExprCompose([(b[8:16],  0, 8)   ,
                                  (b[0:8]  , 8, 16)  ,
                                  (b[24:32], 16, 24),
                                  (b[16:24], 24, 32)]))]
-    return None, e, []
+    return e, []
 
 def rotr(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('>>>', b, c)))
-    return None, e, []
+    return e, []
 
 def add_d(ir, instr, a, b, c):
     # XXX TODO check
     e = []
     e.append(ExprAff(a, ExprOp('fadd', b, c)))
-    return None, e, []
+    return e, []
 
 def sub_d(ir, instr, a, b, c):
     # XXX TODO check
     e = []
     e.append(ExprAff(a, ExprOp('fsub', b, c)))
-    return None, e, []
+    return e, []
 
 def div_d(ir, instr, a, b, c):
     # XXX TODO check
     e = []
     e.append(ExprAff(a, ExprOp('fdiv', b, c)))
-    return None, e, []
+    return e, []
 
 def mul_d(ir, instr, a, b, c):
     # XXX TODO check
     e = []
     e.append(ExprAff(a, ExprOp('fmul', b, c)))
-    return None, e, []
+    return e, []
 
 def mov_d(ir, instr, a, b):
     # XXX TODO check
     e = []
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 def mfc0(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 def mfc1(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 def mtc0(ir, instr, a, b):
     e = []
     e.append(ExprAff(b, a))
-    return None, e, []
+    return e, []
 
 def mtc1(ir, instr, a, b):
     e = []
     e.append(ExprAff(b, a))
-    return None, e, []
+    return e, []
 
 def tlbwi(ir, instr):
     # TODO XXX
     e = []
-    return None, e, []
+    return e, []
 
 def tlbp(ir, instr):
     # TODO XXX
     e = []
-    return None, e, []
+    return e, []
 
 def ins(ir, instr, a, b, c, d):
     e = []
@@ -310,55 +333,57 @@ def ins(ir, instr, a, b, c, d):
         my_slices.append((a[pos+l:], pos+l, 32))
     r = ExprCompose(my_slices)
     e.append(ExprAff(a, r))
-    return None, e, []
+    return e, []
 
 
 def lwc1(ir, instr, a, b):
     e = []
     src = ExprOp('mem_%.2d_to_single' % b.size, b)
     e.append(ExprAff(a, src))
-    return None, e, []
+    return e, []
 
 def swc1(ir, instr, a, b):
     e = []
     src = ExprOp('single_to_mem_%.2d' % a.size, a)
     e.append(ExprAff(b, src))
-    return None, e, []
+    return e, []
 
 def c_lt_d(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('fcomp_lt', b, c)))
-    return None, e, []
+    return e, []
 
 def c_eq_d(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('fcomp_eq', b, c)))
-    return None, e, []
+    return e, []
 
 def c_le_d(ir, instr, a, b, c):
     e = []
     e.append(ExprAff(a, ExprOp('fcomp_le', b, c)))
-    return None, e, []
+    return e, []
 
 def bc1t(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a, b, n)
     e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 def bc1f(ir, instr, a, b):
     e = []
     n = ExprId(ir.get_next_break_label(instr))
     dst_o = ExprCond(a, n, b)
     e = [ExprAff(PC, dst_o)]
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 def cvt_d_w(ir, instr, a, b):
     e = []
     # TODO XXX
     e.append(ExprAff(a, ExprOp('flt_d_w', b)))
-    return None, e, []
+    return e, []
 
 def mult(ir, instr, a, b):
     e = []
@@ -367,17 +392,17 @@ def mult(ir, instr, a, b):
 
     e.append(ExprAff(R_LO, r[:32]))
     e.append(ExprAff(R_HI, r[32:]))
-    return None, e, []
+    return e, []
 
 def mfhi(ir, instr, a):
     e = []
     e.append(ExprAff(a, R_HI))
-    return None, e, []
+    return e, []
 
 def mflo(ir, instr, a):
     e = []
     e.append(ExprAff(a, R_LO))
-    return None, e, []
+    return e, []
 
 
 mnemo_func = {
@@ -458,8 +483,8 @@ mnemo_func = {
     }
 
 def get_mnemo_expr(ir, instr, *args):
-    dst, instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
-    return dst, instr, extra_ir
+    instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
+    return instr, extra_ir
 
 class ir_mips32(ir):
 
@@ -467,10 +492,11 @@ class ir_mips32(ir):
         ir.__init__(self, mn_mips32, None, symbol_pool)
         self.pc = mn_mips32.getpc()
         self.sp = mn_mips32.getsp()
+        self.IRDst = ExprId('IRDst', 32)
 
     def get_ir(self, instr):
         args = instr.args
-        dst, instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
+        instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
 
         for i, x in enumerate(instr_ir):
             x = ExprAff(x.dst, x.src.replace_expr(
@@ -482,12 +508,16 @@ class ir_mips32(ir):
                     x = ExprAff(x.dst, x.src.replace_expr(
                         {self.pc: ExprInt32(instr.offset + 4)}))
                     irs[i] = x
-        return dst, instr_ir, extra_ir
+        return instr_ir, extra_ir
+
+    def get_next_instr(self, instr):
+        l = self.symbol_pool.getby_offset_create(instr.offset  + 4)
+        return l
 
     def get_next_break_label(self, instr):
         l = self.symbol_pool.getby_offset_create(instr.offset  + 8)
         return l
-
+    """
     def add_bloc(self, bloc, gen_pc_updt = False):
         c = None
         ir_blocs_all = []
@@ -495,7 +525,7 @@ class ir_mips32(ir):
             if c is None:
                 # print 'new c'
                 label = self.get_label(l)
-                c = irbloc(label)
+                c = irbloc(label, [], [])
                 ir_blocs_all.append(c)
                 bloc_dst = None
             # print 'Translate', l
@@ -523,3 +553,4 @@ class ir_mips32(ir):
                 c = None
         self.post_add_bloc(bloc, ir_blocs_all)
         return ir_blocs_all
+    """
diff --git a/miasm2/arch/msp430/ira.py b/miasm2/arch/msp430/ira.py
index 8e9a70dd..ea8bdc2c 100644
--- a/miasm2/arch/msp430/ira.py
+++ b/miasm2/arch/msp430/ira.py
@@ -65,7 +65,8 @@ class ir_a_msp430(ir_a_msp430_base):
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
             irs = self.call_effects(pc_val)
-            nbloc = irbloc(new_lbl, ExprId(lbl, size=self.pc.size), irs)
+            irs.append([ExprAff(IRDst, ExprId(lbl, size=self.pc.size))])
+            nbloc = irbloc(new_lbl, irs)
             nbloc.lines = [l]
             self.blocs[new_lbl] = nbloc
             irb.dst = ExprId(new_lbl, size=self.pc.size)
diff --git a/miasm2/arch/msp430/jit.py b/miasm2/arch/msp430/jit.py
index 0a39be06..711011bc 100644
--- a/miasm2/arch/msp430/jit.py
+++ b/miasm2/arch/msp430/jit.py
@@ -17,7 +17,7 @@ class jitter_msp430(jitter):
         from miasm2.arch.msp430.sem import ir_msp430
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_msp430(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.PC
+        self.ir_arch.jit_pc = self.ir_arch.arch.regs.PC
 
     def vm_push_uint16_t(self, v):
         regs = self.cpu.vm_get_gpreg()
diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py
index 6fea2c21..3a9ead35 100644
--- a/miasm2/arch/msp430/sem.py
+++ b/miasm2/arch/msp430/sem.py
@@ -93,17 +93,15 @@ def mov_b(ir, instr, a, b):
     else:
         a = a[:8].zeroExtend(16)
     e.append(ExprAff(b, a))
-    return None, e, []
+    return e, []
 
 
 def mov_w(ir, instr, a, b):
     e, a, b = mng_autoinc(a, b, 16)
     e.append(ExprAff(b, a))
     if b == ir.pc:
-        dst = PC
-    else:
-        dst = None
-    return dst, e, []
+        e.append(ExprAff(ir.IRDst, a))
+    return e, []
 
 
 def and_b(ir, instr, a, b):
@@ -113,7 +111,7 @@ def and_b(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_cf_inv_zf(c)
     e += [ExprAff(of, ExprInt1(0))]
-    return None, e, []
+    return e, []
 
 
 def and_w(ir, instr, a, b):
@@ -123,7 +121,7 @@ def and_w(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_cf_inv_zf(c)
     e += [ExprAff(of, ExprInt1(0))]
-    return None, e, []
+    return e, []
 
 
 def bic_b(ir, instr, a, b):
@@ -131,21 +129,21 @@ def bic_b(ir, instr, a, b):
     c = (a[:8] ^ ExprInt8(0xff)) & b[:8]
     c = c.zeroExtend(b.size)
     e.append(ExprAff(b, c))
-    return None, e, []
+    return e, []
 
 
 def bic_w(ir, instr, a, b):
     e, a, b = mng_autoinc(a, b, 16)
     c = (a ^ ExprInt16(0xffff)) & b
     e.append(ExprAff(b, c))
-    return None, e, []
+    return e, []
 
 
 def bis_w(ir, instr, a, b):
     e, a, b = mng_autoinc(a, b, 16)
     c = a | b
     e.append(ExprAff(b, c))
-    return None, e, []
+    return e, []
 
 
 def bit_w(ir, instr, a, b):
@@ -154,7 +152,7 @@ def bit_w(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_cf_inv_zf(c)
     e.append(ExprAff(of, ExprInt1(0)))
-    return None, e, []
+    return e, []
 
 """
 def sub_b(ir, instr, a, b):
@@ -176,7 +174,7 @@ def sub_w(ir, instr, a, b):
     # micrcorruption
     # e += update_flag_sub_of(a, b, c)
     # e += update_flag_sub_of(b, a, c)
-    return None, e, []
+    return e, []
 
 
 def add_w(ir, instr, a, b):
@@ -186,7 +184,7 @@ def add_w(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_add_cf(a, b, c)
     e += update_flag_add_of(a, b, c)
-    return None, e, []
+    return e, []
 
 
 def dadd_w(ir, instr, a, b):
@@ -205,7 +203,7 @@ def dadd_w(ir, instr, a, b):
     e.append(ExprAff(cf, ExprOp("bcdadd_cf", b, a)))  # +zeroExtend(cf, 16))))
 
     # of : undefined
-    return None, e, []
+    return e, []
 
 
 def xor_w(ir, instr, a, b):
@@ -215,14 +213,14 @@ def xor_w(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_cf_inv_zf(c)
     e.append(ExprAff(of, b.msb() & a.msb()))
-    return None, e, []
+    return e, []
 
 
 def push_w(ir, instr, a):
     e = []
     e.append(ExprAff(ExprMem(SP - ExprInt16(2), 16), a))
     e.append(ExprAff(SP, SP - ExprInt16(2)))
-    return None, e, []
+    return e, []
 
 
 def call(ir, instr, a):
@@ -231,7 +229,8 @@ def call(ir, instr, a):
     e.append(ExprAff(ExprMem(SP - ExprInt16(2), 16), n))
     e.append(ExprAff(SP, SP - ExprInt16(2)))
     e.append(ExprAff(PC, a))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, a))
+    return e, []
 
 
 def swpb(ir, instr, a):
@@ -239,7 +238,7 @@ def swpb(ir, instr, a):
     x, y = a[:8], a[8:16]
     e.append(ExprAff(a, ExprCompose([(y, 0, 8),
                                      (x, 8, 16)])))
-    return None, e, []
+    return e, []
 
 
 def cmp_w(ir, instr, a, b):
@@ -248,7 +247,7 @@ def cmp_w(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_sub_cf(a, b, c)
     e += update_flag_sub_of(a, b, c)
-    return None, e, []
+    return e, []
 
 
 def cmp_b(ir, instr, a, b):
@@ -257,55 +256,62 @@ def cmp_b(ir, instr, a, b):
     e += update_flag_zn_r(c)
     e += update_flag_sub_cf(a[:8], b[:8], c)
     e += update_flag_sub_of(a[:8], b[:8], c)
-    return None, e, []
+    return e, []
 
 
 def jz(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(zf, a, n)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, a, n)))
+    return e, []
 
 
 def jnz(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(zf, n, a)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, n, a)))
+    return e, []
 
 
 def jl(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(nf ^ of, a, n)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, n)))
+    return e, []
 
 
 def jc(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(cf, a, n)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, a, n)))
+    return e, []
 
 
 def jnc(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(cf, n, a)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, n, a)))
+    return e, []
 
 
 def jge(ir, instr, a):
     n = ExprId(ir.get_next_label(instr), 16)
     e = []
     e.append(ExprAff(PC, ExprCond(nf ^ of, n, a)))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, n, a)))
+    return e, []
 
 
 def jmp(ir, instr, a):
     e = []
     e.append(ExprAff(PC, a))
-    return PC, e, []
+    e.append(ExprAff(ir.IRDst, a))
+    return e, []
 
 
 def rrc_w(ir, instr, a):
@@ -322,7 +328,7 @@ def rrc_w(ir, instr, a):
     e += reset_sr_res()
 
     e.append(ExprAff(of, ExprInt1(0)))
-    return None, e, []
+    return e, []
 
 
 def rra_w(ir, instr, a):
@@ -340,7 +346,7 @@ def rra_w(ir, instr, a):
     e += reset_sr_res()
 
     e.append(ExprAff(of, ExprInt1(0)))
-    return None, e, []
+    return e, []
 
 
 def sxt(ir, instr, a):
@@ -352,7 +358,7 @@ def sxt(ir, instr, a):
     e += update_flag_cf_inv_zf(c)
     e.append(ExprAff(of, ExprInt1(0)))
 
-    return None, e, []
+    return e, []
 
 mnemo_func = {
     "mov.b": mov_b,
@@ -412,6 +418,7 @@ class ir_msp430(ir):
         ir.__init__(self, mn_msp430, None, symbol_pool)
         self.pc = PC
         self.sp = SP
+        self.IRDst = ExprId('IRDst', 16)
 
     def mod_pc(self, instr, instr_ir, extra_ir):
         pass
@@ -419,10 +426,10 @@ class ir_msp430(ir):
     def get_ir(self, instr):
         # print instr#, args
         args = instr.args
-        dst, instr_ir, extra_ir = mnemo_func[instr.name](self, instr, *args)
+        instr_ir, extra_ir = mnemo_func[instr.name](self, instr, *args)
         self.mod_sr(instr, instr_ir, extra_ir)
 
-        return dst, instr_ir, extra_ir
+        return instr_ir, extra_ir
 
     def mod_sr(self, instr, instr_ir, extra_ir):
         for i, x in enumerate(instr_ir):
diff --git a/miasm2/arch/x86/ira.py b/miasm2/arch/x86/ira.py
index c7dfb2ac..bf07e7c2 100644
--- a/miasm2/arch/x86/ira.py
+++ b/miasm2/arch/x86/ira.py
@@ -59,7 +59,9 @@ class ir_a_x86_16(ir_x86_16, ira):
             lbl = bloc.get_next()
             new_lbl = self.gen_label()
             irs = self.call_effects(l.args[0])
-            nbloc = irbloc(new_lbl, ExprId(lbl, size=self.pc.size), irs)
+            irs.append([ExprAff(self.IRDst, ExprId(lbl, size=self.pc.size))])
+
+            nbloc = irbloc(new_lbl, irs)
             nbloc.lines = [l]
             self.blocs[new_lbl] = nbloc
             b.dst = ExprId(new_lbl, size=self.pc.size)
diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py
index a365502f..f06ca306 100644
--- a/miasm2/arch/x86/jit.py
+++ b/miasm2/arch/x86/jit.py
@@ -17,21 +17,21 @@ class jitter_x86_16(jitter):
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_16(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.RIP
-        self.my_ir.do_stk_segm = False
-        self.orig_irbloc_fix_regs_for_mode = self.my_ir.irbloc_fix_regs_for_mode
-        self.my_ir.irbloc_fix_regs_for_mode = self.my_irbloc_fix_regs_for_mode
+        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
 
-    def my_irbloc_fix_regs_for_mode(self, irbloc, attrib=64):
+    def ir_archbloc_fix_regs_for_mode(self, irbloc, attrib=64):
         self.orig_irbloc_fix_regs_for_mode(irbloc, 64)
 
     def vm_push_uint16_t(self, v):
-        self.cpu.SP -= self.my_ir.sp.size / 8
+        self.cpu.SP -= self.ir_arch.sp.size / 8
         self.vm.vm_set_mem(self.cpu.SP, pck16(v))
 
     def vm_pop_uint16_t(self):
-        x = upck16(self.vm.vm_get_mem(self.cpu.SP, self.my_ir.sp.size / 8))
-        self.cpu.SP += self.my_ir.sp.size / 8
+        x = upck16(self.vm.vm_get_mem(self.cpu.SP, self.ir_arch.sp.size / 8))
+        self.cpu.SP += self.ir_arch.sp.size / 8
         return x
 
     def get_stack_arg(self, n):
@@ -48,22 +48,22 @@ class jitter_x86_32(jitter):
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_32(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.RIP
-        self.my_ir.do_stk_segm = False
+        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.my_ir.irbloc_fix_regs_for_mode
-        self.my_ir.irbloc_fix_regs_for_mode = self.my_irbloc_fix_regs_for_mode
+        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
 
-    def my_irbloc_fix_regs_for_mode(self, irbloc, attrib=64):
+    def ir_archbloc_fix_regs_for_mode(self, irbloc, attrib=64):
         self.orig_irbloc_fix_regs_for_mode(irbloc, 64)
 
     def vm_push_uint32_t(self, v):
-        self.cpu.ESP -= self.my_ir.sp.size / 8
+        self.cpu.ESP -= self.ir_arch.sp.size / 8
         self.vm.vm_set_mem(self.cpu.ESP, pck32(v))
 
     def vm_pop_uint32_t(self):
-        x = upck32(self.vm.vm_get_mem(self.cpu.ESP, self.my_ir.sp.size / 8))
-        self.cpu.ESP += self.my_ir.sp.size / 8
+        x = upck32(self.vm.vm_get_mem(self.cpu.ESP, self.ir_arch.sp.size / 8))
+        self.cpu.ESP += self.ir_arch.sp.size / 8
         return x
 
     def get_stack_arg(self, n):
@@ -123,7 +123,7 @@ class jitter_x86_32(jitter):
                 log.debug('%s' % repr(fname))
                 raise ValueError('unknown api', hex(jitter.vm_pop_uint32_t()), repr(fname))
             f(jitter)
-            jitter.pc = getattr(jitter.cpu, jitter.my_ir.pc.name)
+            jitter.pc = getattr(jitter.cpu, jitter.ir_arch.pc.name)
             return True
 
         for f_addr in libs.fad2cname:
@@ -139,22 +139,22 @@ class jitter_x86_64(jitter):
     def __init__(self, *args, **kwargs):
         sp = asmbloc.asm_symbol_pool()
         jitter.__init__(self, ir_x86_64(sp), *args, **kwargs)
-        self.my_ir.jit_pc = self.my_ir.arch.regs.RIP
-        self.my_ir.do_stk_segm = False
+        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.my_ir.irbloc_fix_regs_for_mode
-        self.my_ir.irbloc_fix_regs_for_mode = self.my_irbloc_fix_regs_for_mode
+        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
 
-    def my_irbloc_fix_regs_for_mode(self, irbloc, attrib=64):
+    def ir_archbloc_fix_regs_for_mode(self, irbloc, attrib=64):
         self.orig_irbloc_fix_regs_for_mode(irbloc, 64)
 
     def vm_push_uint64_t(self, v):
-        self.cpu.RSP -= self.my_ir.sp.size / 8
+        self.cpu.RSP -= self.ir_arch.sp.size / 8
         self.vm.vm_set_mem(self.cpu.RSP, pck64(v))
 
     def vm_pop_uint64_t(self):
-        x = upck64(self.vm.vm_get_mem(self.cpu.RSP, self.my_ir.sp.size / 8))
-        self.cpu.RSP += self.my_ir.sp.size / 8
+        x = upck64(self.vm.vm_get_mem(self.cpu.RSP, self.ir_arch.sp.size / 8))
+        self.cpu.RSP += self.ir_arch.sp.size / 8
         return x
 
     def get_stack_arg(self, n):
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 40dd835a..57ce3e5e 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -173,23 +173,23 @@ def mov(ir, instr, a, b):
     if b in [ES, CS, SS, DS, FS, GS]:
         b = b.zeroExtend(a.size)
     e = [ExprAff(a, b)]
-    return None, e, []
+    return e, []
 
 
 def xchg(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, b))
     e.append(ExprAff(b, a))
-    return None, e, []
+    return e, []
 
 
 def movzx(ir, instr, a, b):
     e = [ExprAff(a, b.zeroExtend(a.size))]
-    return None, e, []
+    return e, []
 
 def movsx(ir, instr, a, b):
     e = [ExprAff(a, b.signExtend(a.size))]
-    return None, e, []
+    return e, []
 
 
 def lea(ir, instr, a, b):
@@ -197,7 +197,7 @@ def lea(ir, instr, a, b):
     if src.size > a.size:
         src = src[:a.size]
     e = [ExprAff(a, src.zeroExtend(a.size))]
-    return None, e, []
+    return e, []
 
 
 def add(ir, instr, a, b):
@@ -207,7 +207,7 @@ def add(ir, instr, a, b):
     e += update_flag_af(c)
     e += update_flag_add(a, b, c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def xadd(ir, instr, a, b):
@@ -218,7 +218,7 @@ def xadd(ir, instr, a, b):
     e += update_flag_add(b, a, c)
     e.append(ExprAff(b, a))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def adc(ir, instr, a, b):
@@ -229,7 +229,7 @@ def adc(ir, instr, a, b):
     e += update_flag_af(c)
     e += update_flag_add(a, b, c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def sub(ir, instr, a, b):
@@ -239,7 +239,7 @@ def sub(ir, instr, a, b):
     e += update_flag_af(c)
     e += update_flag_sub(a, b, c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 # a-(b+cf)
 
@@ -252,7 +252,7 @@ def sbb(ir, instr, a, b):
     e += update_flag_af(c)
     e += update_flag_sub(a, b, c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def neg(ir, instr, b):
@@ -264,14 +264,14 @@ def neg(ir, instr, b):
     e += update_flag_sub(a, b, c)
     e += update_flag_af(c)
     e.append(ExprAff(b, c))
-    return None, e, []
+    return e, []
 
 
 def l_not(ir, instr, b):
     e = []
     c = ~b
     e.append(ExprAff(b, c))
-    return None, e, []
+    return e, []
 
 
 def l_cmp(ir, instr, a, b):
@@ -280,7 +280,7 @@ def l_cmp(ir, instr, a, b):
     e += update_flag_arith(c)
     e += update_flag_sub(a, b, c)
     e += update_flag_af(c)
-    return None, e, []
+    return e, []
 
 
 def xor(ir, instr, a, b):
@@ -288,7 +288,7 @@ def xor(ir, instr, a, b):
     c = a ^ b
     e += update_flag_logic(c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def l_or(ir, instr, a, b):
@@ -296,7 +296,7 @@ def l_or(ir, instr, a, b):
     c = a | b
     e += update_flag_logic(c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def l_and(ir, instr, a, b):
@@ -304,14 +304,14 @@ def l_and(ir, instr, a, b):
     c = a & b
     e += update_flag_logic(c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def l_test(ir, instr, a, b):
     e = []
     c = a & b
     e += update_flag_logic(c)
-    return None, e, []
+    return e, []
 
 
 
@@ -336,7 +336,7 @@ def l_rol(ir, instr, a, b):
     # hack (only valid if b=1)
     e.append(ExprAff(of, c.msb() ^ new_cf))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def l_ror(ir, instr, a, b):
@@ -348,7 +348,7 @@ def l_ror(ir, instr, a, b):
     # hack (only valid if b=1): when count == 1: a = msb-1(dest)
     e.append(ExprAff(of, (c ^ a).msb()))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def rcl(ir, instr, a, b):
@@ -361,7 +361,7 @@ def rcl(ir, instr, a, b):
     # hack (only valid if b=1)
     e.append(ExprAff(of, c.msb() ^ new_cf))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def rcr(ir, instr, a, b):
@@ -375,7 +375,7 @@ def rcr(ir, instr, a, b):
     e.append(ExprAff(of, (a ^ c).msb()))
     e.append(ExprAff(a, c))
 
-    return None, e, []
+    return e, []
 
 
 def sar(ir, instr, a, b):
@@ -391,7 +391,8 @@ def sar(ir, instr, a, b):
     e_do = [
         ExprAff(cf, new_cf),
         ExprAff(of, ExprInt_from(of, 0)),
-        ExprAff(a, c)
+        ExprAff(a, c),
+        ExprAdd(ir.IRDst, lbl_skip)
     ]
 
     e_do += update_flag_znp(c)
@@ -399,11 +400,13 @@ def sar(ir, instr, a, b):
     # dont generate conditional shifter on constant
     if isinstance(shifter, ExprInt):
         if int(shifter.arg) != 0:
-            return None, e_do, []
+            return e_do, []
         else:
-            return None, [], []
+            return [], []
 
-    return ExprCond(shifter, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e = []
+    e.append(ExprAff(ir.IRDst, ExprCond(shifter, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def shr(ir, instr, a, b):
@@ -421,7 +424,7 @@ def shr(ir, instr, a, b):
     e.append(ExprAff(of, a.msb()))
     e += update_flag_znp(c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def shrd_cl(ir, instr, a, b):
@@ -438,7 +441,7 @@ def shrd_cl(ir, instr, a, b):
     e.append(ExprAff(of, a.msb()))
     e += update_flag_znp(c)
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def shrd(ir, instr, a, b, c):
@@ -455,7 +458,7 @@ def shrd(ir, instr, a, b, c):
     e.append(ExprAff(of, a.msb()))
     e += update_flag_znp(d)
     e.append(ExprAff(a, d))
-    return None, e, []
+    return e, []
 
 
 def sal(ir, instr, a, b):
@@ -471,7 +474,7 @@ def sal(ir, instr, a, b):
     e += update_flag_znp(c)
     e.append(ExprAff(of, c.msb() ^ new_cf))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def shl(ir, instr, a, b):
@@ -487,7 +490,7 @@ def shl(ir, instr, a, b):
     e += update_flag_znp(c)
     e.append(ExprAff(of, c.msb() ^ new_cf))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def shld_cl(ir, instr, a, b):
@@ -514,44 +517,44 @@ def shld(ir, instr, a, b, c):
     e.append(ExprAff(a, ExprCond(shifter,
                                  c,
                                  a)))
-    return None, e, []
+    return e, []
 
 
 # XXX todo ###
 def cmc(ir, instr):
     e = [ExprAff(cf, ExprCond(cf, ExprInt_from(cf, 0), ExprInt_from(cf, 1)))]
-    return None, e, []
+    return e, []
 
 
 def clc(ir, instr):
     e = [ExprAff(cf, ExprInt_from(cf, 0))]
-    return None, e, []
+    return e, []
 
 
 def stc(ir, instr):
     e = [ExprAff(cf, ExprInt_from(cf, 1))]
-    return None, e, []
+    return e, []
 
 
 def cld(ir, instr):
     e = [ExprAff(df, ExprInt_from(df, 0))]
-    return None, e, []
+    return e, []
 
 
 def std(ir, instr):
     e = [ExprAff(df, ExprInt_from(df, 1))]
-    return None, e, []
+    return e, []
 
 
 def cli(ir, instr):
     e = [ExprAff(i_f, ExprInt_from(i_f, 0))]
-    return None, e, []
+    return e, []
 
 
 def sti(ir, instr):
     e = [ExprAff(exception_flags, ExprInt32(EXCEPT_PRIV_INSN))]
     e = []  # XXX TODO HACK
-    return None, e, []
+    return e, []
 
 
 def inc(ir, instr, a):
@@ -563,7 +566,7 @@ def inc(ir, instr, a):
 
     e.append(update_flag_add_of(a, b, c))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 def dec(ir, instr, a):
     e = []
@@ -574,7 +577,7 @@ def dec(ir, instr, a):
 
     e.append(update_flag_add_of(a, b, c))
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def push(ir, instr, a):
@@ -596,7 +599,7 @@ def push(ir, instr, a):
     if ir.do_stk_segm:
         c = ExprOp('segm', SS, c)
     e.append(ExprAff(ExprMem(c, a.size), a))
-    return None, e, []
+    return e, []
 
 
 def pop(ir, instr, a):
@@ -618,26 +621,26 @@ def pop(ir, instr, a):
     if ir.do_stk_segm:
         c = ExprOp('segm', SS, c)
     e.append(ExprAff(a, ExprMem(c, a.size)))
-    return None, e, []
+    return e, []
 
 
 def sete(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(zf, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def setnz(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(zf, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def setl(ir, instr, a):
     e = []
     e.append(
         ExprAff(a, ExprCond(nf - of, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def setg(ir, instr, a):
@@ -645,14 +648,14 @@ def setg(ir, instr, a):
     a0 = ExprInt_from(a, 0)
     a1 = ExprInt_from(a, 1)
     e.append(ExprAff(a, ExprCond(zf, a0, a1) & ExprCond(nf - of, a0, a1)))
-    return None, e, []
+    return e, []
 
 
 def setge(ir, instr, a):
     e = []
     e.append(
         ExprAff(a, ExprCond(nf - of, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def seta(ir, instr, a):
@@ -661,19 +664,19 @@ def seta(ir, instr, a):
                                  ExprInt_from(a, 0),
                                  ExprInt_from(a, 1))))
 
-    return None, e, []
+    return e, []
 
 
 def setae(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(cf, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def setb(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(cf, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def setbe(ir, instr, a):
@@ -682,37 +685,37 @@ def setbe(ir, instr, a):
                                  ExprInt_from(a, 1),
                                  ExprInt_from(a, 0)))
              )
-    return None, e, []
+    return e, []
 
 
 def setns(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(nf, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def sets(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(nf, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def seto(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(of, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def setp(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(pf, ExprInt_from(a, 1), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def setnp(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(pf, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def setle(ir, instr, a):
@@ -720,7 +723,7 @@ def setle(ir, instr, a):
     a0 = ExprInt_from(a, 0)
     a1 = ExprInt_from(a, 1)
     e.append(ExprAff(a, ExprCond(zf, a1, a0) | ExprCond(nf ^ of, a1, a0)))
-    return None, e, []
+    return e, []
 
 
 def setna(ir, instr, a):
@@ -728,7 +731,7 @@ def setna(ir, instr, a):
     a0 = ExprInt_from(a, 0)
     a1 = ExprInt_from(a, 1)
     e.append(ExprAff(a, ExprCond(cf, a1, a0) & ExprCond(zf, a1, a0)))
-    return None, e, []
+    return e, []
 
 
 def setnbe(ir, instr, a):
@@ -737,19 +740,19 @@ def setnbe(ir, instr, a):
                                  ExprInt_from(a, 0),
                                  ExprInt_from(a, 1)))
              )
-    return None, e, []
+    return e, []
 
 
 def setno(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(of, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def setnb(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprCond(cf, ExprInt_from(a, 0), ExprInt_from(a, 1))))
-    return None, e, []
+    return e, []
 
 
 def setalc(ir, instr):
@@ -757,7 +760,7 @@ def setalc(ir, instr):
     e = []
     e.append(
         ExprAff(a, ExprCond(cf, ExprInt_from(a, 0xff), ExprInt_from(a, 0))))
-    return None, e, []
+    return e, []
 
 
 def bswap(ir, instr, a):
@@ -785,7 +788,7 @@ def bswap(ir, instr, a):
     else:
         raise ValueError('the size DOES matter')
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 
 def cmps(ir, instr, size):
@@ -798,19 +801,22 @@ def cmps(ir, instr, size):
     a = ExprMem(mRDI[instr.mode][:s], size)
     b = ExprMem(mRSI[instr.mode][:s], size)
 
-    dummy, e, extra = l_cmp(ir, instr, a, b)
+    e, extra = l_cmp(ir, instr, a, b)
 
     e0 = []
     e0.append(ExprAff(a.arg, a.arg + ExprInt_from(a.arg, size / 8)))
     e0.append(ExprAff(b.arg, b.arg + ExprInt_from(b.arg, size / 8)))
-    e0 = irbloc(lbl_df_0.name, lbl_next, [e0])
+    e0.append(ExprAff(ir.IRDst, lbl_next))
+    e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(ExprAff(a.arg, a.arg - ExprInt_from(a.arg, size / 8)))
     e1.append(ExprAff(b.arg, b.arg - ExprInt_from(b.arg, size / 8)))
-    e1 = irbloc(lbl_df_1.name, lbl_next, [e1])
+    e1.append(ExprAff(ir.IRDst, lbl_next))
+    e1 = irbloc(lbl_df_1.name, [e1])
 
-    return ExprCond(df, lbl_df_1, lbl_df_0), e, [e0, e1]
+    e.append(ExprAff(ir.IRDst, ExprCond(df, lbl_df_1, lbl_df_0)))
+    return e, [e0, e1]
 
 
 def scas(ir, instr, size):
@@ -822,17 +828,21 @@ def scas(ir, instr, size):
     s = instr.v_admode()
     a = ExprMem(mRDI[instr.mode][:s], size)
 
-    dummy, e, extra = l_cmp(ir, instr, mRAX[instr.mode][:size], a)
+    e, extra = l_cmp(ir, instr, mRAX[instr.mode][:size], a)
 
     e0 = []
     e0.append(ExprAff(a.arg, a.arg + ExprInt_from(a.arg, size / 8)))
-    e0 = irbloc(lbl_df_0.name, lbl_next, [e0])
+    e0.append(ExprAff(ir.IRDst, lbl_next))
+    e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(ExprAff(a.arg, a.arg - ExprInt_from(a.arg, size / 8)))
-    e1 = irbloc(lbl_df_1.name, lbl_next, [e1])
+    e1.append(ExprAff(ir.IRDst, lbl_next))
+    e1 = irbloc(lbl_df_1.name, [e1])
+
+    e.append(ExprAff(ir.IRDst, ExprCond(df, lbl_df_1, lbl_df_0)))
 
-    return ExprCond(df, lbl_df_1, lbl_df_0), e, [e0, e1]
+    return e, [e0, e1]
 
 
 def compose_eflag(s=32):
@@ -894,7 +904,7 @@ def popfd(ir, instr):
                               )
                      )
              )
-    return None, e, []
+    return e, []
 
 
 def popfw(ir, instr):
@@ -912,7 +922,7 @@ def popfw(ir, instr):
     e.append(ExprAff(iopl, ExprSlice(tmp, 12, 14)))
     e.append(ExprAff(nt, ExprSlice(tmp, 14, 15)))
     e.append(ExprAff(esp, esp + ExprInt32(2)))
-    return None, e, []
+    return e, []
 
 
 def pushad(ir, instr):
@@ -932,7 +942,7 @@ def pushad(ir, instr):
         c = mRSP[instr.mode][:s] + ExprInt_fromsize(s, -(s / 8) * (i + 1))
         e.append(ExprAff(ExprMem(c, s), regs[i]))
     e.append(ExprAff(mRSP[instr.mode][:s], c))
-    return None, e, []
+    return e, []
 
 
 def popad(ir, instr):
@@ -957,7 +967,7 @@ def popad(ir, instr):
     c = myesp + ExprInt_from(myesp, ((s / 8) * (i + 1)))
     e.append(ExprAff(myesp, c))
 
-    return None, e, []
+    return e, []
 
 
 def call(ir, instr, dst):
@@ -981,6 +991,8 @@ def call(ir, instr, dst):
         e.append(ExprAff(CS, m1))
         e.append(ExprAff(meip, m2))
 
+        e.append(ExprAff(ir.IRDst, m2))
+
         c = myesp + ExprInt_fromsize(s, -s/8)
         e.append(ExprAff(ExprMem(c, size=s).zeroExtend(s), CS.zeroExtend(s)))
 
@@ -989,7 +1001,7 @@ def call(ir, instr, dst):
 
         c = myesp + ExprInt_fromsize(s, (-2*s) / 8)
         e.append(ExprAff(myesp, c))
-        return meip, e, []
+        return e, []
 
 
     c = myesp + ExprInt_fromsize(s, (-s / 8))
@@ -998,9 +1010,10 @@ def call(ir, instr, dst):
         c = ExprOp('segm', SS, c)
     e.append(ExprAff(ExprMem(c, size=s), n))
     e.append(ExprAff(meip, dst.zeroExtend(instr.mode)))
-    if not expr_is_int_or_label(dst):
-        dst = meip
-    return dst, e, []
+    e.append(ExprAff(ir.IRDst, dst.zeroExtend(instr.mode)))
+    #if not expr_is_int_or_label(dst):
+    #    dst = meip
+    return e, []
 
 
 def ret(ir, instr, a=None):
@@ -1021,7 +1034,8 @@ def ret(ir, instr, a=None):
     if ir.do_stk_segm:
         c = ExprOp('segm', SS, c)
     e.append(ExprAff(meip, ExprMem(c, size=s).zeroExtend(s)))
-    return meip, e, []
+    e.append(ExprAff(ir.IRDst, ExprMem(c, size=s).zeroExtend(s)))
+    return e, []
 
 
 def retf(ir, instr, a=None):
@@ -1040,6 +1054,7 @@ def retf(ir, instr, a=None):
     if ir.do_stk_segm:
         c = ExprOp('segm', SS, c)
     e.append(ExprAff(meip, ExprMem(c, size=s).zeroExtend(s)))
+    e.append(ExprAff(ir.IRDst, ExprMem(c, size=s).zeroExtend(s)))
     # e.append(ExprAff(meip, ExprMem(c, size = s)))
     c = myesp + ExprInt_fromsize(s, (s / 8))
     if ir.do_stk_segm:
@@ -1047,7 +1062,7 @@ def retf(ir, instr, a=None):
     e.append(ExprAff(CS, ExprMem(c, size=16)))
 
     e.append(ExprAff(myesp, (myesp + (ExprInt_fromsize(s, (2*s) / 8) + a))))
-    return meip, e, []
+    return e, []
 
 
 def leave(ir, instr):
@@ -1059,7 +1074,7 @@ def leave(ir, instr):
     e.append(ExprAff(mRBP[s], ExprMem(mRBP[instr.mode], size=s)))
     e.append(ExprAff(myesp,
     ExprInt_fromsize(instr.mode, instr.mode / 8) + mRBP[instr.mode]))
-    return None, e, []
+    return e, []
 
 
 def enter(ir, instr, a, b):
@@ -1077,16 +1092,18 @@ def enter(ir, instr, a, b):
                      myebp))
     e.append(ExprAff(myebp, esp_tmp))
     e.append(ExprAff(myesp, myesp - (a + ExprInt_fromsize(s, s / 8))))
-    return None, e, []
+    return e, []
 
 
 def jmp(ir, instr, dst):
     e = []
     meip = mRIP[instr.mode]
     e.append(ExprAff(meip, dst))  # dst.zeroExtend(instr.mode)))
+    e.append(ExprAff(ir.IRDst, dst))  # dst.zeroExtend(instr.mode)))
+
     if isinstance(dst, ExprMem):
         dst = meip
-    return dst, e, []
+    return e, []
 
 
 def jmpf(ir, instr, a):
@@ -1104,7 +1121,8 @@ def jmpf(ir, instr, a):
 
     e.append(ExprAff(CS, m1))
     e.append(ExprAff(meip, m2))
-    return meip, e, []
+    e.append(ExprAff(ir.IRDst, m2))
+    return e, []
 
 
 def jz(ir, instr, dst):
@@ -1112,8 +1130,10 @@ def jz(ir, instr, dst):
     meip = mRIP[instr.mode]
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(zf, dst, n).zeroExtend(instr.mode)
-    e = [ExprAff(meip, dst_o)]
-    return dst_o, e, []
+    e = [ExprAff(meip, dst_o),
+         ExprAff(ir.IRDst, dst_o),
+     ]
+    return e, []
 
 
 def jcxz(ir, instr, dst):
@@ -1122,7 +1142,8 @@ def jcxz(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(mRCX[instr.mode][:16], n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jecxz(ir, instr, dst):
@@ -1131,7 +1152,8 @@ def jecxz(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(mRCX[instr.mode][:32], n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jrcxz(ir, instr, dst):
@@ -1140,7 +1162,8 @@ def jrcxz(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(mRCX[instr.mode], n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jnz(ir, instr, dst):
@@ -1149,7 +1172,8 @@ def jnz(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(zf, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jp(ir, instr, dst):
@@ -1158,7 +1182,8 @@ def jp(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(pf, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jnp(ir, instr, dst):
@@ -1167,7 +1192,8 @@ def jnp(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(pf, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def ja(ir, instr, dst):
@@ -1176,7 +1202,8 @@ def ja(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(cf | zf, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jae(ir, instr, dst):
@@ -1185,7 +1212,8 @@ def jae(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(cf, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jb(ir, instr, dst):
@@ -1194,7 +1222,8 @@ def jb(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(cf, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jbe(ir, instr, dst):
@@ -1203,7 +1232,8 @@ def jbe(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(cf | zf, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jge(ir, instr, dst):
@@ -1212,7 +1242,8 @@ def jge(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(nf - of, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jg(ir, instr, dst):
@@ -1221,7 +1252,8 @@ def jg(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(zf | (nf - of), n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jl(ir, instr, dst):
@@ -1230,7 +1262,8 @@ def jl(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(nf - of, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jle(ir, instr, dst):
@@ -1239,7 +1272,8 @@ def jle(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(zf | (nf - of), dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def js(ir, instr, dst):
@@ -1248,7 +1282,8 @@ def js(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(nf, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jns(ir, instr, dst):
@@ -1257,7 +1292,8 @@ def jns(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(nf, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jo(ir, instr, dst):
@@ -1266,7 +1302,8 @@ def jo(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(of, dst, n).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def jno(ir, instr, dst):
@@ -1275,7 +1312,8 @@ def jno(ir, instr, dst):
     n = ExprId(ir.get_next_label(instr), dst.size)
     dst_o = ExprCond(of, n, dst).zeroExtend(instr.mode)
     e.append(ExprAff(meip, dst_o))
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, dst_o))
+    return e, []
 
 
 def loop(ir, instr, dst):
@@ -1289,8 +1327,9 @@ def loop(ir, instr, dst):
     c = myecx - ExprInt_from(myecx, 1)
     e.append(ExprAff(myecx, c))
     e.append(ExprAff(meip, ExprCond(c, dst, n).zeroExtend(instr.mode)))
-    dst_o = ExprCond(myecx, dst, n).zeroExtend(instr.mode)
-    return dst_o, e, []
+    e.append(ExprAff(ir.IRDst, ExprCond(myecx, dst, n).zeroExtend(instr.mode)))
+    #dst_o = ExprCond(myecx, dst, n).zeroExtend(instr.mode)
+    return e, []
 
 
 def loopne(ir, instr, dst):
@@ -1315,8 +1354,9 @@ def loopne(ir, instr, dst):
                  ExprInt1(1),
                  ExprInt1(0))
     c &= zf ^ ExprInt1(1)
-    dst_o = ExprCond(c, dst, n).zeroExtend(instr.mode)
-    return dst_o, e, []
+    #dst_o = ExprCond(c, dst, n).zeroExtend(instr.mode)
+    e.append(ExprAff(ir.IRDst, ExprCond(c, dst, n).zeroExtend(instr.mode)))
+    return e, []
 
 
 def loope(ir, instr, dst):
@@ -1340,8 +1380,9 @@ def loope(ir, instr, dst):
                  ExprInt1(1),
                  ExprInt1(0))
     c &= zf
-    dst_o = ExprCond(c, dst, n).zeroExtend(instr.mode)
-    return dst_o, e, []
+    #dst_o = ExprCond(c, dst, n).zeroExtend(instr.mode)
+    e.append(ExprAff(ir.IRDst, ExprCond(c, dst, n).zeroExtend(instr.mode)))
+    return e, []
 
 
 # XXX size to do; eflag
@@ -1375,7 +1416,7 @@ def div(ir, instr, a):
     else:
         e.append(ExprAff(s1, c_r[:s]))
         e.append(ExprAff(s2, c_d[:s]))
-    return None, e, []
+    return e, []
 
 # XXX size to do; eflag
 
@@ -1407,7 +1448,7 @@ def idiv(ir, instr, a):
     else:
         e.append(ExprAff(s1, c_r[:s]))
         e.append(ExprAff(s2, c_d[:s]))
-    return None, e, []
+    return e, []
 
 # XXX size to do; eflag
 
@@ -1437,7 +1478,7 @@ def mul(ir, instr, a):
                                   ExprInt1(1),
                                   ExprInt1(0))))
 
-    return None, e, []
+    return e, []
 
 
 def imul(ir, instr, a, b=None, c=None):
@@ -1483,7 +1524,7 @@ def imul(ir, instr, a, b=None, c=None):
             ExprAff(of, ExprCond(result - result[:size].signExtend(size * 2),
                                  ExprInt1(1),
                     ExprInt1(0))))
-    return None, e, []
+    return e, []
 
 
 def cbw(ir, instr):
@@ -1491,7 +1532,7 @@ def cbw(ir, instr):
     tempAL = mRAX[instr.mode][:8]
     tempAX = mRAX[instr.mode][:16]
     e.append(ExprAff(tempAX, tempAL.signExtend(16)))
-    return None, e, []
+    return e, []
 
 
 def cwde(ir, instr):
@@ -1499,7 +1540,7 @@ def cwde(ir, instr):
     tempAX = mRAX[instr.mode][:16]
     tempEAX = mRAX[instr.mode][:32]
     e.append(ExprAff(tempEAX, tempAX.signExtend(32)))
-    return None, e, []
+    return e, []
 
 
 def cdqe(ir, instr):
@@ -1507,7 +1548,7 @@ def cdqe(ir, instr):
     tempEAX = mRAX[instr.mode][:32]
     tempRAX = mRAX[instr.mode][:64]
     e.append(ExprAff(tempRAX, tempEAX.signExtend(64)))
-    return None, e, []
+    return e, []
 
 
 def cwd(ir, instr):
@@ -1517,7 +1558,7 @@ def cwd(ir, instr):
     c = tempAX.signExtend(32)
     e.append(ExprAff(tempAX, c[:16]))
     e.append(ExprAff(tempDX, c[16:32]))
-    return None, e, []
+    return e, []
 
 
 def cdq(ir, instr):
@@ -1527,7 +1568,7 @@ def cdq(ir, instr):
     c = tempEAX.signExtend(64)
     e.append(ExprAff(tempEAX, c[:32]))
     e.append(ExprAff(tempEDX, c[32:64]))
-    return None, e, []
+    return e, []
 
 
 def cqo(ir, instr):
@@ -1537,7 +1578,7 @@ def cqo(ir, instr):
     c = tempEAX.signExtend(128)
     e.append(ExprAff(tempRAX, c[:64]))
     e.append(ExprAff(tempRDX, c[64:127]))
-    return None, e, []
+    return e, []
 
 
 def stos(ir, instr, size):
@@ -1561,16 +1602,18 @@ def stos(ir, instr, size):
 
     e0 = []
     e0.append(ExprAff(addr_o, addr_p))
-    e0 = irbloc(lbl_df_0.name, lbl_next, [e0])
+    e0.append(ExprAff(ir.IRDst, lbl_next))
+    e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(ExprAff(addr_o, addr_m))
-    e1 = irbloc(lbl_df_1.name, lbl_next, [e1])
+    e1.append(ExprAff(ir.IRDst, lbl_next))
+    e1 = irbloc(lbl_df_1.name, [e1])
 
     e = []
     e.append(ExprAff(ExprMem(addr, size), b))
-
-    return ExprCond(df, lbl_df_1, lbl_df_0), e, [e0, e1]
+    e.append(ExprAff(ir.IRDst, ExprCond(df, lbl_df_1, lbl_df_0)))
+    return e, [e0, e1]
 
 
 def lods(ir, instr, size):
@@ -1594,16 +1637,19 @@ def lods(ir, instr, size):
 
     e0 = []
     e0.append(ExprAff(addr_o, addr_p))
-    e0 = irbloc(lbl_df_0.name, lbl_next, [e0])
+    e0.append(ExprAff(ir.IRDst, lbl_next))
+    e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(ExprAff(addr_o, addr_m))
-    e1 = irbloc(lbl_df_1.name, lbl_next, [e1])
+    e1.append(ExprAff(ir.IRDst, lbl_next))
+    e1 = irbloc(lbl_df_1.name, [e1])
 
     e = []
     e.append(ExprAff(b, ExprMem(addr, size)))
 
-    return ExprCond(df, lbl_df_1, lbl_df_0), e, [e0, e1]
+    e.append(ExprAff(ir.IRDst, ExprCond(df, lbl_df_1, lbl_df_0)))
+    return e, [e0, e1]
 
 
 def movs(ir, instr, size):
@@ -1631,14 +1677,17 @@ def movs(ir, instr, size):
     e0 = []
     e0.append(ExprAff(a, a + ExprInt_from(a, size / 8)))
     e0.append(ExprAff(b, b + ExprInt_from(b, size / 8)))
-    e0 = irbloc(lbl_df_0.name, lbl_next, [e0])
+    e0.append(ExprAff(ir.IRDst, lbl_next))
+    e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(ExprAff(a, a - ExprInt_from(a, size / 8)))
     e1.append(ExprAff(b, b - ExprInt_from(b, size / 8)))
-    e1 = irbloc(lbl_df_1.name, lbl_next, [e1])
+    e1.append(ExprAff(ir.IRDst, lbl_next))
+    e1 = irbloc(lbl_df_1.name, [e1])
 
-    return ExprCond(df, lbl_df_1, lbl_df_0), e, [e0, e1]
+    e.append(ExprAff(ir.IRDst, ExprCond(df, lbl_df_1, lbl_df_0)))
+    return e, [e0, e1]
 
 def movsd(ir, instr, a, b):
     e = []
@@ -1648,7 +1697,7 @@ def movsd(ir, instr, a, b):
         a = ExprMem(a.arg, b.size)
 
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 def movsd_dispatch(ir, instr, a = None, b = None):
     if a is None and b is None:
@@ -1712,7 +1761,7 @@ def fcom(ir, instr, a, b = None):
     e.append(ExprAff(float_c3, ExprOp('fcom_c3', a, b)))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def ficom(ir, instr, a, b = None):
@@ -1729,7 +1778,7 @@ def ficom(ir, instr, a, b = None):
     e.append(ExprAff(float_c3, ExprOp('fcom_c3', a, b.zeroExtend(a.size))))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 
@@ -1759,7 +1808,7 @@ def fucomip(ir, instr, a, b):
     e += float_pop()
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fcomp(ir, instr, a, b = None):
@@ -1796,7 +1845,7 @@ def fld(ir, instr, a):
         ExprAff(float_stack_ptr, float_stack_ptr + ExprInt_fromsize(3, 1)))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fst(ir, instr, a):
@@ -1810,7 +1859,7 @@ def fst(ir, instr, a):
     e.append(ExprAff(a, src))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fstp(ir, instr, a):
@@ -1824,7 +1873,7 @@ def fist(ir, instr, a):
     e.append(ExprAff(a, ExprOp('double_to_int_%d' % a.size, float_st0)))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fistp(ir, instr, a):
     dst, e, extra = fist(ir, instr, a)
@@ -1836,7 +1885,7 @@ def fist(ir, instr, a):
     e.append(ExprAff(a, ExprOp('double_to_int_%d' % a.size, float_st0)))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fisttp(ir, instr, a):
     e = []
@@ -1844,7 +1893,7 @@ def fisttp(ir, instr, a):
 
     e += set_float_cs_eip(instr)
     e += float_pop(a)
-    return None, e, []
+    return e, []
 
 
 def fild(ir, instr, a):
@@ -1891,7 +1940,7 @@ def fadd(ir, instr, a, b=None):
     e.append(ExprAff(a, ExprOp('fadd', a, src)))
 
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fiadd(ir, instr, a, b=None):
     if b is None:
@@ -1906,7 +1955,7 @@ def fiadd(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fiadd', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def faddp(ir, instr, a, b=None):
@@ -1923,13 +1972,13 @@ def faddp(ir, instr, a, b=None):
     e.append(ExprAff(float_prev(a), ExprOp('fadd', a, src)))
     e += set_float_cs_eip(instr)
     e += float_pop(a)
-    return None, e, []
+    return e, []
 
 
 def fninit(ir, instr):
     e = []
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fnstenv(ir, instr, a):
@@ -1957,7 +2006,7 @@ def fnstenv(ir, instr, a):
     e.append(ExprAff(ad, float_address[:s]))
     ad = ExprMem(a.arg + ExprInt_from(a.arg, s / 8 * 6), size=16)
     e.append(ExprAff(ad, float_ds))
-    return None, e, []
+    return e, []
 
 
 def fsub(ir, instr, a, b=None):
@@ -1973,7 +2022,7 @@ def fsub(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fsub', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fsubp(ir, instr, a, b=None):
     if b is None:
@@ -1989,7 +2038,7 @@ def fsubp(ir, instr, a, b=None):
     e.append(ExprAff(float_prev(a), ExprOp('fsub', a, src)))
     e += set_float_cs_eip(instr)
     e += float_pop(a)
-    return None, e, []
+    return e, []
 
 
 def fsubr(ir, instr, a, b=None):
@@ -2005,7 +2054,7 @@ def fsubr(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fsub', src, a)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fmul(ir, instr, a, b=None):
@@ -2021,7 +2070,7 @@ def fmul(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fmul', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fimul(ir, instr, a, b=None):
     if b is None:
@@ -2036,7 +2085,7 @@ def fimul(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fimul', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fdiv(ir, instr, a, b=None):
@@ -2052,7 +2101,7 @@ def fdiv(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fdiv', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 def fdivr(ir, instr, a, b=None):
     if b is None:
@@ -2067,7 +2116,7 @@ def fdivr(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fdiv', src, a)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fidiv(ir, instr, a, b=None):
@@ -2083,7 +2132,7 @@ def fidiv(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fidiv', a, src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fidivr(ir, instr, a, b=None):
@@ -2099,7 +2148,7 @@ def fidivr(ir, instr, a, b=None):
         src = b
     e.append(ExprAff(a, ExprOp('fidiv', src, a)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fdivp(ir, instr, a, b=None):
@@ -2117,7 +2166,7 @@ def fdivp(ir, instr, a, b=None):
     e.append(ExprAff(float_prev(a), ExprOp('fdiv', a, src)))
     e += set_float_cs_eip(instr)
     e += float_pop(a)
-    return None, e, []
+    return e, []
 
 
 def fmulp(ir, instr, a, b=None):
@@ -2135,7 +2184,7 @@ def fmulp(ir, instr, a, b=None):
     e.append(ExprAff(float_prev(a), ExprOp('fmul', a, src)))
     e += set_float_cs_eip(instr)
     e += float_pop(a)
-    return None, e, []
+    return e, []
 
 
 def ftan(ir, instr, a):
@@ -2148,7 +2197,7 @@ def ftan(ir, instr, a):
         src = a
     e.append(ExprAff(float_st0, ExprOp('ftan', src)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fxch(ir, instr, a):
@@ -2162,7 +2211,7 @@ def fxch(ir, instr, a):
     e.append(ExprAff(float_st0, src))
     e.append(ExprAff(src, float_st0))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fptan(ir, instr):
@@ -2177,56 +2226,56 @@ def fptan(ir, instr):
     e.append(ExprAff(float_st0, ExprOp('int_32_to_double', ExprInt32(1))))
     e.append(
         ExprAff(float_stack_ptr, float_stack_ptr + ExprInt_fromsize(3, 1)))
-    return None, e, []
+    return e, []
 
 
 def frndint(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('frndint', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fsin(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsin', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fcos(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fcos', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fscale(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fscale', float_st0, float_st1)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def f2xm1(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('f2xm1', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fsqrt(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fsqrt', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fabs(ir, instr):
     e = []
     e.append(ExprAff(float_st0, ExprOp('fabs', float_st0)))
     e += set_float_cs_eip(instr)
-    return None, e, []
+    return e, []
 
 
 def fnstsw(ir, instr, dst):
@@ -2238,34 +2287,34 @@ def fnstsw(ir, instr, dst):
             (float_c3,           14, 15),
             (ExprInt1(0), 15, 16)]
     e = [ExprAff(dst, ExprCompose(args))]
-    return None, e, []
+    return e, []
 
 
 def fnstcw(ir, instr, a):
     e = []
     e.append(ExprAff(a, float_control))
-    return None, e, []
+    return e, []
 
 
 def fldcw(ir, instr, a):
     e = []
     e.append(ExprAff(float_control, a))
-    return None, e, []
+    return e, []
 
 
 def fwait(ir, instr):
-    return None, [], None
+    return [], None
 
 
 def nop(ir, instr, a=None):
-    return None, [], []
+    return [], []
 
 
 def hlt(ir, instr):
     e = []
     except_int = EXCEPT_PRIV_INSN
     e.append(ExprAff(exception_flags, ExprInt32(except_int)))
-    return None, e, []
+    return e, []
 
 
 def rdtsc(ir, instr):
@@ -2275,12 +2324,12 @@ def rdtsc(ir, instr):
     e.append(ExprAff(tsc1, tsc1 + ExprInt32(1)))
     e.append(ExprAff(myEAX, tsc1))
     e.append(ExprAff(myEDX, tsc2))
-    return None, e, []
+    return e, []
 
 
 # XXX TODO
 def daa(ir, instr):
-    return None, [], None
+    return [], None
 
 
 def aam(ir, instr, a):
@@ -2293,7 +2342,7 @@ def aam(ir, instr, a):
                          ])
     e += [ExprAff(mRAX[instr.mode], newEAX)]
     e += update_flag_arith(newEAX)
-    return None, e, []
+    return e, []
 
 
 def aad(ir, instr, a):
@@ -2308,7 +2357,7 @@ def aad(ir, instr, a):
                          ])
     e += [ExprAff(mRAX[instr.mode], newEAX)]
     e += update_flag_arith(newEAX)
-    return None, e, []
+    return e, []
 
 
 def aaa(ir, instr, ):
@@ -2336,7 +2385,7 @@ def aaa(ir, instr, ):
         (mRAX[instr.mode][16:], 16, mRAX[instr.mode].size)])))
     e.append(ExprAff(af, c))
     e.append(ExprAff(cf, c))
-    return None, e, []
+    return e, []
 
 
 def aas(ir, instr, ):
@@ -2364,7 +2413,7 @@ def aas(ir, instr, ):
         (mRAX[instr.mode][16:], 16, mRAX[instr.mode].size)])))
     e.append(ExprAff(af, c))
     e.append(ExprAff(cf, c))
-    return None, e, []
+    return e, []
 
 
 def bsf(ir, instr, a, b):
@@ -2375,7 +2424,9 @@ def bsf(ir, instr, a, b):
 
     e_do = []
     e_do.append(ExprAff(a, ExprOp('bsf', b)))
-    return ExprCond(b, lbl_do, lbl_skip), e, [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(b, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def bsr(ir, instr, a, b):
@@ -2386,19 +2437,21 @@ def bsr(ir, instr, a, b):
 
     e_do = []
     e_do.append(ExprAff(a, ExprOp('bsr', b)))
-    return ExprCond(b, lbl_do, lbl_skip), e, [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(b, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def arpl(ir, instr, a, b):
     e = []
     e.append(ExprAff(exception_flags, ExprInt32(1 << 7)))
-    return None, e, []
+    return e, []
 
 
 def ins(ir, instr, size):
     e = []
     e.append(ExprAff(exception_flags, ExprInt32(1 << 7)))
-    return None, e, []
+    return e, []
 
 
 def sidt(ir, instr, a):
@@ -2411,112 +2464,160 @@ def sidt(ir, instr, a):
     e.append(
         ExprAff(ExprMem(ExprOp("+", b,
         ExprInt_from(b, 4)), 16), ExprInt16(0x8245)))
-    return None, e, []
+    return e, []
 
 
 def sldt(ir, instr, a):
     # XXX TOOD
     e = [ExprAff(exception_flags, ExprInt32(EXCEPT_PRIV_INSN))]
-    return None, e, []
+    return e, []
 
 
 def cmovz(ir, instr, a, b):
+    e = []
     lbl_do = ExprId(ir.gen_label(), instr.mode)
     lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
-
-    dum, e_do, extra_irs = mov(ir, instr, a, b)
-    return ExprCond(zf, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovnz(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(zf, a, b)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovge(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(nf ^ of, a, b)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovg(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(zf | (nf ^ of), a, b)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf | (nf ^ of), lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovl(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(nf ^ of, b, a)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovle(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond((nf ^ of) | zf, b, a)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf | (nf ^ of), lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmova(ir, instr, a, b):
+    e = []
     lbl_do = ExprId(ir.gen_label(), instr.mode)
     lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
-    dum, e_do, extra_irs = mov(ir, instr, a, b)
-    return ExprCond(cf | zf, lbl_skip, lbl_do), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf | zf, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovae(ir, instr, a, b):
+    e = []
     lbl_do = ExprId(ir.gen_label(), instr.mode)
     lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
-    dum, e_do, extra_irs = mov(ir, instr, a, b)
-    return ExprCond(cf, lbl_skip, lbl_do), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovbe(ir, instr, a, b):
+    e = []
     lbl_do = ExprId(ir.gen_label(), instr.mode)
     lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
-    dum, e_do, extra_irs = mov(ir, instr, a, b)
-    return ExprCond(cf | zf, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf | zf, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovb(ir, instr, a, b):
+    e = []
     lbl_do = ExprId(ir.gen_label(), instr.mode)
     lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
-    dum, e_do, extra_irs = mov(ir, instr, a, b)
-    return ExprCond(cf, lbl_do, lbl_skip), [], [irbloc(lbl_do.name, lbl_skip, [e_do])]
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovo(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(of, b, a)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(of, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovno(ir, instr, a, b):
     e = []
-    e.append(ExprAff(a, ExprCond(of, a, b)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(of, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovs(ir, instr, a, b):
     e = []
-    # SF is called nf in miasm
-    e.append(ExprAff(a, ExprCond(nf, b, a)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf, lbl_do, lbl_skip)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def cmovns(ir, instr, a, b):
     e = []
-    # SF is called nf in miasm
-    e.append(ExprAff(a, ExprCond(nf, a, b)))
-    return None, e, []
+    lbl_do = ExprId(ir.gen_label(), instr.mode)
+    lbl_skip = ExprId(ir.get_next_label(instr), instr.mode)
+    e_do, extra_irs = mov(ir, instr, a, b)
+    e_do.append(ExprAff(ir.IRDst, lbl_skip))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf, lbl_skip, lbl_do)))
+    return e, [irbloc(lbl_do.name, [e_do])]
 
 
 def icebp(ir, instr):
     e = []
     e.append(ExprAff(exception_flags,
                      ExprInt32(EXCEPT_PRIV_INSN)))
-    return None, e, []
+    return e, []
 # XXX
 
 
@@ -2529,14 +2630,14 @@ def l_int(ir, instr, a):
         except_int = EXCEPT_INT_XX
     e.append(ExprAff(exception_flags,
                      ExprInt32(except_int)))
-    return None, e, []
+    return e, []
 
 
 def l_sysenter(ir, instr):
     e = []
     e.append(ExprAff(exception_flags,
                      ExprInt32(EXCEPT_PRIV_INSN)))
-    return None, e, []
+    return e, []
 
 # XXX
 
@@ -2545,7 +2646,7 @@ def l_out(ir, instr, a, b):
     e = []
     e.append(ExprAff(exception_flags,
                      ExprInt32(EXCEPT_PRIV_INSN)))
-    return None, e, []
+    return e, []
 
 # XXX
 
@@ -2554,7 +2655,7 @@ def l_outs(ir, instr, size):
     e = []
     e.append(ExprAff(exception_flags,
                      ExprInt32(EXCEPT_PRIV_INSN)))
-    return None, e, []
+    return e, []
 
 # XXX actually, xlat performs al = (ds:[e]bx + ZeroExtend(al))
 
@@ -2565,7 +2666,7 @@ def xlat(ir, instr):
                      (mRAX[instr.mode][0:8], 0, 8)])
     b = ExprMem(ExprOp('+', mRBX[instr.mode], a), 8)
     e.append(ExprAff(mRAX[instr.mode][0:8], b))
-    return None, e, []
+    return e, []
 
 
 def cpuid(ir, instr):
@@ -2582,7 +2683,7 @@ def cpuid(ir, instr):
     e.append(
         ExprAff(mRDX[instr.mode],
         ExprOp('cpuid', mRAX[instr.mode], ExprInt32(3))))
-    return None, e, []
+    return e, []
 
 
 def bittest_get(a, b):
@@ -2609,7 +2710,7 @@ def bt(ir, instr, a, b):
     d, off_bit = bittest_get(a, b)
     d = d >> off_bit
     e.append(ExprAff(cf, d[:1]))
-    return None, e, []
+    return e, []
 
 
 def btc(ir, instr, a, b):
@@ -2620,7 +2721,7 @@ def btc(ir, instr, a, b):
     m = ExprInt_from(a, 1) << off_bit
     e.append(ExprAff(d, d ^ m))
 
-    return None, e, []
+    return e, []
 
 
 def bts(ir, instr, a, b):
@@ -2630,7 +2731,7 @@ def bts(ir, instr, a, b):
     m = ExprInt_from(a, 1) << off_bit
     e.append(ExprAff(d, d | m))
 
-    return None, e, []
+    return e, []
 
 
 def btr(ir, instr, a, b):
@@ -2640,18 +2741,18 @@ def btr(ir, instr, a, b):
     m = ~(ExprInt_from(a, 1) << off_bit)
     e.append(ExprAff(d, d & m))
 
-    return None, e, []
+    return e, []
 
 
 def into(ir, instr):
-    return None, [], None
+    return [], None
 
 
 def l_in(ir, instr, a, b):
     e = []
     e.append(ExprAff(exception_flags,
                      ExprInt32(EXCEPT_PRIV_INSN)))
-    return None, e, []
+    return e, []
 
 
 def cmpxchg(ir, instr, a, b):
@@ -2669,7 +2770,7 @@ def cmpxchg(ir, instr, a, b):
                                  a,
                                  c)
                      ))
-    return None, e, []
+    return e, []
 
 
 def lds(ir, instr, a, b):
@@ -2677,7 +2778,7 @@ def lds(ir, instr, a, b):
     e.append(ExprAff(a, ExprMem(b.arg, size=a.size)))
     e.append(ExprAff(DS, ExprMem(b.arg + ExprInt_from(b.arg, a.size/8),
                                  size=16)))
-    return None, e, []
+    return e, []
 
 
 def les(ir, instr, a, b):
@@ -2685,7 +2786,7 @@ def les(ir, instr, a, b):
     e.append(ExprAff(a, ExprMem(b.arg, size=a.size)))
     e.append(ExprAff(ES, ExprMem(b.arg + ExprInt_from(b.arg, a.size/8),
                                  size=16)))
-    return None, e, []
+    return e, []
 
 
 def lss(ir, instr, a, b):
@@ -2693,21 +2794,21 @@ def lss(ir, instr, a, b):
     e.append(ExprAff(a, ExprMem(b.arg, size=a.size)))
     e.append(ExprAff(SS, ExprMem(b.arg + ExprInt_from(b.arg, a.size/8),
                                  size=16)))
-    return None, e, []
+    return e, []
 
 def lfs(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprMem(b.arg, size=a.size)))
     e.append(ExprAff(FS, ExprMem(b.arg + ExprInt_from(b.arg, a.size/8),
                                  size=16)))
-    return None, e, []
+    return e, []
 
 def lgs(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprMem(b.arg, size=a.size)))
     e.append(ExprAff(GS, ExprMem(b.arg + ExprInt_from(b.arg, a.size/8),
                                  size=16)))
-    return None, e, []
+    return e, []
 
 
 def lahf(ir, instr):
@@ -2717,7 +2818,7 @@ def lahf(ir, instr):
     for i in xrange(len(regs)):
         args.append((regs[i], i, i + 1))
     e.append(ExprAff(mRAX[instr.mode][8:16], ExprCompose(args)))
-    return None, e, []
+    return e, []
 
 
 def sahf(ir, instr):
@@ -2728,37 +2829,37 @@ def sahf(ir, instr):
     e.append(ExprAff(af, tmp[4:5]))
     e.append(ExprAff(zf, tmp[6:7]))
     e.append(ExprAff(nf, tmp[7:8]))
-    return None, e, []
+    return e, []
 
 
 def lar(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprOp('access_segment', b)))
     e.append(ExprAff(zf, ExprOp('access_segment_ok', b)))
-    return None, e, []
+    return e, []
 
 
 def lsl(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprOp('load_segment_limit', b)))
     e.append(ExprAff(zf, ExprOp('load_segment_limit_ok', b)))
-    return None, e, []
+    return e, []
 
 
 def fclex(ir, instr):
     # XXX TODO
-    return None, [], None
+    return [], None
 
 
 def fnclex(ir, instr):
     # XXX TODO
-    return None, [], None
+    return [], None
 
 
 def l_str(ir, instr, a):
     e = []
     e.append(ExprAff(a, ExprOp('load_tr_segment_selector', ExprInt32(0))))
-    return None, e, []
+    return e, []
 
 
 def movd(ir, instr, a, b):
@@ -2767,7 +2868,7 @@ def movd(ir, instr, a, b):
         e.append(ExprAff(a, ExprCompose([(ExprInt32(0), 32, 64), (b, 0, 32)])))
     else:
         e.append(ExprAff(a, b[0:32]))
-    return None, e, []
+    return e, []
 
 
 def xorps(ir, instr, a, b):
@@ -2775,7 +2876,7 @@ def xorps(ir, instr, a, b):
     if isinstance(b, ExprMem):
         b = ExprMem(b.arg, a.size)
     e.append(ExprAff(a, ExprOp('xorps', a, b)))
-    return None, e, []
+    return e, []
 
 ### MMX/SSE/AVX operations
 ###
@@ -2809,7 +2910,7 @@ def __vec_vertical_instr_gen(op, elt_size, sem):
             b = ExprMem(b.arg, a.size)
         reg_size = a.size
         e.append(ExprAff(a, sem(op, elt_size, reg_size, a, b)))
-        return None, e, []
+        return e, []
     return vec_instr
 
 def vec_vertical_instr(op, elt_size):
@@ -2861,7 +2962,7 @@ def pand(ir, instr, a, b):
     c = a & b
     # No flag affected
     e.append(ExprAff(a, c))
-    return None, e, []
+    return e, []
 
 def movaps(ir, instr, a, b):
     e = []
@@ -2870,25 +2971,25 @@ def movaps(ir, instr, a, b):
     if isinstance(b, ExprMem):
         b = ExprMem(b.arg, a.size)
     e.append(ExprAff(a, b))
-    return None, e, []
+    return e, []
 
 
 def pminsw(ir, instr, a, b):
     e = []
     e.append(ExprAff(a, ExprCond((a - b).msb(), a, b)))
-    return None, e, []
+    return e, []
 
 
 def cvtsi2sd(ir, instr, a, b):
     e = []
     e.append(ExprAff(a[:b.size], ExprOp('cvtsi2sd', b)))
-    return None, e, []
+    return e, []
 
 
 def movss(ir, instr, a, b):
     e = []
     e.append(ExprAff(a[:b.size], ExprOp('movss', b)))
-    return None, e, []
+    return e, []
 
 
 def ucomiss(ir, instr, a, b):
@@ -2901,7 +3002,7 @@ def ucomiss(ir, instr, a, b):
     e.append(ExprAff(af, ExprInt1(0)))
     e.append(ExprAff(nf, ExprInt1(0)))
 
-    return None, e, []
+    return e, []
 
 mnemo_func = {'mov': mov,
               'xchg': xchg,
@@ -3232,6 +3333,7 @@ class ir_x86_16(ir):
         self.do_all_segm = False
         self.pc = IP
         self.sp = SP
+        self.IRDst = ExprId('IRDst', 16)
 
     def mod_pc(self, instr, instr_ir, extra_ir):
         pass
@@ -3249,7 +3351,7 @@ class ir_x86_16(ir):
                 if isinstance(a, ExprMem) and not a.is_op_segm():
                     args[i] = ExprMem(ExprOp('segm', my_ss, a.arg), a.size)
 
-        dst, instr_ir, extra_ir = mnemo_func[
+        instr_ir, extra_ir = mnemo_func[
             instr.name.lower()](self, instr, *args)
         self.mod_pc(instr, instr_ir, extra_ir)
 
@@ -3257,9 +3359,9 @@ class ir_x86_16(ir):
         instr.additional_info.except_on_instr = False
         if instr.additional_info.g1.value & 6 == 0 or \
                 not instr.name in repeat_mn:
-            return dst, instr_ir, extra_ir
+            return instr_ir, extra_ir
         if instr.name == "MOVSD" and len(instr.args) == 2:
-            return dst, instr_ir, extra_ir
+            return instr_ir, extra_ir
 
         instr.additional_info.except_on_instr = True
         # get instruction size
@@ -3292,21 +3394,19 @@ class ir_x86_16(ir):
         lbl_next = ExprId(self.get_next_label(instr), instr.mode)
 
         for b in extra_ir:
-            # print repr(b)
-            # print b
-            # self.replace_expr_in_ir(b, {lbl_next:lbl_end})
-            b.dst = b.dst.replace_expr({lbl_next: lbl_end})
-            # print b
-
+            for ir in b.irs:
+                for e in ir:
+                    e.src = e.src.replace_expr({lbl_next: lbl_end})
         cond_bloc = []
         cond_bloc.append(ExprAff(c_reg, c_reg - ExprInt_from(c_reg, 1)))
-        cond_bloc = irbloc(
-            lbl_end.name, ExprCond(c_cond, lbl_skip, lbl_do), [cond_bloc])
+        cond_bloc.append(ExprAff(self.IRDst, ExprCond(c_cond, lbl_skip, lbl_do)))
+        cond_bloc = irbloc(lbl_end.name, [cond_bloc])
         e_do = instr_ir
 
-        c = irbloc(lbl_do.name, dst, [e_do])
+        c = irbloc(lbl_do.name, [e_do])
         c.except_automod = False
-        return ExprCond(c_reg, lbl_do, lbl_skip), [], [cond_bloc, c] + extra_ir
+        e_n = [ExprAff(self.IRDst, ExprCond(c_reg, lbl_do, lbl_skip))]
+        return e_n, [cond_bloc, c] + extra_ir
 
     def expr_fix_regs_for_mode(self, e, mode=64):
         return e.replace_expr(replace_regs[mode])
@@ -3343,6 +3443,7 @@ class ir_x86_32(ir_x86_16):
         self.do_all_segm = False
         self.pc = EIP
         self.sp = ESP
+        self.IRDst = ExprId('IRDst', 32)
 
 
 class ir_x86_64(ir_x86_16):
@@ -3355,6 +3456,7 @@ class ir_x86_64(ir_x86_16):
         self.do_all_segm = False
         self.pc = RIP
         self.sp = RSP
+        self.IRDst = ExprId('IRDst', 64)
 
     def mod_pc(self, instr, instr_ir, extra_ir):
         # fix RIP for 64 bit
diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py
index fc2edd30..ac317e0b 100644
--- a/miasm2/core/asmbloc.py
+++ b/miasm2/core/asmbloc.py
@@ -800,8 +800,7 @@ def gen_non_free_mapping(group_bloc, dont_erase=[]):
     return non_free_mapping
 
 
-def resolve_symbol(
-    group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF):
+def resolve_symbol(group_bloc, symbol_pool, dont_erase=[], max_offset=0xFFFFFFFF):
     """
     place all asmblocs
     """
diff --git a/miasm2/ir/analysis.py b/miasm2/ir/analysis.py
index c20c7f7a..eaa5f6c8 100644
--- a/miasm2/ir/analysis.py
+++ b/miasm2/ir/analysis.py
@@ -94,7 +94,6 @@ class ira:
                 for l in irs:
                     ir_txt.append(str(l))
                 ir_txt.append("")
-            ir_txt.append("DstBloc: %s" % str(b.dst))
             ir_txt.append("")
             all_lbls[id(lbl)] = "\l\\\n".join(ir_txt)
         for l, v in all_lbls.items():
@@ -212,7 +211,7 @@ class ira:
                 x = ExprId(r.name, r.size)
                 x.is_term = True
                 symbols_init[r] = x
-            sb = symbexec(self.arch, dict(symbols_init))
+            sb = symbexec(self, dict(symbols_init))
             sb.emulbloc(irb)
             eqs = []
             for n_w in sb.symbols:
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index a5d079ca..9db6d696 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -30,17 +30,29 @@ from miasm2.core.asmbloc import asm_symbol_pool
 
 class irbloc:
 
-    def __init__(self, label, dst=None, irs=None, lines=None):
+    def __init__(self, label, irs, lines = []):
         assert(isinstance(label, asmbloc.asm_label))
         self.label = label
-        self.dst = dst
-        self.lines = []
-        self.irs = []
-        if irs is not None:
-            self.irs = irs
-        if lines is not None:
-            self.lines = lines
+        self.irs = irs
+        self.lines = lines
         self.except_automod = True
+        self._dst = None
+
+
+    def get_dst(self):
+        if self._dst is not None:
+            return self._dst
+        dst = None
+        for ir in self.irs:
+            for i in ir:
+                if isinstance(i.dst, m2_expr.ExprId) and i.dst.name == "IRDst":
+                    if dst is not None:
+                        raise ValueError('Multiple destinations!')
+                    dst = i.src
+        self._dst = dst
+        return dst
+
+    dst = property(get_dst)
 
     def get_rw(self):
         self.r = []
@@ -82,7 +94,6 @@ class irbloc:
             for e in expr:
                 o.append('\t%s' % e)
             o.append("")
-        o.append('\tDst: %s' % self.dst)
 
         return "\n".join(o)
 
@@ -100,8 +111,8 @@ class ir(object):
         self.attrib = attrib
 
     def instr2ir(self, l):
-        dst, ir_bloc_cur, ir_blocs_extra = self.get_ir(l)
-        return dst, ir_bloc_cur, ir_blocs_extra
+        ir_bloc_cur, ir_blocs_extra = self.get_ir(l)
+        return ir_bloc_cur, ir_blocs_extra
 
     def get_bloc(self, ad):
         if isinstance(ad, m2_expr.ExprId) and isinstance(ad.name,
@@ -194,28 +205,19 @@ class ir(object):
         ir_blocs_all = []
         for l in bloc.lines:
             if c is None:
-                # print 'new c'
                 label = self.get_label(l)
-                c = irbloc(label)
+                c = irbloc(label, [], [])
                 ir_blocs_all.append(c)
-                bloc_dst = None
-            # print 'Translate', l
-            dst, ir_bloc_cur, ir_blocs_extra = self.instr2ir(l)
-            # print ir_bloc_cur
-            # for xxx in ir_bloc_cur:
-            #    print "\t", xxx
-            assert((dst is None) or (bloc_dst is None))
-            bloc_dst = dst
-            if bloc_dst is not None:
-                c.dst = bloc_dst
+            ir_bloc_cur, ir_blocs_extra = self.instr2ir(l)
 
             if gen_pc_updt is not False:
                 self.gen_pc_update(c, l)
 
             c.irs.append(ir_bloc_cur)
             c.lines.append(l)
+
+
             if ir_blocs_extra:
-                # print 'split'
                 for b in ir_blocs_extra:
                     b.lines = [l] * len(b.irs)
                 ir_blocs_all += ir_blocs_extra
@@ -246,7 +248,8 @@ class ir(object):
                 continue
             dst = m2_expr.ExprId(self.get_next_label(bloc.lines[-1]),
                                  self.pc.size)
-            b.dst = dst
+            b.irs.append([m2_expr.ExprAff(self.IRDst, dst)])
+            b.lines.append(b.lines[-1])
 
     def gen_edges(self, bloc, ir_blocs):
         pass
diff --git a/miasm2/ir/ir2C.py b/miasm2/ir/ir2C.py
index 76620dc8..136f3e85 100644
--- a/miasm2/ir/ir2C.py
+++ b/miasm2/ir/ir2C.py
@@ -257,10 +257,12 @@ if (vmcpu->exception_flags && vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) {
 code_exception_post_instr = r"""
 // except post instr
 if (vmcpu->exception_flags) {
-    if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP)
+    if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) {
       %s;
-    else
+    }
+    else {
       %s;
+    }
     RETURN_PC;
 }
 """
@@ -275,14 +277,21 @@ if ((vmcpu->exception_flags & ~EXCEPT_CODE_AUTOMOD) && vmcpu->exception_flags >
 
 code_exception_post_instr_noautomod = r"""
 if (vmcpu->exception_flags & ~EXCEPT_CODE_AUTOMOD) {
-    if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP)
+    if (vmcpu->exception_flags > EXCEPT_NUM_UPDT_EIP) {
       %s;
-    else
+    }
+    else {
       %s;
+    }
     RETURN_PC;
 }
 """
 
+goto_local_code = r"""
+if (BlockDst.is_local) {
+    goto *local_labels[BlockDst.address];
+}
+"""
 
 my_size_mask = {1: 1, 2: 3, 3: 7, 7: 0x7f,
                 8: 0xFF,
@@ -293,15 +302,59 @@ my_size_mask = {1: 1, 2: 3, 3: 7, 7: 0x7f,
 exception_flags = ExprId('exception_flags', 32)
 
 
-def set_pc(my_ir, src):
-    dst = my_ir.jit_pc
+def set_pc(ir_arch, src):
+    dst = ir_arch.jit_pc
     if not isinstance(src, Expr):
         src = ExprInt_from(dst, src)
     e = ExprAff(dst, src.zeroExtend(dst.size))
     return e
 
 
-def Expr2C(my_ir, l, exprs, gen_exception_code=False):
+def gen_resolve_int(ir_arch, e):
+    return 'Resolve_dst(%X, 0)'%(e)
+
+def gen_resolve_id_lbl(ir_arch, e):
+    if e.name.name.startswith("lbl_gen_"):
+        # TODO XXX CLEAN
+        return 'Resolve_dst(0x%X, 1)'%(e.name.index)
+    else:
+        return 'Resolve_dst(0x%X, 0)'%(e.name.offset)
+
+def gen_resolve_id(ir_arch, e):
+    return 'Resolve_dst(%s, 0)'%(patch_c_id(ir_arch.arch, e).toC())
+
+def gen_resolve_mem(ir_arch, e):
+    return 'Resolve_dst(%s, 0)'%(patch_c_id(ir_arch.arch, e).toC())
+
+def gen_resolve_other(ir_arch, e):
+    return 'Resolve_dst(%s, 0)'%(patch_c_id(ir_arch.arch, e).toC())
+
+def gen_resolve_dst_simple(ir_arch, e):
+    if isinstance(e, ExprInt):
+        return gen_resolve_int(ir_arch, e)
+    elif isinstance(e, ExprId) and isinstance(e.name, asmbloc.asm_label):
+        return gen_resolve_id_lbl(ir_arch, e)
+    elif isinstance(e, ExprId):
+        return gen_resolve_id(ir_arch, e)
+    elif isinstance(e, 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, ExprCond):
+        dst_cond_c = patch_c_id(ir_arch.arch, e.cond).toC()
+        out.append("if (%s)"%dst_cond_c)
+        out.append('    BlockDst = %s;'%(gen_resolve_dst_simple(ir_arch, e.src1)))
+        out.append("else")
+        out.append('    BlockDst = %s;'%(gen_resolve_dst_simple(ir_arch, e.src2)))
+    else:
+        out.append('BlockDst = %s;'%(gen_resolve_dst_simple(ir_arch, e)))
+    return out
+
+def Expr2C(ir_arch, l, exprs, gen_exception_code=False):
     id_to_update = []
     out = ["// %s" % (l)]
     out_pc = []
@@ -312,8 +365,8 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
     prefect_index = {8: 0, 16: 0, 32: 0, 64: 0}
     new_expr = []
 
-    e = set_pc(my_ir, l.offset & mask_int)
-    #out.append("%s;" % patch_c_id(my_ir.arch, e).toC())
+    e = set_pc(ir_arch, l.offset & mask_int)
+    #out.append("%s;" % patch_c_id(ir_arch.arch, e).toC())
 
     pc_is_dst = False
     fetch_mem = False
@@ -360,22 +413,31 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
     mem_k = src_mem.keys()
     mem_k.sort()
     for k in mem_k:
-        str_src = patch_c_id(my_ir.arch, k).toC()
-        str_dst = patch_c_id(my_ir.arch, src_mem[k]).toC()
+        str_src = patch_c_id(ir_arch.arch, k).toC()
+        str_dst = patch_c_id(ir_arch.arch, src_mem[k]).toC()
         out.append('%s = %s;' % (str_dst, str_src))
     src_w_len = {}
     for k, v in src_mem.items():
         src_w_len[k] = v
     for e in new_expr:
+
         src, dst = e.src, e.dst
         # reload src using prefetch
         src = src.replace_expr(src_w_len)
-        str_src = patch_c_id(my_ir.arch, src).toC()
-        str_dst = patch_c_id(my_ir.arch, dst).toC()
+        if dst is ir_arch.IRDst:
+            out += gen_irdst(ir_arch, src)
+            continue
+
+
+        str_src = patch_c_id(ir_arch.arch, src).toC()
+        str_dst = patch_c_id(ir_arch.arch, dst).toC()
+
+
+
         if isinstance(dst, ExprId):
             id_to_update.append(dst)
-            str_dst = patch_c_new_id(my_ir.arch, dst)
-            if dst in my_ir.arch.regs.regs_flt_expr:
+            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:
@@ -386,7 +448,7 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
             str_dst = str_dst.replace('MEM_LOOKUP', 'MEM_WRITE')
             out_mem.append('%s, %s);' % (str_dst[:-1], str_src))
 
-        if e.dst == my_ir.arch.pc[my_ir.attrib]:
+        if e.dst == ir_arch.arch.pc[ir_arch.attrib]:
             pc_is_dst = True
             out_pc += ["RETURN_PC;"]
 
@@ -397,17 +459,21 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
 
     if gen_exception_code:
         if fetch_mem:
-            e = set_pc(my_ir, l.offset & mask_int)
-            s1 = "%s" % patch_c_id(my_ir.arch, e).toC()
+            e = set_pc(ir_arch, l.offset & mask_int)
+            s1 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+            s1 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%(l.offset & mask_int)
             out.append(code_exception_fetch_mem_at_instr_noautomod % s1)
         if set_exception_flags:
-            e = set_pc(my_ir, l.offset & mask_int)
-            s1 = "%s" % patch_c_id(my_ir.arch, e).toC()
+            e = set_pc(ir_arch, l.offset & mask_int)
+            s1 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+            s1 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%(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(my_ir.arch, i), patch_c_new_id(my_ir.arch, i)))
+                   (patch_c_id(ir_arch.arch, i), patch_c_new_id(ir_arch.arch, i)))
 
     post_instr = []
     # test stop exec ####
@@ -417,10 +483,12 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
                 post_instr.append("if (vm_mngr->exception_flags) { " +
                     "/*pc = 0x%X; */RETURN_PC; }" % (l.offset))
             else:
-                e = set_pc(my_ir, l.offset & mask_int)
-                s1 = "%s" % patch_c_id(my_ir.arch, e).toC()
-                e = set_pc(my_ir, (l.offset + l.l) & mask_int)
-                s2 = "%s" % patch_c_id(my_ir.arch, e).toC()
+                e = set_pc(ir_arch, l.offset & mask_int)
+                s1 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+                s1 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%(l.offset & mask_int)
+                e = set_pc(ir_arch, (l.offset + l.l) & mask_int)
+                s2 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+                s2 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%((l.offset + l.l) & mask_int)
                 post_instr.append(
                     code_exception_post_instr_noautomod % (s1, s2))
 
@@ -430,8 +498,9 @@ def Expr2C(my_ir, l, exprs, gen_exception_code=False):
             else:
                 offset = l.offset + l.l
 
-            e = set_pc(my_ir, offset & mask_int)
-            s1 = "%s" % patch_c_id(my_ir.arch, e).toC()
+            e = set_pc(ir_arch, offset & mask_int)
+            s1 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+            s1 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%(offset & mask_int)
             post_instr.append(
                 code_exception_fetch_mem_post_instr_noautomod % (s1))
 
@@ -459,17 +528,19 @@ def expr2pyobj(arch, e):
     return src_c
 
 
-def ir2C(my_ir, irbloc, lbl_done,
+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, exprs in zip(irbloc.lines, irbloc.irs):
         if l.offset not in lbl_done:
-            e = set_pc(my_ir, l.offset & mask_int)
-            s1 = "%s" % patch_c_id(my_ir.arch, e).toC()
+            e = set_pc(ir_arch, l.offset & mask_int)
+            s1 = "%s" % patch_c_id(ir_arch.arch, e).toC()
+            s1 += ';\n    BlockDst = Resolve_dst(0x%X, 0);\n'%(l.offset & mask_int)
             out.append([pre_instr_test_exception % (s1)])
             lbl_done.add(l.offset)
 
@@ -481,14 +552,34 @@ def ir2C(my_ir, irbloc, lbl_done,
         # print l
         # gen pc update
         post_instr = ""
-        c_code, post_instr, _ = Expr2C(my_ir, l, exprs, gen_exception_code)
+        c_code, post_instr, _ = Expr2C(ir_arch, l, exprs, gen_exception_code)
         out.append(c_code + post_instr)
+    out.append([goto_local_code ] )
     return out
 
 
-def irblocs2C(my_ir, resolvers, label, irblocs,
+def irblocs2C(ir_arch, resolvers, label, irblocs,
     gen_exception_code=False, log_mn=False, log_regs=False):
     out = []
+    out.append("block_id BlockDst = {0, 0};")
+    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, lbl_index_max = 0, 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)
+        lbl_index_max = max(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("goto %s;" % label.name)
     bloc_labels = [x.label for x in irblocs]
     assert(label in bloc_labels)
@@ -498,57 +589,16 @@ def irblocs2C(my_ir, resolvers, label, irblocs,
     for irbloc in irblocs:
         # XXXX TEST
         if irbloc.label.offset is None:
-            b_out = ir2C(my_ir, irbloc, lbl_done, gen_exception_code)
+            b_out = ir2C(ir_arch, irbloc, lbl_done, gen_exception_code)
         else:
             b_out = ir2C(
-                my_ir, irbloc, lbl_done, gen_exception_code, log_mn, log_regs)
+                ir_arch, irbloc, lbl_done, gen_exception_code, log_mn, log_regs)
         for exprs in b_out:
             for l in exprs:
                 out.append(l)
         dst = irbloc.dst
         out.append("")
-        if asmbloc.expr_is_label(dst):
-            if dst.name in bloc_labels:
-                out.append("goto %s;" % dst.name.name)
-            else:
-                resolver = resolvers.get_resolver(dst.name.offset)
-
-                e = set_pc(my_ir, dst.name.offset & mask_int)
-                #out.append("%s;" % patch_c_id(my_ir.arch, e).toC())
-                out.append(resolver.ret())
-        elif isinstance(dst, ExprSlice) and isinstance(dst.arg, ExprId):
-            e = set_pc(my_ir, dst)
-            #out.append("%s;" % patch_c_id(my_ir.arch, e).toC())
-
-            e = patch_c_id(my_ir.arch, dst).toC()
-            out.append("return PyLong_FromUnsignedLongLong(%s);" % e)
-
-        elif isinstance(dst, ExprId):
-            e = set_pc(my_ir, dst)
-            #out.append("%s;" % patch_c_id(my_ir.arch, e).toC())
-
-            e = patch_c_id(my_ir.arch, dst).toC()
-            out.append("return PyLong_FromUnsignedLongLong(%s);" % e)
-        elif isinstance(dst, ExprCond):
-            dst_cond_c = patch_c_id(my_ir.arch, dst.cond).toC()
-            out.append("if (%s)" % dst_cond_c)
-
-            if dst.src1.name in bloc_labels:
-                out.append("    goto %s;" % dst.src1.name.name)
-            else:
-                resolver = resolvers.get_resolver(dst.src1.name.offset)
-                out.append(resolver.ret())
-
-            out.append("else")
+        out.append("return BlockDst;")
 
-            if dst.src2.name in bloc_labels:
-                out.append("    goto %s;" % dst.src2.name.name)
-            else:
-                resolver = resolvers.get_resolver(dst.src2.name.offset)
-                out.append(resolver.ret())
-
-        else:
-            raise NotImplementedError('unknown type for dst: %s' % type(dst))
-    #print '\n'.join(out)
     return out
 
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index 08608142..3954a543 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -81,7 +81,7 @@ class symbols():
 
 class symbexec:
 
-    def __init__(self, arch, known_symbols,
+    def __init__(self, ir_arch, known_symbols,
                  func_read=None,
                  func_write=None,
                  sb_expr_simp=expr_simp):
@@ -90,7 +90,7 @@ class symbexec:
             self.symbols[k] = v
         self.func_read = func_read
         self.func_write = func_write
-        self.arch = arch
+        self.ir_arch = ir_arch
         self.expr_simp = sb_expr_simp
 
     def find_mem_by_addr(self, e):
@@ -220,7 +220,7 @@ class symbexec:
 
     def modified_regs(self, init_state=None):
         if init_state is None:
-            init_state = self.arch.regs.regs_init
+            init_state = self.ir_arch.arch.regs.regs_init
         ids = self.symbols.symbols_id.keys()
         ids.sort()
         for i in ids:
@@ -246,9 +246,9 @@ class symbexec:
         ids = self.symbols.symbols_id.keys()
         ids.sort()
         for i in ids:
-            if i in self.arch.regs.regs_init and \
+            if i in self.ir_arch.arch.regs.regs_init and \
                     i in self.symbols.symbols_id and \
-                    self.symbols.symbols_id[i] == self.arch.regs.regs_init[i]:
+                    self.symbols.symbols_id[i] == self.ir_arch.arch.regs.regs_init[i]:
                 continue
             print i, self.symbols.symbols_id[i]
 
@@ -401,24 +401,22 @@ class symbexec:
             if step:
                 print '_' * 80
                 self.dump_id()
-        if bloc_ir.dst is None:
-            return None
-        return self.eval_expr(bloc_ir.dst)
+        return self.eval_expr(self.ir_arch.IRDst)
 
-    def emul_ir_bloc(self, myir, ad):
+    def emul_ir_bloc(self, myir, ad, step = False):
         b = myir.get_bloc(ad)
         if b is not None:
-            ad = self.emulbloc(b)
+            ad = self.emulbloc(b, step = step)
         return ad
 
-    def emul_ir_blocs(self, myir, ad, lbl_stop=None):
+    def emul_ir_blocs(self, myir, ad, lbl_stop=None, step = False):
         while True:
             b = myir.get_bloc(ad)
             if b is None:
                 break
             if b.label == lbl_stop:
                 break
-            ad = self.emulbloc(b)
+            ad = self.emulbloc(b, step = step)
         return ad
 
     def del_mem_above_stack(self, sp):
diff --git a/miasm2/jitter/Jittcc.c b/miasm2/jitter/Jittcc.c
index 710a6175..8c5b2046 100644
--- a/miasm2/jitter/Jittcc.c
+++ b/miasm2/jitter/Jittcc.c
@@ -121,17 +121,37 @@ PyObject* tcc_set_emul_lib_path(PyObject* self, PyObject* args)
 }
 
 
+typedef struct {
+	uint8_t is_local;
+	uint64_t address;
+} block_id;
+
+
 PyObject* tcc_exec_bloc(PyObject* self, PyObject* args)
 {
-	PyObject* (*func)(void*, void*);
+	//PyObject* (*func)(void*, void*);
+	block_id (*func)(void*, void*);
 	uint64_t vm;
 	uint64_t cpu;
 	PyObject* ret;
+	block_id BlockDst;
 
 	if (!PyArg_ParseTuple(args, "KKK", &func, &cpu, &vm))
 		return NULL;
-	ret = func((void*)cpu, (void*)vm);
-	return ret;
+	BlockDst = func((void*)cpu, (void*)vm);
+
+	ret = PyTuple_New(2);
+	if (ret == NULL) {
+		fprintf(stderr, "Erreur alloc!\n");
+		exit(1);
+	}
+
+	if (BlockDst.is_local == 1) {
+		fprintf(stderr, "return on local label!\n");
+		exit(1);
+	}
+
+	return PyLong_FromUnsignedLongLong(BlockDst.address);
 }
 
 PyObject* tcc_compil(PyObject* self, PyObject* args)
diff --git a/miasm2/jitter/arch/JitCore.c b/miasm2/jitter/arch/JitCore.c
new file mode 100644
index 00000000..739beb74
--- /dev/null
+++ b/miasm2/jitter/arch/JitCore.c
@@ -0,0 +1,10 @@
+#include <Python.h>
+#include "JitCore.h"
+
+block_id Resolve_dst(uint64_t addr, uint64_t is_local)
+{
+	block_id b;
+	b.address = addr;
+	b.is_local = is_local;
+	return b;
+}
diff --git a/miasm2/jitter/arch/JitCore.h b/miasm2/jitter/arch/JitCore.h
index 2686cb46..723a10cc 100644
--- a/miasm2/jitter/arch/JitCore.h
+++ b/miasm2/jitter/arch/JitCore.h
@@ -64,3 +64,10 @@
 		return 0;						\
 	}
 
+
+typedef struct {
+	uint8_t is_local;
+	uint64_t address;
+} block_id;
+
+block_id Resolve_dst(uint64_t addr, uint64_t is_local);
diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h
index e92db860..cf985ea7 100644
--- a/miasm2/jitter/arch/JitCore_arm.h
+++ b/miasm2/jitter/arch/JitCore_arm.h
@@ -144,4 +144,5 @@ typedef struct {
 
 
 
-#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+//#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+#define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h
index 65666d88..ac128250 100644
--- a/miasm2/jitter/arch/JitCore_mips32.h
+++ b/miasm2/jitter/arch/JitCore_mips32.h
@@ -239,5 +239,5 @@ typedef struct {
 }vm_cpu_t;
 
 
-
-#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+//#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+#define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h
index c65989b0..e1c001b7 100644
--- a/miasm2/jitter/arch/JitCore_msp430.h
+++ b/miasm2/jitter/arch/JitCore_msp430.h
@@ -156,7 +156,8 @@ typedef struct {
 
 }vm_cpu_t;
 
-#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+//#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->PC);
+#define RETURN_PC return BlockDst;
 
 uint16_t bcdadd_16(uint16_t a, uint16_t b);
 
diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h
index 5ed0feff..844c13c0 100644
--- a/miasm2/jitter/arch/JitCore_x86.h
+++ b/miasm2/jitter/arch/JitCore_x86.h
@@ -290,4 +290,5 @@ uint16_t umod16(vm_cpu_t* vmcpu, uint16_t a, uint16_t b);
 int16_t idiv16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
 int16_t imod16(vm_cpu_t* vmcpu, int16_t a, int16_t b);
 
-#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->RIP);
+//#define RETURN_PC return PyLong_FromUnsignedLongLong(vmcpu->RIP);
+#define RETURN_PC return BlockDst;
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 81193406..1af7333f 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -24,13 +24,13 @@ class JitCore(object):
 
     "JiT management. This is an abstract class"
 
-    def __init__(self, my_ir, bs=None):
+    def __init__(self, ir_arch, bs=None):
         """Initialise a JitCore instance.
-        @my_ir: ir instance for current architecture
+        @ir_arch: ir instance for current architecture
         @bs: bitstream
         """
 
-        self.my_ir = my_ir
+        self.ir_arch = ir_arch
         self.bs = bs
         self.known_blocs = {}
         self.lbl2jitbloc = {}
@@ -98,7 +98,7 @@ class JitCore(object):
         @b: the bloc to add
         """
 
-        irblocs = self.my_ir.add_bloc(b, gen_pc_updt = True)
+        irblocs = self.ir_arch.add_bloc(b, gen_pc_updt = True)
         b.irblocs = irblocs
         self.jitirblocs(b.label, irblocs)
 
@@ -109,18 +109,18 @@ class JitCore(object):
         if isinstance(addr, asmbloc.asm_label):
             addr = addr.offset
 
-        l = self.my_ir.symbol_pool.getby_offset_create(addr)
+        l = self.ir_arch.symbol_pool.getby_offset_create(addr)
         cur_bloc = asmbloc.asm_bloc(l)
 
         # Disassemble it
         try:
-            asmbloc.dis_bloc(self.my_ir.arch, self.bs, cur_bloc, addr,
-                             set(), self.my_ir.symbol_pool, [],
+            asmbloc.dis_bloc(self.ir_arch.arch, self.bs, cur_bloc, addr,
+                             set(), self.ir_arch.symbol_pool, [],
                              follow_call=False, patch_instr_symb=True,
                              dontdis_retcall=False,
                              lines_wd=self.options["jit_maxline"],
                              # max 10 asm lines
-                             attrib=self.my_ir.attrib,
+                             attrib=self.ir_arch.attrib,
                              split_dis=self.split_dis)
         except IOError:
             # vm_exception_flag is set
@@ -161,7 +161,7 @@ class JitCore(object):
         """
 
         if lbl is None:
-            lbl = cpu.vm_get_gpreg()[self.my_ir.pc.name]
+            lbl = cpu.vm_get_gpreg()[self.ir_arch.pc.name]
 
         if not lbl in self.lbl2jitbloc:
             # Need to JiT the bloc
diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py
index 03bfb90b..9d139550 100644
--- a/miasm2/jitter/jitcore_llvm.py
+++ b/miasm2/jitter/jitcore_llvm.py
@@ -19,8 +19,8 @@ class JitCore_LLVM(jitcore.JitCore):
                            "msp430": "JitCore_msp430.so",
                            "mips32": "JitCore_mips32.so"}
 
-    def __init__(self, my_ir, bs=None):
-        super(JitCore_LLVM, self).__init__(my_ir, bs)
+    def __init__(self, ir_arch, bs=None):
+        super(JitCore_LLVM, self).__init__(ir_arch, bs)
 
         self.options.update({"safe_mode": False,   # Verify each function
                              "optimise": False,     # Optimise functions
@@ -31,8 +31,9 @@ class JitCore_LLVM(jitcore.JitCore):
 
         self.exec_wrapper = Jitllvm.llvm_exec_bloc
         self.exec_engines = []
+        self.ir_arch = ir_arch
 
-    def load(self, arch):
+    def load(self):
 
         # Library to load within Jit context
         libs_to_load = []
@@ -42,7 +43,7 @@ class JitCore_LLVM(jitcore.JitCore):
         lib_dir = os.path.join(lib_dir, 'arch')
         try:
             jit_lib = os.path.join(
-                lib_dir, self.arch_dependent_libs[arch.name])
+                lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name])
             libs_to_load.append(jit_lib)
         except KeyError:
             pass
@@ -54,10 +55,10 @@ class JitCore_LLVM(jitcore.JitCore):
         self.context.optimise_level()
 
         # Save the current architecture parameters
-        self.arch = arch
+        self.arch = self.ir_arch.arch
 
         # Get the correspondance between registers and vmcpu struct
-        mod_name = "miasm2.jitter.arch.JitCore_%s" % (arch.name)
+        mod_name = "miasm2.jitter.arch.JitCore_%s" % (self.ir_arch.arch.name)
         mod = importlib.import_module(mod_name)
         self.context.set_vmcpu(mod.get_gpreg_offset_all())
 
@@ -65,7 +66,7 @@ class JitCore_LLVM(jitcore.JitCore):
         self.mod_base_str = str(self.context.mod)
 
         # Set IRs transformation to apply
-        self.context.set_IR_transformation(self.my_ir.expr_fix_regs_for_mode)
+        self.context.set_IR_transformation(self.ir_arch.expr_fix_regs_for_mode)
 
     def add_bloc(self, bloc):
 
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index 90c8bace..c2fb4be1 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -49,18 +49,19 @@ def update_engine_from_cpu(cpu, exec_engine):
 class JitCore_Python(jitcore.JitCore):
     "JiT management, using Miasm2 Symbol Execution engine as backend"
 
-    def __init__(self, my_ir, bs=None):
-        super(JitCore_Python, self).__init__(my_ir, bs)
+    def __init__(self, ir_arch, bs=None):
+        super(JitCore_Python, self).__init__(ir_arch, bs)
         self.symbexec = None
+        self.ir_arch = ir_arch
 
-    def load(self, arch):
+    def load(self):
         "Preload symbols according to current architecture"
 
         symbols_init =  {}
-        for i, r in enumerate(arch.regs.all_regs_ids_no_alias):
-            symbols_init[r] = arch.regs.all_regs_ids_init[i]
+        for i, r in enumerate(self.ir_arch.arch.regs.all_regs_ids_no_alias):
+            symbols_init[r] = self.ir_arch.arch.regs.all_regs_ids_init[i]
 
-        self.symbexec = symbexec(arch, symbols_init,
+        self.symbexec = symbexec(self.ir_arch, symbols_init,
                                  func_read = self.func_read,
                                  func_write = self.func_write)
 
@@ -157,7 +158,7 @@ class JitCore_Python(jitcore.JitCore):
                         return line.offset
 
                 # Get next bloc address
-                ad = expr_simp(exec_engine.eval_expr(irb.dst))
+                ad = expr_simp(exec_engine.eval_expr(self.ir_arch.IRDst))
 
                 # Updates @cpu instance according to new CPU values
                 update_cpu_from_engine(cpu, exec_engine)
diff --git a/miasm2/jitter/jitcore_tcc.py b/miasm2/jitter/jitcore_tcc.py
index cb92361f..ce1397a8 100644
--- a/miasm2/jitter/jitcore_tcc.py
+++ b/miasm2/jitter/jitcore_tcc.py
@@ -30,6 +30,7 @@ def gen_core(arch, attrib):
     txt = ""
     txt += '#include "%s/queue.h"\n' % lib_dir
     txt += '#include "%s/vm_mngr.h"\n' % lib_dir
+    txt += '#include "%s/arch/JitCore.h"\n' % lib_dir
     txt += '#include "%s/arch/JitCore_%s.h"\n' % (lib_dir, arch.name)
 
     txt += r'''
@@ -38,11 +39,11 @@ def gen_core(arch, attrib):
     return txt
 
 
-def gen_C_source(my_ir, func_code):
+def gen_C_source(ir_arch, func_code):
     c_source = ""
     c_source += "\n".join(func_code)
 
-    c_source = gen_core(my_ir.arch, my_ir.attrib) + c_source
+    c_source = gen_core(ir_arch.arch, ir_arch.attrib) + c_source
 
     c_source = """
  #ifdef __x86_64__
@@ -90,17 +91,18 @@ class JitCore_Tcc(jitcore.JitCore):
 
     "JiT management, using LibTCC as backend"
 
-    def __init__(self, my_ir, bs=None):
-        super(JitCore_Tcc, self).__init__(my_ir, bs)
+    def __init__(self, ir_arch, bs=None):
+        super(JitCore_Tcc, self).__init__(ir_arch, bs)
         self.resolver = resolver()
         self.exec_wrapper = Jittcc.tcc_exec_bloc
         self.tcc_states =[]
+        self.ir_arch = ir_arch
 
-    def load(self, arch):
+    def load(self):
         # os.path.join(os.path.dirname(os.path.realpath(__file__)), "jitter")
         lib_dir = os.path.dirname(os.path.realpath(__file__))
         libs = []
-        libs.append(os.path.join(lib_dir, 'arch/JitCore_%s.so' % (arch.name)))
+        libs.append(os.path.join(lib_dir, 'arch/JitCore_%s.so' % (self.ir_arch.arch.name)))
         libs = ';'.join(libs)
         jittcc_path = Jittcc.__file__
         include_dir = os.path.dirname(jittcc_path)
@@ -127,20 +129,18 @@ class JitCore_Tcc(jitcore.JitCore):
             Jittcc.tcc_end(tcc_state)
 
     def jitirblocs(self, label, irblocs):
-        # irbloc = self.lbl2irbloc[lbl]
         f_name = "bloc_%s" % label.name
-        f_declaration = \
-            'PyObject* %s(vm_cpu_t* vmcpu, vm_mngr_t* vm_mngr)' % f_name
-        out = irblocs2C(self.my_ir, self.resolver, label, irblocs,
+        f_declaration = 'block_id %s(vm_cpu_t* vmcpu, vm_mngr_t* vm_mngr)' % f_name
+        out = irblocs2C(self.ir_arch, self.resolver, label, irblocs,
                         gen_exception_code=True,
                         log_mn=self.log_mn,
                         log_regs=self.log_regs)
         out = [f_declaration + '{'] + out + ['}\n']
         c_code = out
 
-        func_code = gen_C_source(self.my_ir, c_code)
-        # print func_code
-        # open('tmp_%.4d.c'%self.jitcount, "w").write(func_code)
+        func_code = gen_C_source(self.ir_arch, c_code)
+
+        open('tmp_%.4d.c'%self.jitcount, "w").write(func_code)
         self.jitcount += 1
         tcc_state, mcode = jit_tcc_compil(f_name, func_code)
         self.tcc_states.append(tcc_state)
@@ -148,4 +148,3 @@ class JitCore_Tcc(jitcore.JitCore):
         self.lbl2jitbloc[label.offset] = mcode
         self.addr2obj[label.offset] = jcode
         self.addr2objref[label.offset] = objref(jcode)
-        # print "ADDR2CODE", hex(b.label.offset), hex(id(jcode))
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index dc1a2a94..285c41dd 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -560,18 +560,18 @@ class jitter:
 
     "Main class for JIT handling"
 
-    def __init__(self, my_ir, jit_type="tcc"):
+    def __init__(self, ir_arch, jit_type="tcc"):
         """Init an instance of jitter.
-        @my_ir: ir instance for this architecture
+        @ir_arch: ir instance for this architecture
         @jit_type: JiT backend to use. Available options are:
             - "tcc"
             - "llvm"
             - "python"
         """
 
-        self.arch = my_ir.arch
-        self.attrib = my_ir.attrib
-        arch_name = my_ir.arch.name  # (my_ir.arch.name, my_ir.attrib)
+        self.arch = ir_arch.arch
+        self.attrib = ir_arch.attrib
+        arch_name = ir_arch.arch.name  # (ir_arch.arch.name, ir_arch.attrib)
         if arch_name == "x86":
             from arch import JitCore_x86 as jcore
         elif arch_name == "arm":
@@ -586,15 +586,15 @@ class jitter:
         self.cpu = jcore.JitCpu()
         self.vm = jcore.VmMngr()
         self.bs = bin_stream_vm(self.vm)
-        self.my_ir = my_ir
+        self.ir_arch = ir_arch
         init_arch_C(self.arch)
 
         if jit_type == "tcc":
-            self.jit = JitCore_Tcc(self.my_ir, self.bs)
+            self.jit = JitCore_Tcc(self.ir_arch, self.bs)
         elif jit_type == "llvm":
-            self.jit = JitCore_LLVM(self.my_ir, self.bs)
+            self.jit = JitCore_LLVM(self.ir_arch, self.bs)
         elif jit_type == "python":
-            self.jit = JitCore_Python(self.my_ir, self.bs)
+            self.jit = JitCore_Python(self.ir_arch, self.bs)
         else:
             raise Exception("Unkown JiT Backend")
 
@@ -605,7 +605,7 @@ class jitter:
 
         self.vm.vm_set_addr2obj(self.jit.addr2obj)
 
-        self.jit.load(self.arch)
+        self.jit.load()
         self.stack_size = 0x10000
         self.stack_base = 0x1230000
 
diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h
index 0cacb708..2bf23f37 100644
--- a/miasm2/jitter/vm_mngr.h
+++ b/miasm2/jitter/vm_mngr.h
@@ -124,6 +124,7 @@ struct memory_breakpoint_info {
 };
 
 
+
 #define PAGE_READ 1
 #define PAGE_WRITE 2
 #define PAGE_EXEC 4