about summary refs log tree commit diff stats
path: root/miasm2/arch
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2/arch')
-rw-r--r--miasm2/arch/aarch64/arch.py77
-rw-r--r--miasm2/arch/aarch64/sem.py34
-rw-r--r--miasm2/arch/arm/arch.py106
-rw-r--r--miasm2/arch/arm/disasm.py3
-rw-r--r--miasm2/arch/arm/jit.py6
-rw-r--r--miasm2/arch/arm/sem.py90
-rw-r--r--miasm2/arch/mips32/arch.py46
-rw-r--r--miasm2/arch/mips32/ira.py12
-rw-r--r--miasm2/arch/mips32/jit.py13
-rw-r--r--miasm2/arch/mips32/sem.py36
-rw-r--r--miasm2/arch/msp430/arch.py56
-rw-r--r--miasm2/arch/msp430/sem.py49
-rw-r--r--miasm2/arch/ppc/arch.py11
-rw-r--r--miasm2/arch/ppc/sem.py27
-rw-r--r--miasm2/arch/sh4/arch.py37
-rw-r--r--miasm2/arch/x86/arch.py34
-rw-r--r--miasm2/arch/x86/jit.py2
-rw-r--r--miasm2/arch/x86/sem.py274
18 files changed, 482 insertions, 431 deletions
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index 94be74fd..a57e585f 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -9,7 +9,6 @@ from collections import defaultdict
 from miasm2.core.bin_stream import bin_stream
 import regs as regs_module
 from regs import *
-from miasm2.core.asmblock import AsmLabel
 from miasm2.core.cpu import log as log_cpu
 from miasm2.expression.modint import uint32, uint64, mod_size2int
 from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp
@@ -277,8 +276,8 @@ class aarch64_arg(m_arg):
             if isinstance(value.name, ExprId):
                 fixed_size.add(value.name.size)
                 return value.name
-            label = symbol_pool.getby_name_create(value.name)
-            return ExprId(label, size_hint)
+            loc_key = symbol_pool.getby_name_create(value.name)
+            return ExprLoc(loc_key, size_hint)
         if isinstance(value, AstInt):
             assert size_hint is not None
             return ExprInt(value.value, size_hint)
@@ -311,44 +310,49 @@ class instruction_aarch64(instruction):
         super(instruction_aarch64, self).__init__(*args, **kargs)
 
     @staticmethod
-    def arg2str(e, pos=None):
+    def arg2str(expr, index=None, symbol_pool=None):
         wb = False
-        if isinstance(e, m2_expr.ExprId) or isinstance(e, m2_expr.ExprInt):
-            return str(e)
-        elif isinstance(e, m2_expr.ExprOp) and e.op in shift_expr:
-            op_str = shift_str[shift_expr.index(e.op)]
-            return "%s %s %s" % (e.args[0], op_str, e.args[1])
-        elif isinstance(e, m2_expr.ExprOp) and e.op == "slice_at":
-            return "%s LSL %s" % (e.args[0], e.args[1])
-        elif isinstance(e, m2_expr.ExprOp) and e.op in extend_lst:
-            op_str = e.op
-            return "%s %s %s" % (e.args[0], op_str, e.args[1])
-        elif isinstance(e, m2_expr.ExprOp) and e.op == "postinc":
-            if e.args[1].arg != 0:
-                return "[%s], %s" % (e.args[0], e.args[1])
+        if expr.is_id() or expr.is_int():
+            return str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                return symbol_pool.str_loc_key(expr.loc_key)
             else:
-                return "[%s]" % (e.args[0])
-        elif isinstance(e, m2_expr.ExprOp) and e.op == "preinc_wb":
-            if e.args[1].arg != 0:
-                return "[%s, %s]!" % (e.args[0], e.args[1])
+                return str(expr)
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op in shift_expr:
+            op_str = shift_str[shift_expr.index(expr.op)]
+            return "%s %s %s" % (expr.args[0], op_str, expr.args[1])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op == "slice_at":
+            return "%s LSL %s" % (expr.args[0], expr.args[1])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op in extend_lst:
+            op_str = expr.op
+            return "%s %s %s" % (expr.args[0], op_str, expr.args[1])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op == "postinc":
+            if expr.args[1].arg != 0:
+                return "[%s], %s" % (expr.args[0], expr.args[1])
             else:
-                return "[%s]" % (e.args[0])
-        elif isinstance(e, m2_expr.ExprOp) and e.op == "preinc":
-            if len(e.args) == 1:
-                return "[%s]" % (e.args[0])
-            elif not isinstance(e.args[1], m2_expr.ExprInt) or e.args[1].arg != 0:
-                return "[%s, %s]" % (e.args[0], e.args[1])
+                return "[%s]" % (expr.args[0])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc_wb":
+            if expr.args[1].arg != 0:
+                return "[%s, %s]!" % (expr.args[0], expr.args[1])
             else:
-                return "[%s]" % (e.args[0])
-        elif isinstance(e, m2_expr.ExprOp) and e.op == 'segm':
-            arg = e.args[1]
+                return "[%s]" % (expr.args[0])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op == "preinc":
+            if len(expr.args) == 1:
+                return "[%s]" % (expr.args[0])
+            elif not isinstance(expr.args[1], m2_expr.ExprInt) or expr.args[1].arg != 0:
+                return "[%s, %s]" % (expr.args[0], expr.args[1])
+            else:
+                return "[%s]" % (expr.args[0])
+        elif isinstance(expr, m2_expr.ExprOp) and expr.op == 'segm':
+            arg = expr.args[1]
             if isinstance(arg, m2_expr.ExprId):
                 arg = str(arg)
             elif arg.op == 'LSL' and arg.args[1].arg == 0:
                 arg = str(arg.args[0])
             else:
                 arg = "%s %s %s" % (arg.args[0], arg.op, arg.args[1])
-            return '[%s, %s]' % (e.args[0], arg)
+            return '[%s, %s]' % (expr.args[0], arg)
 
         else:
             raise NotImplementedError("bad op")
@@ -366,13 +370,12 @@ class instruction_aarch64(instruction):
 
     def dstflow2label(self, symbol_pool):
         index = self.mnemo_flow_to_dst_index(self.name)
-        e = self.args[index]
-        if not isinstance(e, m2_expr.ExprInt):
+        expr = self.args[index]
+        if not expr.is_int():
             return
-        ad = e.arg + self.offset
-        l = symbol_pool.getby_offset_create(ad)
-        s = m2_expr.ExprId(l, e.size)
-        self.args[index] = s
+        addr = expr.arg + self.offset
+        loc_key = symbol_pool.getby_offset_create(addr)
+        self.args[index] = m2_expr.ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
         return self.name in BRCOND + ["BR", "BLR", "RET", "ERET", "DRPS", "B", "BL"]
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index 88b0d0a7..ad582878 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -593,14 +593,14 @@ def udiv(arg1, arg2, arg3):
 
 @sbuild.parse
 def cbz(arg1, arg2):
-    dst = m2_expr.ExprId(ir.get_next_label(instr), 64) if arg1 else arg2
+    dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if arg1 else arg2
     PC = dst
     ir.IRDst = dst
 
 
 @sbuild.parse
 def cbnz(arg1, arg2):
-    dst = arg2 if arg1 else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg2 if arg1 else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -609,7 +609,7 @@ def cbnz(arg1, arg2):
 def tbz(arg1, arg2, arg3):
     bitmask = m2_expr.ExprInt(1, arg1.size) << arg2
     dst = m2_expr.ExprId(
-        ir.get_next_label(instr), 64) if arg1 & bitmask else arg3
+        ir.get_next_loc_key(instr), 64) if arg1 & bitmask else arg3
     PC = dst
     ir.IRDst = dst
 
@@ -618,21 +618,21 @@ def tbz(arg1, arg2, arg3):
 def tbnz(arg1, arg2, arg3):
     bitmask = m2_expr.ExprInt(1, arg1.size) << arg2
     dst = arg3 if arg1 & bitmask else m2_expr.ExprId(
-        ir.get_next_label(instr), 64)
+        ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
 
 @sbuild.parse
 def b_ne(arg1):
-    dst = m2_expr.ExprId(ir.get_next_label(instr), 64) if zf else arg1
+    dst = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64) if zf else arg1
     PC = dst
     ir.IRDst = dst
 
 
 @sbuild.parse
 def b_eq(arg1):
-    dst = arg1 if zf else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if zf else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -640,7 +640,7 @@ def b_eq(arg1):
 @sbuild.parse
 def b_ge(arg1):
     cond = cond2expr['GE']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -648,7 +648,7 @@ def b_ge(arg1):
 @sbuild.parse
 def b_gt(arg1):
     cond = cond2expr['GT']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -656,7 +656,7 @@ def b_gt(arg1):
 @sbuild.parse
 def b_cc(arg1):
     cond = cond2expr['CC']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -664,7 +664,7 @@ def b_cc(arg1):
 @sbuild.parse
 def b_cs(arg1):
     cond = cond2expr['CS']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -672,7 +672,7 @@ def b_cs(arg1):
 @sbuild.parse
 def b_hi(arg1):
     cond = cond2expr['HI']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -680,7 +680,7 @@ def b_hi(arg1):
 @sbuild.parse
 def b_le(arg1):
     cond = cond2expr['LE']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -688,7 +688,7 @@ def b_le(arg1):
 @sbuild.parse
 def b_ls(arg1):
     cond = cond2expr['LS']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -696,7 +696,7 @@ def b_ls(arg1):
 @sbuild.parse
 def b_lt(arg1):
     cond = cond2expr['LT']
-    dst = arg1 if cond else m2_expr.ExprId(ir.get_next_label(instr), 64)
+    dst = arg1 if cond else m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
     PC = dst
     ir.IRDst = dst
 
@@ -732,7 +732,7 @@ def br(arg1):
 def blr(arg1):
     PC = arg1
     ir.IRDst = arg1
-    LR = m2_expr.ExprId(ir.get_next_label(instr), 64)
+    LR = m2_expr.ExprLoc(ir.get_next_loc_key(instr), 64)
 
 @sbuild.parse
 def nop():
@@ -877,7 +877,7 @@ class ir_aarch64l(IntermediateRepresentation):
                 src = self.expr_fix_regs_for_mode(src)
                 new_assignblk[dst] = src
             irs.append(AssignBlock(new_assignblk, assignblk.instr))
-        return IRBlock(irblock.label, irs)
+        return IRBlock(irblock.loc_key, irs)
 
     def mod_pc(self, instr, instr_ir, extra_ir):
         "Replace PC by the instruction's offset"
@@ -908,7 +908,7 @@ class ir_aarch64l(IntermediateRepresentation):
                 new_dsts = {dst:src for dst, src in assignblk.iteritems()
                                 if dst not in regs_to_fix}
                 irs.append(AssignBlock(new_dsts, assignblk.instr))
-            new_irblocks.append(IRBlock(irblock.label, irs))
+            new_irblocks.append(IRBlock(irblock.loc_key, irs))
 
         return instr_ir, new_irblocks
 
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index 35574a84..17b57ba4 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -343,62 +343,67 @@ class instruction_arm(instruction):
         super(instruction_arm, self).__init__(*args, **kargs)
 
     @staticmethod
-    def arg2str(e, pos = None):
+    def arg2str(expr, index=None, symbol_pool=None):
         wb = False
-        if isinstance(e, ExprId) or isinstance(e, ExprInt):
-            return str(e)
-        if isinstance(e, ExprOp) and e.op in expr2shift_dct:
-            if len(e.args) == 1:
-                return '%s %s' % (e.args[0], expr2shift_dct[e.op])
-            elif len(e.args) == 2:
-                return '%s %s %s' % (e.args[0], expr2shift_dct[e.op], e.args[1])
+        if expr.is_id() or expr.is_int():
+            return str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                return symbol_pool.str_loc_key(expr.loc_key)
+            else:
+                return str(expr)
+        if isinstance(expr, ExprOp) and expr.op in expr2shift_dct:
+            if len(expr.args) == 1:
+                return '%s %s' % (expr.args[0], expr2shift_dct[expr.op])
+            elif len(expr.args) == 2:
+                return '%s %s %s' % (expr.args[0], expr2shift_dct[expr.op], expr.args[1])
             else:
                 raise NotImplementedError('zarb arg2str')
 
 
         sb = False
-        if isinstance(e, ExprOp) and e.op == "sbit":
+        if isinstance(expr, ExprOp) and expr.op == "sbit":
             sb = True
-            e = e.args[0]
-        if isinstance(e, ExprOp) and e.op == "reglist":
-            o = [gpregs.expr.index(x) for x in e.args]
+            expr = expr.args[0]
+        if isinstance(expr, ExprOp) and expr.op == "reglist":
+            o = [gpregs.expr.index(x) for x in expr.args]
             out = reglist2str(o)
             if sb:
                 out += "^"
             return out
 
 
-        if isinstance(e, ExprOp) and e.op == 'wback':
+        if isinstance(expr, ExprOp) and expr.op == 'wback':
             wb = True
-            e = e.args[0]
-        if isinstance(e, ExprId):
-            out = str(e)
+            expr = expr.args[0]
+        if isinstance(expr, ExprId):
+            out = str(expr)
             if wb:
                 out += "!"
             return out
 
-        if not isinstance(e, ExprMem):
-            return str(e)
+        if not isinstance(expr, ExprMem):
+            return str(expr)
 
-        e = e.arg
-        if isinstance(e, ExprOp) and e.op == 'wback':
+        expr = expr.arg
+        if isinstance(expr, ExprOp) and expr.op == 'wback':
             wb = True
-            e = e.args[0]
+            expr = expr.args[0]
 
 
-        if isinstance(e, ExprId):
-            r, s = e, None
-        elif len(e.args) == 1 and isinstance(e.args[0], ExprId):
-            r, s = e.args[0], None
-        elif isinstance(e.args[0], ExprId):
-            r, s = e.args[0], e.args[1]
+        if isinstance(expr, ExprId):
+            r, s = expr, None
+        elif len(expr.args) == 1 and isinstance(expr.args[0], ExprId):
+            r, s = expr.args[0], None
+        elif isinstance(expr.args[0], ExprId):
+            r, s = expr.args[0], expr.args[1]
         else:
-            r, s = e.args[0].args
+            r, s = expr.args[0].args
         if isinstance(s, ExprOp) and s.op in expr2shift_dct:
             s = ' '.join([str(x)
                 for x in s.args[0], expr2shift_dct[s.op], s.args[1]])
 
-        if isinstance(e, ExprOp) and e.op == 'postinc':
+        if isinstance(expr, ExprOp) and expr.op == 'postinc':
             o = '[%s]' % r
             if s and not (isinstance(s, ExprInt) and s.arg == 0):
                 o += ', %s' % s
@@ -418,16 +423,15 @@ class instruction_arm(instruction):
         return self.name in conditional_branch + unconditional_branch
 
     def dstflow2label(self, symbol_pool):
-        e = self.args[0]
-        if not isinstance(e, ExprInt):
+        expr = self.args[0]
+        if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            ad = e.arg + self.offset
+            addr = expr.arg + self.offset
         else:
-            ad = e.arg + self.offset
-        l = symbol_pool.getby_offset_create(ad)
-        s = ExprId(l, e.size)
-        self.args[0] = s
+            addr = expr.arg + self.offset
+        loc_key = symbol_pool.getby_offset_create(addr)
+        self.args[0] = ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
         if self.name in conditional_branch + unconditional_branch:
@@ -492,27 +496,29 @@ class instruction_armt(instruction_arm):
 
     def dstflow2label(self, symbol_pool):
         if self.name in ["CBZ", "CBNZ"]:
-            e = self.args[1]
+            expr = self.args[1]
         else:
-            e = self.args[0]
-        if not isinstance(e, ExprInt):
+            expr = self.args[0]
+        if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            ad = e.arg + (self.offset & 0xfffffffc)
+            addr = expr.arg + (self.offset & 0xfffffffc)
         elif self.name == 'BL':
-            ad = e.arg + self.offset
+            addr = expr.arg + self.offset
         elif self.name.startswith('BP'):
-            ad = e.arg + self.offset
+            addr = expr.arg + self.offset
         elif self.name.startswith('CB'):
-            ad = e.arg + self.offset + self.l + 2
+            addr = expr.arg + self.offset + self.l + 2
         else:
-            ad = e.arg + self.offset
-        l = symbol_pool.getby_offset_create(ad)
-        s = ExprId(l, e.size)
+            addr = expr.arg + self.offset
+
+        loc_key = symbol_pool.getby_offset_create(addr)
+        dst = ExprLoc(loc_key, expr.size)
+
         if self.name in ["CBZ", "CBNZ"]:
-            self.args[1] = s
+            self.args[1] = dst
         else:
-            self.args[0] = s
+            self.args[0] = dst
 
     def breakflow(self):
         if self.name in conditional_branch + unconditional_branch +["CBZ", "CBNZ", 'TBB', 'TBH']:
@@ -774,8 +780,8 @@ class arm_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            label = symbol_pool.getby_name_create(arg.name)
-            return ExprId(label, 32)
+            loc_key = symbol_pool.getby_name_create(arg.name)
+            return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args]
             if None in args:
diff --git a/miasm2/arch/arm/disasm.py b/miasm2/arch/arm/disasm.py
index 586fa903..956a894b 100644
--- a/miasm2/arch/arm/disasm.py
+++ b/miasm2/arch/arm/disasm.py
@@ -24,7 +24,8 @@ def cb_arm_fix_call(mn, cur_bloc, symbol_pool, offsets_to_dis, *args, **kwargs):
         return
     if not l2.args[1] in values:
         return
-    cur_bloc.add_cst(l1.offset + 4, AsmConstraint.c_next, symbol_pool)
+    loc_key_cst = self.symbol_pool.getby_offset_create(l1.offset + 4)
+    cur_bloc.add_cst(loc_key_cst, AsmConstraint.c_next, symbol_pool)
     offsets_to_dis.add(l1.offset + 4)
 
 cb_arm_funcs = [cb_arm_fix_call]
diff --git a/miasm2/arch/arm/jit.py b/miasm2/arch/arm/jit.py
index 1a37b7f1..b92e2c32 100644
--- a/miasm2/arch/arm/jit.py
+++ b/miasm2/arch/arm/jit.py
@@ -7,6 +7,7 @@ from miasm2.arch.arm.sem import ir_armb, ir_arml, ir_armtl, ir_armtb, cond_dct_i
 from miasm2.jitter.codegen import CGen
 from miasm2.expression.expression import ExprId, ExprAff, ExprCond
 from miasm2.ir.ir import IRBlock, AssignBlock
+from miasm2.ir.translators.C import TranslatorC
 
 log = logging.getLogger('jit_arm')
 hnd = logging.StreamHandler()
@@ -17,11 +18,6 @@ log.setLevel(logging.CRITICAL)
 
 
 class arm_CGen(CGen):
-    def __init__(self, ir_arch):
-        self.ir_arch = ir_arch
-        self.PC = self.ir_arch.arch.regs.PC
-        self.init_arch_C()
-
 
     def block2assignblks(self, block):
         """
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 2cf2e5a4..c80e9826 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -441,16 +441,16 @@ def sdiv(ir, instr, a, b, c=None):
     if c is None:
         b, c = a, b
 
-    lbl_div = ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_except = ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_div = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+    loc_except = ExprId(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+    loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
-    e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except)))
+    e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except)))
 
     do_except = []
     do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
-    do_except.append(ExprAff(ir.IRDst, lbl_next))
-    blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)])
+    do_except.append(ExprAff(ir.IRDst, loc_next))
+    blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)])
 
 
 
@@ -461,8 +461,8 @@ def sdiv(ir, instr, a, b, c=None):
     if dst is not None:
         do_div.append(ExprAff(ir.IRDst, r))
 
-    do_div.append(ExprAff(ir.IRDst, lbl_next))
-    blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)])
+    do_div.append(ExprAff(ir.IRDst, loc_next))
+    blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)])
 
     return e, [blk_div, blk_except]
 
@@ -474,16 +474,16 @@ def udiv(ir, instr, a, b, c=None):
 
 
 
-    lbl_div = ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_except = ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_div = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+    loc_except = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+    loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
-    e.append(ExprAff(ir.IRDst, ExprCond(c, lbl_div, lbl_except)))
+    e.append(ExprAff(ir.IRDst, ExprCond(c, loc_div, loc_except)))
 
     do_except = []
     do_except.append(ExprAff(exception_flags, ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
-    do_except.append(ExprAff(ir.IRDst, lbl_next))
-    blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)])
+    do_except.append(ExprAff(ir.IRDst, loc_next))
+    blk_except = IRBlock(loc_except.loc_key, [AssignBlock(do_except, instr)])
 
 
     r = ExprOp("udiv", b, c)
@@ -493,8 +493,8 @@ def udiv(ir, instr, a, b, c=None):
     if dst is not None:
         do_div.append(ExprAff(ir.IRDst, r))
 
-    do_div.append(ExprAff(ir.IRDst, lbl_next))
-    blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)])
+    do_div.append(ExprAff(ir.IRDst, loc_next))
+    blk_div = IRBlock(loc_div.loc_key, [AssignBlock(do_div, instr)])
 
     return e, [blk_div, blk_except]
 
@@ -932,19 +932,20 @@ def pop(ir, instr, a):
 
 def cbz(ir, instr, a, b):
     e = []
-    lbl_next = ExprId(ir.get_next_label(instr), 32)
-    e.append(ExprAff(ir.IRDst, ExprCond(a, lbl_next, b)))
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 32)
+    e.append(ExprAff(ir.IRDst, ExprCond(a, loc_next_expr, b)))
     return e, []
 
 
 def cbnz(ir, instr, a, b):
     e = []
-    lbl_next = ExprId(ir.get_next_label(instr), 32)
-    e.append(ExprAff(ir.IRDst, ExprCond(a, b, lbl_next)))
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 32)
+    e.append(ir.IRDst, ExprCond(a, b, loc_next_expr))
     return e, []
 
 
-
 def uxtb(ir, instr, a, b):
     e = []
     r = b[:8].zeroExtend(32)
@@ -1264,10 +1265,14 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
         raise ValueError('unknown condition %r' % cond)
     cond = tab_cond[cond]
 
-    lbl_next = ExprId(ir.get_next_label(instr), 32)
-    lbl_do = ExprId(ir.gen_label(), 32)
 
-    dst_cond = ExprCond(cond, lbl_do, lbl_next)
+
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 32)
+    loc_do = ir.symbol_pool.gen_loc_key()
+    loc_do_expr = ExprLoc(loc_do, 32)
+
+    dst_cond = ExprCond(cond, loc_do_expr, loc_next_expr)
     assert(isinstance(instr_ir, list))
 
     has_irdst = False
@@ -1276,8 +1281,8 @@ def add_condition_expr(ir, instr, cond, instr_ir, extra_ir):
             has_irdst = True
             break
     if not has_irdst:
-        instr_ir.append(ExprAff(ir.IRDst, lbl_next))
-    e_do = IRBlock(lbl_do.name, [AssignBlock(instr_ir, instr)])
+        instr_ir.append(ExprAff(ir.IRDst, loc_next_expr))
+    e_do = IRBlock(loc_do, [AssignBlock(instr_ir, instr)])
     e = [ExprAff(ir.IRDst, dst_cond)]
     return e, [e_do] + extra_ir
 
@@ -1527,7 +1532,7 @@ class ir_arml(IntermediateRepresentation):
                 raise ValueError("IT name invalid %s" % instr)
         return out, instr.args[0]
 
-    def do_it_block(self, label, index, block, assignments, gen_pc_updt):
+    def do_it_block(self, loc, index, block, assignments, gen_pc_updt):
         instr = block.lines[index]
         it_hints, it_cond = self.parse_itt(instr)
         cond_num = cond_dct_inv[it_cond.name]
@@ -1539,14 +1544,14 @@ class ir_arml(IntermediateRepresentation):
         ir_blocks_all = []
 
         # Gen dummy irblock for IT instr
-        label_next = self.get_next_label(instr)
-        dst = ExprAff(self.IRDst, ExprId(label_next, 32))
+        loc_next = self.get_next_loc_key(instr)
+        dst = ExprAff(self.IRDst, ExprId(loc_next, 32))
         dst_blk = AssignBlock([dst], instr)
         assignments.append(dst_blk)
-        irblock = IRBlock(label, assignments)
+        irblock = IRBlock(loc, assignments)
         ir_blocks_all.append([irblock])
 
-        label = label_next
+        loc = loc_next
         assignments = []
         for hint in it_hints:
             irblocks = []
@@ -1554,33 +1559,33 @@ class ir_arml(IntermediateRepresentation):
             instr = block.lines[index]
 
             # Add conditionnal jump to current irblock
-            label_do = self.symbol_pool.gen_label()
-            label_next = self.get_next_label(instr)
+            loc_do = self.symbol_pool.gen_loc_key()
+            loc_next = self.get_next_loc_key(instr)
 
             if hint:
                 local_cond = ~cond_eq
             else:
                 local_cond = cond_eq
-            dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprId(label_do, 32), ExprId(label_next, 32)))
+            dst = ExprAff(self.IRDst, ExprCond(local_cond, ExprLoc(loc_do, 32), ExprLoc(loc_next, 32)))
             dst_blk = AssignBlock([dst], instr)
             assignments.append(dst_blk)
-            irblock = IRBlock(label, assignments)
+            irblock = IRBlock(loc, assignments)
 
             irblocks.append(irblock)
 
             assignments = []
-            label = label_do
+            loc = loc_do
             split = self.add_instr_to_irblock(block, instr, assignments,
                                               irblocks, gen_pc_updt)
             if split:
                 raise NotImplementedError("Unsupported instr in IT block (%s)" % instr)
 
-            dst = ExprAff(self.IRDst, ExprId(label_next, 32))
+            dst = ExprAff(self.IRDst, ExprId(loc_next, 32))
             dst_blk = AssignBlock([dst], instr)
             assignments.append(dst_blk)
-            irblock = IRBlock(label, assignments)
+            irblock = IRBlock(loc, assignments)
             irblocks.append(irblock)
-            label = label_next
+            loc = loc_next
             assignments = []
             ir_blocks_all.append(irblocks)
         return index, ir_blocks_all
@@ -1594,7 +1599,8 @@ class ir_arml(IntermediateRepresentation):
 
         it_hints = None
         it_cond = None
-        label = None
+        label = block.loc_key
+        assignments = []
         ir_blocks_all = []
         index = -1
         while index + 1 < len(block.lines):
@@ -1602,7 +1608,7 @@ class ir_arml(IntermediateRepresentation):
             instr = block.lines[index]
             if label is None:
                 assignments = []
-                label = self.get_instr_label(instr)
+                label = self.get_loc_key_for_instr(instr)
             if instr.name.startswith("IT"):
                 index, irblocks_it = self.do_it_block(label, index, block, assignments, gen_pc_updt)
                 for irblocks in irblocks_it:
@@ -1621,7 +1627,7 @@ class ir_arml(IntermediateRepresentation):
 
         new_ir_blocks_all = self.post_add_block(block, ir_blocks_all)
         for irblock in new_ir_blocks_all:
-            self.blocks[irblock.label] = irblock
+            self.blocks[irblock.loc_key] = irblock
         return new_ir_blocks_all
 
 
diff --git a/miasm2/arch/mips32/arch.py b/miasm2/arch/mips32/arch.py
index 15c59cf0..939ce5b0 100644
--- a/miasm2/arch/mips32/arch.py
+++ b/miasm2/arch/mips32/arch.py
@@ -5,7 +5,7 @@ from collections import defaultdict
 
 from pyparsing import Literal, Group, Optional
 
-from miasm2.expression.expression import ExprMem, ExprInt, ExprId, ExprOp
+from miasm2.expression.expression import ExprMem, ExprInt, ExprId, ExprOp, ExprLoc
 from miasm2.core.bin_stream import bin_stream
 import miasm2.arch.mips32.regs as regs
 import miasm2.core.cpu as cpu
@@ -60,11 +60,16 @@ class instruction_mips32(cpu.instruction):
 
 
     @staticmethod
-    def arg2str(e, pos = None):
-        if isinstance(e, ExprId) or isinstance(e, ExprInt):
-            return str(e)
-        assert(isinstance(e, ExprMem))
-        arg = e.arg
+    def arg2str(expr, index=None, symbol_pool=None):
+        if expr.is_id() or expr.is_int():
+            return str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                return symbol_pool.str_loc_key(expr.loc_key)
+            else:
+                return str(expr)
+        assert(isinstance(expr, ExprMem))
+        arg = expr.arg
         if isinstance(arg, ExprId):
             return "(%s)"%arg
         assert(len(arg.args) == 2 and arg.op == '+')
@@ -90,21 +95,20 @@ class instruction_mips32(cpu.instruction):
 
     def dstflow2label(self, symbol_pool):
         if self.name in ["J", 'JAL']:
-            e = self.args[0].arg
-            ad = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + e
-            l = symbol_pool.getby_offset_create(ad)
-            self.args[0] = ExprId(l, e.size)
+            expr = self.args[0].arg
+            addr = (self.offset & (0xFFFFFFFF ^ ((1<< 28)-1))) + expr
+            label = symbol_pool.getby_offset_create(addr)
+            self.args[0] = ExprLoc(label.loc_key, expr.size)
             return
 
         ndx = self.get_dst_num()
-        e = self.args[ndx]
+        expr = self.args[ndx]
 
-        if not isinstance(e, ExprInt):
+        if not isinstance(expr, ExprInt):
             return
-        ad = e.arg + self.offset
-        l = symbol_pool.getby_offset_create(ad)
-        s = ExprId(l, e.size)
-        self.args[ndx] = s
+        addr = expr.arg + self.offset
+        loc_key = symbol_pool.getby_offset_create(addr)
+        self.args[ndx] = ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
         if self.name == 'BREAK':
@@ -261,8 +265,8 @@ class mips32_arg(cpu.m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            label = symbol_pool.getby_name_create(arg.name)
-            return ExprId(label, 32)
+            loc_key = symbol_pool.getby_name_create(arg.name)
+            return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args]
             if None in args:
@@ -403,9 +407,9 @@ class mips32_dreg_imm(mips32_arg):
         return True
 
     @staticmethod
-    def arg2str(e):
-        assert(isinstance(e, ExprMem))
-        arg = e.arg
+    def arg2str(expr, index=None):
+        assert(isinstance(expr, ExprMem))
+        arg = expr.arg
         if isinstance(arg, ExprId):
             return "(%s)"%arg
         assert(len(arg.args) == 2 and arg.op == '+')
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index 7aefad32..b6d92ee0 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -4,7 +4,6 @@ from miasm2.expression.expression import ExprAff, ExprInt, ExprId
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.ir.analysis import ira
 from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b
-from miasm2.core.asmblock import expr_is_int_or_label, expr_is_label
 
 class ir_a_mips32l(ir_mips32l, ira):
     def __init__(self, symbol_pool=None):
@@ -28,14 +27,15 @@ class ir_a_mips32l(ir_mips32l, ira):
             if pc_val is None or lr_val is None:
                 new_irblocks.append(irb)
                 continue
-            if not expr_is_int_or_label(lr_val):
-                new_irblocks.append(irb)
+            if lr_val.is_loc():
+                offset = self.symbol_pool.loc_key_to_offset(lr_val.loc_key)
+                if offset is not None:
+                    lr_val = ExprInt(offset, 32)
+            if not lr_val.is_int():
                 continue
-            if expr_is_label(lr_val):
-                lr_val = ExprInt(lr_val.name.offset, 32)
 
             instr = block.lines[-2]
-            if lr_val.arg != instr.offset + 8:
+            if int(lr_val) != instr.offset + 8:
                 raise ValueError("Wrong arg")
 
             # CALL
diff --git a/miasm2/arch/mips32/jit.py b/miasm2/arch/mips32/jit.py
index 16d88067..180f8b0a 100644
--- a/miasm2/arch/mips32/jit.py
+++ b/miasm2/arch/mips32/jit.py
@@ -57,10 +57,10 @@ class mipsCGen(CGen):
                         self.ir_arch.pc]
                     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), 32)
+                    dst_loc_key = self.ir_arch.get_next_instr(assignblock.instr)
+                    assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(dst_loc_key, 32)
                     irs.append(AssignBlock(assignments, assignblock.instr))
-                irblocks[blk_idx] = IRBlock(irblock.label, irs)
+                irblocks[blk_idx] = IRBlock(irblock.loc_key, irs)
 
         return irblocks_list
 
@@ -69,12 +69,13 @@ class mipsCGen(CGen):
         Generate the C code for the final block instruction
         """
 
-        lbl = self.get_block_post_label(block)
-        out = (self.CODE_RETURN_NO_EXCEPTION % (self.label_to_jitlabel(lbl),
+        loc_key = self.get_block_post_label(block)
+        offset = self.ir_arch.symbol_pool.loc_key_to_offset(loc_key)
+        out = (self.CODE_RETURN_NO_EXCEPTION % (self.loc_key_to_jitlabel(loc_key),
                                                 self.C_PC,
                                                 m2_expr.ExprId('branch_dst_irdst', 32),
                                                 m2_expr.ExprId('branch_dst_irdst', 32),
-                                                self.id_to_c(m2_expr.ExprInt(lbl.offset, 32)))
+                                                self.id_to_c(m2_expr.ExprInt(offset, 32)))
               ).split('\n')
         return out
 
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index 99c81a33..fd4fa655 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -35,7 +35,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), 32)
+    RA = ExprLoc(ir.get_next_break_loc_key(instr), RA.size)
 
 @sbuild.parse
 def jalr(arg1, arg2):
@@ -43,13 +43,13 @@ def jalr(arg1, arg2):
     address in another register @arg2"""
     PC = arg1
     ir.IRDst = arg1
-    arg2 = ExprId(ir.get_next_break_label(instr), 32)
+    arg2 = ExprLoc(ir.get_next_break_loc_key(instr), arg2.size)
 
 @sbuild.parse
 def bal(arg1):
     PC = arg1
     ir.IRDst = arg1
-    RA = ExprId(ir.get_next_break_label(instr), 32)
+    RA = ExprLoc(ir.get_next_break_loc_key(instr), RA.size)
 
 @sbuild.parse
 def l_b(arg1):
@@ -76,7 +76,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), 32) if arg1 - arg2 else arg3
+    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 - arg2 else arg3
     PC = dst
     ir.IRDst = dst
 
@@ -84,7 +84,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), 32) if arg1.msb() else arg2
+    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1.msb() else arg2
     PC = dst
     ir.IRDst = dst
 
@@ -92,7 +92,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), 32)
+    dst = arg3 if arg1 - arg2 else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst
     ir.IRDst = dst
 
@@ -230,7 +230,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), 32)
+    dst_o = arg2 if arg1.msb() else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -238,7 +238,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), 32)
+    dst_o = arg2 if cond else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -246,7 +246,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), 32) if cond else arg2
+    dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if cond else arg2
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -346,13 +346,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), 32)
+    dst_o = arg2 if arg1 else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst_o
     ir.IRDst = dst_o
 
 @sbuild.parse
 def bc1f(arg1, arg2):
-    dst_o = ExprId(ir.get_next_break_label(instr), 32) if arg1 else arg2
+    dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 else arg2
     PC = dst_o
     ir.IRDst = dst_o
 
@@ -415,22 +415,22 @@ def ehb(arg1):
 def teq(ir, instr, arg1, arg2):
     e = []
 
-    lbl_except, lbl_except_expr = ir.gen_label_and_expr(ir.IRDst.size)
-    lbl_next = ir.get_next_label(instr)
-    lbl_next_expr = m2_expr.ExprId(lbl_next, ir.IRDst.size)
+    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
 
     do_except = []
     do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt(
         EXCEPT_DIV_BY_ZERO, exception_flags.size)))
-    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr))
-    blk_except = IRBlock(lbl_except, [AssignBlock(do_except, instr)])
+    do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)])
 
     cond = arg1 - arg2
 
 
     e = []
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(cond, lbl_next_expr, lbl_except_expr)))
+                             m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr)))
 
     return e, [blk_except]
 
@@ -492,7 +492,7 @@ class ir_mips32l(IntermediateRepresentation):
     def get_next_instr(self, instr):
         return self.symbol_pool.getby_offset_create(instr.offset  + 4)
 
-    def get_next_break_label(self, instr):
+    def get_next_break_loc_key(self, instr):
         return self.symbol_pool.getby_offset_create(instr.offset  + 8)
 
 class ir_mips32b(ir_mips32l):
diff --git a/miasm2/arch/msp430/arch.py b/miasm2/arch/msp430/arch.py
index e4d03edb..1842f577 100644
--- a/miasm2/arch/msp430/arch.py
+++ b/miasm2/arch/msp430/arch.py
@@ -69,8 +69,8 @@ class msp430_arg(m_arg):
                 index = gpregs.str.index(name)
                 reg = gpregs.expr[index]
                 return reg
-            label = symbol_pool.getby_name_create(value.name)
-            return ExprId(label, 16)
+            loc_key = symbol_pool.getby_name_create(value.name)
+            return ExprLoc(loc_key, 16)
         if isinstance(value, AstOp):
             args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in value.args]
             if None in args:
@@ -102,40 +102,44 @@ class instruction_msp430(instruction):
         return self.name in ['call']
 
     @staticmethod
-    def arg2str(e, pos = None):
-        if isinstance(e, ExprId):
-            o = str(e)
-        elif isinstance(e, ExprInt):
-            o = str(e)
-        elif isinstance(e, ExprOp) and e.op == "autoinc":
-            o = "@%s+" % str(e.args[0])
-        elif isinstance(e, ExprMem):
-            if isinstance(e.arg, ExprId):
-                if pos == 0:
-                    o = "@%s" % e.arg
+    def arg2str(expr, index=None, symbol_pool=None):
+        if isinstance(expr, ExprId):
+            o = str(expr)
+        elif isinstance(expr, ExprInt):
+            o = str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                return symbol_pool.str_loc_key(expr.loc_key)
+            else:
+                return str(expr)
+        elif isinstance(expr, ExprOp) and expr.op == "autoinc":
+            o = "@%s+" % str(expr.args[0])
+        elif isinstance(expr, ExprMem):
+            if isinstance(expr.arg, ExprId):
+                if index == 0:
+                    o = "@%s" % expr.arg
                 else:
-                    o = "0x0(%s)" % e.arg
-            elif isinstance(e.arg, ExprInt):
-                o = "@%s" % e.arg
-            elif isinstance(e.arg, ExprOp):
-                o = "%s(%s)" % (e.arg.args[1], e.arg.args[0])
+                    o = "0x0(%s)" % expr.arg
+            elif isinstance(expr.arg, ExprInt):
+                o = "@%s" % expr.arg
+            elif isinstance(expr.arg, ExprOp):
+                o = "%s(%s)" % (expr.arg.args[1], expr.arg.args[0])
         else:
-            raise NotImplementedError('unknown instance e = %s' % type(e))
+            raise NotImplementedError('unknown instance expr = %s' % type(expr))
         return o
 
 
     def dstflow2label(self, symbol_pool):
-        e = self.args[0]
-        if not isinstance(e, ExprInt):
+        expr = self.args[0]
+        if not isinstance(expr, ExprInt):
             return
         if self.name == "call":
-            ad = e.arg
+            addr = expr.arg
         else:
-            ad = e.arg + int(self.offset)
+            addr = expr.arg + int(self.offset)
 
-        l = symbol_pool.getby_offset_create(ad)
-        s = ExprId(l, e.size)
-        self.args[0] = s
+        loc_key = symbol_pool.getby_offset_create(addr)
+        self.args[0] = ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
         if self.name in conditional_branch + unconditional_branch:
diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py
index dd24abb1..877c2a70 100644
--- a/miasm2/arch/msp430/sem.py
+++ b/miasm2/arch/msp430/sem.py
@@ -238,8 +238,11 @@ def push_w(ir, instr, a):
 
 def call(ir, instr, a):
     e, a, dummy = mng_autoinc(a, None, 16)
-    n = ExprId(ir.get_next_label(instr), 16)
-    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), n))
+
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
+
+    e.append(ExprAff(ExprMem(SP - ExprInt(2, 16), 16), loc_next_expr))
     e.append(ExprAff(SP, SP - ExprInt(2, 16)))
     e.append(ExprAff(PC, a))
     e.append(ExprAff(ir.IRDst, a))
@@ -272,50 +275,56 @@ def cmp_b(ir, instr, a, b):
 
 
 def jz(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(zf, a, n)))
-    e.append(ExprAff(ir.IRDst, ExprCond(zf, a, n)))
+    e.append(ExprAff(PC, ExprCond(zf, a, loc_next_expr)))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, a, loc_next_expr)))
     return e, []
 
 
 def jnz(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(zf, n, a)))
-    e.append(ExprAff(ir.IRDst, ExprCond(zf, n, a)))
+    e.append(ExprAff(PC, ExprCond(zf, loc_next_expr, a)))
+    e.append(ExprAff(ir.IRDst, ExprCond(zf, loc_next_expr, a)))
     return e, []
 
 
 def jl(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(nf ^ of, a, n)))
-    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, n)))
+    e.append(ExprAff(PC, ExprCond(nf ^ of, a, loc_next_expr)))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, a, loc_next_expr)))
     return e, []
 
 
 def jc(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(cf, a, n)))
-    e.append(ExprAff(ir.IRDst, ExprCond(cf, a, n)))
+    e.append(ExprAff(PC, ExprCond(cf, a, loc_next_expr)))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, a, loc_next_expr)))
     return e, []
 
 
 def jnc(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(cf, n, a)))
-    e.append(ExprAff(ir.IRDst, ExprCond(cf, n, a)))
+    e.append(ExprAff(PC, ExprCond(cf, loc_next_expr, a)))
+    e.append(ExprAff(ir.IRDst, ExprCond(cf, loc_next_expr, a)))
     return e, []
 
 
 def jge(ir, instr, a):
-    n = ExprId(ir.get_next_label(instr), 16)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = ExprLoc(loc_next, 16)
     e = []
-    e.append(ExprAff(PC, ExprCond(nf ^ of, n, a)))
-    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, n, a)))
+    e.append(ExprAff(PC, ExprCond(nf ^ of, loc_next_expr, a)))
+    e.append(ExprAff(ir.IRDst, ExprCond(nf ^ of, loc_next_expr, a)))
     return e, []
 
 
diff --git a/miasm2/arch/ppc/arch.py b/miasm2/arch/ppc/arch.py
index 945824a0..5336ea21 100644
--- a/miasm2/arch/ppc/arch.py
+++ b/miasm2/arch/ppc/arch.py
@@ -5,7 +5,6 @@ from miasm2.expression.expression import *
 from miasm2.core.cpu import *
 from collections import defaultdict
 from miasm2.core.bin_stream import bin_stream
-from miasm2.core.asmblock import asm_label
 import miasm2.arch.ppc.regs as regs_module
 from miasm2.arch.ppc.regs import *
 from miasm2.core.asm_ast import AstInt, AstId, AstMem, AstOp
@@ -41,8 +40,8 @@ class ppc_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            label = symbol_pool.getby_name_create(arg.name)
-            return ExprId(label, 32)
+            loc_key = symbol_pool.getby_name_create(arg.name)
+            return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args]
             if None in args:
@@ -74,7 +73,7 @@ class instruction_ppc(instruction):
         super(instruction_ppc, self).__init__(*args, **kargs)
 
     @staticmethod
-    def arg2str(e, pos = None):
+    def arg2str(e, pos = None, symbol_pool=None):
         if isinstance(e, ExprId) or isinstance(e, ExprInt):
             return str(e)
         elif isinstance(e, ExprMem):
@@ -132,8 +131,8 @@ class instruction_ppc(instruction):
                 ad = e.arg + self.offset
             else:
                 ad = e.arg
-            l = symbol_pool.getby_offset_create(ad)
-            s = ExprId(l, e.size)
+            loc_key = symbol_pool.getby_offset_create(ad)
+            s = ExprLoc(loc_key, e.size)
             self.args[address_index] = s
 
     def breakflow(self):
diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py
index 741ae24b..8ddb43ef 100644
--- a/miasm2/arch/ppc/sem.py
+++ b/miasm2/arch/ppc/sem.py
@@ -606,21 +606,21 @@ def mn_do_store(ir, instr, arg1, arg2, arg3=None):
             ret.append(ExprAff(arg2, address))
 
     if is_stwcx:
-        lbl_do = ExprId(ir.gen_label(), ir.IRDst.size)
-        lbl_dont = ExprId(ir.gen_label(), ir.IRDst.size)
-        lbl_next = ExprId(ir.get_next_label(instr), ir.IRDst.size)
+        loc_do = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+        loc_dont = ExprLoc(ir.symbol_pool.gen_loc_key(), ir.IRDst.size)
+        loc_next = ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
         flags = [ ExprAff(CR0_LT, ExprInt(0,1)),
                   ExprAff(CR0_GT, ExprInt(0,1)),
                   ExprAff(CR0_SO, XER_SO)]
         ret += flags
         ret.append(ExprAff(CR0_EQ, ExprInt(1,1)))
-        ret.append(ExprAff(ir.IRDst, lbl_next))
+        ret.append(ExprAff(ir.IRDst, loc_next))
         dont = flags + [ ExprAff(CR0_EQ, ExprInt(0,1)),
-                         ExprAff(ir.IRDst, lbl_next) ]
-        additional_ir = [ IRBlock(lbl_do.name, [ AssignBlock(ret) ]),
-                          IRBlock(lbl_dont.name, [ AssignBlock(dont) ]) ]
+                         ExprAff(ir.IRDst, loc_next) ]
+        additional_ir = [ IRBlock(loc_do, [ AssignBlock(ret) ]),
+                          IRBlock(loc_dont, [ AssignBlock(dont) ]) ]
         ret = [ ExprAff(reserve, ExprInt(0, 1)),
-                ExprAff(ir.IRDst, ExprCond(reserve, lbl_do, lbl_dont)) ]
+                ExprAff(ir.IRDst, ExprCond(reserve, loc_do, loc_dont)) ]
 
     return ret, additional_ir
 
@@ -690,7 +690,8 @@ def mn_b(ir, instr, arg1, arg2 = None):
 def mn_bl(ir, instr, arg1, arg2 = None):
     if arg2 is not None:
         arg1 = arg2
-    return [ ExprAff(LR, ExprId(ir.get_next_instr(instr), 32)),
+    dst = ir.get_next_instr(instr)
+    return [ ExprAff(LR, ExprLoc(dst, 32)),
              ExprAff(PC, arg1),
              ExprAff(ir.IRDst, arg1) ], []
 
@@ -726,13 +727,15 @@ def mn_do_cond_branch(ir, instr, dest):
                 condition = condition & cond_cond
         else:
             condition = cond_cond
+        dst = ir.get_next_instr(instr)
         dest_expr = ExprCond(condition, dest,
-                             ExprId(ir.get_next_instr(instr), 32))
+                             ExprLoc(dst, 32))
     else:
         dest_expr = dest
 
     if instr.name[-1] == 'L' or instr.name[-2:-1] == 'LA':
-        ret.append(ExprAff(LR, ExprId(ir.get_next_instr(instr), 32)))
+        dst = ir.get_next_instr(instr)
+        ret.append(ExprAff(LR, ExprLoc(dst, 32)))
 
     ret.append(ExprAff(PC, dest_expr))
     ret.append(ExprAff(ir.IRDst, dest_expr))
@@ -916,6 +919,6 @@ class ir_ppc32b(IntermediateRepresentation):
         l = self.symbol_pool.getby_offset_create(instr.offset  + 4)
         return l
 
-    def get_next_break_label(self, instr):
+    def get_next_break_loc_key(self, instr):
         l = self.symbol_pool.getby_offset_create(instr.offset  + 4)
         return l
diff --git a/miasm2/arch/sh4/arch.py b/miasm2/arch/sh4/arch.py
index 14f46265..477edeaf 100644
--- a/miasm2/arch/sh4/arch.py
+++ b/miasm2/arch/sh4/arch.py
@@ -102,8 +102,8 @@ class sh4_arg(m_arg):
                 return arg.name
             if arg.name in gpregs.str:
                 return None
-            label = symbol_pool.getby_name_create(arg.name)
-            return ExprId(label, 32)
+            loc_key = symbol_pool.getby_name_create(arg.name)
+            return ExprLoc(loc_key, 32)
         if isinstance(arg, AstOp):
             args = [self.asm_ast_to_expr(tmp, symbol_pool) for tmp in arg.args]
             if None in args:
@@ -406,24 +406,29 @@ class instruction_sh4(instruction):
         return self.name.startswith('J')
 
     @staticmethod
-    def arg2str(e, pos = None):
-        if isinstance(e, ExprId) or isinstance(e, ExprInt):
-            return str(e)
-        assert(isinstance(e, ExprMem))
-        e = e.arg
-
-        if isinstance(e, ExprOp):
-            if e.op == "predec":
-                s = '-%s' % e.args[0]
-            elif e.op == "postinc":
-                s = '%s+' % e.args[0]
+    def arg2str(expr, index=None, symbol_pool=None):
+        if isinstance(expr, ExprId) or isinstance(expr, ExprInt):
+            return str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                return symbol_pool.str_loc_key(expr.loc_key)
+            else:
+                return str(expr)
+        assert(isinstance(expr, ExprMem))
+        expr = expr.arg
+
+        if isinstance(expr, ExprOp):
+            if expr.op == "predec":
+                s = '-%s' % expr.args[0]
+            elif expr.op == "postinc":
+                s = '%s+' % expr.args[0]
             else:
                 s = ','.join([str(x).replace('(', '').replace(')', '')
-                              for x in e.args])
+                              for x in expr.args])
                 s = "(%s)"%s
             s = "@%s" % s
-        elif isinstance(e, ExprId):
-            s = "@%s" % e
+        elif isinstance(expr, ExprId):
+            s = "@%s" % expr
         else:
             raise NotImplementedError('zarb arg2str')
         return s
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index fc3a5882..2be64c0e 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -7,7 +7,6 @@ from miasm2.core.cpu import *
 from collections import defaultdict
 import miasm2.arch.x86.regs as regs_module
 from miasm2.arch.x86.regs import *
-from miasm2.core.asmblock import AsmLabel
 from miasm2.core.asm_ast import AstNode, AstInt, AstId, AstMem, AstOp
 
 
@@ -273,8 +272,8 @@ class x86_arg(m_arg):
             if value.name in ["FAR"]:
                 return None
 
-            label = symbol_pool.getby_name_create(value.name)
-            return ExprId(label, size_hint)
+            loc_key = symbol_pool.getby_name_create(value.name)
+            return ExprLoc(loc_key, size_hint)
         if isinstance(value, AstOp):
             # First pass to retreive fixed_size
             if value.op == "segm":
@@ -474,16 +473,11 @@ class instruction_x86(instruction):
         if self.additional_info.g1.value & 6 and self.name in repeat_mn:
             return
         expr = self.args[0]
-        if isinstance(expr, ExprId):
-            if not isinstance(expr.name, AsmLabel) and expr not in all_regs_ids:
-                raise ValueError("ExprId must be a label or a register")
-        elif isinstance(expr, ExprInt):
-            ad = expr.arg + int(self.offset)
-            l = symbol_pool.getby_offset_create(ad)
-            s = ExprId(l, expr.size)
-            self.args[0] = s
-        else:
+        if not expr.is_int():
             return
+        addr = expr.arg + int(self.offset)
+        loc_key = symbol_pool.getby_offset_create(addr)
+        self.args[0] = ExprLoc(loc_key, expr.size)
 
     def breakflow(self):
         if self.name in conditional_branch + unconditional_branch:
@@ -519,10 +513,9 @@ class instruction_x86(instruction):
 
     def getdstflow(self, symbol_pool):
         if self.additional_info.g1.value & 6 and self.name in repeat_mn:
-            ad = int(self.offset)
-            l = symbol_pool.getby_offset_create(ad)
-            s = ExprId(l, self.v_opmode())
-            return [s]
+            addr = int(self.offset)
+            loc_key = symbol_pool.getby_offset_create(addr)
+            return [ExprLoc(loc_key, self.v_opmode())]
         return [self.args[0]]
 
     def get_symbol_size(self, symbol, symbol_pool):
@@ -566,9 +559,14 @@ class instruction_x86(instruction):
         return args
 
     @staticmethod
-    def arg2str(expr, pos=None):
-        if isinstance(expr, ExprId) or isinstance(expr, ExprInt):
+    def arg2str(expr, index=None, symbol_pool=None):
+        if expr.is_id() or expr.is_int():
             o = str(expr)
+        elif expr.is_loc():
+            if symbol_pool is not None:
+                o = symbol_pool.str_loc_key(expr.loc_key)
+            else:
+                o = str(expr)
         elif ((isinstance(expr, ExprOp) and expr.op == 'far' and
                isinstance(expr.args[0], ExprMem)) or
               isinstance(expr, ExprMem)):
diff --git a/miasm2/arch/x86/jit.py b/miasm2/arch/x86/jit.py
index 50501060..a12a66f5 100644
--- a/miasm2/arch/x86/jit.py
+++ b/miasm2/arch/x86/jit.py
@@ -5,6 +5,7 @@ from miasm2.core import asmblock
 from miasm2.core.utils import pck16, pck32, pck64, upck16, upck32, upck64
 from miasm2.arch.x86.sem import ir_x86_16, ir_x86_32, ir_x86_64
 from miasm2.jitter.codegen import CGen
+from miasm2.ir.translators.C import TranslatorC
 
 log = logging.getLogger('jit_x86')
 hnd = logging.StreamHandler()
@@ -17,6 +18,7 @@ class x86_32_CGen(CGen):
     def __init__(self, ir_arch):
         self.ir_arch = ir_arch
         self.PC = self.ir_arch.arch.regs.RIP
+        self.translator = TranslatorC(self.ir_arch.symbol_pool)
         self.init_arch_C()
 
     def gen_post_code(self, attrib):
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 276b796f..d53677be 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -240,11 +240,13 @@ def gen_jcc(ir, instr, cond, dst, jmp_if):
 
     e = []
     meip = mRIP[ir.IRDst.size]
-    next_lbl = m2_expr.ExprId(ir.get_next_label(instr), dst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, dst.size)
+
     if jmp_if:
-        dstA, dstB = dst, next_lbl
+        dstA, dstB = dst, loc_next_expr
     else:
-        dstA, dstB = next_lbl, dst
+        dstA, dstB = loc_next_expr, dst
     mn_dst = m2_expr.ExprCond(cond,
                               dstA.zeroExtend(ir.IRDst.size),
                               dstB.zeroExtend(ir.IRDst.size))
@@ -260,17 +262,18 @@ def gen_fcmov(ir, instr, cond, arg1, arg2, mov_if):
     @cond: condition
     @mov_if: invert condition if False"""
 
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_skip = ir.get_next_loc_key(instr)
+    loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size)
     if mov_if:
-        dstA, dstB = lbl_do, lbl_skip
+        dstA, dstB = loc_do_expr, loc_skip_expr
     else:
-        dstA, dstB = lbl_skip, lbl_do
+        dstA, dstB = loc_skip_expr, loc_do_expr
     e = []
     e_do, extra_irs = [m2_expr.ExprAff(arg1, arg2)], []
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr))
     e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(cond, dstA, dstB)))
-    return e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])]
+    return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])]
 
 
 def gen_cmov(ir, instr, cond, dst, src, mov_if):
@@ -280,17 +283,18 @@ def gen_cmov(ir, instr, cond, dst, src, mov_if):
     @cond: condition
     @mov_if: invert condition if False"""
 
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_skip = ir.get_next_loc_key(instr)
+    loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size)
     if mov_if:
-        dstA, dstB = lbl_do, lbl_skip
+        dstA, dstB = loc_do_expr, loc_skip_expr
     else:
-        dstA, dstB = lbl_skip, lbl_do
+        dstA, dstB = loc_skip_expr, loc_do_expr
     e = []
     e_do, extra_irs = mov(ir, instr, dst, src)
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr))
     e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(cond, dstA, dstB)))
-    return e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])]
+    return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])]
 
 
 def mov(_, instr, dst, src):
@@ -504,12 +508,14 @@ def _rotate_tpl(ir, instr, dst, src, op, left=False):
         else:
             return ([], [])
     e = []
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_skip = ir.get_next_loc_key(instr)
+    loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size)
+
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr))
     e.append(m2_expr.ExprAff(
-        ir.IRDst, m2_expr.ExprCond(shifter, lbl_do, lbl_skip)))
-    return (e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])])
+        ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr, loc_skip_expr)))
+    return (e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])])
 
 
 def l_rol(ir, instr, dst, src):
@@ -551,12 +557,14 @@ def rotate_with_carry_tpl(ir, instr, op, dst, src):
         else:
             return ([], [])
     e = []
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_skip = ir.get_next_loc_key(instr)
+    loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size)
+
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr))
     e.append(m2_expr.ExprAff(
-        ir.IRDst, m2_expr.ExprCond(shifter, lbl_do, lbl_skip)))
-    return (e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])])
+        ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr, loc_skip_expr)))
+    return (e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])])
 
 def rcl(ir, instr, dst, src):
     return rotate_with_carry_tpl(ir, instr, '<<<', dst, src)
@@ -638,12 +646,13 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False,
             return [], []
 
     e = []
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_skip = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
-    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, lbl_do,
-                                                        lbl_skip)))
-    return e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])]
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_skip = ir.get_next_loc_key(instr)
+    loc_skip_expr = m2_expr.ExprLoc(loc_skip, ir.IRDst.size)
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_skip_expr))
+    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(shifter, loc_do_expr,
+                                                        loc_skip_expr)))
+    return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)])]
 
 
 def sar(ir, instr, dst, src):
@@ -973,9 +982,9 @@ def bswap(_, instr, dst):
 
 
 def cmps(ir, instr, size):
-    lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     src1 = mRSI[instr.mode][:instr.v_admode()]
     src2 = mRDI[instr.mode][:instr.v_admode()]
@@ -999,24 +1008,24 @@ def cmps(ir, instr, size):
     e0 = []
     e0.append(m2_expr.ExprAff(src1, src1 + offset))
     e0.append(m2_expr.ExprAff(src2, src2 + offset))
-    e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)])
+    e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)])
 
     e1 = []
     e1.append(m2_expr.ExprAff(src1, src1 - offset))
     e1.append(m2_expr.ExprAff(src2, src2 - offset))
-    e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)])
+    e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)])
 
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(df, lbl_df_1, lbl_df_0)))
+                             m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr)))
     return e, [e0, e1]
 
 
 def scas(ir, instr, size):
-    lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     src = mRDI[instr.mode][:instr.v_admode()]
 
@@ -1036,16 +1045,16 @@ def scas(ir, instr, size):
     e0 = []
     e0.append(m2_expr.ExprAff(src, src + offset))
 
-    e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)])
+    e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)])
 
     e1 = []
     e1.append(m2_expr.ExprAff(src, src - offset))
-    e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)])
+    e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)])
 
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(df, lbl_df_1, lbl_df_0)))
+                             m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr)))
 
     return e, [e0, e1]
 
@@ -1185,7 +1194,7 @@ def call(ir, instr, dst):
     meip = mRIP[ir.IRDst.size]
     opmode, admode = s, instr.v_admode()
     myesp = mRSP[instr.mode][:opmode]
-    n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     if isinstance(dst, m2_expr.ExprOp):
         if dst.op == "segm":
@@ -1229,8 +1238,6 @@ def call(ir, instr, dst):
     e.append(m2_expr.ExprAff(ir.ExprMem(c, size=s), n))
     e.append(m2_expr.ExprAff(meip, dst.zeroExtend(ir.IRDst.size)))
     e.append(m2_expr.ExprAff(ir.IRDst, dst.zeroExtend(ir.IRDst.size)))
-    # if not expr_is_int_or_label(dst):
-    #    dst = meip
     return e, []
 
 
@@ -1432,7 +1439,7 @@ def loop(ir, instr, dst):
     admode = instr.v_admode()
     myecx = mRCX[instr.mode][:admode]
 
-    n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
     c = myecx - m2_expr.ExprInt(1, myecx.size)
     dst_o = m2_expr.ExprCond(c,
                              dst.zeroExtend(ir.IRDst.size),
@@ -1449,7 +1456,7 @@ def loopne(ir, instr, dst):
     admode = instr.v_admode()
     myecx = mRCX[instr.mode][:admode]
 
-    n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size),
                          m2_expr.ExprInt(1, 1),
@@ -1471,7 +1478,7 @@ def loope(ir, instr, dst):
     admode = instr.v_admode()
     myecx = mRCX[instr.mode][:admode]
 
-    n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    n = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
     c = m2_expr.ExprCond(myecx - m2_expr.ExprInt(1, size=myecx.size),
                          m2_expr.ExprInt(1, 1),
                          m2_expr.ExprInt(0, 1))
@@ -1508,24 +1515,25 @@ def div(ir, instr, src1):
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
 
-    lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_div, loc_div_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
 
     do_div = []
     do_div += e
-    do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)])
+    do_div.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    blk_div = IRBlock(loc_div, [AssignBlock(do_div, instr)])
 
     do_except = []
     do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt(
         EXCEPT_DIV_BY_ZERO, exception_flags.size)))
-    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)])
+    do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)])
 
     e = []
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(src1, lbl_div, lbl_except)))
+                             m2_expr.ExprCond(src1, loc_div_expr, loc_except_expr)))
 
     return e, [blk_div, blk_except]
 
@@ -1554,24 +1562,25 @@ def idiv(ir, instr, src1):
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
 
-    lbl_div = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_except = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_div, loc_div_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
 
     do_div = []
     do_div += e
-    do_div.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    blk_div = IRBlock(lbl_div.name, [AssignBlock(do_div, instr)])
+    do_div.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    blk_div = IRBlock(loc_div, [AssignBlock(do_div, instr)])
 
     do_except = []
     do_except.append(m2_expr.ExprAff(exception_flags, m2_expr.ExprInt(
         EXCEPT_DIV_BY_ZERO, exception_flags.size)))
-    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    blk_except = IRBlock(lbl_except.name, [AssignBlock(do_except, instr)])
+    do_except.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    blk_except = IRBlock(loc_except, [AssignBlock(do_except, instr)])
 
     e = []
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(src1, lbl_div, lbl_except)))
+                             m2_expr.ExprCond(src1, loc_div_expr, loc_except_expr)))
 
     return e, [blk_div, blk_except]
 
@@ -1713,9 +1722,9 @@ def cqo(_, instr):
 
 
 def stos(ir, instr, size):
-    lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     addr_o = mRDI[instr.mode][:instr.v_admode()]
     addr = addr_o
@@ -1732,25 +1741,25 @@ def stos(ir, instr, size):
 
     e0 = []
     e0.append(m2_expr.ExprAff(addr_o, addr_p))
-    e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)])
+    e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)])
 
     e1 = []
     e1.append(m2_expr.ExprAff(addr_o, addr_m))
-    e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)])
+    e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)])
 
     e = []
     e.append(m2_expr.ExprAff(ir.ExprMem(addr, size), b))
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(df, lbl_df_1, lbl_df_0)))
+                             m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr)))
     return e, [e0, e1]
 
 
 def lods(ir, instr, size):
-    lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
     e = []
 
     addr_o = mRSI[instr.mode][:instr.v_admode()]
@@ -1768,13 +1777,13 @@ def lods(ir, instr, size):
 
     e0 = []
     e0.append(m2_expr.ExprAff(addr_o, addr_p))
-    e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)])
+    e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)])
 
     e1 = []
     e1.append(m2_expr.ExprAff(addr_o, addr_m))
-    e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)])
+    e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)])
 
     e = []
     if instr.mode == 64 and b.size == 32:
@@ -1784,14 +1793,14 @@ def lods(ir, instr, size):
         e.append(m2_expr.ExprAff(b, ir.ExprMem(addr, size)))
 
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(df, lbl_df_1, lbl_df_0)))
+                             m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr)))
     return e, [e0, e1]
 
 
 def movs(ir, instr, size):
-    lbl_df_0 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_df_1 = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_df_0, loc_df_0_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_df_1, loc_df_1_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next_expr = m2_expr.ExprLoc(ir.get_next_loc_key(instr), ir.IRDst.size)
 
     dst = mRDI[instr.mode][:instr.v_admode()]
     src = mRSI[instr.mode][:instr.v_admode()]
@@ -1815,17 +1824,17 @@ def movs(ir, instr, size):
     e0 = []
     e0.append(m2_expr.ExprAff(src, src + offset))
     e0.append(m2_expr.ExprAff(dst, dst + offset))
-    e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e0 = IRBlock(lbl_df_0.name, [AssignBlock(e0, instr)])
+    e0.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e0 = IRBlock(loc_df_0, [AssignBlock(e0, instr)])
 
     e1 = []
     e1.append(m2_expr.ExprAff(src, src - offset))
     e1.append(m2_expr.ExprAff(dst, dst - offset))
-    e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    e1 = IRBlock(lbl_df_1.name, [AssignBlock(e1, instr)])
+    e1.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    e1 = IRBlock(loc_df_1, [AssignBlock(e1, instr)])
 
     e.append(m2_expr.ExprAff(ir.IRDst,
-                             m2_expr.ExprCond(df, lbl_df_1, lbl_df_0)))
+                             m2_expr.ExprCond(df, loc_df_1_expr, loc_df_0_expr)))
     return e, [e0, e1]
 
 
@@ -2876,14 +2885,15 @@ def bsr_bsf(ir, instr, dst, src, op_func):
         ZF = 0
         DEST = @op_func(SRC)
     """
-    lbl_src_null = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_src_not_null = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_src_null, loc_src_null_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_src_not_null, loc_src_not_null_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
 
-    aff_dst = m2_expr.ExprAff(ir.IRDst, lbl_next)
+    aff_dst = m2_expr.ExprAff(ir.IRDst, loc_next_expr)
     e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(src,
-                                                    lbl_src_not_null,
-                                                    lbl_src_null))]
+                                                    loc_src_not_null_expr,
+                                                    loc_src_null_expr))]
     e_src_null = []
     e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt(1, zf.size)))
     # XXX destination is undefined
@@ -2894,8 +2904,8 @@ def bsr_bsf(ir, instr, dst, src, op_func):
     e_src_not_null.append(m2_expr.ExprAff(dst, op_func(src)))
     e_src_not_null.append(aff_dst)
 
-    return e, [IRBlock(lbl_src_null.name, [AssignBlock(e_src_null, instr)]),
-               IRBlock(lbl_src_not_null.name, [AssignBlock(e_src_not_null, instr)])]
+    return e, [IRBlock(loc_src_null, [AssignBlock(e_src_null, instr)]),
+               IRBlock(loc_src_not_null, [AssignBlock(e_src_not_null, instr)])]
 
 
 def bsf(ir, instr, dst, src):
@@ -3925,9 +3935,10 @@ def pshufd(_, instr, dst, src, imm):
 
 
 def ps_rl_ll(ir, instr, dst, src, op, size):
-    lbl_zero = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_do = m2_expr.ExprId(ir.gen_label(), ir.IRDst.size)
-    lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
+    loc_zero, loc_zero_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_do, loc_do_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
 
     if src.size == 8:
         count = src.zeroExtend(dst.size)
@@ -3940,8 +3951,8 @@ def ps_rl_ll(ir, instr, dst, src, op, size):
     test = expr_simp(count & m2_expr.ExprInt(
         ((1 << dst.size) - 1) ^ mask, dst.size))
     e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(test,
-                                                    lbl_zero,
-                                                    lbl_do))]
+                                                    loc_zero_expr,
+                                                    loc_do_expr))]
 
     slices = []
     for i in xrange(0, dst.size, size):
@@ -3954,12 +3965,12 @@ def ps_rl_ll(ir, instr, dst, src, op, size):
             return [m2_expr.ExprAff(dst, m2_expr.ExprInt(0, dst.size))], []
 
     e_zero = [m2_expr.ExprAff(dst, m2_expr.ExprInt(0, dst.size)),
-              m2_expr.ExprAff(ir.IRDst, lbl_next)]
+              m2_expr.ExprAff(ir.IRDst, loc_next_expr)]
     e_do = []
     e.append(m2_expr.ExprAff(dst[0:dst.size], m2_expr.ExprCompose(*slices)))
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
-    return e, [IRBlock(lbl_do.name, [AssignBlock(e_do, instr)]),
-               IRBlock(lbl_zero.name, [AssignBlock(e_zero, instr)])]
+    e_do.append(m2_expr.ExprAff(ir.IRDst, loc_next_expr))
+    return e, [IRBlock(loc_do, [AssignBlock(e_do, instr)]),
+               IRBlock(loc_zero, [AssignBlock(e_zero, instr)])]
 
 
 def psrlw(ir, instr, dst, src):
@@ -4463,7 +4474,8 @@ 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)
+    loc_next = ir.get_next_loc_key(instr)
+    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)
     blks = []
 
     # For each possibility, check if a write is necessary
@@ -4477,32 +4489,32 @@ def maskmovq(ir, instr, src, mask):
     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
+        next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr
         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)]))
+        blks.append(IRBlock(cur_label.name.loc_key, [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
+        next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else loc_next_expr
         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)]))
+        blks.append(IRBlock(cur_label.name.loc_key, [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))]
+                                                    loc_next_expr))]
     return e, blks
 
 
@@ -5145,13 +5157,15 @@ class ir_x86_16(IntermediateRepresentation):
             c_cond = cond_dec | (zf ^ m2_expr.ExprInt(1, 1))
 
         # gen while
-        lbl_do = m2_expr.ExprId(self.gen_label(), self.IRDst.size)
-        lbl_end = m2_expr.ExprId(self.gen_label(), self.IRDst.size)
-        lbl_skip = m2_expr.ExprId(self.get_next_label(instr), self.IRDst.size)
-        lbl_next = m2_expr.ExprId(self.get_next_label(instr), self.IRDst.size)
-
-        fix_next_lbl = {lbl_next: lbl_end}
-        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fix_next_lbl))
+        loc_do, loc_do_expr = self.gen_loc_key_and_expr(self.IRDst.size)
+        loc_end, loc_end_expr = self.gen_loc_key_and_expr(self.IRDst.size)
+        loc_skip = self.get_next_loc_key(instr)
+        loc_skip_expr = m2_expr.ExprLoc(loc_skip, self.IRDst.size)
+        loc_next = self.get_next_loc_key(instr)
+        loc_next_expr = m2_expr.ExprLoc(loc_next, self.IRDst.size)
+
+        fix_next_loc = {loc_next_expr: loc_end_expr}
+        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fix_next_loc))
                         for irblock in extra_ir]
 
         cond_bloc = []
@@ -5159,14 +5173,14 @@ class ir_x86_16(IntermediateRepresentation):
                                          c_reg - m2_expr.ExprInt(1,
                                                                  c_reg.size)))
         cond_bloc.append(m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_cond,
-                                                                      lbl_skip,
-                                                                      lbl_do)))
-        cond_bloc = IRBlock(lbl_end.name, [AssignBlock(cond_bloc, instr)])
+                                                                      loc_skip_expr,
+                                                                      loc_do_expr)))
+        cond_bloc = IRBlock(loc_end, [AssignBlock(cond_bloc, instr)])
         e_do = instr_ir
 
-        c = IRBlock(lbl_do.name, [AssignBlock(e_do, instr)])
-        e_n = [m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_reg, lbl_do,
-                                                            lbl_skip))]
+        c = IRBlock(loc_do, [AssignBlock(e_do, instr)])
+        e_n = [m2_expr.ExprAff(self.IRDst, m2_expr.ExprCond(c_reg, loc_do_expr,
+                                                            loc_skip_expr))]
         return e_n, [cond_bloc, c] + new_extra_ir
 
     def expr_fix_regs_for_mode(self, e, mode=64):
@@ -5195,7 +5209,7 @@ class ir_x86_16(IntermediateRepresentation):
                 src = self.expr_fix_regs_for_mode(src, mode)
                 new_assignblk[dst] = src
             irs.append(AssignBlock(new_assignblk, assignblk.instr))
-        return IRBlock(irblock.label, irs)
+        return IRBlock(irblock.loc_key, irs)
 
 
 class ir_x86_32(ir_x86_16):