about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--example/expression/simplification_add.py4
-rw-r--r--example/expression/solve_condition_stp.py8
-rw-r--r--example/ida/depgraph.py2
-rw-r--r--miasm2/arch/aarch64/arch.py12
-rw-r--r--miasm2/arch/aarch64/sem.py36
-rw-r--r--miasm2/arch/arm/arch.py4
-rw-r--r--miasm2/arch/arm/sem.py2
-rw-r--r--miasm2/arch/msp430/sem.py8
-rw-r--r--miasm2/arch/x86/arch.py18
-rw-r--r--miasm2/arch/x86/sem.py222
-rw-r--r--miasm2/core/asmbloc.py2
-rw-r--r--miasm2/core/cpu.py2
-rw-r--r--miasm2/expression/expression.py59
-rw-r--r--miasm2/expression/modint.py35
-rw-r--r--miasm2/expression/simplifications_common.py170
-rw-r--r--miasm2/ir/ir.py5
-rw-r--r--miasm2/ir/symbexec.py39
-rw-r--r--test/arch/arm/sem.py2
-rw-r--r--test/arch/msp430/sem.py2
-rw-r--r--test/arch/x86/sem.py24
-rw-r--r--test/expression/expression.py6
-rw-r--r--test/ir/symbexec.py17
22 files changed, 382 insertions, 297 deletions
diff --git a/example/expression/simplification_add.py b/example/expression/simplification_add.py
index 008e094b..06b683fe 100644
--- a/example/expression/simplification_add.py
+++ b/example/expression/simplification_add.py
@@ -30,7 +30,7 @@ def simp_add_mul(expr_simp, expr):
 
         # Effective simplification
         return m2_expr.ExprOp("*", expr.args[0],
-                              m2_expr.ExprInt_from(expr.args[0], 3))
+                              m2_expr.ExprInt(3, expr.args[0].size))
     else:
         # Do not simplify
         return expr
@@ -48,4 +48,4 @@ print "\t%s = %s" % (base_expr, expr_simp(base_expr))
 
 # Automatic fail
 assert(expr_simp(base_expr) == m2_expr.ExprOp("*", a,
-                                              m2_expr.ExprInt_from(a, 3)))
+                                              m2_expr.ExprInt(3, a.size)))
diff --git a/example/expression/solve_condition_stp.py b/example/expression/solve_condition_stp.py
index 93c17018..67d536d5 100644
--- a/example/expression/solve_condition_stp.py
+++ b/example/expression/solve_condition_stp.py
@@ -80,11 +80,11 @@ def emul_symb(ir_arch, mdis, states_todo, states_done):
             # Create 2 states, each including complementary conditions
             p1 = sb.symbols.copy()
             p2 = sb.symbols.copy()
-            c1 = {ad.cond: ExprInt_from(ad.cond, 0)}
-            c2 = {ad.cond: ExprInt_from(ad.cond, 1)}
+            c1 = {ad.cond: ExprInt(0, ad.cond.size)}
+            c2 = {ad.cond: ExprInt(1, ad.cond.size)}
             print ad.cond
-            p1[ad.cond] = ExprInt_from(ad.cond, 0)
-            p2[ad.cond] = ExprInt_from(ad.cond, 1)
+            p1[ad.cond] = ExprInt(0, ad.cond.size)
+            p2[ad.cond] = ExprInt(1, ad.cond.size)
             ad1 = expr_simp(sb.eval_expr(ad.replace_expr(c1), {}))
             ad2 = expr_simp(sb.eval_expr(ad.replace_expr(c2), {}))
             if not (isinstance(ad1, ExprInt) or (isinstance(ad1, ExprId) and isinstance(ad1.name, asmbloc.asm_label)) and
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 3c57e51b..002075ee 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -167,7 +167,7 @@ for irb in ir_arch.blocs.values():
     fix_stack = irb.label.offset is not None and settings.unalias_stack
     for i, assignblk in enumerate(irb.irs):
         if fix_stack:
-            stk_high = m2_expr.ExprInt_from(ir_arch.sp, GetSpd(irb.lines[i].offset))
+            stk_high = m2_expr.ExprInt(GetSpd(irb.lines[i].offset), ir_arch.sp.size)
             fix_dct = {ir_arch.sp: mn.regs.regs_init[ir_arch.sp] + stk_high}
 
         for dst, src in assignblk.items():
diff --git a/miasm2/arch/aarch64/arch.py b/miasm2/arch/aarch64/arch.py
index 96945ff2..b495821b 100644
--- a/miasm2/arch/aarch64/arch.py
+++ b/miasm2/arch/aarch64/arch.py
@@ -913,7 +913,7 @@ class aarch64_gpreg_ext(reg_noarg, m_arg):
         reg = gpregsz_info[size].expr[v]
 
         self.expr = m2_expr.ExprOp(extend_lst[self.parent.option.value],
-                           reg, m2_expr.ExprInt_from(reg, self.parent.imm.value))
+                           reg, m2_expr.ExprInt(self.parent.imm.value, reg.size))
         return True
 
 EXT2_OP = {0b010: 'UXTW',
@@ -983,10 +983,10 @@ class aarch64_gpreg_ext2(reg_noarg, m_arg):
         if opt in EXT2_OP:
             if self.parent.shift.value == 1:
                 arg = m2_expr.ExprOp(EXT2_OP[opt], arg,
-                             m2_expr.ExprInt_from(arg, self.get_size()))
+                             m2_expr.ExprInt(self.get_size(), arg.size))
             else:
                 arg = m2_expr.ExprOp(EXT2_OP[opt], arg,
-                             m2_expr.ExprInt_from(arg, 0))
+                             m2_expr.ExprInt(0, arg.size))
 
         reg = self.parent.rn.reg_info.expr[self.parent.rn.value]
         self.expr = m2_expr.ExprOp('segm', reg, arg)
@@ -1047,7 +1047,7 @@ class aarch64_gpreg_sftimm(reg_noarg, m_arg):
         amount = self.parent.imm.value
         if amount != 0:
             e = m2_expr.ExprOp(
-                shift_expr[self.parent.shift.value], e, m2_expr.ExprInt_from(e, amount))
+                shift_expr[self.parent.shift.value], e, m2_expr.ExprInt(amount, e.size))
         self.expr = e
         return True
 
@@ -1417,8 +1417,8 @@ class aarch64_b40(m_arg):
     parser = base_expr
 
     def decode(self, v):
-        self.expr = m2_expr.ExprInt_from(
-            self.parent.rt.expr, (self.parent.sf.value << self.l) | v)
+        self.expr = m2_expr.ExprInt(
+            (self.parent.sf.value << self.l) | v, self.parent.rt.expr.size)
         return True
 
     def encode(self):
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index 0bceb8dc..c3ed56d5 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -123,7 +123,7 @@ def extend_arg(dst, arg):
         base = reg.zeroExtend(dst.size)
 
     out = base << (shift.zeroExtend(dst.size)
-                   & m2_expr.ExprInt_from(dst, dst.size - 1))
+                   & m2_expr.ExprInt(dst.size - 1, dst.size))
     return out
 
 
@@ -250,18 +250,18 @@ def tst(ir, instr, arg1, arg2):
 
 @sbuild.parse
 def lsl(arg1, arg2, arg3):
-    arg1 = arg2 << (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1))
+    arg1 = arg2 << (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size))
 
 
 @sbuild.parse
 def lsr(arg1, arg2, arg3):
-    arg1 = arg2 >> (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1))
+    arg1 = arg2 >> (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size))
 
 
 @sbuild.parse
 def asr(arg1, arg2, arg3):
     arg1 = m2_expr.ExprOp(
-        'a>>', arg2, (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1)))
+        'a>>', arg2, (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size)))
 
 
 @sbuild.parse
@@ -311,7 +311,7 @@ def csinc(ir, instr, arg1, arg2, arg3, arg4):
     cond_expr = cond2expr[arg4.name]
     e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
                                                     arg2,
-                                                    arg3 + m2_expr.ExprInt_from(arg3, 1))))
+                                                    arg3 + m2_expr.ExprInt(1, arg3.size))))
     return e, []
 
 
@@ -337,9 +337,9 @@ def cset(ir, instr, arg1, arg2):
     e = []
     cond_expr = cond2expr[arg2.name]
     e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
-                                                    m2_expr.ExprInt_from(
-                                                        arg1, 1),
-                                                    m2_expr.ExprInt_from(arg1, 0))))
+                                                    m2_expr.ExprInt(
+                                                        1, arg1.size),
+                                                    m2_expr.ExprInt(0, arg1.size))))
     return e, []
 
 
@@ -347,9 +347,9 @@ def csetm(ir, instr, arg1, arg2):
     e = []
     cond_expr = cond2expr[arg2.name]
     e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr,
-                                                    m2_expr.ExprInt_from(
-                                                        arg1, -1),
-                                                    m2_expr.ExprInt_from(arg1, 0))))
+                                                    m2_expr.ExprInt(
+                                                        -1, arg1.size),
+                                                    m2_expr.ExprInt(0, arg1.size))))
     return e, []
 
 
@@ -452,7 +452,7 @@ def stp(ir, instr, arg1, arg2, arg3):
     addr, updt = get_mem_access(arg3)
     e.append(m2_expr.ExprAff(m2_expr.ExprMem(addr, arg1.size), arg1))
     e.append(
-        m2_expr.ExprAff(m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, arg1.size / 8), arg2.size), arg2))
+        m2_expr.ExprAff(m2_expr.ExprMem(addr + m2_expr.ExprInt(arg1.size / 8, addr.size), arg2.size), arg2))
     if updt:
         e.append(updt)
     return e, []
@@ -463,7 +463,7 @@ def ldp(ir, instr, arg1, arg2, arg3):
     addr, updt = get_mem_access(arg3)
     e.append(m2_expr.ExprAff(arg1, m2_expr.ExprMem(addr, arg1.size)))
     e.append(
-        m2_expr.ExprAff(arg2, m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, arg1.size / 8), arg2.size)))
+        m2_expr.ExprAff(arg2, m2_expr.ExprMem(addr + m2_expr.ExprInt(arg1.size / 8, addr.size), arg2.size)))
     if updt:
         e.append(updt)
     return e, []
@@ -485,7 +485,7 @@ def sbfm(ir, instr, arg1, arg2, arg3, arg4):
     if sim > rim:
         res = arg2[rim:sim].signExtend(arg1.size)
     else:
-        shift = m2_expr.ExprInt_from(arg2, arg2.size - rim)
+        shift = m2_expr.ExprInt(arg2.size - rim, arg2.size)
         res = (arg2[:sim].signExtend(arg1.size) << shift)
     e.append(m2_expr.ExprAff(arg1, res))
     return e, []
@@ -497,7 +497,7 @@ def ubfm(ir, instr, arg1, arg2, arg3, arg4):
     if sim > rim:
         res = arg2[rim:sim].zeroExtend(arg1.size)
     else:
-        shift = m2_expr.ExprInt_from(arg2, arg2.size - rim)
+        shift = m2_expr.ExprInt(arg2.size - rim, arg2.size)
         res = (arg2[:sim].zeroExtend(arg1.size) << shift)
     e.append(m2_expr.ExprAff(arg1, res))
     return e, []
@@ -510,7 +510,7 @@ def bfm(ir, instr, arg1, arg2, arg3, arg4):
         e.append(m2_expr.ExprAff(arg1[:sim-rim], res))
     else:
         shift_i = arg2.size - rim
-        shift = m2_expr.ExprInt_from(arg2, shift_i)
+        shift = m2_expr.ExprInt(shift_i, arg2.size)
         res = arg2[:sim]
         e.append(m2_expr.ExprAff(arg1[shift_i:shift_i+sim], res))
     return e, []
@@ -547,7 +547,7 @@ def cbnz(arg1, arg2):
 
 @sbuild.parse
 def tbz(arg1, arg2, arg3):
-    bitmask = m2_expr.ExprInt_from(arg1, 1) << arg2
+    bitmask = m2_expr.ExprInt(1, arg1.size) << arg2
     dst = m2_expr.ExprId(
         ir.get_next_label(instr), 64) if arg1 & bitmask else arg3
     PC = dst
@@ -556,7 +556,7 @@ def tbz(arg1, arg2, arg3):
 
 @sbuild.parse
 def tbnz(arg1, arg2, arg3):
-    bitmask = m2_expr.ExprInt_from(arg1, 1) << arg2
+    bitmask = m2_expr.ExprInt(1, arg1.size) << arg2
     dst = arg3 if arg1 & bitmask else m2_expr.ExprId(
         ir.get_next_label(instr), 64)
     PC = dst
diff --git a/miasm2/arch/arm/arch.py b/miasm2/arch/arm/arch.py
index e0ead4f4..04e47585 100644
--- a/miasm2/arch/arm/arch.py
+++ b/miasm2/arch/arm/arch.py
@@ -439,7 +439,7 @@ class instruction_arm(instruction):
 
     def get_asm_offset(self, expr):
         # LDR XXX, [PC, offset] => PC is self.offset+8
-        return ExprInt_from(expr, self.offset+8)
+        return ExprInt(self.offset+8, expr.size)
 
 class instruction_armt(instruction_arm):
     __slots__ = []
@@ -511,7 +511,7 @@ class instruction_armt(instruction_arm):
     def get_asm_offset(self, expr):
         # ADR XXX, PC, imm => PC is 4 aligned + imm
         new_offset = ((self.offset+self.l)/4)*4
-        return ExprInt_from(expr, new_offset)
+        return ExprInt(new_offset, expr.size)
 
 
 class mn_arm(cls_mn):
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index e251ca75..225b393c 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -398,7 +398,7 @@ def neg(ir, instr, a, b):
     return e
 
 def negs(ir, instr, a, b):
-    e = subs(ir, instr, a, ExprInt_from(b, 0), b)
+    e = subs(ir, instr, a, ExprInt(0, b.size), b)
     return e
 
 def bic(ir, instr, a, b, c=None):
diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py
index a99e500c..92b005ad 100644
--- a/miasm2/arch/msp430/sem.py
+++ b/miasm2/arch/msp430/sem.py
@@ -29,7 +29,7 @@ def reset_sr_res():
 
 
 def update_flag_zf(a):
-    return [ExprAff(zf, ExprCond(a, ExprInt_from(zf, 0), ExprInt_from(zf, 1)))]
+    return [ExprAff(zf, ExprCond(a, ExprInt(0, zf.size), ExprInt(1, zf.size)))]
 
 
 def update_flag_nf(a):
@@ -37,11 +37,11 @@ def update_flag_nf(a):
 
 
 def update_flag_pf(a):
-    return [ExprAff(pf, ExprOp('parity', a & ExprInt_from(a, 0xFF)))]
+    return [ExprAff(pf, ExprOp('parity', a & ExprInt(0xFF, a.size)))]
 
 
 def update_flag_cf_inv_zf(a):
-    return [ExprAff(cf, ExprCond(a, ExprInt_from(cf, 1), ExprInt_from(cf, 0)))]
+    return [ExprAff(cf, ExprCond(a, ExprInt(1, cf.size), ExprInt(0, cf.size)))]
 
 
 def update_flag_zn_r(a):
@@ -75,7 +75,7 @@ def mng_autoinc(a, b, size):
         return e, a, b
 
     a_r = a.args[0]
-    e.append(ExprAff(a_r, a_r + ExprInt_from(a_r, size / 8)))
+    e.append(ExprAff(a_r, a_r + ExprInt(size / 8, a_r.size)))
     a = ExprMem(a_r, size)
     if isinstance(b, ExprMem) and a_r in b.arg:
         b = ExprMem(b.arg + ExprInt16(size / 8), b.size)
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 4a07571f..87e91756 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -157,7 +157,7 @@ def parse_deref_int(s, l, t):
 def parse_deref_regint(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
-    i1 = ExprInt_from(r1, t[1].arg)
+    i1 = ExprInt(t[1].arg, r1.size)
     return r1 + i1
 
 
@@ -170,7 +170,7 @@ def parse_deref_regregint(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
     r2 = reg2exprid(t[1][0])
-    i1 = ExprInt_from(r1, t[2].arg)
+    i1 = ExprInt(t[2].arg, r1.size)
     return r1 + r2 + i1
 
 
@@ -178,7 +178,7 @@ def parse_deref_reg_intmreg(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
     r2 = reg2exprid(t[1][0])
-    i1 = ExprInt_from(r1, t[2].arg)
+    i1 = ExprInt(t[2].arg, r1.size)
     return r1 + (r2 * i1)
 
 
@@ -186,23 +186,23 @@ def parse_deref_reg_intmreg_int(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
     r2 = reg2exprid(t[1][0])
-    i1 = ExprInt_from(r1, t[2].arg)
-    i2 = ExprInt_from(r1, t[3].arg)
+    i1 = ExprInt(t[2].arg, r1.size)
+    i2 = ExprInt(t[3].arg, r1.size)
     return r1 + (r2 * i1) + i2
 
 
 def parse_deref_intmreg(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
-    i1 = ExprInt_from(r1, t[1].arg)
+    i1 = ExprInt(t[1].arg, r1.size)
     return r1 * i1
 
 
 def parse_deref_intmregint(s, l, t):
     t = t[0]
     r1 = reg2exprid(t[0][0])
-    i1 = ExprInt_from(r1, t[1].arg)
-    i2 = ExprInt_from(r1, t[1].arg)
+    i1 = ExprInt(t[1].arg, r1.size)
+    i2 = ExprInt(t[1].arg, r1.size)
     return (r1 * i1) + i2
 
 
@@ -903,7 +903,7 @@ class mn_x86(cls_mn):
 
     def ir_pre_instruction(self):
         return [ExprAff(mRIP[self.mode],
-            ExprInt_from(mRIP[self.mode], self.offset + self.l))]
+            ExprInt(self.offset + self.l, mRIP[self.mode].size))]
 
     @classmethod
     def filter_asm_candidates(cls, instr, candidates):
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 5dc49efc..152208d4 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -70,8 +70,8 @@ OF(A-B) = ((A XOR D) AND (A XOR B)) < 0
 
 def update_flag_zf(a):
     return [m2_expr.ExprAff(
-        zf, m2_expr.ExprCond(a, m2_expr.ExprInt_from(zf, 0),
-                             m2_expr.ExprInt_from(zf, 1)))]
+        zf, m2_expr.ExprCond(a, m2_expr.ExprInt(0, zf.size),
+                             m2_expr.ExprInt(1, zf.size)))]
 
 
 def update_flag_nf(a):
@@ -81,7 +81,7 @@ def update_flag_nf(a):
 def update_flag_pf(a):
     return [m2_expr.ExprAff(pf,
                             m2_expr.ExprOp('parity',
-                                           a & m2_expr.ExprInt_from(a, 0xFF)))]
+                                           a & m2_expr.ExprInt(0xFF, a.size)))]
 
 
 def update_flag_af(op1, op2, res):
@@ -99,8 +99,8 @@ def update_flag_znp(a):
 def update_flag_logic(a):
     e = []
     e += update_flag_znp(a)
-    e.append(m2_expr.ExprAff(of, m2_expr.ExprInt_from(of, 0)))
-    e.append(m2_expr.ExprAff(cf, m2_expr.ExprInt_from(cf, 0)))
+    e.append(m2_expr.ExprAff(of, m2_expr.ExprInt(0, of.size)))
+    e.append(m2_expr.ExprAff(cf, m2_expr.ExprInt(0, cf.size)))
     return e
 
 
@@ -169,7 +169,7 @@ def set_float_cs_eip(instr):
     e = []
     # XXX TODO check float updt
     e.append(m2_expr.ExprAff(float_eip,
-                             m2_expr.ExprInt_from(float_eip, instr.offset)))
+                             m2_expr.ExprInt(instr.offset, float_eip.size)))
     e.append(m2_expr.ExprAff(float_cs, CS))
     return e
 
@@ -363,7 +363,7 @@ def sbb(ir, instr, a, b):
 
 def neg(ir, instr, b):
     e = []
-    a = m2_expr.ExprInt_from(b, 0)
+    a = m2_expr.ExprInt(0, b.size)
 
     c = a - b
     e += update_flag_arith(c)
@@ -434,9 +434,9 @@ def get_shift(a, b):
     else:
         b = b.zeroExtend(a.size)
     if a.size == 64:
-        shift = b & m2_expr.ExprInt_from(b, 0x3f)
+        shift = b & m2_expr.ExprInt(0x3f, b.size)
     else:
-        shift = b & m2_expr.ExprInt_from(b, 0x1f)
+        shift = b & m2_expr.ExprInt(0x1f, b.size)
     shift = expr_simp(shift)
     return shift
 
@@ -519,7 +519,7 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False,
 
     res = m2_expr.ExprOp(op, a, shifter)
     cf_from_dst = m2_expr.ExprOp(op, a,
-                                 (shifter - m2_expr.ExprInt_from(a, 1)))
+                                 (shifter - m2_expr.ExprInt(1, a.size)))
     cf_from_dst = cf_from_dst.msb() if left else cf_from_dst[:1]
 
     new_cf = cf_from_dst
@@ -561,7 +561,7 @@ def _shift_tpl(op, ir, instr, a, b, c=None, op_inv=None, left=False,
     e_do = [
         m2_expr.ExprAff(cf, new_cf),
         m2_expr.ExprAff(of, m2_expr.ExprCond(shifter - i1,
-                                             m2_expr.ExprInt_from(of, 0),
+                                             m2_expr.ExprInt(0, of.size),
                                              value_of)),
         m2_expr.ExprAff(a, res),
     ]
@@ -607,33 +607,33 @@ def shld(ir, instr, a, b, c):
 
 # XXX todo ###
 def cmc(ir, instr):
-    e = [m2_expr.ExprAff(cf, m2_expr.ExprCond(cf, m2_expr.ExprInt_from(cf, 0),
-                                              m2_expr.ExprInt_from(cf, 1)))]
+    e = [m2_expr.ExprAff(cf, m2_expr.ExprCond(cf, m2_expr.ExprInt(0, cf.size),
+                                              m2_expr.ExprInt(1, cf.size)))]
     return e, []
 
 
 def clc(ir, instr):
-    e = [m2_expr.ExprAff(cf, m2_expr.ExprInt_from(cf, 0))]
+    e = [m2_expr.ExprAff(cf, m2_expr.ExprInt(0, cf.size))]
     return e, []
 
 
 def stc(ir, instr):
-    e = [m2_expr.ExprAff(cf, m2_expr.ExprInt_from(cf, 1))]
+    e = [m2_expr.ExprAff(cf, m2_expr.ExprInt(1, cf.size))]
     return e, []
 
 
 def cld(ir, instr):
-    e = [m2_expr.ExprAff(df, m2_expr.ExprInt_from(df, 0))]
+    e = [m2_expr.ExprAff(df, m2_expr.ExprInt(0, df.size))]
     return e, []
 
 
 def std(ir, instr):
-    e = [m2_expr.ExprAff(df, m2_expr.ExprInt_from(df, 1))]
+    e = [m2_expr.ExprAff(df, m2_expr.ExprInt(1, df.size))]
     return e, []
 
 
 def cli(ir, instr):
-    e = [m2_expr.ExprAff(i_f, m2_expr.ExprInt_from(i_f, 0))]
+    e = [m2_expr.ExprAff(i_f, m2_expr.ExprInt(0, i_f.size))]
     return e, []
 
 
@@ -644,7 +644,7 @@ def sti(ir, instr):
 
 def inc(ir, instr, a):
     e = []
-    b = m2_expr.ExprInt_from(a, 1)
+    b = m2_expr.ExprInt(1, a.size)
     c = a + b
     e += update_flag_arith(c)
     e += update_flag_af(a, b, c)
@@ -656,7 +656,7 @@ def inc(ir, instr, a):
 
 def dec(ir, instr, a):
     e = []
-    b = m2_expr.ExprInt_from(a, -1)
+    b = m2_expr.ExprInt(-1, a.size)
     c = a + b
     e += update_flag_arith(c)
     e += update_flag_af(a, b, ~c)
@@ -678,7 +678,7 @@ def push_gen(ir, instr, a, size):
         raise ValueError('strange arg size')
 
     sp = mRSP[instr.mode]
-    new_sp = sp - m2_expr.ExprInt_from(sp, size / 8)
+    new_sp = sp - m2_expr.ExprInt(size / 8, sp.size)
     e.append(m2_expr.ExprAff(sp, new_sp))
     if ir.do_stk_segm:
         new_sp = m2_expr.ExprOp('segm', SS, new_sp)
@@ -700,7 +700,7 @@ def pop_gen(ir, instr, a, size):
         raise ValueError('bad size stacker!')
 
     sp = mRSP[instr.mode]
-    new_sp = sp + m2_expr.ExprInt_from(sp, size / 8)
+    new_sp = sp + m2_expr.ExprInt(size / 8, sp.size)
     # don't generate ESP incrementation on POP ESP
     if a != ir.sp:
         e.append(m2_expr.ExprAff(sp, new_sp))
@@ -725,16 +725,16 @@ def popw(ir, instr, a):
 def sete(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(zf, m2_expr.ExprInt_from(a, 1),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(zf, m2_expr.ExprInt(1, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def setnz(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(zf, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(zf, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
@@ -742,15 +742,15 @@ def setl(ir, instr, a):
     e = []
     e.append(
         m2_expr.ExprAff(
-            a, m2_expr.ExprCond(nf - of, m2_expr.ExprInt_from(a, 1),
-                                m2_expr.ExprInt_from(a, 0))))
+            a, m2_expr.ExprCond(nf - of, m2_expr.ExprInt(1, a.size),
+                                m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def setg(ir, instr, a):
     e = []
-    a0 = m2_expr.ExprInt_from(a, 0)
-    a1 = m2_expr.ExprInt_from(a, 1)
+    a0 = m2_expr.ExprInt(0, a.size)
+    a1 = m2_expr.ExprInt(1, a.size)
     ret = m2_expr.ExprCond(zf, a0, a1) & m2_expr.ExprCond(nf - of, a0, a1)
     e.append(m2_expr.ExprAff(a, ret))
     return e, []
@@ -760,16 +760,16 @@ def setge(ir, instr, a):
     e = []
     e.append(
         m2_expr.ExprAff(
-            a, m2_expr.ExprCond(nf - of, m2_expr.ExprInt_from(a, 0),
-                                m2_expr.ExprInt_from(a, 1))))
+            a, m2_expr.ExprCond(nf - of, m2_expr.ExprInt(0, a.size),
+                                m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
 def seta(ir, instr, a):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprCond(cf | zf,
-                                                 m2_expr.ExprInt_from(a, 0),
-                                                 m2_expr.ExprInt_from(a, 1))))
+                                                 m2_expr.ExprInt(0, a.size),
+                                                 m2_expr.ExprInt(1, a.size))))
 
     return e, []
 
@@ -777,24 +777,24 @@ def seta(ir, instr, a):
 def setae(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
 def setb(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt_from(a, 1),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt(1, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def setbe(ir, instr, a):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprCond(cf | zf,
-                                                 m2_expr.ExprInt_from(a, 1),
-                                                 m2_expr.ExprInt_from(a, 0)))
+                                                 m2_expr.ExprInt(1, a.size),
+                                                 m2_expr.ExprInt(0, a.size)))
              )
     return e, []
 
@@ -802,47 +802,47 @@ def setbe(ir, instr, a):
 def setns(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(nf, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(nf, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
 def sets(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(nf, m2_expr.ExprInt_from(a, 1),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(nf, m2_expr.ExprInt(1, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def seto(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(of, m2_expr.ExprInt_from(a, 1),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(of, m2_expr.ExprInt(1, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def setp(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(pf, m2_expr.ExprInt_from(a, 1),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(pf, m2_expr.ExprInt(1, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
 def setnp(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(pf, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(pf, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
 def setle(ir, instr, a):
     e = []
-    a0 = m2_expr.ExprInt_from(a, 0)
-    a1 = m2_expr.ExprInt_from(a, 1)
+    a0 = m2_expr.ExprInt(0, a.size)
+    a1 = m2_expr.ExprInt(1, a.size)
     ret = m2_expr.ExprCond(zf, a1, a0) | m2_expr.ExprCond(nf ^ of, a1, a0)
     e.append(m2_expr.ExprAff(a, ret))
     return e, []
@@ -850,8 +850,8 @@ def setle(ir, instr, a):
 
 def setna(ir, instr, a):
     e = []
-    a0 = m2_expr.ExprInt_from(a, 0)
-    a1 = m2_expr.ExprInt_from(a, 1)
+    a0 = m2_expr.ExprInt(0, a.size)
+    a1 = m2_expr.ExprInt(1, a.size)
     ret = m2_expr.ExprCond(cf, a1, a0) & m2_expr.ExprCond(zf, a1, a0)
     e.append(m2_expr.ExprAff(a, ret))
     return e, []
@@ -860,8 +860,8 @@ def setna(ir, instr, a):
 def setnbe(ir, instr, a):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprCond(cf | zf,
-                                                 m2_expr.ExprInt_from(a, 0),
-                                                 m2_expr.ExprInt_from(a, 1)))
+                                                 m2_expr.ExprInt(0, a.size),
+                                                 m2_expr.ExprInt(1, a.size)))
              )
     return e, []
 
@@ -869,16 +869,16 @@ def setnbe(ir, instr, a):
 def setno(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(of, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(of, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
 def setnb(ir, instr, a):
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt_from(a, 0),
-                                            m2_expr.ExprInt_from(a, 1))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt(0, a.size),
+                                            m2_expr.ExprInt(1, a.size))))
     return e, []
 
 
@@ -886,8 +886,8 @@ def setalc(ir, instr):
     a = mRAX[instr.mode][0:8]
     e = []
     e.append(
-        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt_from(a, 0xff),
-                                            m2_expr.ExprInt_from(a, 0))))
+        m2_expr.ExprAff(a, m2_expr.ExprCond(cf, m2_expr.ExprInt(0xff, a.size),
+                                            m2_expr.ExprInt(0, a.size))))
     return e, []
 
 
@@ -919,17 +919,17 @@ def cmps(ir, instr, size):
 
     e0 = []
     e0.append(m2_expr.ExprAff(a.arg,
-                              a.arg + m2_expr.ExprInt_from(a.arg, size / 8)))
+                              a.arg + m2_expr.ExprInt(size / 8, a.arg.size)))
     e0.append(m2_expr.ExprAff(b.arg,
-                              b.arg + m2_expr.ExprInt_from(b.arg, size / 8)))
+                              b.arg + m2_expr.ExprInt(size / 8, b.arg.size)))
     e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(m2_expr.ExprAff(a.arg,
-                              a.arg - m2_expr.ExprInt_from(a.arg, size / 8)))
+                              a.arg - m2_expr.ExprInt(size / 8, a.arg.size)))
     e1.append(m2_expr.ExprAff(b.arg,
-                              b.arg - m2_expr.ExprInt_from(b.arg, size / 8)))
+                              b.arg - m2_expr.ExprInt(size / 8, b.arg.size)))
     e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e1 = irbloc(lbl_df_1.name, [e1])
 
@@ -950,13 +950,13 @@ def scas(ir, instr, size):
 
     e0 = []
     e0.append(m2_expr.ExprAff(a.arg,
-                              a.arg + m2_expr.ExprInt_from(a.arg, size / 8)))
+                              a.arg + m2_expr.ExprInt(size / 8, a.arg.size)))
     e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
     e1.append(m2_expr.ExprAff(a.arg,
-                              a.arg - m2_expr.ExprInt_from(a.arg, size / 8)))
+                              a.arg - m2_expr.ExprInt(size / 8, a.arg.size)))
     e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e1 = irbloc(lbl_df_1.name, [e1])
 
@@ -1016,7 +1016,7 @@ def popfd(ir, instr):
     e.append(m2_expr.ExprAff(vip, m2_expr.ExprSlice(tmp, 20, 21)))
     e.append(m2_expr.ExprAff(i_d, m2_expr.ExprSlice(tmp, 21, 22)))
     e.append(m2_expr.ExprAff(mRSP[instr.mode],
-                             mRSP[instr.mode] + m2_expr.ExprInt_from(mRSP[instr.mode], instr.mode / 8)))
+                             mRSP[instr.mode] + m2_expr.ExprInt(instr.mode / 8, mRSP[instr.mode].size)))
     e.append(m2_expr.ExprAff(exception_flags,
                              m2_expr.ExprCond(m2_expr.ExprSlice(tmp, 8, 9),
                                               m2_expr.ExprInt32(
@@ -1107,7 +1107,7 @@ def call(ir, instr, dst):
             # Far call far [eax]
             addr = dst.args[0].arg
             m1 = m2_expr.ExprMem(addr, CS.size)
-            m2 = m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, 2),
+            m2 = m2_expr.ExprMem(addr + m2_expr.ExprInt(2, addr.size),
                                  meip.size)
         else:
             raise RuntimeError("bad call operator")
@@ -1241,7 +1241,7 @@ def jmp(ir, instr, dst):
             # Far jmp far [eax]
             addr = dst.args[0].arg
             m1 = m2_expr.ExprMem(addr, CS.size)
-            m2 = m2_expr.ExprMem(addr + m2_expr.ExprInt_from(addr, 2),
+            m2 = m2_expr.ExprMem(addr + m2_expr.ExprInt(2, addr.size),
                                  meip.size)
         else:
             raise RuntimeError("bad jmp operator")
@@ -1343,7 +1343,7 @@ def loop(ir, instr, dst):
     myecx = mRCX[instr.mode][:admode]
 
     n = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size)
-    c = myecx - m2_expr.ExprInt_from(myecx, 1)
+    c = myecx - m2_expr.ExprInt(1, myecx.size)
     dst_o = m2_expr.ExprCond(c,
                              dst.zeroExtend(ir.IRDst.size),
                              n.zeroExtend(ir.IRDst.size))
@@ -1366,7 +1366,7 @@ def loopne(ir, instr, dst):
                          m2_expr.ExprInt1(0))
     c &= zf ^ m2_expr.ExprInt1(1)
 
-    e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt_from(myecx, 1)))
+    e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt(1, myecx.size)))
     dst_o = m2_expr.ExprCond(c,
                              dst.zeroExtend(ir.IRDst.size),
                              n.zeroExtend(ir.IRDst.size))
@@ -1386,7 +1386,7 @@ def loope(ir, instr, dst):
                          m2_expr.ExprInt1(1),
                          m2_expr.ExprInt1(0))
     c &= zf
-    e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt_from(myecx, 1)))
+    e.append(m2_expr.ExprAff(myecx, myecx - m2_expr.ExprInt(1, myecx.size)))
     dst_o = m2_expr.ExprCond(c,
                              dst.zeroExtend(ir.IRDst.size),
                              n.zeroExtend(ir.IRDst.size))
@@ -1584,8 +1584,8 @@ def stos(ir, instr, size):
 
     addr_o = mRDI[instr.mode][:s]
     addr = addr_o
-    addr_p = addr + m2_expr.ExprInt_from(addr, size / 8)
-    addr_m = addr - m2_expr.ExprInt_from(addr, size / 8)
+    addr_p = addr + m2_expr.ExprInt(size / 8, addr.size)
+    addr_m = addr - m2_expr.ExprInt(size / 8, addr.size)
     if ir.do_str_segm:
         mss = ES
         if instr.additional_info.g2.value:
@@ -1620,8 +1620,8 @@ def lods(ir, instr, size):
 
     addr_o = mRSI[instr.mode][:s]
     addr = addr_o
-    addr_p = addr + m2_expr.ExprInt_from(addr, size / 8)
-    addr_m = addr - m2_expr.ExprInt_from(addr, size / 8)
+    addr_p = addr + m2_expr.ExprInt(size / 8, addr.size)
+    addr_m = addr - m2_expr.ExprInt(size / 8, addr.size)
     if ir.do_str_segm:
         mss = DS
         if instr.additional_info.g2.value:
@@ -1675,14 +1675,14 @@ def movs(ir, instr, size):
                              m2_expr.ExprMem(src, size)))
 
     e0 = []
-    e0.append(m2_expr.ExprAff(a, a + m2_expr.ExprInt_from(a, size / 8)))
-    e0.append(m2_expr.ExprAff(b, b + m2_expr.ExprInt_from(b, size / 8)))
+    e0.append(m2_expr.ExprAff(a, a + m2_expr.ExprInt(size / 8, a.size)))
+    e0.append(m2_expr.ExprAff(b, b + m2_expr.ExprInt(size / 8, b.size)))
     e0.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e0 = irbloc(lbl_df_0.name, [e0])
 
     e1 = []
-    e1.append(m2_expr.ExprAff(a, a - m2_expr.ExprInt_from(a, size / 8)))
-    e1.append(m2_expr.ExprAff(b, b - m2_expr.ExprInt_from(b, size / 8)))
+    e1.append(m2_expr.ExprAff(a, a - m2_expr.ExprInt(size / 8, a.size)))
+    e1.append(m2_expr.ExprAff(b, b - m2_expr.ExprInt(size / 8, b.size)))
     e1.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     e1 = irbloc(lbl_df_1.name, [e1])
 
@@ -1734,7 +1734,7 @@ def float_pop(avoid_flt=None, popcount=1):
                                      float_list[i + popcount]))
     for i in xrange(8 - popcount, 8):
         e.append(m2_expr.ExprAff(float_list[i],
-                                 m2_expr.ExprInt_from(float_list[i], 0)))
+                                 m2_expr.ExprInt(0, float_list[i].size)))
     e.append(
         m2_expr.ExprAff(float_stack_ptr,
                         float_stack_ptr - m2_expr.ExprInt(popcount, 3)))
@@ -2176,19 +2176,19 @@ def fnstenv(ir, instr, a):
     s = min(32, s)
     ad = m2_expr.ExprMem(a.arg, size=16)
     e.append(m2_expr.ExprAff(ad, float_control))
-    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt_from(a.arg, s / 8 * 1),
+    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt(s / 8 * 1, a.arg.size),
                          size=16)
     e.append(m2_expr.ExprAff(ad, status_word))
-    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt_from(a.arg, s / 8 * 3),
+    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt(s / 8 * 3, a.arg.size),
                          size=s)
     e.append(m2_expr.ExprAff(ad, float_eip[:s]))
-    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt_from(a.arg, s / 8 * 4),
+    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt(s / 8 * 4, a.arg.size),
                          size=16)
     e.append(m2_expr.ExprAff(ad, float_cs))
-    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt_from(a.arg, s / 8 * 5),
+    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt(s / 8 * 5, a.arg.size),
                          size=s)
     e.append(m2_expr.ExprAff(ad, float_address[:s]))
-    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt_from(a.arg, s / 8 * 6),
+    ad = m2_expr.ExprMem(a.arg + m2_expr.ExprInt(s / 8 * 6, a.arg.size),
                          size=16)
     e.append(m2_expr.ExprAff(ad, float_ds))
     return e, []
@@ -2663,8 +2663,13 @@ def _tpl_aaa(ir, instr, op):
     cond |= af & i1
 
     to_add = m2_expr.ExprInt(0x106, size=r_ax.size)
-    new_ax = m2_expr.ExprOp(op, r_ax, to_add) & m2_expr.ExprInt(0xff0f,
-                                                                size=r_ax.size)
+    if op == "-":
+        # Avoid ExprOp("-", A, B), should be ExprOp("+", A, ExprOp("-", B))
+        first_part = r_ax - to_add
+    else:
+        first_part = m2_expr.ExprOp(op, r_ax, to_add)
+    new_ax = first_part & m2_expr.ExprInt(0xff0f,
+                                          size=r_ax.size)
     # set AL
     e.append(m2_expr.ExprAff(r_ax, m2_expr.ExprCond(cond, new_ax, r_ax)))
     e.append(m2_expr.ExprAff(af, cond))
@@ -2698,12 +2703,12 @@ def bsr_bsf(ir, instr, a, b, op_name):
                                                     lbl_src_not_null,
                                                     lbl_src_null))]
     e_src_null = []
-    e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 1)))
+    e_src_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt(1, zf.size)))
     # XXX destination is undefined
     e_src_null.append(aff_dst)
 
     e_src_not_null = []
-    e_src_not_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt_from(zf, 0)))
+    e_src_not_null.append(m2_expr.ExprAff(zf, m2_expr.ExprInt(0, zf.size)))
     e_src_not_null.append(m2_expr.ExprAff(a, m2_expr.ExprOp(op_name, b)))
     e_src_not_null.append(aff_dst)
 
@@ -2741,7 +2746,7 @@ def sidt(ir, instr, a):
                              m2_expr.ExprInt32(0xe40007ff)))
     e.append(
         m2_expr.ExprAff(m2_expr.ExprMem(m2_expr.ExprOp("+", b,
-                                                       m2_expr.ExprInt_from(b, 4)), 16), m2_expr.ExprInt16(0x8245)))
+                                                       m2_expr.ExprInt(4, b.size)), 16), m2_expr.ExprInt16(0x8245)))
     return e, []
 
 
@@ -2904,13 +2909,12 @@ def bittest_get(a, b):
         off_bit = b.zeroExtend(
             a.size) & m2_expr.ExprInt((1 << b_mask[a.size]) - 1,
                                       a.size)
-        off_byte = ((b.zeroExtend(ptr.size) >> m2_expr.ExprInt_from(ptr, 3)) &
-                    m2_expr.ExprInt_from(ptr,
-                                         ((1 << a.size) - 1) ^ b_decal[a.size]))
+        off_byte = ((b.zeroExtend(ptr.size) >> m2_expr.ExprInt(3, ptr.size)) &
+                    m2_expr.ExprInt(((1 << a.size) - 1) ^ b_decal[a.size], ptr.size))
 
         d = m2_expr.ExprMem(ptr + off_byte, a.size)
     else:
-        off_bit = m2_expr.ExprOp('&', b, m2_expr.ExprInt_from(a, a.size - 1))
+        off_bit = m2_expr.ExprOp('&', b, m2_expr.ExprInt(a.size - 1, a.size))
         d = a
     return d, off_bit
 
@@ -2929,7 +2933,7 @@ def btc(ir, instr, a, b):
     d, off_bit = bittest_get(a, b)
     e.append(m2_expr.ExprAff(cf, (d >> off_bit)[:1]))
 
-    m = m2_expr.ExprInt_from(a, 1) << off_bit
+    m = m2_expr.ExprInt(1, a.size) << off_bit
     e.append(m2_expr.ExprAff(d, d ^ m))
 
     return e, []
@@ -2939,7 +2943,7 @@ def bts(ir, instr, a, b):
     e = []
     d, off_bit = bittest_get(a, b)
     e.append(m2_expr.ExprAff(cf, (d >> off_bit)[:1]))
-    m = m2_expr.ExprInt_from(a, 1) << off_bit
+    m = m2_expr.ExprInt(1, a.size) << off_bit
     e.append(m2_expr.ExprAff(d, d | m))
 
     return e, []
@@ -2949,7 +2953,7 @@ def btr(ir, instr, a, b):
     e = []
     d, off_bit = bittest_get(a, b)
     e.append(m2_expr.ExprAff(cf, (d >> off_bit)[:1]))
-    m = ~(m2_expr.ExprInt_from(a, 1) << off_bit)
+    m = ~(m2_expr.ExprInt(1, a.size) << off_bit)
     e.append(m2_expr.ExprAff(d, d & m))
 
     return e, []
@@ -2992,7 +2996,7 @@ def cmpxchg8b(arg1):
 def lds(ir, instr, a, b):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(b.arg, size=a.size)))
-    DS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt_from(b.arg, a.size / 8),
+    DS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt(a.size / 8, b.arg.size),
                                size=16)
     e.append(m2_expr.ExprAff(DS, DS_value))
     return e, []
@@ -3001,7 +3005,7 @@ def lds(ir, instr, a, b):
 def les(ir, instr, a, b):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(b.arg, size=a.size)))
-    ES_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt_from(b.arg, a.size / 8),
+    ES_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt(a.size / 8, b.arg.size),
                                size=16)
     e.append(m2_expr.ExprAff(ES, ES_value))
     return e, []
@@ -3010,7 +3014,7 @@ def les(ir, instr, a, b):
 def lss(ir, instr, a, b):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(b.arg, size=a.size)))
-    SS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt_from(b.arg, a.size / 8),
+    SS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt(a.size / 8, b.arg.size),
                                size=16)
     e.append(m2_expr.ExprAff(SS, SS_value))
     return e, []
@@ -3019,7 +3023,7 @@ def lss(ir, instr, a, b):
 def lfs(ir, instr, a, b):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(b.arg, size=a.size)))
-    FS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt_from(b.arg, a.size / 8),
+    FS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt(a.size / 8, b.arg.size),
                                size=16)
     e.append(m2_expr.ExprAff(FS, FS_value))
     return e, []
@@ -3028,7 +3032,7 @@ def lfs(ir, instr, a, b):
 def lgs(ir, instr, a, b):
     e = []
     e.append(m2_expr.ExprAff(a, m2_expr.ExprMem(b.arg, size=a.size)))
-    GS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt_from(b.arg, a.size / 8),
+    GS_value = m2_expr.ExprMem(b.arg + m2_expr.ExprInt(a.size / 8, b.arg.size),
                                size=16)
     e.append(m2_expr.ExprAff(GS, GS_value))
     return e, []
@@ -3137,7 +3141,7 @@ def rdmsr(ir, instr):
     e.append(
         m2_expr.ExprAff(mRAX[instr.mode][:32], m2_expr.ExprMem(msr_addr, 32)))
     e.append(m2_expr.ExprAff(mRDX[instr.mode][:32], m2_expr.ExprMem(
-        msr_addr + m2_expr.ExprInt_from(msr_addr, 4), 32)))
+        msr_addr + m2_expr.ExprInt(4, msr_addr.size), 32)))
     return e, []
 
 
@@ -4462,7 +4466,7 @@ class ir_x86_16(ir):
             if e.dst == zf:
                 zf_val = e.src
 
-        cond_dec = m2_expr.ExprCond(c_reg - m2_expr.ExprInt_from(c_reg, 1),
+        cond_dec = m2_expr.ExprCond(c_reg - m2_expr.ExprInt(1, c_reg.size),
                                     m2_expr.ExprInt1(0), m2_expr.ExprInt1(1))
         # end condition
         if zf_val is None:
@@ -4485,8 +4489,8 @@ class ir_x86_16(ir):
                     ir[i] = m2_expr.ExprAff(e.dst, src)
         cond_bloc = []
         cond_bloc.append(m2_expr.ExprAff(c_reg,
-                                         c_reg - m2_expr.ExprInt_from(c_reg,
-                                                                      1)))
+                                         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)))
diff --git a/miasm2/core/asmbloc.py b/miasm2/core/asmbloc.py
index f6d6154b..730d6d7d 100644
--- a/miasm2/core/asmbloc.py
+++ b/miasm2/core/asmbloc.py
@@ -871,7 +871,7 @@ def fix_expr_val(expr, symbols):
     def expr_calc(e):
         if isinstance(e, m2_expr.ExprId):
             s = symbols._name2label[e.name]
-            e = m2_expr.ExprInt_from(e, s.offset)
+            e = m2_expr.ExprInt(s.offset, e.size)
         return e
     result = expr.visit(expr_calc)
     result = expr_simp(result)
diff --git a/miasm2/core/cpu.py b/miasm2/core/cpu.py
index 81c18f1f..a6a65796 100644
--- a/miasm2/core/cpu.py
+++ b/miasm2/core/cpu.py
@@ -921,7 +921,7 @@ class instruction(object):
         return o
 
     def get_asm_offset(self, expr):
-        return m2_expr.ExprInt_from(expr, self.offset)
+        return m2_expr.ExprInt(self.offset, expr.size)
 
     def resolve_args_with_symbols(self, symbols=None):
         if symbols is None:
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index 581dc8dc..0001dc24 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -353,6 +353,30 @@ class Expr(object):
 
     mask = property(lambda self: ExprInt(-1, self.size))
 
+    def is_int(self, value=None):
+        return False
+
+    def is_id(self, name=None):
+        return False
+
+    def is_aff(self):
+        return False
+
+    def is_cond(self):
+        return False
+
+    def is_mem(self):
+        return False
+
+    def is_op(self, op=None):
+        return False
+
+    def is_slice(self, start=None, stop=None):
+        return False
+
+    def is_compose(self):
+        return False
+
 
 class ExprInt(Expr):
 
@@ -380,6 +404,8 @@ class ExprInt(Expr):
             if size is not None and num.size != size:
                 raise RuntimeError("size must match modint size")
         elif size is not None:
+            if size not in mod_size2uint:
+                define_uint(size)
             self.__arg = mod_size2uint[size](num)
             self.__size = self.arg.size
         else:
@@ -446,6 +472,11 @@ class ExprInt(Expr):
     def __long__(self):
         return long(self.arg)
 
+    def is_int(self, value=None):
+        if value is not None and self.__arg != value:
+            return False
+        return True
+
 
 class ExprId(Expr):
 
@@ -512,6 +543,11 @@ class ExprId(Expr):
     def graph_recursive(self, graph):
         graph.add_node(self)
 
+    def is_id(self, name=None):
+        if name is not None and self.__name != name:
+            return False
+        return True
+
 
 class ExprAff(Expr):
 
@@ -610,6 +646,9 @@ class ExprAff(Expr):
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
+    def is_aff(self):
+        return True
+
 
 class ExprCond(Expr):
 
@@ -703,6 +742,9 @@ class ExprCond(Expr):
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
+    def is_cond(self):
+        return True
+
 
 class ExprMem(Expr):
 
@@ -785,6 +827,9 @@ class ExprMem(Expr):
         self.__arg.graph_recursive(graph)
         graph.add_uniq_edge(self, self.__arg)
 
+    def is_mem(self):
+        return True
+
 
 class ExprOp(Expr):
 
@@ -951,6 +996,10 @@ class ExprOp(Expr):
             arg.graph_recursive(graph)
             graph.add_uniq_edge(self, arg)
 
+    def is_op(self, op=None):
+        if op is None:
+            return True
+        return self.op == op
 
 class ExprSlice(Expr):
 
@@ -1034,6 +1083,13 @@ class ExprSlice(Expr):
         self.__arg.graph_recursive(graph)
         graph.add_uniq_edge(self, self.__arg)
 
+    def is_slice(self, start=None, stop=None):
+        if start is not None and self.__start != start:
+            return False
+        if stop is not None and self.__stop != stop:
+            return False
+        return True
+
 
 class ExprCompose(Expr):
 
@@ -1133,6 +1189,9 @@ class ExprCompose(Expr):
             yield index, arg
             index += arg.size
 
+    def is_compose(self):
+        return True
+
 # Expression order for comparaison
 expr_order_dict = {ExprId: 1,
                    ExprCond: 2,
diff --git a/miasm2/expression/modint.py b/miasm2/expression/modint.py
index 76896eb9..a801c948 100644
--- a/miasm2/expression/modint.py
+++ b/miasm2/expression/modint.py
@@ -198,25 +198,36 @@ mod_size2int = {}
 mod_uint2size = {}
 mod_int2size = {}
 
+def define_int(size):
+    """Build the 'modint' instance corresponding to size @size"""
+    global mod_size2int, mod_int2size
+
+    name = 'int%d' % size
+    cls = type(name, (modint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2int[size] = cls
+    mod_int2size[cls] = size
+    return cls
+
+def define_uint(size):
+    """Build the 'moduint' instance corresponding to size @size"""
+    global mod_size2uint, mod_uint2size
+
+    name = 'uint%d' % size
+    cls = type(name, (moduint,), {"size": size, "limit": 1 << size})
+    globals()[name] = cls
+    mod_size2uint[size] = cls
+    mod_uint2size[cls] = size
+    return cls
 
 def define_common_int():
     "Define common int: ExprInt1, ExprInt2, .."
-    global mod_size2int, mod_int2size, mod_size2uint, mod_uint2size
-
     common_int = xrange(1, 257)
 
     for i in common_int:
-        name = 'uint%d' % i
-        c = type(name, (moduint,), {"size": i, "limit": 1 << i})
-        globals()[name] = c
-        mod_size2uint[i] = c
-        mod_uint2size[c] = i
+        define_int(i)
 
     for i in common_int:
-        name = 'int%d' % i
-        c = type(name, (modint,), {"size": i, "limit": 1 << i})
-        globals()[name] = c
-        mod_size2int[i] = c
-        mod_int2size[c] = i
+        define_uint(i)
 
 define_common_int()
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index a070fb81..4bd35390 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -22,8 +22,8 @@ def simp_cst_propagation(e_s, e):
     # TODO: <<< >>> << >> are architecture dependant
     if op in op_propag_cst:
         while (len(args) >= 2 and
-            isinstance(args[-1], ExprInt) and
-            isinstance(args[-2], ExprInt)):
+            args[-1].is_int() and
+            args[-2].is_int()):
             i2 = args.pop()
             i1 = args.pop()
             if op == '+':
@@ -83,48 +83,45 @@ def simp_cst_propagation(e_s, e):
             args.append(o)
 
     # bsf(int) => int
-    if op == "bsf" and isinstance(args[0], ExprInt) and args[0].arg != 0:
+    if op == "bsf" and args[0].is_int() and args[0].arg != 0:
         i = 0
         while args[0].arg & (1 << i) == 0:
             i += 1
-        return ExprInt_from(args[0], i)
+        return ExprInt(i, args[0].size)
 
     # bsr(int) => int
-    if op == "bsr" and isinstance(args[0], ExprInt) and args[0].arg != 0:
+    if op == "bsr" and args[0].is_int() and args[0].arg != 0:
         i = args[0].size - 1
         while args[0].arg & (1 << i) == 0:
             i -= 1
-        return ExprInt_from(args[0], i)
+        return ExprInt(i, args[0].size)
 
     # -(-(A)) => A
-    if op == '-' and len(args) == 1 and isinstance(args[0], ExprOp) and \
-            args[0].op == '-' and len(args[0].args) == 1:
+    if (op == '-' and len(args) == 1 and args[0].is_op('-') and
+        len(args[0].args) == 1):
         return args[0].args[0]
 
     # -(int) => -int
-    if op == '-' and len(args) == 1 and isinstance(args[0], ExprInt):
+    if op == '-' and len(args) == 1 and args[0].is_int():
         return ExprInt(-args[0].arg)
     # A op 0 =>A
     if op in ['+', '|', "^", "<<", ">>", "<<<", ">>>"] and len(args) > 1:
-        if isinstance(args[-1], ExprInt) and args[-1].arg == 0:
+        if args[-1].is_int(0):
             args.pop()
     # A - 0 =>A
-    if op == '-' and len(args) > 1 and args[-1].arg == 0:
+    if op == '-' and len(args) > 1 and args[-1].is_int(0):
         assert(len(args) == 2) # Op '-' with more than 2 args: SantityCheckError
         return args[0]
 
     # A * 1 =>A
-    if op == "*" and len(args) > 1:
-        if isinstance(args[-1], ExprInt) and args[-1].arg == 1:
-            args.pop()
+    if op == "*" and len(args) > 1 and args[-1].is_int(1):
+        args.pop()
 
     # for cannon form
     # A * -1 => - A
-    if op == "*" and len(args) > 1:
-        if (isinstance(args[-1], ExprInt) and
-            args[-1].arg == (1 << args[-1].size) - 1):
-            args.pop()
-            args[-1] = - args[-1]
+    if op == "*" and len(args) > 1 and args[-1].is_int((1 << args[-1].size) - 1):
+        args.pop()
+        args[-1] = - args[-1]
 
     # op A => A
     if op in ['+', '*', '^', '&', '|', '>>', '<<',
@@ -140,28 +137,23 @@ def simp_cst_propagation(e_s, e):
         return ExprOp('+', args[0], -args[1])
 
     # A op 0 => 0
-    if op in ['&', "*"] and isinstance(args[1], ExprInt) and args[1].arg == 0:
-        return ExprInt_from(e, 0)
+    if op in ['&', "*"] and args[1].is_int(0):
+        return ExprInt(0, e.size)
 
     # - (A + B +...) => -A + -B + -C
-    if (op == '-' and
-        len(args) == 1 and
-        isinstance(args[0], ExprOp) and
-        args[0].op == '+'):
+    if op == '-' and len(args) == 1 and args[0].is_op('+'):
         args = [-a for a in args[0].args]
         e = ExprOp('+', *args)
         return e
 
     # -(a?int1:int2) => (a?-int1:-int2)
-    if (op == '-' and
-        len(args) == 1 and
-        isinstance(args[0], ExprCond) and
-        isinstance(args[0].src1, ExprInt) and
-        isinstance(args[0].src2, ExprInt)):
+    if (op == '-' and len(args) == 1 and
+        args[0].is_cond() and
+        args[0].src1.is_int() and args[0].src2.is_int()):
         i1 = args[0].src1
         i2 = args[0].src2
-        i1 = ExprInt_from(i1, -i1.arg)
-        i2 = ExprInt_from(i2, -i2.arg)
+        i1 = ExprInt(-i1.arg, i1.size)
+        i2 = ExprInt(-i2.arg, i2.size)
         return ExprCond(args[0].cond, i1, i2)
 
     i = 0
@@ -170,19 +162,19 @@ def simp_cst_propagation(e_s, e):
         while j < len(args):
             # A ^ A => 0
             if op == '^' and args[i] == args[j]:
-                args[i] = ExprInt_from(args[i], 0)
+                args[i] = ExprInt(0, args[i].size)
                 del(args[j])
                 continue
             # A + (- A) => 0
-            if op == '+' and isinstance(args[j], ExprOp) and args[j].op == "-":
+            if op == '+' and args[j].is_op("-"):
                 if len(args[j].args) == 1 and args[i] == args[j].args[0]:
-                    args[i] = ExprInt_from(args[i], 0)
+                    args[i] = ExprInt(0, args[i].size)
                     del(args[j])
                     continue
             # (- A) + A => 0
-            if op == '+' and isinstance(args[i], ExprOp) and args[i].op == "-":
+            if op == '+' and args[i].is_op("-"):
                 if len(args[i].args) == 1 and args[j] == args[i].args[0]:
-                    args[i] = ExprInt_from(args[i], 0)
+                    args[i] = ExprInt(0, args[i].size)
                     del(args[j])
                     continue
             # A | A => A
@@ -201,13 +193,13 @@ def simp_cst_propagation(e_s, e):
 
     # A <<< A.size => A
     if (op in ['<<<', '>>>'] and
-        isinstance(args[1], ExprInt) and
+        args[1].is_int() and
         args[1].arg == args[0].size):
         return args[0]
 
     # A <<< X <<< Y => A <<< (X+Y) (ou <<< >>>)
     if (op in ['<<<', '>>>'] and
-        isinstance(args[0], ExprOp) and
+        args[0].is_op() and
         args[0].op in ['<<<', '>>>']):
         op1 = op
         op2 = args[0].op
@@ -223,8 +215,7 @@ def simp_cst_propagation(e_s, e):
 
     # A >> X >> Y  =>  A >> (X+Y)
     if (op in ['<<', '>>'] and
-        isinstance(args[0], ExprOp) and
-        args[0].op == op):
+        args[0].is_op(op)):
         args = [args[0].args[0], args[0].args[1] + args[1]]
 
     # ((A & A.mask)
@@ -239,15 +230,13 @@ def simp_cst_propagation(e_s, e):
     # TODO
 
     # ((A & mask) >> shift) whith mask < 2**shift => 0
-    if (op == ">>" and
-        isinstance(args[1], ExprInt) and
-        isinstance(args[0], ExprOp) and args[0].op == "&"):
-        if (isinstance(args[0].args[1], ExprInt) and
+    if op == ">>" 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):
-            return ExprInt_from(args[0], 0)
+            return ExprInt(0, args[0].size)
 
     # parity(int) => int
-    if op == 'parity' and isinstance(args[0], ExprInt):
+    if op == 'parity' and args[0].is_int():
         return ExprInt1(parity(args[0].arg))
 
     # (-a) * b * (-c) * (-d) => (-a) * b * c * d
@@ -255,7 +244,7 @@ def simp_cst_propagation(e_s, e):
         new_args = []
         counter = 0
         for a in args:
-            if isinstance(a, ExprOp) and a.op == '-' and len(a.args) == 1:
+            if a.is_op('-') and len(a.args) == 1:
                 new_args.append(a.args[0])
                 counter += 1
             else:
@@ -265,8 +254,8 @@ def simp_cst_propagation(e_s, e):
         args = new_args
 
     # A << int with A ExprCompose => move index
-    if (op == "<<" and isinstance(args[0], ExprCompose) and
-        isinstance(args[1], ExprInt) and int(args[1]) != 0):
+    if (op == "<<" and args[0].is_compose() and
+        args[1].is_int() and int(args[1]) != 0):
         final_size = args[0].size
         shift = int(args[1])
         new_args = []
@@ -291,7 +280,7 @@ def simp_cst_propagation(e_s, e):
         return ExprCompose(*args)
 
     # A >> int with A ExprCompose => move index
-    if op == ">>" and isinstance(args[0], ExprCompose) and isinstance(args[1], ExprInt):
+    if op == ">>" and args[0].is_compose() and args[1].is_int():
         final_size = args[0].size
         shift = int(args[1])
         new_args = []
@@ -316,7 +305,7 @@ def simp_cst_propagation(e_s, e):
 
 
     # Compose(a) OP Compose(b) with a/b same bounds => Compose(a OP b)
-    if op in ['|', '&', '^'] and all([isinstance(arg, ExprCompose) for arg in args]):
+    if op in ['|', '&', '^'] and all([arg.is_compose() for arg in args]):
         bounds = set()
         for arg in args:
             bound = tuple([expr.size for expr in arg.args])
@@ -337,10 +326,9 @@ def simp_cst_propagation(e_s, e):
         assert len(args) == 3
         dest, rounds, cf = args
         # Skipped if rounds is 0
-        if (isinstance(rounds, ExprInt) and
-            int(rounds) == 0):
+        if rounds.is_int(0):
             return dest
-        elif all(map(lambda x: isinstance(x, ExprInt), args)):
+        elif all(map(lambda x: x.is_int(), args)):
             # The expression can be resolved
             tmp = int(dest)
             cf = int(cf)
@@ -375,12 +363,12 @@ def simp_cond_op_int(e_s, e):
         return e
     if len(e.args) < 2:
         return e
-    if not isinstance(e.args[-1], ExprInt):
+    if not e.args[-1].is_int():
         return e
     a_int = e.args[-1]
     conds = []
     for a in e.args[:-1]:
-        if not isinstance(a, ExprCond):
+        if not a.is_cond():
             return e
         conds.append(a)
     if not conds:
@@ -404,7 +392,7 @@ def simp_cond_factor(e_s, e):
     not_conds = []
     multi_cond = False
     for a in e.args:
-        if not isinstance(a, ExprCond):
+        if not a.is_cond():
             not_conds.append(a)
             continue
         c = a.cond
@@ -437,19 +425,19 @@ def simp_slice(e_s, e):
     if e.start == 0 and e.stop == e.arg.size:
         return e.arg
     # Slice(int) => int
-    elif isinstance(e.arg, ExprInt):
+    elif e.arg.is_int():
         total_bit = e.stop - e.start
         mask = (1 << (e.stop - e.start)) - 1
         return ExprInt(int((e.arg.arg >> e.start) & mask), total_bit)
     # Slice(Slice(A, x), y) => Slice(A, z)
-    elif isinstance(e.arg, ExprSlice):
+    elif e.arg.is_slice():
         if e.stop - e.start > e.arg.stop - e.arg.start:
             raise ValueError('slice in slice: getting more val', str(e))
 
         new_e = ExprSlice(e.arg.arg, e.start + e.arg.start,
                           e.start + e.arg.start + (e.stop - e.start))
         return new_e
-    elif isinstance(e.arg, ExprCompose):
+    elif e.arg.is_compose():
         # Slice(Compose(A), x) => Slice(A, y)
         for index, arg in e.arg.iter_args():
             if index <= e.start and index+arg.size >= e.stop:
@@ -489,38 +477,33 @@ def simp_slice(e_s, e):
 
     # ExprMem(x, size)[:A] => ExprMem(x, a)
     # XXXX todo hum, is it safe?
-    elif (isinstance(e.arg, ExprMem) and
-        e.start == 0 and
-        e.arg.size > e.stop and e.stop % 8 == 0):
+    elif (e.arg.is_mem() and
+          e.start == 0 and
+          e.arg.size > e.stop and e.stop % 8 == 0):
         e = ExprMem(e.arg.arg, size=e.stop)
         return e
     # distributivity of slice and &
     # (a & int)[x:y] => 0 if int[x:y] == 0
-    elif (isinstance(e.arg, ExprOp) and
-        e.arg.op == "&" and
-        isinstance(e.arg.args[-1], ExprInt)):
+    elif e.arg.is_op("&") and e.arg.args[-1].is_int():
         tmp = e_s.expr_simp_wrapper(e.arg.args[-1][e.start:e.stop])
-        if isinstance(tmp, ExprInt) and tmp.arg == 0:
+        if tmp.is_int(0):
             return tmp
     # distributivity of slice and exprcond
     # (a?int1:int2)[x:y] => (a?int1[x:y]:int2[x:y])
-    elif (isinstance(e.arg, ExprCond) and
-        isinstance(e.arg.src1, ExprInt) and
-        isinstance(e.arg.src2, ExprInt)):
+    elif e.arg.is_cond() and e.arg.src1.is_int() and e.arg.src2.is_int():
         src1 = e.arg.src1[e.start:e.stop]
         src2 = e.arg.src2[e.start:e.stop]
         e = ExprCond(e.arg.cond, src1, src2)
 
     # (a * int)[0:y] => (a[0:y] * int[0:y])
-    elif (e.start == 0 and isinstance(e.arg, ExprOp) and
-        e.arg.op == "*" and isinstance(e.arg.args[-1], ExprInt)):
+    elif e.start == 0 and e.arg.is_op("*") and e.arg.args[-1].is_int():
         args = [e_s.expr_simp_wrapper(a[e.start:e.stop]) for a in e.arg.args]
         e = ExprOp(e.arg.op, *args)
 
     # (a >> int)[x:y] => a[x+int:y+int] with int+y <= a.size
     # (a << int)[x:y] => a[x-int:y-int] with x-int >= 0
-    elif (isinstance(e.arg, ExprOp) and e.arg.op in [">>", "<<"] and
-          isinstance(e.arg.args[1], ExprInt)):
+    elif (e.arg.is_op() and e.arg.op in [">>", "<<"] and
+          e.arg.args[1].is_int()):
         arg, shift = e.arg.args
         shift = int(shift)
         if e.arg.op == ">>":
@@ -541,7 +524,7 @@ def simp_compose(e_s, e):
     out = []
     # compose of compose
     for arg in args:
-        if isinstance(arg, ExprCompose):
+        if arg.is_compose():
             out += arg.args
         else:
             out.append(arg)
@@ -551,10 +534,8 @@ def simp_compose(e_s, e):
         return args[0]
 
     # {(X[z:], 0, X.size-z), (0, X.size-z, X.size)} => (X >> z)
-    if (len(args) == 2 and
-        isinstance(args[1], ExprInt) and
-        int(args[1]) == 0):
-        if (isinstance(args[0], ExprSlice) and
+    if len(args) == 2 and args[1].is_int(0):
+        if (args[0].is_slice() and
             args[0].stop == args[0].arg.size and
             args[0].size + args[1].size == args[0].arg.size):
             new_e = args[0].arg >> ExprInt(args[0].start, args[0].arg.size)
@@ -571,7 +552,7 @@ def simp_compose(e_s, e):
             ok = False
             break
         expr_ints_or_conds.append(arg)
-        if isinstance(arg, ExprCond):
+        if arg.is_cond():
             if expr_cond_index is not None:
                 ok = False
             expr_cond_index = i
@@ -589,7 +570,7 @@ def simp_compose(e_s, e):
                 src2.append(arg)
         src1 = e_s.apply_simp(ExprCompose(*src1))
         src2 = e_s.apply_simp(ExprCompose(*src2))
-        if isinstance(src1, ExprInt) and isinstance(src2, ExprInt):
+        if src1.is_int() and src2.is_int():
             return ExprCond(cond.cond, src1, src2)
     return ExprCompose(*args)
 
@@ -598,43 +579,40 @@ def simp_cond(e_s, e):
     "Common simplifications on ExprCond"
     # eval exprcond src1/src2 with satifiable/unsatisfiable condition
     # propagation
-    if (not isinstance(e.cond, ExprInt)) and e.cond.size == 1:
+    if (not e.cond.is_int()) and e.cond.size == 1:
         src1 = e.src1.replace_expr({e.cond: ExprInt1(1)})
         src2 = e.src2.replace_expr({e.cond: ExprInt1(0)})
         if src1 != e.src1 or src2 != e.src2:
             return ExprCond(e.cond, src1, src2)
 
     # -A ? B:C => A ? B:C
-    if (isinstance(e.cond, ExprOp) and
-        e.cond.op == '-' and
-        len(e.cond.args) == 1):
+    if e.cond.is_op('-') and len(e.cond.args) == 1:
         e = ExprCond(e.cond.args[0], e.src1, e.src2)
     # a?x:x
     elif e.src1 == e.src2:
         e = e.src1
     # int ? A:B => A or B
-    elif isinstance(e.cond, ExprInt):
+    elif e.cond.is_int():
         if e.cond.arg == 0:
             e = e.src2
         else:
             e = e.src1
     # a?(a?b:c):x => a?b:x
-    elif isinstance(e.src1, ExprCond) and e.cond == e.src1.cond:
+    elif e.src1.is_cond() and e.cond == e.src1.cond:
         e = ExprCond(e.cond, e.src1.src1, e.src2)
     # a?x:(a?b:c) => a?x:c
-    elif isinstance(e.src2, ExprCond) and e.cond == e.src2.cond:
+    elif e.src2.is_cond() and e.cond == e.src2.cond:
         e = ExprCond(e.cond, e.src1, e.src2.src2)
     # a|int ? b:c => b with int != 0
-    elif (isinstance(e.cond, ExprOp) and
-        e.cond.op == '|' and
-        isinstance(e.cond.args[1], ExprInt) and
-        e.cond.args[1].arg != 0):
+    elif (e.cond.is_op('|') and
+          e.cond.args[1].is_int() and
+          e.cond.args[1].arg != 0):
         return e.src1
 
     # (C?int1:int2)?(A:B) =>
-    elif (isinstance(e.cond, ExprCond) and
-          isinstance(e.cond.src1, ExprInt) and
-          isinstance(e.cond.src2, ExprInt)):
+    elif (e.cond.is_cond() and
+          e.cond.src1.is_int() and
+          e.cond.src2.is_int()):
         int1 = e.cond.src1.arg.arg
         int2 = e.cond.src2.arg.arg
         if int1 and int2:
diff --git a/miasm2/ir/ir.py b/miasm2/ir/ir.py
index e513c179..582faee6 100644
--- a/miasm2/ir/ir.py
+++ b/miasm2/ir/ir.py
@@ -359,8 +359,9 @@ class ir(object):
 
     def gen_pc_update(self, c, l):
         c.irs.append(AssignBlock([m2_expr.ExprAff(self.pc,
-                                                  m2_expr.ExprInt_from(self.pc,
-                                                                       l.offset))]))
+                                                  m2_expr.ExprInt(l.offset,
+                                                                  self.pc.size)
+                                                  )]))
         c.lines.append(l)
 
     def add_bloc(self, bloc, gen_pc_updt=False):
diff --git a/miasm2/ir/symbexec.py b/miasm2/ir/symbexec.py
index db3eacdc..fd8413fc 100644
--- a/miasm2/ir/symbexec.py
+++ b/miasm2/ir/symbexec.py
@@ -204,7 +204,7 @@ class symbexec(object):
             return expr
         elif isinstance(expr, m2_expr.ExprId):
             if isinstance(expr.name, asmbloc.asm_label) and expr.name.offset is not None:
-                ret = m2_expr.ExprInt_from(expr, expr.name.offset)
+                ret = m2_expr.ExprInt(expr.name.offset, expr.size)
             else:
                 ret = state.get(expr, expr)
         elif isinstance(expr, m2_expr.ExprMem):
@@ -392,6 +392,28 @@ class symbexec(object):
 
         return pool_out.iteritems()
 
+    def apply_change(self, dst, src):
+        """
+        Apply @dst = @src on the current state WITHOUT evaluating both side
+        @dst: Expr, destination
+        @src: Expr, source
+        """
+        if isinstance(dst, m2_expr.ExprMem):
+            mem_overlap = self.get_mem_overlapping(dst)
+            for _, base in mem_overlap:
+                diff_mem = self.substract_mems(base, dst)
+                del self.symbols[base]
+                for new_mem, new_val in diff_mem:
+                    self.symbols[new_mem] = new_val
+        src_o = self.expr_simp(src)
+        self.symbols[dst] = src_o
+        if dst == src_o:
+            del self.symbols[dst]
+        if isinstance(dst, m2_expr.ExprMem):
+            if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
+                self.func_write(self, dst, src_o)
+                del self.symbols[dst]
+
     def eval_ir(self, assignblk):
         """
         Apply an AssignBlock on the current state
@@ -400,21 +422,8 @@ class symbexec(object):
         mem_dst = []
         src_dst = self.eval_ir_expr(assignblk)
         for dst, src in src_dst:
+            self.apply_change(dst, src)
             if isinstance(dst, m2_expr.ExprMem):
-                mem_overlap = self.get_mem_overlapping(dst)
-                for _, base in mem_overlap:
-                    diff_mem = self.substract_mems(base, dst)
-                    del self.symbols[base]
-                    for new_mem, new_val in diff_mem:
-                        self.symbols[new_mem] = new_val
-            src_o = self.expr_simp(src)
-            self.symbols[dst] = src_o
-            if dst == src_o:
-                del self.symbols[dst]
-            if isinstance(dst, m2_expr.ExprMem):
-                if self.func_write and isinstance(dst.arg, m2_expr.ExprInt):
-                    self.func_write(self, dst, src_o)
-                    del self.symbols[dst]
                 mem_dst.append(dst)
         return mem_dst
 
diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py
index 8fc609fb..922642d3 100644
--- a/test/arch/arm/sem.py
+++ b/test/arch/arm/sem.py
@@ -21,7 +21,7 @@ def M(addr):
 
 def compute(asm, inputstate={}, debug=False):
     sympool = dict(regs_init)
-    sympool.update({k: ExprInt_from(k, v) for k, v in inputstate.iteritems()})
+    sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()})
     interm = ir_arch()
     symexec = symbexec(interm, sympool)
     instr = mn.fromstring(asm, "l")
diff --git a/test/arch/msp430/sem.py b/test/arch/msp430/sem.py
index 515b4c53..4d39d357 100644
--- a/test/arch/msp430/sem.py
+++ b/test/arch/msp430/sem.py
@@ -19,7 +19,7 @@ def M(addr):
 
 def compute(asm, inputstate={}, debug=False):
     sympool = dict(regs_init)
-    sympool.update({k: ExprInt_from(k, v) for k, v in inputstate.iteritems()})
+    sympool.update({k: ExprInt(v, k.size) for k, v in inputstate.iteritems()})
     interm = ir_arch()
     symexec = symbexec(interm, sympool)
     instr = mn.fromstring(asm, mode)
diff --git a/test/arch/x86/sem.py b/test/arch/x86/sem.py
index 7cf81828..93d2ff83 100644
--- a/test/arch/x86/sem.py
+++ b/test/arch/x86/sem.py
@@ -88,12 +88,12 @@ SSE_B = ExprId('B', 128)
 class TestX86Semantic(unittest.TestCase):
 
     def int_sse_op(self, name, op, elt_size, reg_size, arg1, arg2):
-        arg1 = ExprInt_from(XMM0, arg1)
-        arg2 = ExprInt_from(XMM0, arg2)
+        arg1 = ExprInt(arg1, XMM0.size)
+        arg2 = ExprInt(arg2, XMM0.size)
         sem = compute(ir_32, m32, '%s XMM0, XMM1' % name,
                                   {XMM0: arg1, XMM1: arg2},
                                   False)
-        ref = ExprInt_from(XMM0, int_vec_op(op, elt_size, reg_size, arg1.arg, arg2.arg))
+        ref = ExprInt(int_vec_op(op, elt_size, reg_size, arg1.arg, arg2.arg), XMM0.size)
         self.assertEqual(sem, {XMM0: ref, XMM1: arg2})
 
     def symb_sse_ops(self, names, a, b, ref):
@@ -105,21 +105,21 @@ class TestX86Semantic(unittest.TestCase):
         self.assertEqual(sem, {XMM0: ref, XMM1: b})
 
     def mmx_logical_op(self, name, op, arg1, arg2):
-        arg1 = ExprInt_from(mm0, arg1)
-        arg2 = ExprInt_from(mm0, arg2)
+        arg1 = ExprInt(arg1, mm0.size)
+        arg2 = ExprInt(arg2, mm0.size)
         sem = compute(ir_32, m32, '%s MM0, MM1' % name,
                                   {mm0: arg1, mm1: arg2},
                                   False)
-        ref = ExprInt_from(mm0, op(arg1.arg, arg2.arg))
+        ref = ExprInt(op(arg1.arg, arg2.arg), mm0.size)
         self.assertEqual(sem, {mm0: ref, mm1: arg2})
 
     def sse_logical_op(self, name, op, arg1, arg2):
-        arg1 = ExprInt_from(XMM0, arg1)
-        arg2 = ExprInt_from(XMM1, arg2)
+        arg1 = ExprInt(arg1, XMM0.size)
+        arg2 = ExprInt(arg2, XMM1.size)
         sem = compute(ir_32, m32, '%s XMM0, XMM1' % name,
                                   {XMM0: arg1, XMM1: arg2},
                                   False)
-        ref = ExprInt_from(XMM0, op(arg1.arg, arg2.arg))
+        ref = ExprInt(op(arg1.arg, arg2.arg), XMM0.size)
         self.assertEqual(sem, {XMM0: ref, XMM1: arg2})
 
     def test_SSE_ADD(self):
@@ -137,9 +137,9 @@ class TestX86Semantic(unittest.TestCase):
             self.int_sse_op(op[0], op_sub, op[1], 128, SSE_V1, SSE_V1)
 
     def test_SSE_simp(self):
-        self.symb_sse_ops(["PADDB", "PADDB", "PSUBB"], ExprInt_from(XMM0, 0), SSE_A, SSE_A)
-        self.symb_sse_ops(["PADDB", "PADDQ", "PSUBQ"], ExprInt_from(XMM0, 0), SSE_A, SSE_A)
-        self.symb_sse_ops(["PADDB", "PSUBQ", "PADDQ"], ExprInt_from(XMM0, 0), SSE_A, SSE_A)
+        self.symb_sse_ops(["PADDB", "PADDB", "PSUBB"], ExprInt(0, XMM0.size), SSE_A, SSE_A)
+        self.symb_sse_ops(["PADDB", "PADDQ", "PSUBQ"], ExprInt(0, XMM0.size), SSE_A, SSE_A)
+        self.symb_sse_ops(["PADDB", "PSUBQ", "PADDQ"], ExprInt(0, XMM0.size), SSE_A, SSE_A)
 
     def test_AND(self):
         self.mmx_logical_op("PAND", op_and, MMX_V0, MMX_V1)
diff --git a/test/expression/expression.py b/test/expression/expression.py
index 847ba7eb..58c0ca37 100644
--- a/test/expression/expression.py
+++ b/test/expression/expression.py
@@ -5,7 +5,13 @@ from pdb import pm
 from miasm2.expression.expression import *
 from miasm2.expression.expression_helper import *
 
+# Expression comparison
 assert(ExprInt64(-1) != ExprInt64(-2))
+assert(ExprInt64(1) != ExprInt32(1))
+
+# Expression size
+big_cst = ExprInt(1, size=0x1000)
+assert big_cst.size == 0x1000
 
 # Possible values
 #- Common constants
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 6df0bbc3..24b02341 100644
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -11,6 +11,7 @@ class TestSymbExec(unittest.TestCase):
             ExprCompose, ExprAff
         from miasm2.arch.x86.sem import ir_x86_32
         from miasm2.ir.symbexec import symbexec
+        from miasm2.ir.ir import AssignBlock
 
         addrX = ExprInt32(-1)
         addr0 = ExprInt32(0)
@@ -59,6 +60,22 @@ class TestSymbExec(unittest.TestCase):
         self.assertEqual(e.apply_expr(ExprAff(id_eax, addr9)), addr9)
         self.assertEqual(e.apply_expr(id_eax), addr9)
 
+        # apply_change / eval_ir / apply_expr
+
+        ## x = a (with a = 0x0)
+        assignblk = AssignBlock()
+        assignblk[id_x] = id_a
+        e.eval_ir(assignblk)
+        self.assertEqual(e.apply_expr(id_x), addr0)
+
+        ## x = a (without replacing 'a' with 0x0)
+        e.apply_change(id_x, id_a)
+        self.assertEqual(e.apply_expr(id_x), id_a)
+
+        ## x = a (with a = 0x0)
+        self.assertEqual(e.apply_expr(assignblk.dst2ExprAff(id_x)), addr0)
+        self.assertEqual(e.apply_expr(id_x), addr0)
+
 if __name__ == '__main__':
     testsuite = unittest.TestLoader().loadTestsFromTestCase(TestSymbExec)
     report = unittest.TextTestRunner(verbosity=2).run(testsuite)