about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2020-04-03 10:16:25 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2020-04-03 11:56:59 +0200
commit95b24655c797f5b4f96c8834ad6ef2f21748699c (patch)
treea1983268549523fcc94376ee53ebfa4cb2c42f42
parent1d5127036dc7e1688c102c5781a6618b5dd27f16 (diff)
downloadmiasm-95b24655c797f5b4f96c8834ad6ef2f21748699c.tar.gz
miasm-95b24655c797f5b4f96c8834ad6ef2f21748699c.zip
Use int(expr) instead of expr.arg.arg
-rw-r--r--miasm/arch/aarch64/arch.py28
-rw-r--r--miasm/arch/aarch64/sem.py12
-rw-r--r--miasm/arch/arm/arch.py16
-rw-r--r--miasm/arch/msp430/arch.py2
-rw-r--r--miasm/arch/ppc/arch.py22
-rw-r--r--miasm/arch/x86/arch.py2
-rw-r--r--miasm/arch/x86/sem.py6
-rw-r--r--miasm/core/asmblock.py6
-rw-r--r--miasm/core/cpu.py12
-rw-r--r--miasm/core/objc.py5
-rw-r--r--miasm/core/parse_asm.py4
-rw-r--r--miasm/expression/expression.py26
-rw-r--r--miasm/expression/simplifications_common.py55
-rw-r--r--miasm/ir/ir.py24
-rw-r--r--miasm/ir/translators/C.py7
-rw-r--r--miasm/jitter/codegen.py8
-rw-r--r--miasm/jitter/emulatedsymbexec.py8
-rwxr-xr-xtest/arch/msp430/sem.py6
-rwxr-xr-xtest/arch/x86/sem.py6
19 files changed, 152 insertions, 103 deletions
diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py
index 10e94517..464d7eff 100644
--- a/miasm/arch/aarch64/arch.py
+++ b/miasm/arch/aarch64/arch.py
@@ -330,19 +330,19 @@ class instruction_aarch64(instruction):
             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:
+            if int(expr.args[1]) != 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 == "preinc_wb":
-            if expr.args[1].arg != 0:
+            if int(expr.args[1]) != 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 == "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:
+            elif not isinstance(expr.args[1], m2_expr.ExprInt) or int(expr.args[1]) != 0:
                 return "[%s, %s]" % (expr.args[0], expr.args[1])
             else:
                 return "[%s]" % (expr.args[0])
@@ -350,7 +350,7 @@ class instruction_aarch64(instruction):
             arg = expr.args[1]
             if isinstance(arg, m2_expr.ExprId):
                 arg = str(arg)
-            elif arg.op == 'LSL' and arg.args[1].arg == 0:
+            elif arg.op == 'LSL' and int(arg.args[1]) == 0:
                 arg = str(arg.args[0])
             else:
                 arg = "%s %s %s" % (arg.args[0], arg.op, arg.args[1])
@@ -375,7 +375,7 @@ class instruction_aarch64(instruction):
         expr = self.args[index]
         if not expr.is_int():
             return
-        addr = expr.arg + self.offset
+        addr = (int(expr) + self.offset) & 0xFFFFFFFFFFFFFFFF
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[index] = m2_expr.ExprLoc(loc_key, expr.size)
 
@@ -403,7 +403,7 @@ class instruction_aarch64(instruction):
         if not isinstance(e, m2_expr.ExprInt):
             log.debug('dyn dst %r', e)
             return
-        off = e.arg - self.offset
+        off = (int(e) + 0x10000000000000000 - self.offset) & 0xFFFFFFFFFFFFFFFF
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[index] = m2_expr.ExprInt(int(off), 64)
@@ -643,7 +643,7 @@ class aarch64_gpreg0(bsi, aarch64_arg):
 
     def encode(self):
         if isinstance(self.expr, m2_expr.ExprInt):
-            if self.expr.arg == 0:
+            if int(self.expr) == 0:
                 self.value = 0x1F
                 return True
             return False
@@ -793,7 +793,7 @@ def set_imm_to_size(size, expr):
     if size > expr.size:
         expr = m2_expr.ExprInt(int(expr), size)
     else:
-        if expr.arg > (1 << size) - 1:
+        if int(expr) > (1 << size) - 1:
             return None
         expr = m2_expr.ExprInt(int(expr), size)
     return expr
@@ -954,11 +954,11 @@ class aarch64_gpreg_ext2(reg_noarg, aarch64_arg):
         if arg1.op not in EXT2_OP_INV:
             return False
         self.parent.option.value = EXT2_OP_INV[arg1.op]
-        if arg1.args[1].arg == 0:
+        if int(arg1.args[1]) == 0:
             self.parent.shift.value = 0
             return True
 
-        if arg1.args[1].arg != self.get_size():
+        if int(arg1.args[1]) != self.get_size():
             return False
 
         self.parent.shift.value = 1
@@ -1273,7 +1273,7 @@ class aarch64_imm_nsr(aarch64_imm_sf, aarch64_arg):
             return False
         if not test_set_sf(self.parent, self.expr.size):
             return False
-        value = self.expr.arg
+        value = int(self.expr)
         if value == 0:
             return False
 
@@ -1376,7 +1376,7 @@ class aarch64_imm_hw_sc(aarch64_arg):
 
     def encode(self):
         if isinstance(self.expr, m2_expr.ExprInt):
-            if self.expr.arg > 0xFFFF:
+            if int(self.expr) > 0xFFFF:
                 return False
             self.value = int(self.expr)
             self.parent.hw.value = 0
@@ -1498,7 +1498,7 @@ class aarch64_deref(aarch64_arg):
 
     def decode(self, v):
         reg = gpregs64_info.expr[v]
-        off = self.parent.imm.expr.arg
+        off = int(self.parent.imm.expr)
         op = self.get_postpre(self.parent)
         off = self.decode_w_size(off)
         self.expr = m2_expr.ExprOp(op, reg, m2_expr.ExprInt(off, 64))
@@ -1568,7 +1568,7 @@ class aarch64_deref_nooff(aarch64_deref):
             reg, off = expr.args
             if not isinstance(off, m2_expr.ExprInt):
                 return False
-            if off.arg != 0:
+            if int(off) != 0:
                 return False
         else:
             return False
diff --git a/miasm/arch/aarch64/sem.py b/miasm/arch/aarch64/sem.py
index e9088bde..2761aed4 100644
--- a/miasm/arch/aarch64/sem.py
+++ b/miasm/arch/aarch64/sem.py
@@ -401,7 +401,7 @@ def movk(ir, instr, arg1, arg2):
         assert(arg2.op == 'slice_at' and
                isinstance(arg2.args[0], ExprInt) and
                isinstance(arg2.args[1], ExprInt))
-        value, shift = int(arg2.args[0].arg), int(arg2.args[1])
+        value, shift = int(arg2.args[0]), int(arg2.args[1])
         e.append(
             ExprAssign(arg1[shift:shift + 16], ExprInt(value, 16)))
     else:
@@ -434,7 +434,7 @@ def csel(arg1, arg2, arg3, arg4):
 def ccmp(ir, instr, arg1, arg2, arg3, arg4):
     e = []
     if(arg2.is_int()):
-        arg2=ExprInt(arg2.arg.arg,arg1.size)
+        arg2=ExprInt(int(arg2),arg1.size)
     default_nf = arg3[0:1]
     default_zf = arg3[1:2]
     default_cf = arg3[2:3]
@@ -697,7 +697,7 @@ def ldp(ir, instr, arg1, arg2, arg3):
 
 def sbfm(ir, instr, arg1, arg2, arg3, arg4):
     e = []
-    rim, sim = int(arg3.arg), int(arg4) + 1
+    rim, sim = int(arg3), int(arg4) + 1
     if sim > rim:
         res = arg2[rim:sim].signExtend(arg1.size)
     else:
@@ -709,7 +709,7 @@ def sbfm(ir, instr, arg1, arg2, arg3, arg4):
 
 def ubfm(ir, instr, arg1, arg2, arg3, arg4):
     e = []
-    rim, sim = int(arg3.arg), int(arg4) + 1
+    rim, sim = int(arg3), int(arg4) + 1
     if sim != arg1.size - 1 and rim == sim:
         # Simple case: lsl
         value = int(rim)
@@ -733,7 +733,7 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4):
 
 def bfm(ir, instr, arg1, arg2, arg3, arg4):
     e = []
-    rim, sim = int(arg3.arg), int(arg4) + 1
+    rim, sim = int(arg3), int(arg4) + 1
     if sim > rim:
         res = arg2[rim:sim]
         e.append(ExprAssign(arg1[:sim-rim], res))
@@ -1038,7 +1038,7 @@ def rev16(ir, instr, arg1, arg2):
 @sbuild.parse
 def extr(arg1, arg2, arg3, arg4):
     compose = ExprCompose(arg2, arg3)
-    arg1 = compose[int(arg4.arg):int(arg4)+arg1.size]
+    arg1 = compose[int(arg4):int(arg4)+arg1.size]
 
 
 @sbuild.parse
diff --git a/miasm/arch/arm/arch.py b/miasm/arch/arm/arch.py
index fc6a0527..4aac13c6 100644
--- a/miasm/arch/arm/arch.py
+++ b/miasm/arch/arm/arch.py
@@ -437,9 +437,9 @@ class instruction_arm(instruction):
         if not isinstance(expr, ExprInt):
             return
         if self.name == 'BLX':
-            addr = expr.arg + self.offset
+            addr = (expr.arg + self.offset) & 0xFFFFFFFF
         else:
-            addr = expr.arg + self.offset
+            addr = (expr.arg + self.offset) & 0xFFFFFFFF
         loc_key = loc_db.get_or_create_offset_location(addr)
         self.args[0] = ExprLoc(loc_key, expr.size)
 
@@ -481,7 +481,7 @@ class instruction_arm(instruction):
         if not isinstance(e, ExprInt):
             log.debug('dyn dst %r', e)
             return
-        off = e.arg - self.offset
+        off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF
         if int(off % 4):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
@@ -516,13 +516,13 @@ class instruction_armt(instruction_arm):
         if self.name == 'BLX':
             addr = expr.arg + (self.offset & 0xfffffffc)
         elif self.name == 'BL':
-            addr = expr.arg + self.offset
+            addr = (expr.arg + self.offset) & 0xFFFFFFFF
         elif self.name.startswith('BP'):
-            addr = expr.arg + self.offset
+            addr = (expr.arg + self.offset) & 0xFFFFFFFF
         elif self.name.startswith('CB'):
-            addr = expr.arg + self.offset + self.l + 2
+            addr = (expr.arg + self.offset + self.l + 2) & 0xFFFFFFFF
         else:
-            addr = expr.arg + self.offset
+            addr = (expr.arg + self.offset) & 0xFFFFFFFF
 
         loc_key = loc_db.get_or_create_offset_location(addr)
         dst = ExprLoc(loc_key, expr.size)
@@ -564,7 +564,7 @@ class instruction_armt(instruction_arm):
         # The first +2 is to compensate instruction len, but strangely, 32 bits
         # thumb2 instructions len is 2... For the second +2, didn't find it in
         # the doc.
-        off = e.arg - self.offset
+        off = (e.arg + 0x100000000 - self.offset) & 0xFFFFFFFF
         if int(off % 2):
             raise ValueError('strange offset! %r' % off)
         self.args[0] = ExprInt(off, 32)
diff --git a/miasm/arch/msp430/arch.py b/miasm/arch/msp430/arch.py
index a700b04a..93854153 100644
--- a/miasm/arch/msp430/arch.py
+++ b/miasm/arch/msp430/arch.py
@@ -64,7 +64,7 @@ class msp430_arg(m_arg):
     def asm_ast_to_expr(self, value, loc_db):
         if isinstance(value, AstId):
             name = value.name
-            if isinstance(name, Expr):
+            if is_expr(name):
                 return name
             assert isinstance(name, str)
             if name in gpregs.str:
diff --git a/miasm/arch/ppc/arch.py b/miasm/arch/ppc/arch.py
index 29550931..8cd0181c 100644
--- a/miasm/arch/ppc/arch.py
+++ b/miasm/arch/ppc/arch.py
@@ -129,9 +129,9 @@ class instruction_ppc(instruction):
             if not isinstance(e, ExprInt):
                 return
             if name[-1] != 'A':
-                ad = e.arg + self.offset
+                ad = (int(e) + self.offset) & 0xFFFFFFFF
             else:
-                ad = e.arg
+                ad = int(e)
             loc_key = loc_db.get_or_create_offset_location(ad)
             s = ExprLoc(loc_key, e.size)
             self.args[address_index] = s
@@ -175,11 +175,11 @@ class instruction_ppc(instruction):
         if self.name[-1] != 'A':
             if self.offset is None:
                 raise ValueError('symbol not resolved %s' % self.l)
-            off = e.arg - (self.offset + self.l)
+            off = (int(e) + 0x100000000 - (self.offset + self.l)) & 0xFFFFFFFF
             if int(off % 4):
                 raise ValueError('Offset %r must be a multiple of four' % off)
         else:
-            off = e.arg
+            off = int(e)
         self.args[0] = ExprInt(off, 32)
 
     def get_args_expr(self):
@@ -343,7 +343,7 @@ class ppc_s14imm_branch(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x3:
             return False
         v = v >> 2
@@ -362,7 +362,7 @@ class ppc_s24imm_branch(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & 0x3:
             return False
         v = v >> 2
@@ -381,7 +381,7 @@ class ppc_s16imm(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if sign_ext(v & self.lmask, 16, 32) != v:
             return False
         self.value = v & self.lmask
@@ -398,7 +398,7 @@ class ppc_u16imm(ppc_imm):
     def encode(self):
         if not isinstance(self.expr, ExprInt):
             return False
-        v = self.expr.arg.arg
+        v = int(self.expr)
         if v & self.lmask != v:
             return False
         self.value = v & self.lmask
@@ -416,7 +416,7 @@ class ppc_spr(ppc_imm):
     def encode(self, e):
         if not isinstance(e, ExprInt):
             return False
-        self.value = ppc_swap_10(e.arg)
+        self.value = ppc_swap_10(int(e))
         return True
 
 class ppc_tbr(ppc_imm):
@@ -428,7 +428,7 @@ class ppc_tbr(ppc_imm):
     def encode(self, e):
         if not isinstance(e, ExprInt):
             return False
-        self.value = ppc_swap_10(e.arg)
+        self.value = ppc_swap_10(int(e))
         return True
 
 class ppc_u08imm(ppc_u16imm):
@@ -520,7 +520,7 @@ class ppc_deref32(ppc_arg):
         if len(addr.args) != 2:
             return False
         reg, disp = addr.args[0], addr.args[1]
-        v = int(disp.arg)
+        v = int(disp)
         if sign_ext(v & 0xFFFF, 16, 32) != v:
             return False
         v &= 0xFFFF
diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py
index 33b41236..52ea1663 100644
--- a/miasm/arch/x86/arch.py
+++ b/miasm/arch/x86/arch.py
@@ -278,7 +278,7 @@ class x86_arg(m_arg):
             if value.name in ["FAR"]:
                 return None
 
-            loc_key = loc_db.get_or_create_name_location(value.name.encode())
+            loc_key = loc_db.get_or_create_name_location(value.name)
             return ExprLoc(loc_key, size_hint)
         if isinstance(value, AstOp):
             # First pass to retrieve fixed_size
diff --git a/miasm/arch/x86/sem.py b/miasm/arch/x86/sem.py
index fdb4efd6..b0fcd054 100644
--- a/miasm/arch/x86/sem.py
+++ b/miasm/arch/x86/sem.py
@@ -3387,9 +3387,11 @@ def icebp(_, instr):
 def l_int(_, instr, src):
     e = []
     # XXX
-    if src.arg == 1:
+    assert src.is_int()
+    value = int(src)
+    if value == 1:
         except_int = EXCEPT_INT_1
-    elif src.arg == 3:
+    elif value == 3:
         except_int = EXCEPT_SOFT_BP
     else:
         except_int = EXCEPT_INT_XX
diff --git a/miasm/core/asmblock.py b/miasm/core/asmblock.py
index 8f47947f..abd2b2c6 100644
--- a/miasm/core/asmblock.py
+++ b/miasm/core/asmblock.py
@@ -960,7 +960,9 @@ def fix_loc_offset(loc_db, loc_key, offset, modified):
     loc_offset = loc_db.get_location_offset(loc_key)
     if loc_offset == offset:
         return
-    loc_db.set_location_offset(loc_key, offset, force=True)
+    if loc_offset is not None:
+        loc_db.unset_location_offset(loc_key)
+    loc_db.set_location_offset(loc_key, offset)
     modified.add(loc_key)
 
 
@@ -1209,7 +1211,7 @@ def assemble_block(mnemo, block, loc_db, conservative=False):
                 data = b""
                 for expr in instr.raw:
                     expr_int = fix_expr_val(expr, loc_db)
-                    data += pck[expr_int.size](expr_int.arg)
+                    data += pck[expr_int.size](int(expr_int))
                 instr.data = data
 
             instr.offset = offset_i
diff --git a/miasm/core/cpu.py b/miasm/core/cpu.py
index 3dc7bd68..ec8d95bc 100644
--- a/miasm/core/cpu.py
+++ b/miasm/core/cpu.py
@@ -1587,16 +1587,8 @@ class imm_noarg(object):
         if e == [None]:
             return None, None
 
-        assert(isinstance(e, m2_expr.Expr))
-        if isinstance(e, tuple):
-            self.expr = self.int2expr(e[1])
-        elif isinstance(e, m2_expr.Expr):
-            self.expr = e
-        else:
-            raise TypeError('zarb expr')
-        if self.expr is None:
-            log.debug('cannot fromstring int %r', text)
-            return None, None
+        assert(m2_expr.is_expr(e))
+        self.expr = e
         return start, stop
 
     def decodeval(self, v):
diff --git a/miasm/core/objc.py b/miasm/core/objc.py
index 123d339a..117e3b7d 100644
--- a/miasm/core/objc.py
+++ b/miasm/core/objc.py
@@ -14,7 +14,8 @@ from functools import total_ordering
 
 from miasm.core.utils import cmp_elts
 from miasm.expression.expression_reduce import ExprReducer
-from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem
+from miasm.expression.expression import ExprInt, ExprId, ExprOp, ExprMem, \
+    is_op_segm
 
 from miasm.core.ctypesmngr import CTypeUnion, CTypeStruct, CTypeId, CTypePtr,\
     CTypeArray, CTypeOp, CTypeSizeof, CTypeEnum, CTypeFunc, CTypeEllipsis
@@ -1045,7 +1046,7 @@ class ExprToAccessC(ExprReducer):
 
     def reduce_op(self, node, lvl=0, **kwargs):
         """Generate access for ExprOp"""
-        if not (node.expr.is_op("+") or node.expr.is_op_segm()) \
+        if not (node.expr.is_op("+") or is_op_segm(node.expr)) \
            or len(node.args) != 2:
             return None
         type_arg1 = self.get_solo_type(node.args[1])
diff --git a/miasm/core/parse_asm.py b/miasm/core/parse_asm.py
index 2b4f1195..b742a2d2 100644
--- a/miasm/core/parse_asm.py
+++ b/miasm/core/parse_asm.py
@@ -65,7 +65,7 @@ def guess_next_new_label(loc_db):
     """Generate a new label
     @loc_db: the LocationDB instance"""
     i = 0
-    gen_name = b"loc_%.8X"
+    gen_name = "loc_%.8X"
     while True:
         name = gen_name % i
         label = loc_db.get_name_location(name)
@@ -121,7 +121,7 @@ def parse_txt(mnemo, attrib, txt, loc_db=None):
         # label beginning with .L
         match_re = LABEL_RE.match(line)
         if match_re:
-            label_name = match_re.group(1).encode()
+            label_name = match_re.group(1)
             label = loc_db.get_or_create_name_location(label_name)
             lines.append(label)
             continue
diff --git a/miasm/expression/expression.py b/miasm/expression/expression.py
index 9ac631fa..d6813cec 100644
--- a/miasm/expression/expression.py
+++ b/miasm/expression/expression.py
@@ -140,6 +140,32 @@ class DiGraphExpr(DiGraph):
 
         return ""
 
+def is_expr(expr):
+    return isinstance(
+        expr,
+        (
+            ExprInt, ExprId, ExprMem,
+            ExprSlice, ExprCompose, ExprCond,
+            ExprLoc, ExprOp
+        )
+    )
+
+def is_associative(expr):
+    "Return True iff current operation is associative"
+    return (expr.op in ['+', '*', '^', '&', '|'])
+
+def is_commutative(expr):
+    "Return True iff current operation is commutative"
+    return (expr.op in ['+', '*', '^', '&', '|'])
+
+def is_op_segm(expr):
+    """Returns True if is ExprOp and op == 'segm'"""
+    return expr.is_op('segm')
+
+def is_mem_segm(expr):
+    """Returns True if is ExprMem and ptr is_op_segm"""
+    return expr.is_mem() and is_op_segm(expr.ptr)
+
 
 @total_ordering
 class LocKey(object):
diff --git a/miasm/expression/simplifications_common.py b/miasm/expression/simplifications_common.py
index 38859f3a..2b69ed0e 100644
--- a/miasm/expression/simplifications_common.py
+++ b/miasm/expression/simplifications_common.py
@@ -32,29 +32,29 @@ def simp_cst_propagation(e_s, expr):
             int2 = args.pop()
             int1 = args.pop()
             if op_name == '+':
-                out = int1.arg + int2.arg
+                out = mod_size2uint[int1.size](int(int1) + int(int2))
             elif op_name == '*':
-                out = int1.arg * int2.arg
+                out = mod_size2uint[int1.size](int(int1) * int(int2))
             elif op_name == '**':
-                out =int1.arg ** int2.arg
+                out = mod_size2uint[int1.size](int(int1) ** int(int2))
             elif op_name == '^':
-                out = int1.arg ^ int2.arg
+                out = mod_size2uint[int1.size](int(int1) ^ int(int2))
             elif op_name == '&':
-                out = int1.arg & int2.arg
+                out = mod_size2uint[int1.size](int(int1) & int(int2))
             elif op_name == '|':
-                out = int1.arg | int2.arg
+                out = mod_size2uint[int1.size](int(int1) | int(int2))
             elif op_name == '>>':
                 if int(int2) > int1.size:
                     out = 0
                 else:
-                    out = int1.arg >> int2.arg
+                    out = mod_size2uint[int1.size](int(int1) >> int(int2))
             elif op_name == '<<':
                 if int(int2) > int1.size:
                     out = 0
                 else:
-                    out = int1.arg << int2.arg
+                    out = mod_size2uint[int1.size](int(int1) << int(int2))
             elif op_name == 'a>>':
-                tmp1 = mod_size2int[int1.arg.size](int1.arg)
+                tmp1 = mod_size2int[int1.size](int1.arg)
                 tmp2 = mod_size2uint[int2.arg.size](int2.arg)
                 if tmp2 > int1.size:
                     is_signed = int(int1) & (1 << (int1.size - 1))
@@ -63,7 +63,7 @@ def simp_cst_propagation(e_s, expr):
                     else:
                         out = 0
                 else:
-                    out = mod_size2uint[int1.arg.size](tmp1 >> tmp2)
+                    out = mod_size2uint[int1.size](tmp1 >> tmp2)
             elif op_name == '>>>':
                 shifter = int2.arg % int2.size
                 out = (int1.arg >> shifter) | (int1.arg << (int2.size - shifter))
@@ -76,28 +76,28 @@ def simp_cst_propagation(e_s, expr):
                 out = int1.arg % int2.arg
             elif op_name == 'sdiv':
                 assert int2.arg.arg
-                tmp1 = mod_size2int[int1.arg.size](int1.arg)
+                tmp1 = mod_size2int[int1.size](int1.arg)
                 tmp2 = mod_size2int[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 // tmp2)
+                out = mod_size2uint[int1.size](tmp1 // tmp2)
             elif op_name == 'smod':
                 assert int2.arg.arg
-                tmp1 = mod_size2int[int1.arg.size](int1.arg)
+                tmp1 = mod_size2int[int1.size](int1.arg)
                 tmp2 = mod_size2int[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 % tmp2)
+                out = mod_size2uint[int1.size](tmp1 % tmp2)
             elif op_name == 'umod':
                 assert int2.arg.arg
-                tmp1 = mod_size2uint[int1.arg.size](int1.arg)
+                tmp1 = mod_size2uint[int1.size](int1.arg)
                 tmp2 = mod_size2uint[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 % tmp2)
+                out = mod_size2uint[int1.size](tmp1 % tmp2)
             elif op_name == 'udiv':
                 assert int2.arg.arg
-                tmp1 = mod_size2uint[int1.arg.size](int1.arg)
+                tmp1 = mod_size2uint[int1.size](int1.arg)
                 tmp2 = mod_size2uint[int2.arg.size](int2.arg)
-                out = mod_size2uint[int1.arg.size](tmp1 // tmp2)
+                out = mod_size2uint[int1.size](tmp1 // tmp2)
 
 
 
-            args.append(ExprInt(out, int1.size))
+            args.append(ExprInt(int(out), int1.size))
 
     # cnttrailzeros(int) => int
     if op_name == "cnttrailzeros" and args[0].is_int():
@@ -120,6 +120,7 @@ def simp_cst_propagation(e_s, expr):
         len(args[0].args) == 1):
         return args[0].args[0]
 
+
     # -(int) => -int
     if op_name == '-' and len(args) == 1 and args[0].is_int():
         return ExprInt(-int(args[0]), expr.size)
@@ -207,13 +208,13 @@ def simp_cst_propagation(e_s, expr):
             j += 1
         i += 1
 
-    if op_name in ['|', '&', '%', '/', '**'] and len(args) == 1:
+    if op_name in ['+', '^', '|', '&', '%', '/', '**'] and len(args) == 1:
         return args[0]
 
     # A <<< A.size => A
     if (op_name in ['<<<', '>>>'] and
         args[1].is_int() and
-        args[1].arg == args[0].size):
+        int(args[1]) == args[0].size):
         return args[0]
 
     # (A <<< X) <<< Y => A <<< (X+Y) (or <<< >>>) if X + Y does not overflow
@@ -277,7 +278,10 @@ def simp_cst_propagation(e_s, expr):
 
     # ((A & A.mask)
     if op_name == "&" and args[-1] == expr.mask:
-        return ExprOp('&', *args[:-1])
+        args = args[:-1]
+        if len(args) == 1:
+            return args[0]
+        return ExprOp('&', *args)
 
     # ((A | A.mask)
     if op_name == "|" and args[-1] == expr.mask:
@@ -289,7 +293,7 @@ def simp_cst_propagation(e_s, expr):
     # ((A & mask) >> shift) with mask < 2**shift => 0
     if op_name == ">>" and args[1].is_int() and args[0].is_op("&"):
         if (args[0].args[1].is_int() and
-            2 ** args[1].arg > args[0].args[1].arg):
+            2 ** int(args[1]) > int(args[0].args[1])):
             return ExprInt(0, args[0].size)
 
     # parity(int) => int
@@ -315,7 +319,6 @@ def simp_cst_propagation(e_s, expr):
         args = args[0].args
         return ExprOp('*', *(list(args[:-1]) + [ExprInt(-int(args[-1]), expr.size)]))
 
-
     # A << int with A ExprCompose => move index
     if (op_name == "<<" and args[0].is_compose() and
         args[1].is_int() and int(args[1]) != 0):
@@ -471,7 +474,7 @@ def simp_slice(e_s, expr):
     if expr.arg.is_int():
         total_bit = expr.stop - expr.start
         mask = (1 << (expr.stop - expr.start)) - 1
-        return ExprInt(int((expr.arg.arg >> expr.start) & mask), total_bit)
+        return ExprInt(int((int(expr.arg) >> expr.start) & mask), total_bit)
     # Slice(Slice(A, x), y) => Slice(A, z)
     if expr.arg.is_slice():
         if expr.stop - expr.start > expr.arg.stop - expr.arg.start:
@@ -626,7 +629,7 @@ def simp_cond(_, expr):
         expr = expr.src1
     # int ? A:B => A or B
     elif expr.cond.is_int():
-        if expr.cond.arg == 0:
+        if int(expr.cond) == 0:
             expr = expr.src2
         else:
             expr = expr.src1
diff --git a/miasm/ir/ir.py b/miasm/ir/ir.py
index 613a4bce..9b2e4ba0 100644
--- a/miasm/ir/ir.py
+++ b/miasm/ir/ir.py
@@ -44,6 +44,26 @@ def _expr_loc_to_symb(expr, loc_db):
             name = sorted(names)[0]
     return m2_expr.ExprId(name, expr.size)
 
+def slice_rest(expr):
+    "Return the completion of the current slice"
+    size = expr.arg.size
+    if expr.start >= size or expr.stop > size:
+        raise ValueError('bad slice rest %s %s %s' %
+                         (size, expr.start, expr.stop))
+
+    if expr.start == expr.stop:
+        return [(0, size)]
+
+    rest = []
+    if expr.start != 0:
+        rest.append((0, expr.start))
+    if expr.stop < size:
+        rest.append((expr.stop, size))
+
+    return rest
+
+
+
 class AssignBlock(object):
     """Represent parallel IR assignment, such as:
     EAX = EBX
@@ -99,7 +119,7 @@ class AssignBlock(object):
             # Complete the source with missing slice parts
             new_dst = dst.arg
             rest = [(m2_expr.ExprSlice(dst.arg, r[0], r[1]), r[0], r[1])
-                    for r in dst.slice_rest()]
+                    for r in slice_rest(dst)]
             all_a = [(src, dst.start, dst.stop)] + rest
             all_a.sort(key=lambda x: x[1])
             args = [expr for (expr, _, _) in all_a]
@@ -752,7 +772,7 @@ class IntermediateRepresentation(object):
 
         if loc_key is None:
             offset = getattr(instr, "offset", None)
-            loc_key = self.loc_db.add_location(offset=offset)
+            loc_key = self.loc_db.get_or_create_offset_location(offset)
         block = AsmBlock(loc_key)
         block.lines = [instr]
         self.add_asmblock_to_ircfg(block, ircfg, gen_pc_updt)
diff --git a/miasm/ir/translators/C.py b/miasm/ir/translators/C.py
index 6be5d961..7778abf7 100644
--- a/miasm/ir/translators/C.py
+++ b/miasm/ir/translators/C.py
@@ -3,7 +3,8 @@ from miasm.expression.modint import size2mask
 from miasm.expression.expression import ExprInt, ExprCond, ExprCompose, \
     TOK_EQUAL, \
     TOK_INF_SIGNED, TOK_INF_UNSIGNED, \
-    TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED
+    TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED, \
+    is_associative
 
 def int_size_to_bn(value, size):
     if size < 32:
@@ -288,7 +289,7 @@ class TranslatorC(Translator):
                     out = "bignum_mask(%s, %d)"% (out, expr.size)
                 return out
 
-            elif expr.is_associative():
+            elif is_associative(expr):
                 args = [self.from_expr(arg)
                         for arg in expr.args]
                 if expr.size <= self.NATIVE_INT_MAX_SIZE:
@@ -466,7 +467,7 @@ class TranslatorC(Translator):
             else:
                 raise NotImplementedError('Unknown op: %r' % expr.op)
 
-        elif len(expr.args) >= 3 and expr.is_associative():  # ?????
+        elif len(expr.args) >= 3 and is_associative(expr):  # ?????
             oper = ['(%s&%s)' % (
                 self.from_expr(arg),
                 self._size2mask(arg.size),
diff --git a/miasm/jitter/codegen.py b/miasm/jitter/codegen.py
index abbf65d2..0b5b7961 100644
--- a/miasm/jitter/codegen.py
+++ b/miasm/jitter/codegen.py
@@ -6,8 +6,8 @@ from builtins import zip
 
 from future.utils import viewitems, viewvalues
 
-from miasm.expression.expression import Expr, ExprId, ExprLoc, ExprInt, \
-    ExprMem, ExprCond, LocKey
+from miasm.expression.expression import ExprId, ExprLoc, ExprInt, \
+    ExprMem, ExprCond, LocKey, is_expr
 from miasm.ir.ir import IRBlock, AssignBlock
 
 from miasm.ir.translators.C import TranslatorC
@@ -123,7 +123,7 @@ class CGen(object):
 
     def dst_to_c(self, src):
         """Translate Expr @src into C code"""
-        if not isinstance(src, Expr):
+        if not is_expr(src):
             src = ExprInt(src, self.PC.size)
         return self.id_to_c(src)
 
@@ -413,7 +413,7 @@ class CGen(object):
         @dst: potential instruction destination"""
 
         out = []
-        if isinstance(dst, Expr):
+        if is_expr(dst):
             out += self.gen_post_code(attrib, "DST_value")
             out.append('BlockDst->address = DST_value;')
             out += self.gen_post_instr_checks(attrib)
diff --git a/miasm/jitter/emulatedsymbexec.py b/miasm/jitter/emulatedsymbexec.py
index aacfba9f..844e7d5f 100644
--- a/miasm/jitter/emulatedsymbexec.py
+++ b/miasm/jitter/emulatedsymbexec.py
@@ -94,10 +94,10 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
         data = self.expr_simp(data)
         if not isinstance(data, m2_expr.ExprInt):
             raise RuntimeError("A simplification is missing: %s" % data)
-        to_write = data.arg.arg
+        to_write = int(data)
 
         # Format information
-        addr = dest.ptr.arg.arg
+        addr = int(dest.ptr)
         size = data.size // 8
         content = hex(to_write).replace("0x", "").replace("L", "")
         content = "0" * (size * 2 - len(content)) + content
@@ -120,7 +120,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
                     if not isinstance(value, m2_expr.ExprInt):
                         raise ValueError("A simplification is missing: %s" % value)
 
-                    setattr(self.cpu, symbol.name, value.arg.arg)
+                    setattr(self.cpu, symbol.name, int(value))
             else:
                 raise NotImplementedError("Type not handled: %s" % symbol)
 
@@ -140,7 +140,7 @@ class EmulatedSymbExec(SymbolicExecutionEngine):
     # CPU specific simplifications
     def _simp_handle_segm(self, e_s, expr):
         """Handle 'segm' operation"""
-        if not expr.is_op_segm():
+        if not m2_expr.is_op_segm(expr):
             return expr
         if not expr.args[0].is_int():
             return expr
diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py
index 2aca66ed..cb101937 100755
--- a/test/arch/msp430/sem.py
+++ b/test/arch/msp430/sem.py
@@ -39,10 +39,12 @@ def compute(asm, inputstate={}, debug=False):
         for k, v in viewitems(symexec.symbols):
             if regs_init.get(k, None) != v:
                 print(k, v)
-    return {
-        k: v.arg.arg for k, v in viewitems(symexec.symbols)
+
+    result =  {
+        k: int(v) for k, v in viewitems(symexec.symbols)
         if k not in EXCLUDE_REGS and regs_init.get(k, None) != v
     }
+    return result
 
 
 class TestMSP430Semantic(unittest.TestCase):
diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py
index 5109d2b4..10980b05 100755
--- a/test/arch/x86/sem.py
+++ b/test/arch/x86/sem.py
@@ -104,7 +104,7 @@ class TestX86Semantic(unittest.TestCase):
         sem = compute(ir_32, m32, '%s XMM0, XMM1' % name,
                                   {XMM0: arg1, XMM1: arg2},
                                   False)
-        ref = ExprInt(int_vec_op(op, elt_size, reg_size, arg1.arg, arg2.arg), XMM0.size)
+        ref = ExprInt(int_vec_op(op, elt_size, reg_size, int(arg1), int(arg2)), XMM0.size)
         self.assertEqual(sem, {XMM0: ref, XMM1: arg2})
 
     def symb_sse_ops(self, names, a, b, ref):
@@ -121,7 +121,7 @@ class TestX86Semantic(unittest.TestCase):
         sem = compute(ir_32, m32, '%s MM0, MM1' % name,
                                   {mm0: arg1, mm1: arg2},
                                   False)
-        ref = ExprInt(op(arg1.arg, arg2.arg), mm0.size)
+        ref = ExprInt(op(int(arg1), int(arg2)), mm0.size)
         self.assertEqual(sem, {mm0: ref, mm1: arg2})
 
     def sse_logical_op(self, name, op, arg1, arg2):
@@ -130,7 +130,7 @@ class TestX86Semantic(unittest.TestCase):
         sem = compute(ir_32, m32, '%s XMM0, XMM1' % name,
                                   {XMM0: arg1, XMM1: arg2},
                                   False)
-        ref = ExprInt(op(arg1.arg, arg2.arg), XMM0.size)
+        ref = ExprInt(op(int(arg1), int(arg2)), XMM0.size)
         self.assertEqual(sem, {XMM0: ref, XMM1: arg2})
 
     def test_SSE_ADD(self):