about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/disasm/callback.py2
-rw-r--r--example/expression/access_c.py8
-rw-r--r--example/expression/basic_simplification.py4
-rw-r--r--example/expression/expr_grapher.py8
-rw-r--r--example/expression/expr_reduce.py2
-rw-r--r--example/expression/get_read_write.py8
-rw-r--r--example/expression/simplification_add.py2
-rw-r--r--example/expression/simplification_tools.py10
-rw-r--r--example/expression/solve_condition_stp.py2
-rw-r--r--example/ida/ctype_propagation.py2
-rw-r--r--example/ida/depgraph.py10
-rw-r--r--example/ida/graph_ir.py4
-rw-r--r--example/symbol_exec/depgraph.py10
-rw-r--r--miasm2/analysis/cst_propag.py4
-rw-r--r--miasm2/analysis/data_analysis.py6
-rw-r--r--miasm2/analysis/data_flow.py89
-rw-r--r--miasm2/analysis/depgraph.py10
-rw-r--r--miasm2/analysis/disasm_cb.py4
-rw-r--r--miasm2/arch/aarch64/arch.py2
-rw-r--r--miasm2/arch/aarch64/disasm.py4
-rw-r--r--miasm2/arch/aarch64/regs.py3
-rw-r--r--miasm2/arch/aarch64/sem.py87
-rw-r--r--miasm2/arch/arm/arch.py6
-rw-r--r--miasm2/arch/arm/disasm.py4
-rw-r--r--miasm2/arch/arm/regs.py32
-rw-r--r--miasm2/arch/mips32/ira.py2
-rw-r--r--miasm2/arch/mips32/jit.py14
-rw-r--r--miasm2/arch/mips32/regs.py4
-rw-r--r--miasm2/arch/mips32/sem.py22
-rw-r--r--miasm2/arch/sh4/arch.py6
-rw-r--r--miasm2/arch/x86/arch.py107
-rw-r--r--miasm2/arch/x86/disasm.py2
-rw-r--r--miasm2/arch/x86/regs.py54
-rw-r--r--miasm2/arch/x86/sem.py531
-rw-r--r--miasm2/core/asmblock.py25
-rw-r--r--miasm2/expression/expression.py5
-rw-r--r--miasm2/expression/simplifications_cond.py6
-rw-r--r--miasm2/ir/ir.py75
-rw-r--r--miasm2/ir/symbexec.py2
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.c10
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.h1
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c23
-rw-r--r--miasm2/jitter/codegen.py4
-rw-r--r--miasm2/jitter/jitcore.py4
-rw-r--r--miasm2/jitter/jitcore_python.py2
-rw-r--r--miasm2/jitter/jitload.py2
-rw-r--r--miasm2/jitter/llvmconvert.py22
-rw-r--r--test/analysis/data_flow.py28
-rw-r--r--test/analysis/depgraph.py72
-rw-r--r--test/arch/x86/arch.py115
-rw-r--r--test/arch/x86/unit/mn_cdq.py445
-rw-r--r--test/core/sembuilder.py12
-rw-r--r--test/expression/expression.py2
-rwxr-xr-xtest/expression/expression_helper.py4
-rw-r--r--test/expression/simplifications.py28
-rw-r--r--test/ir/ir.py4
-rwxr-xr-xtest/ir/symbexec.py6
-rwxr-xr-xtest/test_all.py1
58 files changed, 1528 insertions, 435 deletions
diff --git a/example/disasm/callback.py b/example/disasm/callback.py
index 63987e85..a9bef20b 100644
--- a/example/disasm/callback.py
+++ b/example/disasm/callback.py
@@ -52,7 +52,7 @@ print "\n".join(str(block) for block in blocks)
 # Enable callback
 cb_x86_funcs.append(cb_x86_callpop)
 ## Other method:
-## mdis.dis_bloc_callback = cb_x86_callpop
+## mdis.dis_block_callback = cb_x86_callpop
 
 print "=" * 40
 print "With callback:\n"
diff --git a/example/expression/access_c.py b/example/expression/access_c.py
index f285eb55..de158730 100644
--- a/example/expression/access_c.py
+++ b/example/expression/access_c.py
@@ -60,15 +60,15 @@ def find_call(ira):
 
     for irb in ira.blocks.values():
         out = set()
-        if len(irb.irs) < 2:
+        if len(irb) < 2:
             continue
-        assignblk = irb.irs[-2]
+        assignblk = irb[-2]
         for src in assignblk.itervalues():
             if not isinstance(src, ExprOp):
                 continue
             if not src.op.startswith('call_func'):
                 continue
-            out.add((irb, len(irb.irs) - 2))
+            out.add((irb, len(irb) - 2))
         if len(out) != 1:
             continue
         irb, index = out.pop()
@@ -98,7 +98,7 @@ def get_funcs_arg0(ctx, ira, lbl_head):
     element = ira.arch.regs.RSI
 
     for irb, index in find_call(ira):
-        instr = irb.irs[index].instr
+        instr = irb[index].instr
         print 'Analysing references from:', hex(instr.offset), instr
         g_list = g_dep.get(irb.label, set([element]), index, set([lbl_head]))
         for dep in g_list:
diff --git a/example/expression/basic_simplification.py b/example/expression/basic_simplification.py
index ef904686..eefdc765 100644
--- a/example/expression/basic_simplification.py
+++ b/example/expression/basic_simplification.py
@@ -6,8 +6,8 @@ Simple expression simplification demo
 """
 
 
-a = ExprId('eax')
-b = ExprId('ebx')
+a = ExprId('eax', 32)
+b = ExprId('ebx', 32)
 
 exprs = [a + b - a,
          ExprInt(0x12, 32) + ExprInt(0x30, 32) - a,
diff --git a/example/expression/expr_grapher.py b/example/expression/expr_grapher.py
index 0de2142b..9bf6cd84 100644
--- a/example/expression/expr_grapher.py
+++ b/example/expression/expr_grapher.py
@@ -2,10 +2,10 @@ from miasm2.expression.expression import *
 
 print "Simple Expression grapher demo"
 
-a = ExprId("A")
-b = ExprId("B")
-c = ExprId("C")
-d = ExprId("D")
+a = ExprId("A", 32)
+b = ExprId("B", 32)
+c = ExprId("C", 32)
+d = ExprId("D", 32)
 m = ExprMem(a + b + c + a)
 
 e1 = ExprCompose(a + b - (c * a) / m | b, a + m)
diff --git a/example/expression/expr_reduce.py b/example/expression/expr_reduce.py
index bb94ceb9..7c6e0c4c 100644
--- a/example/expression/expr_reduce.py
+++ b/example/expression/expr_reduce.py
@@ -75,7 +75,7 @@ class StructLookup(ExprReducer):
 def test():
     struct_lookup = StructLookup()
 
-    ptr = ExprId('ECX')
+    ptr = ExprId('ECX', 32)
     int4 = ExprInt(4, 32)
     tests = [
         (ptr, StructLookup.FIELD_A_PTR),
diff --git a/example/expression/get_read_write.py b/example/expression/get_read_write.py
index f4dde4b5..b4a0773b 100644
--- a/example/expression/get_read_write.py
+++ b/example/expression/get_read_write.py
@@ -16,10 +16,10 @@ l.offset, l.l = 0, 15
 ir_arch.add_instr(l)
 
 print '*' * 80
-for lbl, b in ir_arch.blocks.items():
-    print b
-    for irs in b.irs:
-        o_r, o_w = get_rw(irs)
+for lbl, irblock in ir_arch.blocks.items():
+    print irblock
+    for assignblk in irblock:
+        o_r, o_w = get_rw(assignblk)
         print 'read:   ', [str(x) for x in o_r]
         print 'written:', [str(x) for x in o_w]
         print
diff --git a/example/expression/simplification_add.py b/example/expression/simplification_add.py
index 41720f3a..621d1139 100644
--- a/example/expression/simplification_add.py
+++ b/example/expression/simplification_add.py
@@ -30,7 +30,7 @@ def simp_add_mul(expr_simp, expr):
         # Do not simplify
         return expr
 
-a = m2_expr.ExprId('a')
+a = m2_expr.ExprId('a', 32)
 base_expr = a + a + a
 print "Without adding the simplification:"
 print "\t%s = %s" % (base_expr, expr_simp(base_expr))
diff --git a/example/expression/simplification_tools.py b/example/expression/simplification_tools.py
index 258b5ce4..1fb95a80 100644
--- a/example/expression/simplification_tools.py
+++ b/example/expression/simplification_tools.py
@@ -7,11 +7,11 @@ Expression simplification demo.
 """
 
 
-a = ExprId('a')
-b = ExprId('b')
-c = ExprId('c')
-d = ExprId('d')
-e = ExprId('e')
+a = ExprId('a', 32)
+b = ExprId('b', 32)
+c = ExprId('c', 32)
+d = ExprId('d', 32)
+e = ExprId('e', 32)
 
 m = ExprMem(a)
 s = a[:8]
diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py
index b3ee6938..24d2dd50 100644
--- a/example/expression/solve_condition_stp.py
+++ b/example/expression/solve_condition_stp.py
@@ -109,7 +109,7 @@ if __name__ == '__main__':
 
     argc = ExprId('argc', 32)
     argv = ExprId('argv', 32)
-    ret_addr = ExprId('ret_addr')
+    ret_addr = ExprId('ret_addr', 32)
     reg_and_id[argc.name] = argc
     reg_and_id[argv.name] = argv
     reg_and_id[ret_addr.name] = ret_addr
diff --git a/example/ida/ctype_propagation.py b/example/ida/ctype_propagation.py
index 8c64c6d2..54b23516 100644
--- a/example/ida/ctype_propagation.py
+++ b/example/ida/ctype_propagation.py
@@ -114,7 +114,7 @@ class SymbExecCTypeFix(SymbExecCType):
         """
 
         offset2cmt = {}
-        for index, assignblk in enumerate(irb.irs):
+        for index, assignblk in enumerate(irb):
             if set(assignblk) == set([self.ir_arch.IRDst, self.ir_arch.pc]):
                 # Don't display on jxx
                 continue
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 915f14bc..5342313a 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -34,7 +34,7 @@ class depGraphSettingsForm(ida_kernwin.Form):
                 cur_block = block
         assert cur_block is not None
         line_nb = None
-        for line_nb, assignblk in enumerate(cur_block.irs):
+        for line_nb, assignblk in enumerate(cur_block):
             if assignblk.instr.offset == self.address:
                 break
         assert line_nb is not None
@@ -110,13 +110,13 @@ Method to use:
         elif mode == 1:
             return value + 1
         else:
-            return len(self.ira.blocks[self.label].irs)
+            return len(self.ira.blocks[self.label])
 
     @property
     def elements(self):
         value = self.cbReg.value
         if value in self.stk_args:
-            line = self.ira.blocks[self.label].irs[self.line_nb].instr
+            line = self.ira.blocks[self.label][self.line_nb].instr
             arg_num = self.stk_args[value]
             stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size)
             stk_off = m2_expr.ExprInt(self.ira.sp.size/8 * arg_num, ir_arch.sp.size)
@@ -174,7 +174,7 @@ def treat_element():
 
     for node in graph.relevant_nodes:
         try:
-            offset = ir_arch.blocks[node.label].irs[node.line_nb].instr.offset
+            offset = ir_arch.blocks[node.label][node.line_nb].instr.offset
         except IndexError:
             print "Unable to highlight %s" % node
             continue
@@ -229,7 +229,7 @@ def launch_depgraph():
     for irb in ir_arch.blocks.values():
         irs = []
         fix_stack = irb.label.offset is not None and settings.unalias_stack
-        for assignblk in irb.irs:
+        for assignblk in irb:
             if fix_stack:
                 stk_high = m2_expr.ExprInt(idc.GetSpd(assignblk.instr.offset), ir_arch.sp.size)
                 fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}
diff --git a/example/ida/graph_ir.py b/example/ida/graph_ir.py
index 8d9dea4f..7e303aac 100644
--- a/example/ida/graph_ir.py
+++ b/example/ida/graph_ir.py
@@ -40,7 +40,7 @@ def color_irblock(irblock, ir_arch):
     out = []
     lbl = idaapi.COLSTR(str(irblock.label), idaapi.SCOLOR_INSN)
     out.append(lbl)
-    for assignblk in irblock.irs:
+    for assignblk in irblock:
         for dst, src in sorted(assignblk.iteritems()):
             dst_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, dst)
             src_f = expr2colorstr(ir_arch.arch.regs.all_regs_ids, src)
@@ -148,7 +148,7 @@ def build_graph(verbose=False, simplify=False):
 
     for irb in ir_arch.blocks.itervalues():
         irs = []
-        for assignblk in irb.irs:
+        for assignblk in irb:
             new_assignblk = {
                 expr_simp(dst): expr_simp(src)
                 for dst, src in assignblk.iteritems()
diff --git a/example/symbol_exec/depgraph.py b/example/symbol_exec/depgraph.py
index c1d6174d..b8d838ae 100644
--- a/example/symbol_exec/depgraph.py
+++ b/example/symbol_exec/depgraph.py
@@ -55,8 +55,8 @@ if args.rename_args:
     if arch == "x86_32":
         # StdCall example
         for i in xrange(4):
-            e_mem = ExprMem(ExprId("ESP_init") + ExprInt(4 * (i + 1), 32), 32)
-            init_ctx[e_mem] = ExprId("arg%d" % i)
+            e_mem = ExprMem(ExprId("ESP_init", 32) + ExprInt(4 * (i + 1), 32), 32)
+            init_ctx[e_mem] = ExprId("arg%d" % i, 32)
 
 # Disassemble the targeted function
 blocks = mdis.dis_multiblock(int(args.func_addr, 0))
@@ -74,14 +74,14 @@ dg = DependencyGraph(ir_arch, implicit=args.implicit,
 # Build information
 target_addr = int(args.target_addr, 0)
 current_block = list(ir_arch.getby_offset(target_addr))[0]
-line_nb = 0
-for line_nb, assignblk in enumerate(current_block.irs):
+assignblk_index = 0
+for assignblk_index, assignblk in enumerate(current_block):
     if assignblk.instr.offset == target_addr:
         break
 
 # Enumerate solutions
 json_solutions = []
-for sol_nb, sol in enumerate(dg.get(current_block.label, elements, line_nb, set())):
+for sol_nb, sol in enumerate(dg.get(current_block.label, elements, assignblk_index, set())):
     fname = "sol_%d.dot" % sol_nb
     with open(fname, "w") as fdesc:
             fdesc.write(sol.graph.dot())
diff --git a/miasm2/analysis/cst_propag.py b/miasm2/analysis/cst_propag.py
index 2a439ccc..7946a496 100644
--- a/miasm2/analysis/cst_propag.py
+++ b/miasm2/analysis/cst_propag.py
@@ -73,7 +73,7 @@ class SymbExecStateFix(SymbolicExecutionEngine):
         self.cst_propag_link = cst_propag_link
 
     def propag_expr_cst(self, expr):
-        """Propagate consttant expressions in @expr
+        """Propagate constant expressions in @expr
         @expr: Expression to update"""
         elements = expr.get_r(mem_read=True)
         to_propag = {}
@@ -93,7 +93,7 @@ class SymbExecStateFix(SymbolicExecutionEngine):
         @step: display intermediate steps
         """
         assignblks = []
-        for index, assignblk in enumerate(irb.irs):
+        for index, assignblk in enumerate(irb):
             new_assignblk = {}
             links = {}
             for dst, src in assignblk.iteritems():
diff --git a/miasm2/analysis/data_analysis.py b/miasm2/analysis/data_analysis.py
index b3e15ca6..130d45a4 100644
--- a/miasm2/analysis/data_analysis.py
+++ b/miasm2/analysis/data_analysis.py
@@ -14,7 +14,7 @@ def intra_block_flow_raw(ir_arch, flow_graph, irb, in_nodes, out_nodes):
     Create data flow for an irbloc using raw IR expressions
     """
     current_nodes = {}
-    for i, assignblk in enumerate(irb.irs):
+    for i, assignblk in enumerate(irb):
         dict_rw = assignblk.get_rw(cst_read=True)
         if irb.label.offset == 0x13:
             print irb.label
@@ -85,7 +85,7 @@ def intra_block_flow_symbexec(ir_arch, flow_graph, irb, in_nodes, out_nodes):
             continue
         read_values = v.get_r(cst_read=True)
         # print n_w, v, [str(x) for x in read_values]
-        node_n_w = get_node_name(irb.label, len(irb.irs), n_w)
+        node_n_w = get_node_name(irb.label, len(irb), n_w)
 
         for n_r in read_values:
             if n_r in current_nodes:
@@ -171,7 +171,7 @@ def create_implicit_flow(ir_arch, flow_graph, irb_in_nodes, irb_out_ndes):
                 # print "###", irb_son
                 # print "###", 'IN', [str(x) for x in irb_son.in_nodes]
 
-                node_n_w = irb.label, len(irb.irs), n_r
+                node_n_w = irb.label, len(irb), n_r
                 irb_out_nodes[irb.label][n_r] = node_n_w
                 if not n_r in irb_in_nodes[irb.label]:
                     irb_in_nodes[irb.label][n_r] = irb.label, 0, n_r
diff --git a/miasm2/analysis/data_flow.py b/miasm2/analysis/data_flow.py
index 67768264..d9f61c56 100644
--- a/miasm2/analysis/data_flow.py
+++ b/miasm2/analysis/data_flow.py
@@ -6,7 +6,7 @@ from miasm2.ir.ir import AssignBlock, IRBlock
 
 class ReachingDefinitions(dict):
     """
-    Computes for each instruction the set of reaching definitions.
+    Computes for each assignblock the set of reaching definitions.
     Example:
     IR block:
     lbl0:
@@ -26,7 +26,7 @@ class ReachingDefinitions(dict):
     IBM Thomas J. Watson Research Division,  Algorithm MK
 
     This class is usable as a dictionnary whose struture is
-    { (block, instr_index): { lvalue: set((block, instr_index)) } }
+    { (block, index): { lvalue: set((block, index)) } }
     """
 
     ir_a = None
@@ -36,12 +36,12 @@ class ReachingDefinitions(dict):
         self.ir_a = ir_a
         self.compute()
 
-    def get_definitions(self, block_lbl, instruction):
-        """Returns the dict { lvalue: set((def_block_lbl, def_instr_index)) }
-        associated with self.ir_a.@block.irs[@instruction]
+    def get_definitions(self, block_lbl, assignblk_index):
+        """Returns the dict { lvalue: set((def_block_lbl, def_index)) }
+        associated with self.ir_a.@block.assignblks[@assignblk_index]
         or {} if it is not yet computed
         """
-        return self.get((block_lbl, instruction), {})
+        return self.get((block_lbl, assignblk_index), {})
 
     def compute(self):
         """This is the main fixpoint"""
@@ -54,12 +54,12 @@ class ReachingDefinitions(dict):
     def process_block(self, block):
         """
         Fetch reach definitions from predecessors and propagate it to
-        the instruction in block @block.
+        the assignblk in block @block.
         """
         predecessor_state = {}
         for pred_lbl in self.ir_a.graph.predecessors(block.label):
             pred = self.ir_a.blocks[pred_lbl]
-            for lval, definitions in self.get_definitions(pred_lbl, len(pred.irs)).iteritems():
+            for lval, definitions in self.get_definitions(pred_lbl, len(pred)).iteritems():
                 predecessor_state.setdefault(lval, set()).update(definitions)
 
         modified = self.get((block.label, 0)) != predecessor_state
@@ -67,33 +67,33 @@ class ReachingDefinitions(dict):
             return False
         self[(block.label, 0)] = predecessor_state
 
-        for instr_index in xrange(len(block.irs)):
-            modified |= self.process_instruction(block, instr_index)
+        for index in xrange(len(block)):
+            modified |= self.process_assignblock(block, index)
         return modified
 
-    def process_instruction(self, block, instr_index):
+    def process_assignblock(self, block, assignblk_index):
         """
         Updates the reach definitions with values defined at
-        instruction @instr_index in block @block.
-        NB: the effect of instruction @instr_index in stored at index
-        (@block, @instr_index + 1).
+        assignblock @assignblk_index in block @block.
+        NB: the effect of assignblock @assignblk_index in stored at index
+        (@block, @assignblk_index + 1).
         """
 
-        instr = block.irs[instr_index]
-        defs = self.get_definitions(block.label, instr_index).copy()
-        for lval in instr:
-            defs.update({lval: set([(block.label, instr_index)])})
+        assignblk = block[assignblk_index]
+        defs = self.get_definitions(block.label, assignblk_index).copy()
+        for lval in assignblk:
+            defs.update({lval: set([(block.label, assignblk_index)])})
 
-        modified = self.get((block.label, instr_index + 1)) != defs
+        modified = self.get((block.label, assignblk_index + 1)) != defs
         if modified:
-            self[(block.label, instr_index + 1)] = defs
+            self[(block.label, assignblk_index + 1)] = defs
 
         return modified
 
 ATTR_DEP = {"color" : "black",
             "_type" : "data"}
 
-InstrNode = namedtuple('InstructionNode', ['label', 'index', 'var'])
+AssignblkNode = namedtuple('AssignblkNode', ['label', 'index', 'var'])
 
 class DiGraphDefUse(DiGraph):
     """Representation of a Use-Definition graph as defined by
@@ -148,18 +148,18 @@ class DiGraphDefUse(DiGraph):
                                         deref_mem=deref_mem)
 
     def _compute_def_use_block(self, block, reaching_defs, deref_mem=False):
-        for ind, instr in enumerate(block.irs):
-            instruction_reaching_defs = reaching_defs.get_definitions(block.label, ind)
-            for lval, expr in instr.iteritems():
-                self.add_node(InstrNode(block.label, ind, lval))
+        for index, assignblk in enumerate(block):
+            assignblk_reaching_defs = reaching_defs.get_definitions(block.label, index)
+            for lval, expr in assignblk.iteritems():
+                self.add_node(AssignblkNode(block.label, index, lval))
 
                 read_vars = expr.get_r(mem_read=deref_mem)
                 if deref_mem and lval.is_mem():
                     read_vars.update(lval.arg.get_r(mem_read=deref_mem))
                 for read_var in read_vars:
-                    for reach in instruction_reaching_defs.get(read_var, set()):
-                        self.add_data_edge(InstrNode(reach[0], reach[1], read_var),
-                                           InstrNode(block.label, ind, lval))
+                    for reach in assignblk_reaching_defs.get(read_var, set()):
+                        self.add_data_edge(AssignblkNode(reach[0], reach[1], read_var),
+                                           AssignblkNode(block.label, index, lval))
 
     def del_edge(self, src, dst):
         super(DiGraphDefUse, self).del_edge(src, dst)
@@ -178,25 +178,25 @@ class DiGraphDefUse(DiGraph):
         self.add_uniq_labeled_edge(src, dst, ATTR_DEP)
 
     def node2lines(self, node):
-        lbl, ind, reg = node
-        yield self.DotCellDescription(text="%s (%s)" % (lbl, ind),
+        lbl, index, reg = node
+        yield self.DotCellDescription(text="%s (%s)" % (lbl, index),
                                       attr={'align': 'center',
                                             'colspan': 2,
                                             'bgcolor': 'grey'})
-        src = self._blocks[lbl].irs[ind][reg]
+        src = self._blocks[lbl][index][reg]
         line = "%s = %s" % (reg, src)
         yield self.DotCellDescription(text=line, attr={})
         yield self.DotCellDescription(text="", attr={})
 
 
-def dead_simp_useful_instrs(defuse, reaching_defs):
+def dead_simp_useful_assignblks(defuse, reaching_defs):
     """Mark useful statements using previous reach analysis and defuse
 
     Source : Kennedy, K. (1979). A survey of data flow analysis techniques.
     IBM Thomas J. Watson Research Division,  Algorithm MK
 
-    Return a set of triplets (block, instruction number, instruction) of
-    useful instructions
+    Return a set of triplets (block, assignblk number, lvalue) of
+    useful definitions
     PRE: compute_reach(self)
 
     """
@@ -215,20 +215,20 @@ def dead_simp_useful_instrs(defuse, reaching_defs):
         # Block has a nonexistant successor or is a leaf
         if keep_all_definitions or (len(successors) == 0):
             valid_definitions = reaching_defs.get_definitions(block_lbl,
-                                                              len(block.irs))
+                                                              len(block))
             for lval, definitions in valid_definitions.iteritems():
                 if (lval in ir_a.get_out_regs(block)
                     or keep_all_definitions):
                     for definition in definitions:
-                        useful.add(InstrNode(definition[0], definition[1], lval))
+                        useful.add(AssignblkNode(definition[0], definition[1], lval))
 
         # Force keeping of specific cases
-        for instr_index, instr in enumerate(block.irs):
-            for lval, rval in instr.iteritems():
+        for index, assignblk in enumerate(block):
+            for lval, rval in assignblk.iteritems():
                 if (lval.is_mem()
                     or ir_a.IRDst == lval
                     or rval.is_function_call()):
-                    useful.add(InstrNode(block_lbl, instr_index, lval))
+                    useful.add(AssignblkNode(block_lbl, index, lval))
 
     # Useful nodes dependencies
     for node in useful:
@@ -237,22 +237,27 @@ def dead_simp_useful_instrs(defuse, reaching_defs):
 
 def dead_simp(ir_a):
     """
+    Remove useless affectations.
+
     This function is used to analyse relation of a * complete function *
     This means the blocks under study represent a solid full function graph.
 
     Source : Kennedy, K. (1979). A survey of data flow analysis techniques.
     IBM Thomas J. Watson Research Division, page 43
+
+    @ir_a: IntermediateRepresentation instance
     """
+
     modified = False
     reaching_defs = ReachingDefinitions(ir_a)
     defuse = DiGraphDefUse(reaching_defs, deref_mem=True)
-    useful = set(dead_simp_useful_instrs(defuse, reaching_defs))
+    useful = set(dead_simp_useful_assignblks(defuse, reaching_defs))
     for block in ir_a.blocks.itervalues():
         irs = []
-        for idx, assignblk in enumerate(block.irs):
+        for idx, assignblk in enumerate(block):
             new_assignblk = dict(assignblk)
             for lval in assignblk:
-                if InstrNode(block.label, idx, lval) not in useful:
+                if AssignblkNode(block.label, idx, lval) not in useful:
                     del new_assignblk[lval]
                     modified = True
             irs.append(AssignBlock(new_assignblk, assignblk.instr))
diff --git a/miasm2/analysis/depgraph.py b/miasm2/analysis/depgraph.py
index d1ac13c8..bd4bfa7e 100644
--- a/miasm2/analysis/depgraph.py
+++ b/miasm2/analysis/depgraph.py
@@ -265,9 +265,9 @@ class DependencyResult(DependencyState):
                 break
             assignmnts = {}
             for element in elements:
-                if element in irb.irs[line_nb]:
+                if element in irb[line_nb]:
                     # constants, label, ... are not in destination
-                    assignmnts[element] = irb.irs[line_nb][element]
+                    assignmnts[element] = irb[line_nb][element]
             assignblks.append(AssignBlock(assignmnts))
 
         return IRBlock(irb.label, assignblks)
@@ -294,7 +294,7 @@ class DependencyResult(DependencyState):
             else:
                 line_nb = None
             assignblks += self.irblock_slice(self._ira.blocks[label],
-                                             line_nb).irs
+                                             line_nb).assignblks
 
         # Eval the block
         temp_label = AsmLabel("Temp")
@@ -581,9 +581,9 @@ class DependencyGraph(object):
         @state: instance of DependencyState"""
 
         irb = self._ira.blocks[state.label]
-        line_nb = len(irb.irs) if state.line_nb is None else state.line_nb
+        line_nb = len(irb) if state.line_nb is None else state.line_nb
 
-        for cur_line_nb, assignblk in reversed(list(enumerate(irb.irs[:line_nb]))):
+        for cur_line_nb, assignblk in reversed(list(enumerate(irb[:line_nb]))):
             self._track_exprs(state, assignblk, cur_line_nb)
 
     def get(self, label, elements, line_nb, heads):
diff --git a/miasm2/analysis/disasm_cb.py b/miasm2/analysis/disasm_cb.py
index 9a75603f..e759e313 100644
--- a/miasm2/analysis/disasm_cb.py
+++ b/miasm2/analysis/disasm_cb.py
@@ -39,7 +39,7 @@ def arm_guess_subcall(
         # print irblock
         pc_val = None
         lr_val = None
-        for exprs in irblock.irs:
+        for exprs in irblock:
             for e in exprs:
                 if e.dst == ir_arch.pc:
                     pc_val = e.src
@@ -84,7 +84,7 @@ def arm_guess_jump_table(
         # print irblock
         pc_val = None
         # lr_val = None
-        for exprs in irblock.irs:
+        for exprs in irblock:
             for e in exprs:
                 if e.dst == ir_arch.pc:
                     pc_val = e.src
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index 7af1953a..2712e60a 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -219,7 +219,7 @@ simdregs_h_zero = (simd32_info.parser |
 
 def ast_id2expr(t):
     if not t in mn_aarch64.regs.all_regs_ids_byname:
-        r = m2_expr.ExprId(AsmLabel(t))
+        r = m2_expr.ExprId(AsmLabel(t), 32)
     else:
         r = mn_aarch64.regs.all_regs_ids_byname[t]
     return r
diff --git a/miasm2/arch/aarch64/disasm.py b/miasm2/arch/aarch64/disasm.py
index a8604fe5..17eec414 100644
--- a/miasm2/arch/aarch64/disasm.py
+++ b/miasm2/arch/aarch64/disasm.py
@@ -14,7 +14,7 @@ class dis_aarch64b(disasmEngine):
     def __init__(self, bs=None, **kwargs):
         super(dis_aarch64b, self).__init__(
             mn_aarch64, self.attrib, bs,
-            dis_bloc_callback = cb_aarch64_disasm,
+            dis_block_callback = cb_aarch64_disasm,
             **kwargs)
 
 
@@ -23,5 +23,5 @@ class dis_aarch64l(disasmEngine):
     def __init__(self, bs=None, **kwargs):
         super(dis_aarch64l, self).__init__(
             mn_aarch64, self.attrib, bs,
-            dis_bloc_callback = cb_aarch64_disasm,
+            dis_block_callback = cb_aarch64_disasm,
             **kwargs)
diff --git a/miasm2/arch/aarch64/regs.py b/miasm2/arch/aarch64/regs.py
index 4589c17a..f2655ea7 100644
--- a/miasm2/arch/aarch64/regs.py
+++ b/miasm2/arch/aarch64/regs.py
@@ -4,6 +4,7 @@ from miasm2.expression.expression import *
 from miasm2.core.cpu import gen_reg, gen_regs
 
 exception_flags = ExprId('exception_flags', 32)
+interrupt_num = ExprId('interrupt_num', 32)
 
 
 gpregs32_str = ["W%d" % i for i in xrange(0x1f)] + ["WSP"]
@@ -86,7 +87,7 @@ all_regs_ids = [
     X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16,
     X17, X18, X19, X20, X21, X22, X23, X24, X25, X26, X27, X28, X29, LR, SP,
 
-    exception_flags,
+    exception_flags, interrupt_num,
     PC,
     WZR,
     zf, nf, of, cf,
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index ab45425c..697fa981 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -3,7 +3,7 @@ from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.aarch64.arch import mn_aarch64, conds_expr, replace_regs
 from miasm2.arch.aarch64.regs import *
 from miasm2.core.sembuilder import SemBuilder
-from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
+from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO, EXCEPT_INT_XX
 
 
 # CPSR: N Z C V
@@ -73,6 +73,13 @@ def update_flag_sub_of(op1, op2, res):
     "Compote OF in @res = @op1 - @op2"
     return m2_expr.ExprAff(of, (((op1 ^ res) & (op1 ^ op2))).msb())
 
+
+# clearing cv flags for bics (see C5.6.25)
+
+def update_flag_bics ():
+    "Clear CF and OF"
+    return [ExprAff(cf, ExprInt (0,1)), ExprAff(of, ExprInt (0,1))]
+
 # z = x+y (+cf?)
 
 
@@ -119,11 +126,14 @@ def extend_arg(dst, arg):
     op, (reg, shift) = arg.op, arg.args
     if op == 'SXTW':
         base = reg.signExtend(dst.size)
-    else:
+        op = "<<"
+    elif op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>']:
         base = reg.zeroExtend(dst.size)
+    else:
+        raise NotImplementedError('Unknown shifter operator')
 
-    out = base << (shift.zeroExtend(dst.size)
-                   & m2_expr.ExprInt(dst.size - 1, dst.size))
+    out = ExprOp(op, base, (shift.zeroExtend(dst.size)
+                            & m2_expr.ExprInt(dst.size - 1, dst.size)))
     return out
 
 
@@ -138,7 +148,9 @@ ctx = {"PC": PC,
        "extend_arg": extend_arg,
        "m2_expr":m2_expr,
        "exception_flags": exception_flags,
+       "interrupt_num": interrupt_num,
        "EXCEPT_DIV_BY_ZERO": EXCEPT_DIV_BY_ZERO,
+       "EXCEPT_INT_XX": EXCEPT_INT_XX,
        }
 
 sbuild = SemBuilder(ctx)
@@ -191,6 +203,14 @@ def bic(arg1, arg2, arg3):
     arg1 = arg2 & (~extend_arg(arg2, arg3))
 
 
+def bics(ir, instr, arg1, arg2, arg3):
+    e = []
+    arg1 = arg2 & (~extend_arg(arg2, arg3))
+    e += update_flag_logic (arg1)
+    e += update_flag_bics ()
+    return e, []
+
+
 @sbuild.parse
 def mvn(arg1, arg2):
     arg1 = (~extend_arg(arg1, arg2))
@@ -402,26 +422,47 @@ def ldr(ir, instr, arg1, arg2):
     return e, []
 
 
-def ldrb(ir, instr, arg1, arg2):
+def ldr_size(ir, instr, arg1, arg2, size):
     e = []
     addr, updt = get_mem_access(arg2)
     e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 8).zeroExtend(arg1.size)))
+        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).zeroExtend(arg1.size)))
     if updt:
         e.append(updt)
     return e, []
 
 
+def ldrb(ir, instr, arg1, arg2):
+    return ldr_size(ir, instr, arg1, arg2, 8)
+
+
 def ldrh(ir, instr, arg1, arg2):
+    return ldr_size(ir, instr, arg1, arg2, 16)
+
+
+def ldrs_size(ir, instr, arg1, arg2, size):
     e = []
     addr, updt = get_mem_access(arg2)
     e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 16).zeroExtend(arg1.size)))
+        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, size).signExtend(arg1.size)))
     if updt:
         e.append(updt)
     return e, []
 
 
+def ldrsb(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 8)
+
+
+def ldrsh(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 16)
+
+
+def ldrsw(ir, instr, arg1, arg2):
+    return ldrs_size(ir, instr, arg1, arg2, 32)
+
+
+
 def l_str(ir, instr, arg1, arg2):
     e = []
     addr, updt = get_mem_access(arg2)
@@ -471,16 +512,6 @@ def ldp(ir, instr, arg1, arg2, arg3):
     return e, []
 
 
-def ldrsw(ir, instr, arg1, arg2):
-    e = []
-    addr, updt = get_mem_access(arg2)
-    e.append(
-        m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, 32).signExtend(arg1.size)))
-    if updt:
-        e.append(updt)
-    return e, []
-
-
 def sbfm(ir, instr, arg1, arg2, arg3, arg4):
     e = []
     rim, sim = int(arg3.arg), int(arg4) + 1
@@ -691,6 +722,12 @@ def extr(arg1, arg2, arg3, arg4):
     compose = m2_expr.ExprCompose(arg2, arg3)
     arg1 = compose[int(arg4.arg):int(arg4)+arg1.size]
 
+
+@sbuild.parse
+def svc(arg1):
+    exception_flags = m2_expr.ExprInt(EXCEPT_INT_XX, exception_flags.size)
+    interrupt_num = m2_expr.ExprInt(int(arg1), interrupt_num.size)
+
 mnemo_func = sbuild.functions
 mnemo_func.update({
     'and': and_l,
@@ -718,6 +755,8 @@ mnemo_func.update({
     'b.ls': b_ls,
     'b.lt': b_lt,
 
+    'bics': bics,
+
     'ret': ret,
     'stp': stp,
     'ldp': ldp,
@@ -728,7 +767,14 @@ mnemo_func.update({
 
     'ldur': ldr,
     'ldurb': ldrb,
+    'ldursb': ldrsb,
     'ldurh': ldrh,
+    'ldursh': ldrsh,
+    'ldursw': ldrsw,
+
+    'ldrsb': ldrsb,
+    'ldrsh': ldrsh,
+    'ldrsw': ldrsw,
 
     'str': l_str,
     'strb': strb,
@@ -738,8 +784,6 @@ mnemo_func.update({
     'sturb': strb,
     'sturh': strh,
 
-    'ldrsw': ldrsw,
-
 
     'bfm': bfm,
     'sbfm': sbfm,
@@ -781,7 +825,6 @@ class ir_aarch64l(IntermediateRepresentation):
         instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
         self.mod_pc(instr, instr_ir, extra_ir)
         instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir)
-
         return instr_ir, extra_ir
 
     def expr_fix_regs_for_mode(self, e):
@@ -794,7 +837,7 @@ class ir_aarch64l(IntermediateRepresentation):
 
     def irbloc_fix_regs_for_mode(self, irblock, mode=64):
         irs = []
-        for assignblk in irblock.irs:
+        for assignblk in irblock:
             new_assignblk = dict(assignblk)
             for dst, src in assignblk.iteritems():
                 del(new_assignblk[dst])
@@ -837,7 +880,7 @@ class ir_aarch64l(IntermediateRepresentation):
         new_irblocks = []
         for irblock in extra_ir:
             irs = []
-            for assignblk in irblock.irs:
+            for assignblk in irblock:
                 new_dsts = {dst:src for dst, src in assignblk.iteritems()
                                 if dst not in regs_to_fix}
                 irs.append(AssignBlock(new_dsts, assignblk.instr))
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index c74d10a8..5e4b02f9 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -18,7 +18,7 @@ log.addHandler(console_handler)
 log.setLevel(logging.DEBUG)
 
 # arm regs ##############
-reg_dum = ExprId('DumReg')
+reg_dum = ExprId('DumReg', 32)
 
 gen_reg('PC', globals())
 
@@ -66,13 +66,13 @@ spsr_regs = reg_info(spsr_regs_str, spsr_regs_expr)
 
 # CP
 cpregs_str = ['c%d' % r for r in xrange(0x10)]
-cpregs_expr = [ExprId(x) for x in cpregs_str]
+cpregs_expr = [ExprId(x, 32) for x in cpregs_str]
 
 cp_regs = reg_info(cpregs_str, cpregs_expr)
 
 # P
 pregs_str = ['p%d' % r for r in xrange(0x10)]
-pregs_expr = [ExprId(x) for x in pregs_str]
+pregs_expr = [ExprId(x, 32) for x in pregs_str]
 
 p_regs = reg_info(pregs_str, pregs_expr)
 
diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py
index 3f6ea4d5..586fa903 100644
--- a/miasm2/arch/arm/disasm.py
+++ b/miasm2/arch/arm/disasm.py
@@ -39,13 +39,13 @@ class dis_armb(disasmEngine):
     attrib = 'b'
     def __init__(self, bs=None, **kwargs):
         super(dis_armb, self).__init__(mn_arm, self.attrib, bs, **kwargs)
-        self.dis_bloc_callback = cb_arm_disasm
+        self.dis_block_callback = cb_arm_disasm
 
 class dis_arml(disasmEngine):
     attrib = 'l'
     def __init__(self, bs=None, **kwargs):
         super(dis_arml, self).__init__(mn_arm, self.attrib, bs, **kwargs)
-        self.dis_bloc_callback = cb_arm_disasm
+        self.dis_block_callback = cb_arm_disasm
 
 class dis_armtb(disasmEngine):
     attrib = 'b'
diff --git a/miasm2/arch/arm/regs.py b/miasm2/arch/arm/regs.py
index 400c6080..8587d7c2 100644
--- a/miasm2/arch/arm/regs.py
+++ b/miasm2/arch/arm/regs.py
@@ -29,22 +29,22 @@ SP = regs32_expr[13]
 LR = regs32_expr[14]
 PC = regs32_expr[15]
 
-R0_init = ExprId("R0_init")
-R1_init = ExprId("R1_init")
-R2_init = ExprId("R2_init")
-R3_init = ExprId("R3_init")
-R4_init = ExprId("R4_init")
-R5_init = ExprId("R5_init")
-R6_init = ExprId("R6_init")
-R7_init = ExprId("R7_init")
-R8_init = ExprId("R8_init")
-R9_init = ExprId("R9_init")
-R10_init = ExprId("R10_init")
-R11_init = ExprId("R11_init")
-R12_init = ExprId("R12_init")
-SP_init = ExprId("SP_init")
-LR_init = ExprId("LR_init")
-PC_init = ExprId("PC_init")
+R0_init = ExprId("R0_init", 32)
+R1_init = ExprId("R1_init", 32)
+R2_init = ExprId("R2_init", 32)
+R3_init = ExprId("R3_init", 32)
+R4_init = ExprId("R4_init", 32)
+R5_init = ExprId("R5_init", 32)
+R6_init = ExprId("R6_init", 32)
+R7_init = ExprId("R7_init", 32)
+R8_init = ExprId("R8_init", 32)
+R9_init = ExprId("R9_init", 32)
+R10_init = ExprId("R10_init", 32)
+R11_init = ExprId("R11_init", 32)
+R12_init = ExprId("R12_init", 32)
+SP_init = ExprId("SP_init", 32)
+LR_init = ExprId("LR_init", 32)
+PC_init = ExprId("PC_init", 32)
 
 
 reg_zf = 'zf'
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index f1e21a41..7aefad32 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -21,7 +21,7 @@ class ir_a_mips32l(ir_mips32l, ira):
         for irb in ir_blocks:
             pc_val = None
             lr_val = None
-            for assignblk in irb.irs:
+            for assignblk in irb:
                 pc_val = assignblk.get(self.arch.regs.PC, pc_val)
                 lr_val = assignblk.get(self.arch.regs.RA, lr_val)
 
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 493da595..1d2ec483 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -35,19 +35,19 @@ class mipsCGen(CGen):
 
     def __init__(self, ir_arch):
         super(mipsCGen, self).__init__(ir_arch)
-        self.delay_slot_dst = m2_expr.ExprId("branch_dst_irdst")
-        self.delay_slot_set = m2_expr.ExprId("branch_dst_set")
+        self.delay_slot_dst = m2_expr.ExprId("branch_dst_irdst", 32)
+        self.delay_slot_set = m2_expr.ExprId("branch_dst_set", 32)
 
     def block2assignblks(self, block):
         irblocks_list = super(mipsCGen, self).block2assignblks(block)
         for irblocks in irblocks_list:
             for blk_idx, irblock in enumerate(irblocks):
-                has_breakflow = any(assignblock.instr.breakflow() for assignblock in irblock.irs)
+                has_breakflow = any(assignblock.instr.breakflow() for assignblock in irblock)
                 if not has_breakflow:
                     continue
 
                 irs = []
-                for assignblock in irblock.irs:
+                for assignblock in irblock:
                     if self.ir_arch.pc not in assignblock:
                         irs.append(AssignBlock(assignments, assignblock.instr))
                         continue
@@ -58,7 +58,7 @@ class mipsCGen(CGen):
                     assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32)
                     # Replace IRDst with next instruction
                     assignments[self.ir_arch.IRDst] = m2_expr.ExprId(
-                        self.ir_arch.get_next_instr(assignblock.instr))
+                        self.ir_arch.get_next_instr(assignblock.instr), 32)
                     irs.append(AssignBlock(assignments, assignblock.instr))
                 irblocks[blk_idx] = IRBlock(irblock.label, irs)
 
@@ -72,8 +72,8 @@ class mipsCGen(CGen):
         lbl = self.get_block_post_label(block)
         out = (self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl),
                                                 self.C_PC,
-                                                m2_expr.ExprId('branch_dst_irdst'),
-                                                m2_expr.ExprId('branch_dst_irdst'),
+                                                m2_expr.ExprId('branch_dst_irdst', 32),
+                                                m2_expr.ExprId('branch_dst_irdst', 32),
                                                 self.id_to_c(m2_expr.ExprInt(lbl.offset, 32)))
               ).split('\n')
         return out
diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py
index fbd55a46..afade869 100644
--- a/miasm2/arch/mips32/regs.py
+++ b/miasm2/arch/mips32/regs.py
@@ -12,8 +12,8 @@ gen_reg('R_HI', globals())
 
 exception_flags = ExprId('exception_flags', 32)
 
-PC_init = ExprId("PC_init")
-PC_FETCH_init = ExprId("PC_FETCH_init")
+PC_init = ExprId("PC_init", 32)
+PC_FETCH_init = ExprId("PC_FETCH_init", 32)
 
 regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\
     ['A%d'%i for i in xrange(4)] +\
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index 645f9a4f..855cb6c8 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -34,7 +34,7 @@ def jal(arg1):
     "Jumps to the calculated address @arg1 and stores the return address in $RA"
     PC = arg1
     ir.IRDst = arg1
-    RA = ExprId(ir.get_next_break_label(instr))
+    RA = ExprId(ir.get_next_break_label(instr), 32)
 
 @sbuild.parse
 def jalr(arg1, arg2):
@@ -42,13 +42,13 @@ def jalr(arg1, arg2):
     address in another register @arg2"""
     PC = arg1
     ir.IRDst = arg1
-    arg2 = ExprId(ir.get_next_break_label(instr))
+    arg2 = ExprId(ir.get_next_break_label(instr), 32)
 
 @sbuild.parse
 def bal(arg1):
     PC = arg1
     ir.IRDst = arg1
-    RA = ExprId(ir.get_next_break_label(instr))
+    RA = ExprId(ir.get_next_break_label(instr), 32)
 
 @sbuild.parse
 def l_b(arg1):
@@ -75,7 +75,7 @@ def lb(arg1, arg2):
 @sbuild.parse
 def beq(arg1, arg2, arg3):
     "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq"
-    dst = ExprId(ir.get_next_break_label(instr)) if arg1 - arg2 else arg3
+    dst = ExprId(ir.get_next_break_label(instr), 32) if arg1 - arg2 else arg3
     PC = dst
     ir.IRDst = dst
 
@@ -83,7 +83,7 @@ def beq(arg1, arg2, arg3):
 def bgez(arg1, arg2):
     """Branches on @arg2 if the quantities of register @arg1 is greater than or
     equal to zero"""
-    dst = ExprId(ir.get_next_break_label(instr)) if arg1.msb() else arg2
+    dst = ExprId(ir.get_next_break_label(instr), 32) if arg1.msb() else arg2
     PC = dst
     ir.IRDst = dst
 
@@ -91,7 +91,7 @@ def bgez(arg1, arg2):
 def bne(arg1, arg2, arg3):
     """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT
     equal"""
-    dst = arg3 if arg1 - arg2 else ExprId(ir.get_next_break_label(instr))
+    dst = arg3 if arg1 - arg2 else ExprId(ir.get_next_break_label(instr), 32)
     PC = dst
     ir.IRDst = dst
 
@@ -229,7 +229,7 @@ def seh(arg1, arg2):
 @sbuild.parse
 def bltz(arg1, arg2):
     """Branches on @arg2 if the register @arg1 is less than zero"""
-    dst_o = arg2 if arg1.msb() else ExprId(ir.get_next_break_label(instr))
+    dst_o = arg2 if arg1.msb() else ExprId(ir.get_next_break_label(instr), 32)
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -237,7 +237,7 @@ def bltz(arg1, arg2):
 def blez(arg1, arg2):
     """Branches on @arg2 if the register @arg1 is less than or equal to zero"""
     cond = (i1(1) if arg1 else i1(0)) | arg1.msb()
-    dst_o = arg2 if cond else ExprId(ir.get_next_break_label(instr))
+    dst_o = arg2 if cond else ExprId(ir.get_next_break_label(instr), 32)
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -245,7 +245,7 @@ def blez(arg1, arg2):
 def bgtz(arg1, arg2):
     """Branches on @arg2 if the register @arg1 is greater than zero"""
     cond = (i1(1) if arg1 else i1(0)) | arg1.msb()
-    dst_o = ExprId(ir.get_next_break_label(instr)) if cond else arg2
+    dst_o = ExprId(ir.get_next_break_label(instr), 32) if cond else arg2
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -345,13 +345,13 @@ def c_le_d(arg1, arg2, arg3):
 
 @sbuild.parse
 def bc1t(arg1, arg2):
-    dst_o = arg2 if arg1 else ExprId(ir.get_next_break_label(instr))
+    dst_o = arg2 if arg1 else ExprId(ir.get_next_break_label(instr), 32)
     PC = dst_o
     ir.IRDst = dst_o
 
 @sbuild.parse
 def bc1f(arg1, arg2):
-    dst_o = ExprId(ir.get_next_break_label(instr)) if arg1 else arg2
+    dst_o = ExprId(ir.get_next_break_label(instr), 32) if arg1 else arg2
     PC = dst_o
     ir.IRDst = dst_o
 
diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py
index eeafd5f5..d7ae4f12 100644
--- a/miasm2/arch/sh4/arch.py
+++ b/miasm2/arch/sh4/arch.py
@@ -7,9 +7,9 @@ from collections import defaultdict
 import miasm2.arch.sh4.regs as regs_module
 from miasm2.arch.sh4.regs import *
 
-jra = ExprId('jra')
-jrb = ExprId('jrb')
-jrc = ExprId('jrc')
+jra = ExprId('jra', 32)
+jrb = ExprId('jrb', 32)
+jrc = ExprId('jrc', 32)
 
 
 # parser helper ###########
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 13c06ae6..72ed3309 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -4306,6 +4306,10 @@ addop("pmaxuw", [bs8(0x0f), bs8(0x38), bs8(0x3e), pref_66] +
 addop("pmaxud", [bs8(0x0f), bs8(0x38), bs8(0x3f), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm))
 
+addop("pmaxsw", [bs8(0x0f), bs8(0xee), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmaxsw", [bs8(0x0f), bs8(0xee), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
 
 addop("pminub", [bs8(0x0f), bs8(0xda), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm))
@@ -4339,6 +4343,11 @@ addop("pcmpgtb", [bs8(0x0f), bs8(0x64), no_xmm_pref] +
 addop("pcmpgtb", [bs8(0x0f), bs8(0x64), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm))
 
+addop("pcmpgtw", [bs8(0x0f), bs8(0x65), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm))
+addop("pcmpgtw", [bs8(0x0f), bs8(0x65), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm))
+
 addop("pcmpgtd", [bs8(0x0f), bs8(0x66), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm))
 addop("pcmpgtd", [bs8(0x0f), bs8(0x66), pref_66] +
@@ -4423,9 +4432,9 @@ addop("pextrq", [bs8(0x0f), bs8(0x3a), bs8(0x16), pref_66] +
 addop("pextrw", [bs8(0x0f), bs8(0x3a), bs8(0x15), pref_66] +
       rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08])
 addop("pextrw", [bs8(0x0f), bs8(0xc5), no_xmm_pref] +
-      rmmod(mm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, mm_reg, u08])
+      rmmod(rmreg, rm_arg_mm) + [u08], [rmreg, rm_arg_mm, u08])
 addop("pextrw", [bs8(0x0f), bs8(0xc5), pref_66] +
-      rmmod(xmm_reg, rm_arg_reg_m16) + [u08], [rm_arg_reg_m16, xmm_reg, u08])
+      rmmod(rmreg, rm_arg_xmm) + [u08], [rmreg, rm_arg_xmm, u08])
 
 
 addop("sqrtpd", [bs8(0x0f), bs8(0x51), pref_66] +
@@ -4453,6 +4462,100 @@ addop("aesdec", [bs8(0x0f), bs8(0x38), bs8(0xde), pref_66] + rmmod(xmm_reg, rm_a
 addop("aesenclast", [bs8(0x0f), bs8(0x38), bs8(0xdd), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
 addop("aesdeclast", [bs8(0x0f), bs8(0x38), bs8(0xdf), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
 
+addop("packsswb", [bs8(0x0f), bs8(0x63), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("packsswb", [bs8(0x0f), bs8(0x63), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("packssdw", [bs8(0x0f), bs8(0x6b), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("packssdw", [bs8(0x0f), bs8(0x6b), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("packuswb", [bs8(0x0f), bs8(0x67), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("packuswb", [bs8(0x0f), bs8(0x67), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("pmullw", [bs8(0x0f), bs8(0xd5), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmullw", [bs8(0x0f), bs8(0xd5), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pmulhuw", [bs8(0x0f), bs8(0xe4), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmulhuw", [bs8(0x0f), bs8(0xe4), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pmulhw", [bs8(0x0f), bs8(0xe5), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmulhw", [bs8(0x0f), bs8(0xe5), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pmuludq", [bs8(0x0f), bs8(0xf4), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmuludq", [bs8(0x0f), bs8(0xf4), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+
+addop("psubusb", [bs8(0x0f), bs8(0xd8), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psubusb", [bs8(0x0f), bs8(0xd8), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("psubusw", [bs8(0x0f), bs8(0xd9), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psubusw", [bs8(0x0f), bs8(0xd9), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("psubsb", [bs8(0x0f), bs8(0xe8), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psubsb", [bs8(0x0f), bs8(0xe8), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("psubsw", [bs8(0x0f), bs8(0xe9), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psubsw", [bs8(0x0f), bs8(0xe9), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+
+addop("paddusb", [bs8(0x0f), bs8(0xdc), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddusb", [bs8(0x0f), bs8(0xdc), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("paddusw", [bs8(0x0f), bs8(0xdd), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddusw", [bs8(0x0f), bs8(0xdd), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("paddsb", [bs8(0x0f), bs8(0xec), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddsb", [bs8(0x0f), bs8(0xec), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("paddsw", [bs8(0x0f), bs8(0xed), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("paddsw", [bs8(0x0f), bs8(0xed), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("pmaddwd", [bs8(0x0f), bs8(0xf5), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pmaddwd", [bs8(0x0f), bs8(0xf5), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("psadbw", [bs8(0x0f), bs8(0xf6), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("psadbw", [bs8(0x0f), bs8(0xf6), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("pavgb", [bs8(0x0f), bs8(0xe0), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pavgb", [bs8(0x0f), bs8(0xe0), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+addop("pavgw", [bs8(0x0f), bs8(0xe3), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_m64))
+addop("pavgw", [bs8(0x0f), bs8(0xe3), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m128))
+
+addop("maskmovq", [bs8(0x0f), bs8(0xf7), no_xmm_pref] +
+      rmmod(mm_reg, rm_arg_mm_reg))
+addop("maskmovdqu", [bs8(0x0f), bs8(0xf7), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_reg))
+
+addop("emms", [bs8(0x0f), bs8(0x77)])
+
+
 mn_x86.bintree = factor_one_bit(mn_x86.bintree)
 # mn_x86.bintree = factor_fields_all(mn_x86.bintree)
 """
diff --git a/miasm2/arch/x86/disasm.py b/miasm2/arch/x86/disasm.py
index fc981c09..ecb1b8da 100644
--- a/miasm2/arch/x86/disasm.py
+++ b/miasm2/arch/x86/disasm.py
@@ -15,7 +15,7 @@ class dis_x86(disasmEngine):
 
     def __init__(self, bs=None, **kwargs):
         super(dis_x86, self).__init__(mn_x86, self.attrib, bs, **kwargs)
-        self.dis_bloc_callback = cb_x86_disasm
+        self.dis_block_callback = cb_x86_disasm
 
 
 class dis_x86_16(dis_x86):
diff --git a/miasm2/arch/x86/regs.py b/miasm2/arch/x86/regs.py
index cb7e0d7b..84590c75 100644
--- a/miasm2/arch/x86/regs.py
+++ b/miasm2/arch/x86/regs.py
@@ -251,23 +251,23 @@ reg_float_address = 'reg_float_address'
 reg_float_ds = 'reg_float_ds'
 
 
-dr0 = ExprId(reg_dr0)
-dr1 = ExprId(reg_dr1)
-dr2 = ExprId(reg_dr2)
-dr3 = ExprId(reg_dr3)
-dr4 = ExprId(reg_dr4)
-dr5 = ExprId(reg_dr5)
-dr6 = ExprId(reg_dr6)
-dr7 = ExprId(reg_dr7)
-
-cr0 = ExprId(reg_cr0)
-cr1 = ExprId(reg_cr1)
-cr2 = ExprId(reg_cr2)
-cr3 = ExprId(reg_cr3)
-cr4 = ExprId(reg_cr4)
-cr5 = ExprId(reg_cr5)
-cr6 = ExprId(reg_cr6)
-cr7 = ExprId(reg_cr7)
+dr0 = ExprId(reg_dr0, 32)
+dr1 = ExprId(reg_dr1, 32)
+dr2 = ExprId(reg_dr2, 32)
+dr3 = ExprId(reg_dr3, 32)
+dr4 = ExprId(reg_dr4, 32)
+dr5 = ExprId(reg_dr5, 32)
+dr6 = ExprId(reg_dr6, 32)
+dr7 = ExprId(reg_dr7, 32)
+
+cr0 = ExprId(reg_cr0, 32)
+cr1 = ExprId(reg_cr1, 32)
+cr2 = ExprId(reg_cr2, 32)
+cr3 = ExprId(reg_cr3, 32)
+cr4 = ExprId(reg_cr4, 32)
+cr5 = ExprId(reg_cr5, 32)
+cr6 = ExprId(reg_cr6, 32)
+cr7 = ExprId(reg_cr7, 32)
 
 mm0 = ExprId(reg_mm0, 64)
 mm1 = ExprId(reg_mm1, 64)
@@ -330,9 +330,9 @@ float_c2 = ExprId(reg_float_c2, size=1)
 float_c3 = ExprId(reg_float_c3, size=1)
 float_stack_ptr = ExprId(reg_float_stack_ptr, size=3)
 float_control = ExprId(reg_float_control, 16)
-float_eip = ExprId(reg_float_eip)
+float_eip = ExprId(reg_float_eip, 32)
 float_cs = ExprId(reg_float_cs, size=16)
-float_address = ExprId(reg_float_address)
+float_address = ExprId(reg_float_address, 32)
 float_ds = ExprId(reg_float_ds, size=16)
 
 float_st0 = ExprId("float_st0", 64)
@@ -352,14 +352,14 @@ float_replace = {fltregs32_expr[i]: float_list[i] for i in xrange(8)}
 float_replace[r_st_all.expr[0]] = float_st0
 
 
-EAX_init = ExprId('EAX_init')
-EBX_init = ExprId('EBX_init')
-ECX_init = ExprId('ECX_init')
-EDX_init = ExprId('EDX_init')
-ESI_init = ExprId('ESI_init')
-EDI_init = ExprId('EDI_init')
-ESP_init = ExprId('ESP_init')
-EBP_init = ExprId('EBP_init')
+EAX_init = ExprId('EAX_init', 32)
+EBX_init = ExprId('EBX_init', 32)
+ECX_init = ExprId('ECX_init', 32)
+EDX_init = ExprId('EDX_init', 32)
+ESI_init = ExprId('ESI_init', 32)
+EDI_init = ExprId('EDI_init', 32)
+ESP_init = ExprId('ESP_init', 32)
+EBP_init = ExprId('EBP_init', 32)
 
 
 RAX_init = ExprId('RAX_init', 64)
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 56aca1c2..589c2eb9 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -1614,22 +1614,25 @@ def imul(_, instr, src1, src2=None, src3=None):
 
 
 def cbw(_, instr):
+    # Only in 16 bit
     e = []
-    tempAL = mRAX[instr.mode][:8]
-    tempAX = mRAX[instr.mode][:16]
+    tempAL = mRAX[instr.v_opmode()][:8]
+    tempAX = mRAX[instr.v_opmode()][:16]
     e.append(m2_expr.ExprAff(tempAX, tempAL.signExtend(16)))
     return e, []
 
 
 def cwde(_, instr):
+    # Only in 32/64 bit
     e = []
-    tempAX = mRAX[instr.mode][:16]
-    tempEAX = mRAX[instr.mode][:32]
+    tempAX = mRAX[instr.v_opmode()][:16]
+    tempEAX = mRAX[instr.v_opmode()][:32]
     e.append(m2_expr.ExprAff(tempEAX, tempAX.signExtend(32)))
     return e, []
 
 
 def cdqe(_, instr):
+    # Only in 64 bit
     e = []
     tempEAX = mRAX[instr.mode][:32]
     tempRAX = mRAX[instr.mode][:64]
@@ -1638,32 +1641,34 @@ def cdqe(_, instr):
 
 
 def cwd(_, instr):
+    # Only in 16 bit
     e = []
     tempAX = mRAX[instr.mode][:16]
     tempDX = mRDX[instr.mode][:16]
-    c = tempAX.signExtend(32)
-    e.append(m2_expr.ExprAff(tempAX, c[:16]))
-    e.append(m2_expr.ExprAff(tempDX, c[16:32]))
+    result = tempAX.signExtend(32)
+    e.append(m2_expr.ExprAff(tempAX, result[:16]))
+    e.append(m2_expr.ExprAff(tempDX, result[16:32]))
     return e, []
 
 
 def cdq(_, instr):
+    # Only in 32/64 bit
     e = []
-    tempEAX = mRAX[instr.mode][:32]
-    tempEDX = mRDX[instr.mode][:32]
-    c = tempEAX.signExtend(64)
-    e.append(m2_expr.ExprAff(tempEAX, c[:32]))
-    e.append(m2_expr.ExprAff(tempEDX, c[32:64]))
+    tempEAX = mRAX[instr.v_opmode()]
+    tempEDX = mRDX[instr.v_opmode()]
+    result = tempEAX.signExtend(64)
+    e.append(m2_expr.ExprAff(tempEDX, result[32:64]))
     return e, []
 
 
 def cqo(_, instr):
+    # Only in 64 bit
     e = []
     tempRAX = mRAX[instr.mode][:64]
     tempRDX = mRDX[instr.mode][:64]
-    c = tempRAX.signExtend(128)
-    e.append(m2_expr.ExprAff(tempRAX, c[:64]))
-    e.append(m2_expr.ExprAff(tempRDX, c[64:128]))
+    result = tempRAX.signExtend(128)
+    e.append(m2_expr.ExprAff(tempRAX, result[:64]))
+    e.append(m2_expr.ExprAff(tempRDX, result[64:128]))
     return e, []
 
 
@@ -3314,62 +3319,104 @@ def vec_op_clip(op, size):
 # Generic vertical operation
 
 
-def vec_vertical_sem(op, elt_size, reg_size, dst, src):
+def vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output):
     assert reg_size % elt_size == 0
     n = reg_size / elt_size
     if op == '-':
         ops = [
-            (dst[i * elt_size:(i + 1) * elt_size]
-             - src[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)]
+            apply_on_output((dst[i * elt_size:(i + 1) * elt_size]
+                             - src[i * elt_size:(i + 1) * elt_size]))
+            for i in xrange(0, n)
+        ]
     else:
-        ops = [m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size],
-                              src[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)]
+        ops = [
+            apply_on_output(m2_expr.ExprOp(op, dst[i * elt_size:(i + 1) * elt_size],
+                                           src[i * elt_size:(i + 1) * elt_size]))
+            for i in xrange(0, n)
+        ]
 
     return m2_expr.ExprCompose(*ops)
 
 
-def float_vec_vertical_sem(op, elt_size, reg_size, dst, src):
+def float_vec_vertical_sem(op, elt_size, reg_size, dst, src, apply_on_output):
     assert reg_size % elt_size == 0
     n = reg_size / elt_size
 
     x_to_int, int_to_x = {32: ('float_to_int_%d', 'int_%d_to_float'),
                           64: ('double_to_int_%d', 'int_%d_to_double')}[elt_size]
     if op == '-':
-        ops = [m2_expr.ExprOp(x_to_int % elt_size,
-                              m2_expr.ExprOp(int_to_x % elt_size, dst[i * elt_size:(i + 1) * elt_size]) -
-                              m2_expr.ExprOp(
-                                  int_to_x % elt_size, src[i * elt_size:(
-                                      i + 1) * elt_size])) for i in xrange(0, n)]
+        ops = [
+            apply_on_output(m2_expr.ExprOp(
+                x_to_int % elt_size,
+                m2_expr.ExprOp(int_to_x % elt_size, dst[i * elt_size:(i + 1) * elt_size]) -
+                m2_expr.ExprOp(
+                    int_to_x % elt_size, src[i * elt_size:(
+                        i + 1) * elt_size])))
+            for i in xrange(0, n)
+        ]
     else:
-        ops = [m2_expr.ExprOp(x_to_int % elt_size,
-                              m2_expr.ExprOp(op,
-                                             m2_expr.ExprOp(
-                                                 int_to_x % elt_size, dst[i * elt_size:(
-                                                     i + 1) * elt_size]),
-                                             m2_expr.ExprOp(
-                                                 int_to_x % elt_size, src[i * elt_size:(
-                                                     i + 1) * elt_size]))) for i in xrange(0, n)]
+        ops = [
+            apply_on_output(m2_expr.ExprOp(
+                x_to_int % elt_size,
+                m2_expr.ExprOp(op,
+                               m2_expr.ExprOp(
+                                   int_to_x % elt_size, dst[i * elt_size:(
+                                       i + 1) * elt_size]),
+                               m2_expr.ExprOp(
+                                   int_to_x % elt_size, src[i * elt_size:(
+                                       i + 1) * elt_size]))))
+            for i in xrange(0, n)]
 
     return m2_expr.ExprCompose(*ops)
 
 
-def __vec_vertical_instr_gen(op, elt_size, sem):
+def __vec_vertical_instr_gen(op, elt_size, sem, apply_on_output):
     def vec_instr(ir, instr, dst, src):
         e = []
         if isinstance(src, m2_expr.ExprMem):
             src = ir.ExprMem(src.arg, dst.size)
         reg_size = dst.size
-        e.append(m2_expr.ExprAff(dst, sem(op, elt_size, reg_size, dst, src)))
+        e.append(m2_expr.ExprAff(dst, sem(op, elt_size, reg_size, dst, src,
+                                          apply_on_output)))
         return e, []
     return vec_instr
 
 
-def vec_vertical_instr(op, elt_size):
-    return __vec_vertical_instr_gen(op, elt_size, vec_vertical_sem)
+def vec_vertical_instr(op, elt_size, apply_on_output=lambda x: x):
+    return __vec_vertical_instr_gen(op, elt_size, vec_vertical_sem,
+                                    apply_on_output)
 
 
-def float_vec_vertical_instr(op, elt_size):
-    return __vec_vertical_instr_gen(op, elt_size, float_vec_vertical_sem)
+def float_vec_vertical_instr(op, elt_size, apply_on_output=lambda x: x):
+    return __vec_vertical_instr_gen(op, elt_size, float_vec_vertical_sem,
+                                    apply_on_output)
+
+
+def _keep_mul_high(expr, signed=False):
+    assert expr.is_op("*") and len(expr.args) == 2
+
+    if signed:
+        arg1 = expr.args[0].signExtend(expr.size * 2)
+        arg2 = expr.args[1].signExtend(expr.size * 2)
+    else:
+        arg1 = expr.args[0].zeroExtend(expr.size * 2)
+        arg2 = expr.args[1].zeroExtend(expr.size * 2)
+    return m2_expr.ExprOp("*", arg1, arg2)[expr.size:]
+
+# Op, signed => associated comparison
+_min_max_func = {
+    ("min", False): m2_expr.expr_is_unsigned_lower,
+    ("min", True): m2_expr.expr_is_signed_lower,
+    ("max", False): m2_expr.expr_is_unsigned_greater,
+    ("max", True): m2_expr.expr_is_signed_greater,
+}
+def _min_max(expr, signed):
+    assert (expr.is_op("min") or expr.is_op("max")) and len(expr.args) == 2
+    return m2_expr.ExprCond(
+        _min_max_func[(expr.op, signed)](expr.args[1], expr.args[0]),
+        expr.args[1],
+        expr.args[0],
+    )
 
 
 # Integer arithmetic
@@ -3393,6 +3440,109 @@ psubw = vec_vertical_instr('-', 16)
 psubd = vec_vertical_instr('-', 32)
 psubq = vec_vertical_instr('-', 64)
 
+# Multiplications
+#
+
+# SSE
+pmullb = vec_vertical_instr('*', 8)
+pmullw = vec_vertical_instr('*', 16)
+pmulld = vec_vertical_instr('*', 32)
+pmullq = vec_vertical_instr('*', 64)
+pmulhub = vec_vertical_instr('*', 8, _keep_mul_high)
+pmulhuw = vec_vertical_instr('*', 16, _keep_mul_high)
+pmulhud = vec_vertical_instr('*', 32, _keep_mul_high)
+pmulhuq = vec_vertical_instr('*', 64, _keep_mul_high)
+pmulhb = vec_vertical_instr('*', 8, lambda x: _keep_mul_high(x, signed=True))
+pmulhw = vec_vertical_instr('*', 16, lambda x: _keep_mul_high(x, signed=True))
+pmulhd = vec_vertical_instr('*', 32, lambda x: _keep_mul_high(x, signed=True))
+pmulhq = vec_vertical_instr('*', 64, lambda x: _keep_mul_high(x, signed=True))
+
+def pmuludq(ir, instr, dst, src):
+    e = []
+    if dst.size == 64:
+        e.append(m2_expr.ExprAff(
+            dst,
+            src[:32].zeroExtend(64) * dst[:32].zeroExtend(64)
+        ))
+    elif dst.size == 128:
+        e.append(m2_expr.ExprAff(
+            dst[:64],
+            src[:32].zeroExtend(64) * dst[:32].zeroExtend(64)
+        ))
+        e.append(m2_expr.ExprAff(
+            dst[64:],
+            src[64:96].zeroExtend(64) * dst[64:96].zeroExtend(64)
+        ))
+    else:
+        raise RuntimeError("Unsupported size %d" % dst.size)
+    return e, []
+
+# Mix
+#
+
+# SSE
+def pmaddwd(ir, instr, dst, src):
+    sizedst = 32
+    sizesrc = 16
+    out = []
+    for start in xrange(0, dst.size, sizedst):
+        base = start
+        mul1 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst)
+        base += sizesrc
+        mul2 = src[base: base + sizesrc].signExtend(sizedst) * dst[base: base + sizesrc].signExtend(sizedst)
+        out.append(mul1 + mul2)
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], []
+
+
+def _absolute(expr):
+    """Return abs(@expr)"""
+    signed = expr.msb()
+    value_unsigned = (expr ^ expr.mask) + m2_expr.ExprInt(1, expr.size)
+    return m2_expr.ExprCond(signed, value_unsigned, expr)
+
+
+def psadbw(ir, instr, dst, src):
+    sizedst = 16
+    sizesrc = 8
+    out_dst = []
+    for start in xrange(0, dst.size, 64):
+        out = []
+        for src_start in xrange(0, 64, sizesrc):
+            beg = start + src_start
+            end = beg + sizesrc
+            # Not clear in the doc equations, but in the text, src and dst are:
+            # "8 unsigned byte integers"
+            out.append(_absolute(dst[beg: end].zeroExtend(sizedst) - src[beg: end].zeroExtend(sizedst)))
+        out_dst.append(m2_expr.ExprOp("+", *out))
+        out_dst.append(m2_expr.ExprInt(0, 64 - sizedst))
+
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out_dst))], []
+
+def _average(expr):
+    assert expr.is_op("avg") and len(expr.args) == 2
+
+    arg1 = expr.args[0].zeroExtend(expr.size * 2)
+    arg2 = expr.args[1].zeroExtend(expr.size * 2)
+    one = m2_expr.ExprInt(1, arg1.size)
+    # avg(unsigned) = (a + b + 1) >> 1, addition beeing at least on one more bit
+    return ((arg1 + arg2 + one) >> one)[:expr.size]
+
+pavgb = vec_vertical_instr('avg', 8, _average)
+pavgw = vec_vertical_instr('avg', 16, _average)
+
+# Comparisons
+#
+
+# SSE
+pminsw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=True))
+pminub = vec_vertical_instr('min', 8, lambda x: _min_max(x, signed=False))
+pminuw = vec_vertical_instr('min', 16, lambda x: _min_max(x, signed=False))
+pminud = vec_vertical_instr('min', 32, lambda x: _min_max(x, signed=False))
+pmaxub = vec_vertical_instr('max', 8, lambda x: _min_max(x, signed=False))
+pmaxuw = vec_vertical_instr('max', 16, lambda x: _min_max(x, signed=False))
+pmaxud = vec_vertical_instr('max', 32, lambda x: _min_max(x, signed=False))
+pmaxsw = vec_vertical_instr('max', 16, lambda x: _min_max(x, signed=True))
+
 # Floating-point arithmetic
 #
 
@@ -3443,12 +3593,6 @@ def por(_, instr, dst, src):
     return e, []
 
 
-def pminsw(_, instr, dst, src):
-    e = []
-    e.append(m2_expr.ExprAff(dst, m2_expr.ExprCond((dst - src).msb(), dst, src)))
-    return e, []
-
-
 def cvtdq2pd(_, instr, dst, src):
     e = []
     e.append(
@@ -3814,62 +3958,6 @@ def iret(ir, instr):
     return exprs, []
 
 
-def pmaxu(_, instr, dst, src, size):
-    e = []
-    for i in xrange(0, dst.size, size):
-        op1 = dst[i:i + size]
-        op2 = src[i:i + size]
-        res = op1 - op2
-        # Compote CF in @res = @op1 - @op2
-        ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()
-
-        e.append(m2_expr.ExprAff(dst[i:i + size],
-                                 m2_expr.ExprCond(ret,
-                                                  src[i:i + size],
-                                                  dst[i:i + size])))
-    return e, []
-
-
-def pmaxub(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 8)
-
-
-def pmaxuw(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 16)
-
-
-def pmaxud(ir, instr, dst, src):
-    return pmaxu(ir, instr, dst, src, 32)
-
-
-def pminu(_, instr, dst, src, size):
-    e = []
-    for i in xrange(0, dst.size, size):
-        op1 = dst[i:i + size]
-        op2 = src[i:i + size]
-        res = op1 - op2
-        # Compote CF in @res = @op1 - @op2
-        ret = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()
-
-        e.append(m2_expr.ExprAff(dst[i:i + size],
-                                 m2_expr.ExprCond(ret,
-                                                  dst[i:i + size],
-                                                  src[i:i + size])))
-    return e, []
-
-
-def pminub(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 8)
-
-
-def pminuw(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 16)
-
-
-def pminud(ir, instr, dst, src):
-    return pminu(ir, instr, dst, src, 32)
-
-
 def pcmpeq(_, instr, dst, src, size):
     e = []
     for i in xrange(0, dst.size, size):
@@ -4168,6 +4256,202 @@ def palignr(ir, instr, dst, src, imm):
     return [m2_expr.ExprAff(dst, result)], []
 
 
+def _signed_saturation(expr, dst_size):
+    """Saturate the expr @expr for @dst_size bit
+    Signed saturation return MAX_INT / MIN_INT or value depending on the value
+    """
+    assert expr.size > dst_size
+
+    median = 1 << (dst_size - 1)
+    min_int = m2_expr.ExprInt(- median, dst_size)
+    max_int = m2_expr.ExprInt(median - 1, dst_size)
+    signed = expr.msb()
+    value_unsigned = (expr ^ expr.mask) + m2_expr.ExprInt(1, expr.size)
+    # Re-use the sign bit
+    value = m2_expr.ExprCompose(expr[:dst_size - 1], signed)
+
+    # Bit hack: to avoid a double signed comparison, use mask
+    # ie., in unsigned, 0xXY > 0x0f iff X is not null
+
+    # if expr >s 0
+    #    if expr[dst_size - 1:] > 0: # bigger than max_int
+    #        -> max_int
+    #    else
+    #        -> value
+    # else # negative
+    #    if expr[dst_size:-1] > 0: # smaller than min_int
+    #        -> value
+    #    else
+    #        -> min_int
+
+    return m2_expr.ExprCond(
+        signed,
+        m2_expr.ExprCond(value_unsigned[dst_size - 1:],
+                         min_int,
+                         value),
+        m2_expr.ExprCond(expr[dst_size - 1:],
+                         max_int,
+                         value),
+    )
+
+
+def _unsigned_saturation(expr, dst_size):
+    """Saturate the expr @expr for @dst_size bit
+    Unsigned saturation return MAX_INT or value depending on the value
+    """
+    assert expr.size > dst_size
+
+    zero = m2_expr.ExprInt(0, dst_size)
+    max_int = m2_expr.ExprInt(-1, dst_size)
+    value = expr[:dst_size]
+    signed = expr.msb()
+
+
+    # Bit hack: to avoid a double signed comparison, use mask
+    # ie., in unsigned, 0xXY > 0x0f iff X is not null
+
+    return m2_expr.ExprCond(
+        signed,
+        zero,
+        m2_expr.ExprCond(expr[dst_size:],
+                         max_int,
+                         value),
+    )
+
+
+
+def packsswb(ir, instr, dst, src):
+    out = []
+    for source in [dst, src]:
+        for start in xrange(0, dst.size, 16):
+            out.append(_signed_saturation(source[start:start + 16], 8))
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], []
+
+
+def packssdw(ir, instr, dst, src):
+    out = []
+    for source in [dst, src]:
+        for start in xrange(0, dst.size, 32):
+            out.append(_signed_saturation(source[start:start + 32], 16))
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], []
+
+
+def packuswb(ir, instr, dst, src):
+    out = []
+    for source in [dst, src]:
+        for start in xrange(0, dst.size, 16):
+            out.append(_unsigned_saturation(source[start:start + 16], 8))
+    return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], []
+
+
+def _saturation_sub_unsigned(expr):
+    assert expr.is_op("+") and len(expr.args) == 2 and expr.args[-1].is_op("-")
+
+    # Compute the soustraction on one more bit to be able to distinguish cases:
+    # 0x48 - 0xd7 in 8 bit, should saturate
+    arg1 = expr.args[0].zeroExtend(expr.size + 1)
+    arg2 = expr.args[1].args[0].zeroExtend(expr.size + 1)
+    return _unsigned_saturation(arg1 - arg2, expr.size)
+
+def _saturation_sub_signed(expr):
+    assert expr.is_op("+") and len(expr.args) == 2 and expr.args[-1].is_op("-")
+
+    # Compute the substraction on two more bits, see _saturation_sub_unsigned
+    arg1 = expr.args[0].signExtend(expr.size + 2)
+    arg2 = expr.args[1].args[0].signExtend(expr.size + 2)
+    return _signed_saturation(arg1 - arg2, expr.size)
+
+def _saturation_add(expr):
+    assert expr.is_op("+") and len(expr.args) == 2
+
+    # Compute the addition on one more bit to be able to distinguish cases:
+    # 0x48 + 0xd7 in 8 bit, should saturate
+
+    arg1 = expr.args[0].zeroExtend(expr.size + 1)
+    arg2 = expr.args[1].zeroExtend(expr.size + 1)
+
+    # We can also use _unsigned_saturation with two additionnal bits (to
+    # distinguish minus and overflow case)
+    # The resulting expression being more complicated with an impossible case
+    # (signed=True), we rewrite the rule here
+
+    return m2_expr.ExprCond((arg1 + arg2).msb(), m2_expr.ExprInt(-1, expr.size),
+                            expr)
+
+def _saturation_add_signed(expr):
+    assert expr.is_op("+") and len(expr.args) == 2
+
+    # Compute the substraction on two more bits, see _saturation_add_unsigned
+
+    arg1 = expr.args[0].signExtend(expr.size + 2)
+    arg2 = expr.args[1].signExtend(expr.size + 2)
+
+    return _signed_saturation(arg1 + arg2, expr.size)
+
+
+# Saturate SSE operations
+
+psubusb = vec_vertical_instr('-', 8, _saturation_sub_unsigned)
+psubusw = vec_vertical_instr('-', 16, _saturation_sub_unsigned)
+paddusb = vec_vertical_instr('+', 8, _saturation_add)
+paddusw = vec_vertical_instr('+', 16, _saturation_add)
+psubsb = vec_vertical_instr('-', 8, _saturation_sub_signed)
+psubsw = vec_vertical_instr('-', 16, _saturation_sub_signed)
+paddsb = vec_vertical_instr('+', 8, _saturation_add_signed)
+paddsw = vec_vertical_instr('+', 16, _saturation_add_signed)
+
+
+# Others SSE operations
+
+def maskmovq(ir, instr, src, mask):
+    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    blks = []
+
+    # For each possibility, check if a write is necessary
+    check_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+                    for _ in xrange(0, mask.size, 8)]
+    # If the write has to be done, do it (otherwise, nothing happen)
+    write_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
+                    for _ in xrange(0, mask.size, 8)]
+
+    # Build check blocks
+    for i, start in enumerate(xrange(0, mask.size, 8)):
+        bit = mask[start + 7: start + 8]
+        cur_label = check_labels[i]
+        next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next
+        write_label = write_labels[i]
+        check = m2_expr.ExprAff(ir.IRDst,
+                                m2_expr.ExprCond(bit,
+                                                 write_label,
+                                                 next_check_label))
+        blks.append(IRBlock(cur_label.name, [AssignBlock([check], instr)]))
+
+    # Build write blocks
+    dst_addr = mRDI[instr.mode]
+    for i, start in enumerate(xrange(0, mask.size, 8)):
+        bit = mask[start + 7: start + 8]
+        cur_label = write_labels[i]
+        next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next
+        write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size)
+
+        # @8[DI/EDI/RDI + i] = src[byte i]
+        write_mem = m2_expr.ExprAff(m2_expr.ExprMem(write_addr, 8),
+                                    src[start: start + 8])
+        jump = m2_expr.ExprAff(ir.IRDst, next_check_label)
+        blks.append(IRBlock(cur_label.name, [AssignBlock([write_mem, jump], instr)]))
+
+    # If mask is null, bypass all
+    e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(mask,
+                                                    check_labels[0],
+                                                    lbl_next))]
+    return e, blks
+
+
+def emms(ir, instr):
+    # Implemented as a NOP
+    return [], []
+
+
 mnemo_func = {'mov': mov,
               'xchg': xchg,
               'movzx': movzx,
@@ -4552,6 +4836,29 @@ mnemo_func = {'mov': mov,
               "psubd": psubd,
               "psubq": psubq,
 
+              # Multiplications
+              # SSE
+              "pmullb": pmullb,
+              "pmullw": pmullw,
+              "pmulld": pmulld,
+              "pmullq": pmullq,
+              "pmulhub": pmulhub,
+              "pmulhuw": pmulhuw,
+              "pmulhud": pmulhud,
+              "pmulhuq": pmulhuq,
+              "pmulhb": pmulhb,
+              "pmulhw": pmulhw,
+              "pmulhd": pmulhd,
+              "pmulhq": pmulhq,
+              "pmuludq": pmuludq,
+
+              # Mix
+              # SSE
+              "pmaddwd": pmaddwd,
+              "psadbw": psadbw,
+              "pavgb": pavgb,
+              "pavgw": pavgw,
+
               # Arithmetic (floating-point)
               #
 
@@ -4609,6 +4916,7 @@ mnemo_func = {'mov': mov,
               "pmaxub": pmaxub,
               "pmaxuw": pmaxuw,
               "pmaxud": pmaxud,
+              "pmaxsw": pmaxsw,
 
               "pminub": pminub,
               "pminuw": pminuw,
@@ -4665,8 +4973,23 @@ mnemo_func = {'mov': mov,
 
               "pmovmskb": pmovmskb,
 
-              "smsw": smsw,
+              "packsswb": packsswb,
+              "packssdw": packssdw,
+              "packuswb": packuswb,
+
+              "psubusb": psubusb,
+              "psubusw": psubusw,
+              "paddusb": paddusb,
+              "paddusw": paddusw,
+              "psubsb": psubsb,
+              "psubsw": psubsw,
+              "paddsb": paddsb,
+              "paddsw": paddsw,
 
+              "smsw": smsw,
+              "maskmovq": maskmovq,
+              "maskmovdqu": maskmovq,
+              "emms": emms,
               }
 
 
@@ -4788,7 +5111,7 @@ class ir_x86_16(IntermediateRepresentation):
 
     def irbloc_fix_regs_for_mode(self, irblock, mode=64):
         irs = []
-        for assignblk in irblock.irs:
+        for assignblk in irblock:
             new_assignblk = dict(assignblk)
             for dst, src in assignblk.iteritems():
                 del new_assignblk[dst]
diff --git a/miasm2/core/asmblock.py b/miasm2/core/asmblock.py
index 5b95976f..7d18c4f5 100644
--- a/miasm2/core/asmblock.py
+++ b/miasm2/core/asmblock.py
@@ -1350,7 +1350,7 @@ class disasmEngine(object):
 
     + callback(arch, attrib, pool_bin, cur_bloc, offsets_to_dis,
                symbol_pool)
-     - dis_bloc_callback: callback after each new disassembled block
+     - dis_block_callback: callback after each new disassembled block
     """
 
     def __init__(self, arch, attrib, bin_stream, **kwargs):
@@ -1372,7 +1372,7 @@ class disasmEngine(object):
         self.dontdis_retcall = False
         self.lines_wd = None
         self.blocs_wd = None
-        self.dis_bloc_callback = None
+        self.dis_block_callback = None
         self.dont_dis_nulstart_bloc = False
         self.dont_dis_retcall_funcs = set()
 
@@ -1387,9 +1387,18 @@ class disasmEngine(object):
         warnings.warn("""DEPRECATION WARNING: "job_done" is not needed anymore, support is dropped.""")
         return
 
+    def get_dis_bloc_callback(self):
+        warnings.warn("""DEPRECATION WARNING: "dis_bloc_callback" use dis_block_callback.""")
+        return self.dis_block_callback
+
+    def set_dis_bloc_callback(self, function):
+        warnings.warn("""DEPRECATION WARNING: "dis_bloc_callback" use dis_block_callback.""")
+        self.dis_block_callback = function
+
 
     # Deprecated
     job_done = property(get_job_done, set_job_done)
+    dis_bloc_callback = property(get_dis_bloc_callback, set_dis_bloc_callback)
 
     def _dis_block(self, offset, job_done=None):
         """Disassemble the block at offset @offset
@@ -1520,11 +1529,11 @@ class disasmEngine(object):
         # Fix multiple constraints
         cur_block.fix_constraints()
 
-        if self.dis_bloc_callback is not None:
-            self.dis_bloc_callback(mn=self.arch, attrib=self.attrib,
-                                   pool_bin=self.bin_stream, cur_bloc=cur_block,
-                                   offsets_to_dis=offsets_to_dis,
-                                   symbol_pool=self.symbol_pool)
+        if self.dis_block_callback is not None:
+            self.dis_block_callback(mn=self.arch, attrib=self.attrib,
+                                    pool_bin=self.bin_stream, cur_bloc=cur_block,
+                                    offsets_to_dis=offsets_to_dis,
+                                    symbol_pool=self.symbol_pool)
         return cur_block, offsets_to_dis
 
     def dis_block(self, offset):
@@ -1573,7 +1582,7 @@ class disasmEngine(object):
             blocks.add_node(cur_block)
 
         blocks.apply_splitting(self.symbol_pool,
-                               dis_block_callback=self.dis_bloc_callback,
+                               dis_block_callback=self.dis_block_callback,
                                mn=self.arch, attrib=self.attrib,
                                pool_bin=self.bin_stream)
         return blocks
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index 6b189c4d..a72c1ec4 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -525,11 +525,14 @@ class ExprId(Expr):
 
     __slots__ = Expr.__slots__ + ["_name"]
 
-    def __init__(self, name, size=32):
+    def __init__(self, name, size=None):
         """Create an identifier
         @name: str, identifier's name
         @size: int, identifier's size
         """
+        if size is None:
+            warnings.warn('DEPRECATION WARNING: size is a mandatory argument: use ExprId(name, SIZE)')
+            size = 32
         super(ExprId, self).__init__(size)
         self._name = name
 
diff --git a/miasm2/expression/simplifications_cond.py b/miasm2/expression/simplifications_cond.py
index 3054d92b..6bdc810f 100644
--- a/miasm2/expression/simplifications_cond.py
+++ b/miasm2/expression/simplifications_cond.py
@@ -19,9 +19,9 @@ import miasm2.expression.expression as m2_expr
 
 # Jokers for expression matching
 
-jok1 = m2_expr.ExprId("jok1")
-jok2 = m2_expr.ExprId("jok2")
-jok3 = m2_expr.ExprId("jok3")
+jok1 = m2_expr.ExprId("jok1", 32)
+jok2 = m2_expr.ExprId("jok2", 32)
+jok3 = m2_expr.ExprId("jok3", 32)
 jok_small = m2_expr.ExprId("jok_small", 1)
 
 
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index afb6b382..64eb3463 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -258,25 +258,43 @@ class IRBlock(object):
     Stand for an intermediate representation  basic block.
     """
 
-    __slots__ = ["label", "_assignments", "_dst", "_dst_linenb"]
+    __slots__ = ["label", "_assignblks", "_dst", "_dst_linenb"]
 
-    def __init__(self, label, irs):
+    def __init__(self, label, assignblks):
         """
         @label: AsmLabel of the IR basic block
-        @irs: list of AssignBlock
+        @assignblks: list of AssignBlock
         """
 
         assert isinstance(label, AsmLabel)
         self.label = label
-        for assignblk in irs:
+        for assignblk in assignblks:
             assert isinstance(assignblk, AssignBlock)
-        self._assignments = tuple(irs)
+        self._assignblks = tuple(assignblks)
         self._dst = None
         self._dst_linenb = None
 
+
+    @property
+    def assignblks(self):
+        return self._assignblks
+
     @property
     def irs(self):
-        return self._assignments
+        warnings.warn('DEPRECATION WARNING: use "irblock.assignblks" instead of "irblock.irs"')
+        return self._assignblks
+
+    def __iter__(self):
+        """Iterate on assignblks"""
+        return self._assignblks.__iter__()
+
+    def __getitem__(self, index):
+        """Getitem on assignblks"""
+        return self._assignblks.__getitem__(index)
+
+    def __len__(self):
+        """Length of assignblks"""
+        return self._assignblks.__len__()
 
     def is_dst_set(self):
         return self._dst is not None
@@ -284,7 +302,7 @@ class IRBlock(object):
     def cache_dst(self):
         final_dst = None
         final_linenb = None
-        for linenb, assignblk in enumerate(self.irs):
+        for linenb, assignblk in enumerate(self):
             for dst, src in assignblk.iteritems():
                 if dst.is_id("IRDst"):
                     if final_dst is not None:
@@ -306,7 +324,7 @@ class IRBlock(object):
         """Generate a new IRBlock with a dst (IRBlock) fixed to @value"""
         irs = []
         dst_found = False
-        for assignblk in self.irs:
+        for assignblk in self:
             new_assignblk = {}
             for dst, src in assignblk.iteritems():
                 if dst.is_id("IRDst"):
@@ -328,7 +346,7 @@ class IRBlock(object):
     def __str__(self):
         out = []
         out.append('%s' % self.label)
-        for assignblk in self.irs:
+        for assignblk in self:
             for dst, src in assignblk.iteritems():
                 out.append('\t%s = %s' % (dst, src))
             out.append("")
@@ -349,7 +367,7 @@ class IRBlock(object):
             mod_src = lambda expr:expr
 
         assignblks = []
-        for assignblk in self.irs:
+        for assignblk in self:
             new_assignblk = {}
             for dst, src in assignblk.iteritems():
                 new_assignblk[mod_dst(dst)] = mod_src(src)
@@ -387,7 +405,7 @@ class DiGraphIR(DiGraph):
         if node not in self._blocks:
             yield [self.DotCellDescription(text="NOT PRESENT", attr={})]
             raise StopIteration
-        for i, assignblk in enumerate(self._blocks[node].irs):
+        for i, assignblk in enumerate(self._blocks[node]):
             for dst, src in assignblk.iteritems():
                 line = "%s = %s" % (dst, src)
                 if self._dot_offset:
@@ -456,7 +474,7 @@ class IntermediateRepresentation(object):
         ir_bloc_cur, extra_irblocks = self.get_ir(instr)
         for index, irb in enumerate(extra_irblocks):
             irs = []
-            for assignblk in irb.irs:
+            for assignblk in irb:
                 irs.append(AssignBlock(assignblk, instr))
             extra_irblocks[index] = IRBlock(irb.label, irs)
         assignblk = AssignBlock(ir_bloc_cur, instr)
@@ -502,7 +520,7 @@ class IntermediateRepresentation(object):
     def getby_offset(self, offset):
         out = set()
         for irb in self.blocks.values():
-            for assignblk in irb.irs:
+            for assignblk in irb:
                 instr = assignblk.instr
                 if instr.offset <= offset < instr.offset + instr.l:
                     out.add(irb)
@@ -607,11 +625,12 @@ class IntermediateRepresentation(object):
         return irblock
 
     def is_pc_written(self, block):
+        """Return the first Assignblk of the @blockin which PC is written
+        @block: IRBlock instance"""
         all_pc = self.arch.pc.values()
-        for irs in block.irs:
-            for assignblk in irs:
-                if assignblk.dst in all_pc:
-                    return assignblk
+        for assignblk in block:
+            if assignblk.dst in all_pc:
+                return assignblk
         return None
 
     def set_empty_dst_to_next(self, block, ir_blocks):
@@ -625,8 +644,8 @@ class IntermediateRepresentation(object):
             else:
                 dst = m2_expr.ExprId(next_lbl,
                                      self.pc.size)
-            assignblk = AssignBlock({self.IRDst: dst}, irblock.irs[-1].instr)
-            ir_blocks[index] = IRBlock(irblock.label, list(irblock.irs) + [assignblk])
+            assignblk = AssignBlock({self.IRDst: dst}, irblock[-1].instr)
+            ir_blocks[index] = IRBlock(irblock.label, list(irblock.assignblks) + [assignblk])
 
     def post_add_block(self, block, ir_blocks):
         self.set_empty_dst_to_next(block, ir_blocks)
@@ -670,13 +689,13 @@ class IntermediateRepresentation(object):
         """
         for label, block in self.blocks.iteritems():
             assignblks = []
-            for assignblk in block.irs:
+            for assignblk in block:
                 new_assignblk = assignblk.simplify(simplifier)
                 assignblks.append(new_assignblk)
             self.blocks[label] = IRBlock(label, assignblks)
 
     def replace_expr_in_ir(self, bloc, rep):
-        for assignblk in bloc.irs:
+        for assignblk in bloc:
             for dst, src in assignblk.items():
                 del assignblk[dst]
                 assignblk[dst.replace_expr(rep)] = src.replace_expr(rep)
@@ -720,7 +739,7 @@ class IntermediateRepresentation(object):
         todo = set([irb.dst])
         done = set()
 
-        for assignblk in reversed(irb.irs):
+        for assignblk in reversed(irb):
             if not todo:
                 break
             out = self._extract_dst(todo, done)
@@ -746,7 +765,7 @@ class IntermediateRepresentation(object):
             for dst in self.dst_trackback(block):
                 if dst.is_int():
                     dst_lbl = self.symbol_pool.getby_offset_create(int(dst))
-                    dst = m2_expr.ExprId(dst_lbl)
+                    dst = m2_expr.ExprId(dst_lbl, self.pc.size)
                 if expr_is_label(dst):
                     self._graph.add_edge(lbl, dst.name)
 
@@ -762,7 +781,7 @@ class IntermediateRepresentation(object):
         modified = False
         for label, block in self.blocks.iteritems():
             irs = []
-            for assignblk in block.irs:
+            for assignblk in block:
                 if len(assignblk):
                     irs.append(assignblk)
                 else:
@@ -779,9 +798,9 @@ class IntermediateRepresentation(object):
         # Find candidates
         jmp_blocks = set()
         for block in self.blocks.itervalues():
-            if len(block.irs) != 1:
+            if len(block) != 1:
                 continue
-            assignblk = block.irs[0]
+            assignblk = block[0]
             if len(assignblk) > 1:
                 continue
             assert set(assignblk.keys()) == set([self.IRDst])
@@ -860,7 +879,7 @@ class IntermediateRepresentation(object):
                 continue
             # Block has one son, son has one parent => merge
             assignblks =[]
-            for assignblk in self.blocks[block].irs:
+            for assignblk in self.blocks[block]:
                 if self.IRDst not in assignblk:
                     assignblks.append(assignblk)
                     continue
@@ -870,7 +889,7 @@ class IntermediateRepresentation(object):
                         affs[dst] = src
                 assignblks.append(AssignBlock(affs, assignblk.instr))
 
-            assignblks += self.blocks[son].irs
+            assignblks += self.blocks[son].assignblks
             new_block = IRBlock(block, assignblks)
 
             self.graph.discard_edge(block, son)
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index 593ab49a..8ecde21c 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -524,7 +524,7 @@ class SymbolicExecutionEngine(object):
         @irb: irbloc instance
         @step: display intermediate steps
         """
-        for assignblk in irb.irs:
+        for assignblk in irb:
             if step:
                 print 'Instr', assignblk.instr
                 print 'Assignblk:'
diff --git a/miasm2/jitter/arch/JitCore_aarch64.c b/miasm2/jitter/arch/JitCore_aarch64.c
index 03113d30..e10d847e 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.c
+++ b/miasm2/jitter/arch/JitCore_aarch64.c
@@ -50,6 +50,10 @@ reg_dict gpreg_dict[] = {
 	{.name = "nf", .offset = offsetof(vm_cpu_t, nf)},
 	{.name = "of", .offset = offsetof(vm_cpu_t, of)},
 	{.name = "cf", .offset = offsetof(vm_cpu_t, cf)},
+
+	{.name = "exception_flags", .offset = offsetof(vm_cpu_t, exception_flags)},
+	{.name = "interrupt_num", .offset = offsetof(vm_cpu_t, interrupt_num)},
+
 };
 
 /************************** JitCpu object **************************/
@@ -375,6 +379,9 @@ getset_reg_u32(of);
 getset_reg_u32(cf);
 
 
+getset_reg_u32(exception_flags);
+getset_reg_u32(interrupt_num);
+
 
 PyObject* get_gpreg_offset_all(void)
 {
@@ -485,6 +492,9 @@ static PyGetSetDef JitCpu_getseters[] = {
     {"of", (getter)JitCpu_get_of, (setter)JitCpu_set_of, "of", NULL},
     {"cf", (getter)JitCpu_get_cf, (setter)JitCpu_set_cf, "cf", NULL},
 
+    {"exception_flags", (getter)JitCpu_get_exception_flags, (setter)JitCpu_set_exception_flags, "exception_flags", NULL},
+    {"interrupt_num", (getter)JitCpu_get_interrupt_num, (setter)JitCpu_set_interrupt_num, "interrupt_num", NULL},
+
     {NULL}  /* Sentinel */
 };
 
diff --git a/miasm2/jitter/arch/JitCore_aarch64.h b/miasm2/jitter/arch/JitCore_aarch64.h
index 4635b395..c7fc3cea 100644
--- a/miasm2/jitter/arch/JitCore_aarch64.h
+++ b/miasm2/jitter/arch/JitCore_aarch64.h
@@ -1,6 +1,7 @@
 
 typedef struct {
 	uint32_t exception_flags;
+	uint32_t interrupt_num;
 
 	/* gpregs */
 
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index 3198eff3..407a01c7 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -178,6 +178,29 @@ PyObject * cpu_init_regs(JitCpu* self)
 
 }
 
+void dump_gpregs_16(vm_cpu_t* vmcpu)
+{
+
+	printf("EAX %.8"PRIX32" EBX %.8"PRIX32" ECX %.8"PRIX32" EDX %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RAX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RBX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RCX & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RDX & 0xFFFFFFFF));
+	printf("ESI %.8"PRIX32" EDI %.8"PRIX32" ESP %.8"PRIX32" EBP %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RSI & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RDI & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RSP & 0xFFFFFFFF),
+	       (uint32_t)(vmcpu->RBP & 0xFFFFFFFF));
+	printf("EIP %.8"PRIX32" ",
+	       (uint32_t)(vmcpu->RIP & 0xFFFFFFFF));
+	printf("zf %.1"PRIX32" nf %.1"PRIX32" of %.1"PRIX32" cf %.1"PRIX32"\n",
+	       (uint32_t)(vmcpu->zf & 0x1),
+	       (uint32_t)(vmcpu->nf & 0x1),
+	       (uint32_t)(vmcpu->of & 0x1),
+	       (uint32_t)(vmcpu->cf & 0x1));
+
+}
+
 void dump_gpregs_32(vm_cpu_t* vmcpu)
 {
 
diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py
index 61a9a784..9ed55f37 100644
--- a/miasm2/jitter/codegen.py
+++ b/miasm2/jitter/codegen.py
@@ -489,7 +489,7 @@ class CGen(object):
         for irblock in irblocks:
             attributes = []
             irblocks_attributes.append(attributes)
-            for assignblk in irblock.irs:
+            for assignblk in irblock:
                 attrib = Attributes(log_mn, log_regs)
                 attributes.append(attrib)
                 self.get_caracteristics(assignblk, attrib)
@@ -534,7 +534,7 @@ class CGen(object):
 
         out = []
         dst2index = None
-        for index, assignblk in enumerate(irblock.irs):
+        for index, assignblk in enumerate(irblock):
             if index == irblock.dst_linenb:
                 c_dst, dst2index = self.gen_assignblk_dst(irblock.dst)
             else:
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index 9c35f829..f2b1375d 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -63,7 +63,7 @@ class JitCore(object):
                                           follow_call=False,
                                           dontdis_retcall=False,
                                           split_dis=self.split_dis,
-                                          dis_bloc_callback=self.disasm_cb)
+                                          dis_block_callback=self.disasm_cb)
 
 
     def set_options(self, **kwargs):
@@ -140,7 +140,7 @@ class JitCore(object):
 
         # Prepare disassembler
         self.mdis.lines_wd = self.options["jit_maxline"]
-        self.mdis.dis_bloc_callback = self.disasm_cb
+        self.mdis.dis_block_callback = self.disasm_cb
 
         # Disassemble it
         try:
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index 6d954aae..a74ef7e6 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -72,7 +72,7 @@ class JitCore_Python(jitcore.JitCore):
                 exec_engine.update_engine_from_cpu()
 
                 # Execute current ir bloc
-                for assignblk in irb.irs:
+                for assignblk in irb:
                     instr = assignblk.instr
                     # For each new instruction (in assembly)
                     if instr.offset not in offsets_jitted:
diff --git a/miasm2/jitter/jitload.py b/miasm2/jitter/jitload.py
index 4760c8dd..ff7ba215 100644
--- a/miasm2/jitter/jitload.py
+++ b/miasm2/jitter/jitload.py
@@ -448,7 +448,7 @@ class jitter:
             return ret
 
     def handle_function(self, f_addr):
-        """Add a brakpoint which will trigger the function handler"""
+        """Add a breakpoint which will trigger the function handler"""
         self.add_breakpoint(f_addr, self.handle_lib)
 
     def add_lib_handler(self, libs, user_globals=None):
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 83349781..65c6aa07 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -966,7 +966,7 @@ class LLVMFunction():
         if isinstance(offset, (int, long)):
             offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status"))
+        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1013,7 +1013,7 @@ class LLVMFunction():
         if isinstance(offset, (int, long)):
             offset = self.add_ir(m2_expr.ExprInt(offset, PC.size))
         self.affect(offset, PC)
-        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status"))
+        self.affect(self.add_ir(m2_expr.ExprInt(1, 8)), m2_expr.ExprId("status", 32))
         self.set_ret(offset)
 
         builder.position_at_end(merge_block)
@@ -1121,7 +1121,7 @@ class LLVMFunction():
         self.gen_post_code(attrib)
         self.affect(dst, PC)
         self.gen_post_instr_checks(attrib, dst)
-        self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), m2_expr.ExprId("status"))
+        self.affect(self.add_ir(m2_expr.ExprInt(0, 8)), m2_expr.ExprId("status", 32))
         self.set_ret(dst)
 
 
@@ -1138,7 +1138,7 @@ class LLVMFunction():
         case_value = None
         instr = instr_attrib.instr
 
-        for index, assignblk in enumerate(irblock.irs):
+        for index, assignblk in enumerate(irblock):
             # Enable cache
             self.main_stream = True
             self.expr_cache = {}
@@ -1215,7 +1215,7 @@ class LLVMFunction():
         m2_exception_flag = self.llvm_context.ir_arch.arch.regs.exception_flags
         t_size = LLVMType.IntType(m2_exception_flag.size)
         self.affect(self.add_ir(m2_expr.ExprInt(1, 8)),
-                    m2_expr.ExprId("status"))
+                    m2_expr.ExprId("status", 32))
         self.affect(t_size(m2_csts.EXCEPT_UNK_MNEMO),
                     m2_exception_flag)
         self.set_ret(LLVMType.IntType(64)(asmblock.label.offset))
@@ -1233,7 +1233,7 @@ class LLVMFunction():
 
             # Common code
             self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status"))
+                        m2_expr.ExprId("status", 32))
 
             # Check if IRDst has been set
             zero_casted = LLVMType.IntType(codegen.delay_slot_set.size)(0)
@@ -1257,7 +1257,7 @@ class LLVMFunction():
             to_ret = self.add_ir(codegen.delay_slot_dst)
             self.affect(to_ret, PC)
             self.affect(self.add_ir(m2_expr.ExprInt(0, 8)),
-                        m2_expr.ExprId("status"))
+                        m2_expr.ExprId("status", 32))
             self.set_ret(to_ret)
 
             # Else Block
@@ -1272,16 +1272,16 @@ class LLVMFunction():
         Prototype : f(i8* jitcpu, i8* vmcpu, i8* vmmngr, i8* status)"""
 
         # Build function signature
-        self.my_args.append((m2_expr.ExprId("jitcpu"),
+        self.my_args.append((m2_expr.ExprId("jitcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "jitcpu"))
-        self.my_args.append((m2_expr.ExprId("vmcpu"),
+        self.my_args.append((m2_expr.ExprId("vmcpu", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmcpu"))
-        self.my_args.append((m2_expr.ExprId("vmmngr"),
+        self.my_args.append((m2_expr.ExprId("vmmngr", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "vmmngr"))
-        self.my_args.append((m2_expr.ExprId("status"),
+        self.my_args.append((m2_expr.ExprId("status", 32),
                              llvm_ir.PointerType(LLVMType.IntType(8)),
                              "status"))
         ret_size = 64
diff --git a/test/analysis/data_flow.py b/test/analysis/data_flow.py
index 2c24773a..dff88470 100644
--- a/test/analysis/data_flow.py
+++ b/test/analysis/data_flow.py
@@ -5,20 +5,20 @@ from miasm2.analysis.data_flow import *
 from miasm2.ir.analysis import ira
 from miasm2.ir.ir import IRBlock, AssignBlock
 
-a = ExprId("a")
-b = ExprId("b")
-c = ExprId("c")
-d = ExprId("d")
-r = ExprId("r")
+a = ExprId("a", 32)
+b = ExprId("b", 32)
+c = ExprId("c", 32)
+d = ExprId("d", 32)
+r = ExprId("r", 32)
 
-a_init = ExprId("a_init")
-b_init = ExprId("b_init")
-c_init = ExprId("c_init")
-d_init = ExprId("d_init")
-r_init = ExprId("r_init") # Return register
+a_init = ExprId("a_init", 32)
+b_init = ExprId("b_init", 32)
+c_init = ExprId("c_init", 32)
+d_init = ExprId("d_init", 32)
+r_init = ExprId("r_init", 32) # Return register
 
-pc = ExprId("pc")
-sp = ExprId("sp")
+pc = ExprId("pc", 32)
+sp = ExprId("sp", 32)
 
 CST1 = ExprInt(0x11, 32)
 CST2 = ExprInt(0x12, 32)
@@ -635,7 +635,7 @@ G17_EXP_IRB0 = gen_irblock(LBL0, [[],
                                    ExprAff(b, a),
                                    ExprAff(c, b)],
 
-                                  G17_IRB0.irs[14]
+                                  G17_IRB0[14]
                                   # Trick because a+b+c != ((a+b)+c)
                                  ])
 
@@ -684,4 +684,4 @@ for test_nb, test in enumerate([(G1_IRA, G1_EXP_IRA),
     # Check that each expr in the blocks are the same
     for lbl, irb in g_ira.blocks.iteritems():
         exp_irb = g_exp_ira.blocks[lbl]
-        assert exp_irb.irs == irb.irs
+        assert exp_irb.assignblks == irb.assignblks
diff --git a/test/analysis/depgraph.py b/test/analysis/depgraph.py
index 63313861..9fb046d0 100644
--- a/test/analysis/depgraph.py
+++ b/test/analysis/depgraph.py
@@ -16,19 +16,19 @@ except ImportError:
     EMULATION = False
 
 STEP_COUNTER = count()
-A = ExprId("a")
-B = ExprId("b")
-C = ExprId("c")
-D = ExprId("d")
-R = ExprId("r")
+A = ExprId("a", 32)
+B = ExprId("b", 32)
+C = ExprId("c", 32)
+D = ExprId("d", 32)
+R = ExprId("r", 32)
 
-A_INIT = ExprId("a_init")
-B_INIT = ExprId("b_init")
-C_INIT = ExprId("c_init")
-D_INIT = ExprId("d_init")
+A_INIT = ExprId("a_init", 32)
+B_INIT = ExprId("b_init", 32)
+C_INIT = ExprId("c_init", 32)
+D_INIT = ExprId("d_init", 32)
 
-PC = ExprId("pc")
-SP = ExprId("sp")
+PC = ExprId("pc", 32)
+SP = ExprId("sp", 32)
 
 CST0 = ExprInt(0x0, 32)
 CST1 = ExprInt(0x1, 32)
@@ -132,7 +132,7 @@ def bloc2graph(irgraph, label=False, lines=True):
             label_attr, label_name)
         block_html_lines = []
         if lines and irblock is not None:
-            for assignblk in irblock.irs:
+            for assignblk in irblock:
                 for dst, src in assignblk.iteritems():
                     if False:
                         out_render = "%.8X</td><td %s> " % (0, td_attr)
@@ -277,8 +277,8 @@ G4_IRA = IRATest()
 G4_IRB0 = gen_irblock(LBL0, [[ExprAff(C, CST1)]])
 G4_IRB1 = gen_irblock(LBL1, [[ExprAff(C, C + CST2)],
                              [ExprAff(G4_IRA.IRDst,
-                                      ExprCond(C, ExprId(LBL2),
-                                               ExprId(LBL1)))]])
+                                      ExprCond(C, ExprId(LBL2, 32),
+                                               ExprId(LBL1, 32)))]])
 
 G4_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]])
 
@@ -296,8 +296,8 @@ G5_IRA = IRATest()
 G5_IRB0 = gen_irblock(LBL0, [[ExprAff(B, CST1)]])
 G5_IRB1 = gen_irblock(LBL1, [[ExprAff(B, B + CST2)],
                              [ExprAff(G5_IRA.IRDst,
-                                      ExprCond(B, ExprId(LBL2),
-                                               ExprId(LBL1)))]])
+                                      ExprCond(B, ExprId(LBL2, 32),
+                                               ExprId(LBL1, 32)))]])
 
 G5_IRB2 = gen_irblock(LBL2, [[ExprAff(A, B)]])
 
@@ -400,16 +400,16 @@ G13_IRA = IRATest()
 G13_IRB0 = gen_irblock(LBL0, [[ExprAff(A, CST1)],
                               #[ExprAff(B, A)],
                               [ExprAff(G13_IRA.IRDst,
-                                       ExprId(LBL1))]])
+                                       ExprId(LBL1, 32))]])
 G13_IRB1 = gen_irblock(LBL1, [[ExprAff(C, A)],
                               #[ExprAff(A, A + CST1)],
                               [ExprAff(G13_IRA.IRDst,
-                                       ExprCond(R, ExprId(LBL2),
-                                                ExprId(LBL1)))]])
+                                       ExprCond(R, ExprId(LBL2, 32),
+                                                ExprId(LBL1, 32)))]])
 
 G13_IRB2 = gen_irblock(LBL2, [[ExprAff(B, A + CST3)], [ExprAff(A, B + CST3)],
                               [ExprAff(G13_IRA.IRDst,
-                                       ExprId(LBL1))]])
+                                       ExprId(LBL1, 32))]])
 
 G13_IRB3 = gen_irblock(LBL3, [[ExprAff(R, C)]])
 
@@ -427,18 +427,18 @@ G14_IRA = IRATest()
 
 G14_IRB0 = gen_irblock(LBL0, [[ExprAff(A, CST1)],
                               [ExprAff(G14_IRA.IRDst,
-                                       ExprId(LBL1))]
+                                       ExprId(LBL1, 32))]
                              ])
 G14_IRB1 = gen_irblock(LBL1, [[ExprAff(B, A)],
                               [ExprAff(G14_IRA.IRDst,
-                                       ExprCond(C, ExprId(LBL2),
-                                                ExprId(LBL3)))]
+                                       ExprCond(C, ExprId(LBL2, 32),
+                                                ExprId(LBL3, 32)))]
                              ])
 
 G14_IRB2 = gen_irblock(LBL2, [[ExprAff(D, A)],
                               [ExprAff(A, D + CST1)],
                               [ExprAff(G14_IRA.IRDst,
-                                       ExprId(LBL1))]
+                                       ExprId(LBL1, 32))]
                              ])
 
 G14_IRB3 = gen_irblock(LBL3, [[ExprAff(R, D + B)]])
@@ -510,72 +510,72 @@ G17_IRA.blocks = dict([(irb.label, irb) for irb in [G17_IRB0, G17_IRB1,
 
 # Test graph 1
 G1_TEST1_DN1 = DependencyNode(
-    G1_IRB2.label, A, len(G1_IRB2.irs))
+    G1_IRB2.label, A, len(G1_IRB2))
 
 G1_INPUT = (set([G1_TEST1_DN1]), set([G1_IRB0.label]))
 
 # Test graph 2
 
 G2_TEST1_DN1 = DependencyNode(
-    G2_IRB2.label, A, len(G2_IRB2.irs))
+    G2_IRB2.label, A, len(G2_IRB2))
 
 G2_INPUT = (set([G2_TEST1_DN1]), set([G2_IRB0.label]))
 
 # Test graph 3
 
 G3_TEST1_0_DN1 = DependencyNode(
-    G3_IRB3.label, A, len(G3_IRB3.irs))
+    G3_IRB3.label, A, len(G3_IRB3))
 
 G3_INPUT = (set([G3_TEST1_0_DN1]), set([G3_IRB0.label]))
 
 # Test graph 4
 
 G4_TEST1_DN1 = DependencyNode(
-    G4_IRB2.label, A, len(G2_IRB0.irs))
+    G4_IRB2.label, A, len(G2_IRB0))
 
 G4_INPUT = (set([G4_TEST1_DN1]), set([G4_IRB0.label]))
 
 # Test graph 5
 
 G5_TEST1_0_DN1 = DependencyNode(
-    G5_IRB2.label, A, len(G5_IRB2.irs))
+    G5_IRB2.label, A, len(G5_IRB2))
 
 G5_INPUT = (set([G5_TEST1_0_DN1]), set([G5_IRB0.label]))
 
 # Test graph 6
 
 G6_TEST1_0_DN1 = DependencyNode(
-    G6_IRB1.label, A, len(G6_IRB1.irs))
+    G6_IRB1.label, A, len(G6_IRB1))
 
 G6_INPUT = (set([G6_TEST1_0_DN1]), set([G6_IRB0.label]))
 
 # Test graph 7
 
 G7_TEST1_0_DN1 = DependencyNode(
-    G7_IRB2.label, D, len(G7_IRB2.irs))
+    G7_IRB2.label, D, len(G7_IRB2))
 
 G7_INPUT = (set([G7_TEST1_0_DN1]), set([G7_IRB0.label]))
 
 # Test graph 8
 
 G8_TEST1_0_DN1 = DependencyNode(
-    G8_IRB2.label, A, len(G8_IRB2.irs))
+    G8_IRB2.label, A, len(G8_IRB2))
 
 G8_INPUT = (set([G8_TEST1_0_DN1]), set([G3_IRB0.label]))
 
 # Test 9: Multi elements
 
 G9_TEST1_0_DN1 = DependencyNode(
-    G8_IRB2.label, A, len(G8_IRB2.irs))
+    G8_IRB2.label, A, len(G8_IRB2))
 G9_TEST1_0_DN5 = DependencyNode(
-    G8_IRB2.label, C, len(G8_IRB2.irs))
+    G8_IRB2.label, C, len(G8_IRB2))
 
 G9_INPUT = (set([G9_TEST1_0_DN1, G9_TEST1_0_DN5]), set([G8_IRB0.label]))
 
 # Test 10: loop at beginning
 
 G10_TEST1_0_DN1 = DependencyNode(
-    G10_IRB2.label, A, len(G10_IRB2.irs))
+    G10_IRB2.label, A, len(G10_IRB2))
 
 G10_INPUT = (set([G10_TEST1_0_DN1]), set([G10_IRB1.label]))
 
@@ -583,7 +583,7 @@ G10_INPUT = (set([G10_TEST1_0_DN1]), set([G10_IRB1.label]))
 # Test 11: no dual bloc emulation
 
 G11_TEST1_DN1 = DependencyNode(
-    G11_IRB2.label, A, len(G11_IRB2.irs))
+    G11_IRB2.label, A, len(G11_IRB2))
 
 G11_INPUT = (set([G11_TEST1_DN1]), set([G11_IRB0.label]))
 
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index d3b2964c..2af90c8a 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -2902,11 +2902,11 @@ reg_tests = [
     (m32, "00000000    PEXTRW     WORD PTR [EDX], XMM2, 0x5",
     "660F3A151205"),
 
+    (m32, "00000000    PEXTRW     EAX, MM2, 0x5",
+    "0fc5c205"),
+    (m32, "00000000    PEXTRW     EAX, XMM2, 0x5",
+    "660fc5c205"),
 
-    (m32, "00000000    PEXTRW     WORD PTR [EDX], MM2, 0x5",
-    "0FC51205"),
-    (m32, "00000000    PEXTRW     WORD PTR [EDX], XMM2, 0x5",
-    "660FC51205"),
 
     (m32, "00000000    PEXTRD     DWORD PTR [EDX], XMM2, 0x5",
     "660F3A161205"),
@@ -2970,6 +2970,113 @@ reg_tests = [
     (m64, "00000000    BNDMOV     BND3, XMMWORD PTR [RSP + 0xB0]",
      "660f1a9c24b0000000"),
 
+    (m32, "00000000    PACKSSWB   MM7, MM0",
+     "0f63f8"),
+    (m32, "00000000    PACKSSWB   XMM0, XMM5",
+     "660f63c5"),
+
+    (m32, "00000000    PACKSSDW   MM2, MM0",
+     "0f6bd0"),
+    (m32, "00000000    PACKSSDW   XMM0, XMM7",
+     "660f6bc7"),
+
+    (m32, "00000000    PACKUSWB   MM1, MM7",
+     "0f67cf"),
+    (m32, "00000000    PACKUSWB   XMM0, XMM6",
+     "660f67c6"),
+
+    (m32, "00000000    PMULLW     MM4, MM2",
+     "0fd5e2"),
+    (m32, "00000000    PMULLW     XMM0, XMM3",
+     "660fd5c3"),
+
+    (m32, "00000000    PSUBUSB    MM5, MM3",
+     "0fd8eb"),
+    (m32, "00000000    PSUBUSB    XMM0, XMM5",
+     "660fd8c5"),
+
+    (m32, "00000000    PSUBUSW    MM5, MM3",
+     "0fd9eb"),
+    (m32, "00000000    PSUBUSW    XMM0, XMM5",
+     "660fd9c5"),
+
+    (m32, "00000000    PADDUSB    MM5, MM3",
+     "0fdceb"),
+    (m32, "00000000    PADDUSB    XMM0, XMM6",
+     "660fdcc6"),
+
+    (m32, "00000000    PADDUSW    MM7, MM5",
+     "0fddfd"),
+    (m32, "00000000    PADDUSW    XMM0, XMM1",
+     "660fddc1"),
+
+    (m32, "00000000    PMULHUW    MM6, MM4",
+     "0fe4f4"),
+    (m32, "00000000    PMULHUW    XMM0, XMM7",
+     "660fe4c7"),
+
+    (m32, "00000000    PMULHW     MM6, MM4",
+     "0fe5f4"),
+    (m32, "00000000    PMULHW     XMM0, XMM7",
+     "660fe5c7"),
+
+    (m32, "00000000    PSUBSB     MM2, MM0",
+     "0fe8d0"),
+    (m32, "00000000    PSUBSB     XMM0, XMM4",
+     "660fe8c4"),
+
+    (m32, "00000000    PSUBSW     MM3, MM1",
+     "0fe9d9"),
+    (m32, "00000000    PSUBSW     XMM0, XMM6",
+     "660fe9c6"),
+
+    (m32, "00000000    PADDSB     MM2, MM0",
+     "0fecd0"),
+    (m32, "00000000    PADDSB     XMM0, XMM4",
+     "660fecc4"),
+
+    (m32, "00000000    PADDSW     MM3, MM1",
+     "0fedd9"),
+    (m32, "00000000    PADDSW     XMM0, XMM6",
+     "660fedc6"),
+
+    (m32, "00000000    PMAXSW     MM3, MM1",
+     "0feed9"),
+    (m32, "00000000    PMAXSW     XMM0, XMM6",
+     "660feec6"),
+
+    (m32, "00000000    PMULUDQ    MM3, MM1",
+     "0ff4d9"),
+    (m32, "00000000    PMULUDQ    XMM0, XMM6",
+     "660ff4c6"),
+
+    (m32, "00000000    PMADDWD    MM3, MM1",
+     "0ff5d9"),
+    (m32, "00000000    PMADDWD    XMM0, XMM6",
+     "660ff5c6"),
+
+    (m32, "00000000    PSADBW     MM3, MM1",
+     "0ff6d9"),
+    (m32, "00000000    PSADBW     XMM0, XMM6",
+     "660ff6c6"),
+
+    (m32, "00000000    PAVGB      MM3, MM1",
+     "0fe0d9"),
+    (m32, "00000000    PAVGB      XMM0, XMM6",
+     "660fe0c6"),
+
+    (m32, "00000000    PAVGW      MM3, MM1",
+     "0fe3d9"),
+    (m32, "00000000    PAVGW      XMM0, XMM6",
+     "660fe3c6"),
+
+    (m32, "00000000    MASKMOVQ   MM2, MM3",
+     "0ff7d3"),
+    (m32, "00000000    MASKMOVDQU XMM4, XMM5",
+     "660ff7e5"),
+
+    (m32, "00000000    EMMS",
+     "0f77"),
 ]
 
 
diff --git a/test/arch/x86/unit/mn_cdq.py b/test/arch/x86/unit/mn_cdq.py
new file mode 100644
index 00000000..f4e4d6e7
--- /dev/null
+++ b/test/arch/x86/unit/mn_cdq.py
@@ -0,0 +1,445 @@
+#! /usr/bin/env python2
+
+import sys
+
+from asm_test import Asm_Test_16, Asm_Test_32, Asm_Test_64
+from miasm2.core.utils import pck16, pck32
+
+
+class Test_CBW_16(Asm_Test_16):
+    MYSTRING = "test CBW 16"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CBW
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x87650021
+        assert self.myjit.cpu.EDX == 0x11223344
+
+
+class Test_CBW_16_signed(Asm_Test_16):
+    MYSTRING = "test CBW 16 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654381
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CBW
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x8765FF81
+        assert self.myjit.cpu.EDX == 0x11223344
+
+
+class Test_CBW_32(Asm_Test_32):
+    MYSTRING = "test CBW 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CBW
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x87650021
+        assert self.myjit.cpu.EDX == 0x11223344
+
+
+class Test_CBW_32_signed(Asm_Test_32):
+    MYSTRING = "test CBW 32 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654381
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CBW
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x8765FF81
+        assert self.myjit.cpu.EDX == 0x11223344
+
+
+class Test_CDQ_32(Asm_Test_32):
+    MYSTRING = "test cdq 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x77654321
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CDQ
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x77654321
+        assert self.myjit.cpu.EDX == 0x0
+
+
+class Test_CDQ_32_signed(Asm_Test_32):
+    MYSTRING = "test cdq 32 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CDQ
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0x87654321
+        assert self.myjit.cpu.EDX == 0xFFFFFFFF
+
+
+class Test_CDQ_64(Asm_Test_64):
+    MYSTRING = "test cdq 64"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567877654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CDQ
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x1234567877654321
+        assert self.myjit.cpu.RDX == 0x0
+
+
+class Test_CDQ_64_signed(Asm_Test_64):
+    MYSTRING = "test cdq 64 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567887654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CDQ
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x1234567887654321
+        assert self.myjit.cpu.RDX == 0x00000000FFFFFFFF
+
+
+class Test_CDQE_64(Asm_Test_64):
+    MYSTRING = "test cdq 64"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567877654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CDQE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x77654321
+        assert self.myjit.cpu.RDX == 0x1122334455667788
+
+
+class Test_CDQE_64_signed(Asm_Test_64):
+    MYSTRING = "test cdq 64 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567887654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CDQE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0xFFFFFFFF87654321
+        assert self.myjit.cpu.RDX == 0x1122334455667788
+
+
+class Test_CWD_32(Asm_Test_32):
+    MYSTRING = "test cdq 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x12345678
+
+    TXT = '''
+    main:
+       CWD
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x87654321
+        assert self.myjit.cpu.RDX == 0x12340000
+
+
+class Test_CWD_32_signed(Asm_Test_32):
+    MYSTRING = "test cdq 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87658321
+        self.myjit.cpu.EDX = 0x12345678
+
+    TXT = '''
+    main:
+       CWD
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x87658321
+        assert self.myjit.cpu.RDX == 0x1234FFFF
+
+
+class Test_CWD_32(Asm_Test_32):
+    MYSTRING = "test cdq 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x12345678
+
+    TXT = '''
+    main:
+       CWD
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x87654321
+        assert self.myjit.cpu.RDX == 0x12340000
+
+
+class Test_CWDE_32(Asm_Test_32):
+    MYSTRING = "test cwde 32"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.EAX = 0x87654321
+        self.myjit.cpu.EDX = 0x11223344
+
+    TXT = '''
+    main:
+       CWDE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x4321
+        assert self.myjit.cpu.RDX == 0x11223344
+
+
+class Test_CWDE_32_signed(Asm_Test_32):
+    MYSTRING = "test cwde 32 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x87658321
+        self.myjit.cpu.RDX = 0x11223344
+
+    TXT = '''
+    main:
+       CWDE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.EAX == 0xFFFF8321
+        assert self.myjit.cpu.RDX == 0x11223344
+
+
+class Test_CWDE_64(Asm_Test_64):
+    MYSTRING = "test cwde 64"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567887654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CWDE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x4321
+        assert self.myjit.cpu.RDX == 0x1122334455667788
+
+
+class Test_CWDE_64_signed(Asm_Test_64):
+    MYSTRING = "test cwde 64 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567887658321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CWDE
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0xFFFF8321
+        assert self.myjit.cpu.RDX == 0x1122334455667788
+
+
+class Test_CQO_64(Asm_Test_64):
+    MYSTRING = "test cwde 64"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x1234567887654321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CQO
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x1234567887654321
+        assert self.myjit.cpu.RDX == 0x0
+
+
+class Test_CQO_64_signed(Asm_Test_64):
+    MYSTRING = "test cwde 64 signed"
+
+    def prepare(self):
+        self.myjit.ir_arch.symbol_pool.add_label("lbl_ret", self.ret_addr)
+
+    def test_init(self):
+        self.myjit.cpu.RAX = 0x8234567887658321
+        self.myjit.cpu.RDX = 0x1122334455667788
+
+    TXT = '''
+    main:
+       CQO
+       JMP lbl_ret
+    '''
+
+    def check(self):
+        assert self.myjit.cpu.RAX == 0x8234567887658321
+        assert self.myjit.cpu.RDX == 0xFFFFFFFFFFFFFFFF
+
+
+
+
+if __name__ == "__main__":
+    tests = [
+        Test_CBW_16,
+        Test_CBW_16_signed,
+
+        Test_CBW_32,
+        Test_CBW_32_signed,
+
+        Test_CWD_32,
+        Test_CWD_32_signed,
+
+        Test_CWDE_32,
+        Test_CWDE_32_signed,
+
+        Test_CWDE_64,
+        Test_CWDE_64_signed,
+
+        Test_CDQ_32,
+        Test_CDQ_32_signed,
+
+        Test_CDQ_64,
+        Test_CDQ_64_signed,
+
+        Test_CDQE_64,
+        Test_CDQE_64_signed,
+    ]
+    if sys.argv[1] not in ["gcc", "tcc"]:
+        # TODO XXX CQO use 128 bit not supported in gcc yet!
+        tests += [
+            Test_CQO_64,
+            Test_CQO_64_signed,
+        ]
+
+    [
+        test(*sys.argv[1:])() for test in tests
+    ]
diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py
index d8fdb6c4..ebf9f385 100644
--- a/test/core/sembuilder.py
+++ b/test/core/sembuilder.py
@@ -8,7 +8,7 @@ from miasm2.core.asmblock import AsmLabel
 # Test classes
 class IR(object):
 
-    IRDst = m2_expr.ExprId("IRDst")
+    IRDst = m2_expr.ExprId("IRDst", 32)
 
     def get_next_instr(self, _):
         return AsmLabel("NEXT")
@@ -41,9 +41,9 @@ def test(Arg1, Arg2, Arg3):
     else:
         alias = {i16(4), i8(5)}
 
-a = m2_expr.ExprId('A')
-b = m2_expr.ExprId('B')
-c = m2_expr.ExprId('C')
+a = m2_expr.ExprId('A', 32)
+b = m2_expr.ExprId('B', 32)
+c = m2_expr.ExprId('C', 32)
 ir = IR()
 instr = Instr()
 res = test(ir, instr, a, b, c)
@@ -59,7 +59,7 @@ for statement in res[0]:
 print "[+] Blocks:"
 for irb in res[1]:
     print irb.label
-    for exprs in irb.irs:
-        for expr in exprs:
+    for assignblk in irb:
+        for expr in assignblk:
             print expr
         print
diff --git a/test/expression/expression.py b/test/expression/expression.py
index ac145a04..6bb6d94c 100644
--- a/test/expression/expression.py
+++ b/test/expression/expression.py
@@ -15,7 +15,7 @@ assert big_cst.size == 0x1000
 
 # Possible values
 #- Common constants
-A = ExprId("A")
+A = ExprId("A", 32)
 cond1 = ExprId("cond1", 1)
 cond2 = ExprId("cond2", 16)
 cst1 = ExprInt(1, 32)
diff --git a/test/expression/expression_helper.py b/test/expression/expression_helper.py
index a4c221e9..35873ca4 100755
--- a/test/expression/expression_helper.py
+++ b/test/expression/expression_helper.py
@@ -12,8 +12,8 @@ class TestExpressionExpressionHelper(unittest.TestCase):
 
         # Build a complex expression
         cst = m2_expr.ExprInt(0x100, 16)
-        eax = m2_expr.ExprId("EAX")
-        ebx = m2_expr.ExprId("EBX")
+        eax = m2_expr.ExprId("EAX", 32)
+        ebx = m2_expr.ExprId("EBX", 32)
         ax = eax[0:16]
         expr = eax + ebx
         expr = m2_expr.ExprCompose(ax, expr[16:32])
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 6d17db10..b4f5b783 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -8,11 +8,11 @@ from miasm2.expression.simplifications import expr_simp, ExpressionSimplifier
 from miasm2.expression.simplifications_cond import ExprOp_inf_signed, ExprOp_inf_unsigned, ExprOp_equal
 
 # Define example objects
-a = ExprId('a')
-b = ExprId('b')
-c = ExprId('c')
-d = ExprId('d')
-e = ExprId('e')
+a = ExprId('a', 32)
+b = ExprId('b', 32)
+c = ExprId('c', 32)
+d = ExprId('d', 32)
+e = ExprId('e', 32)
 f = ExprId('f', size=64)
 
 m = ExprMem(a)
@@ -382,17 +382,17 @@ for e, e_check in to_test[:]:
 
 
 
-x = ExprId('x')
-y = ExprId('y')
-z = ExprId('z')
-a = ExprId('a')
-b = ExprId('b')
-c = ExprId('c')
+x = ExprId('x', 32)
+y = ExprId('y', 32)
+z = ExprId('z', 32)
+a = ExprId('a', 32)
+b = ExprId('b', 32)
+c = ExprId('c', 32)
 
 
-jra = ExprId('jra')
-jrb = ExprId('jrb')
-jrint1 = ExprId('jrint1')
+jra = ExprId('jra', 32)
+jrb = ExprId('jrb', 32)
+jrint1 = ExprId('jrint1', 32)
 
 
 e1 = ExprMem((a & ExprInt(0xFFFFFFFC, 32)) + ExprInt(0x10, 32), 32)
diff --git a/test/ir/ir.py b/test/ir/ir.py
index 05936d75..3774e4e9 100644
--- a/test/ir/ir.py
+++ b/test/ir/ir.py
@@ -2,8 +2,8 @@ from miasm2.expression.expression import *
 from miasm2.ir.ir import AssignBlock
 from miasm2.expression.simplifications import expr_simp
 
-id_a = ExprId("a")
-id_b = ExprId("b")
+id_a = ExprId("a", 32)
+id_b = ExprId("b", 32)
 int0 = ExprInt(0, id_a.size)
 
 # Test AssignBlock
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index f8d8c7bf..492dcfec 100755
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -30,10 +30,10 @@ class TestSymbExec(unittest.TestCase):
         mem40w = ExprMem(addr40, 16)
         mem50v = ExprMem(addr50,  8)
         mem50w = ExprMem(addr50, 16)
-        id_x = ExprId('x')
+        id_x = ExprId('x', 32)
         id_y = ExprId('y', 8)
-        id_a = ExprId('a')
-        id_eax = ExprId('eax_init')
+        id_a = ExprId('a', 32)
+        id_eax = ExprId('eax_init', 32)
 
         e = SymbolicExecutionEngine(ir_x86_32(),
                                     {mem0: id_x, mem1: id_y, mem9: id_x,
diff --git a/test/test_all.py b/test/test_all.py
index 23937366..04aca62e 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -79,6 +79,7 @@ for script in ["x86/sem.py",
                "x86/unit/mn_pextr.py",
                "x86/unit/mn_pmovmskb.py",
                "x86/unit/mn_pushpop.py",
+               "x86/unit/mn_cdq.py",
                "x86/unit/mn_seh.py",
                "x86/unit/mn_cpuid.py",
                "x86/unit/mn_div.py",