about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorFabrice Desclaux <fabrice.desclaux@cea.fr>2016-10-21 16:19:09 +0200
committerFabrice Desclaux <fabrice.desclaux@cea.fr>2016-11-04 16:45:46 +0100
commit3771288cffdd53c1ff87857374bd13c550b355dc (patch)
treeb85469ca5e38aeb54e19d24ccb4bea1ecf627b5e
parent589d4fd9ebd61216155bba9f1988bbd5c3094a2b (diff)
downloadmiasm-3771288cffdd53c1ff87857374bd13c550b355dc.tar.gz
miasm-3771288cffdd53c1ff87857374bd13c550b355dc.zip
ExprCompose: add new api
The ExprComposes uses directly its arguments sizes to guess the slices
locations.
Old api:  ExprCompose([(a, 0, 32), (b, 32, 64)])
becomes:  ExprCompose(a, b)
-rw-r--r--example/expression/basic_simplification.py3
-rw-r--r--example/expression/expr_grapher.py2
-rw-r--r--example/expression/simplification_tools.py8
-rw-r--r--miasm2/arch/aarch64/sem.py3
-rw-r--r--miasm2/arch/arm/sem.py20
-rw-r--r--miasm2/arch/mips32/sem.py7
-rw-r--r--miasm2/arch/msp430/sem.py22
-rw-r--r--miasm2/arch/x86/sem.py213
-rw-r--r--miasm2/core/sembuilder.py2
-rw-r--r--miasm2/expression/expression.py47
-rw-r--r--miasm2/ir/translators/miasm.py6
-rw-r--r--test/arch/arm/sem.py2
-rw-r--r--test/expression/expression.py8
-rw-r--r--test/expression/expression_helper.py5
-rw-r--r--test/expression/simplifications.py178
-rw-r--r--test/ir/symbexec.py6
-rw-r--r--test/ir/translators/z3_ir.py2
17 files changed, 224 insertions, 310 deletions
diff --git a/example/expression/basic_simplification.py b/example/expression/basic_simplification.py
index 27c86096..17b1a35b 100644
--- a/example/expression/basic_simplification.py
+++ b/example/expression/basic_simplification.py
@@ -11,8 +11,7 @@ b = ExprId('ebx')
 
 exprs = [a + b - a,
          ExprInt32(0x12) + ExprInt32(0x30) - a,
-         ExprCompose([(a[:8], 0, 8),
-                      (a[8:16], 8, 16)])]
+         ExprCompose(a[:8], a[8:16])]
 
 for e in exprs:
     print '*' * 40
diff --git a/example/expression/expr_grapher.py b/example/expression/expr_grapher.py
index 22dff7cf..3137e6d2 100644
--- a/example/expression/expr_grapher.py
+++ b/example/expression/expr_grapher.py
@@ -8,7 +8,7 @@ c = ExprId("C")
 d = ExprId("D")
 m = ExprMem(a + b + c + a)
 
-e1 = ExprCompose([(a + b - (c * a) / m | b, 0, 32), (a + m, 32, 64)])
+e1 = ExprCompose(a + b - (c * a) / m | b, a + m)
 e2 = ExprInt64(15)
 e = ExprCond(d, e1, e2)[0:32]
 
diff --git a/example/expression/simplification_tools.py b/example/expression/simplification_tools.py
index b2df58d3..9b8aeed5 100644
--- a/example/expression/simplification_tools.py
+++ b/example/expression/simplification_tools.py
@@ -25,11 +25,9 @@ i1 = ExprInt(uint32(0x1))
 i2 = ExprInt(uint32(0x2))
 cc = ExprCond(a, b, c)
 
-o = ExprCompose([(a[:8], 8, 16),
-                 (a[8:16], 0, 8)])
+o = ExprCompose(a[8:16], a[:8])
 
-o2 = ExprCompose([(a[8:16], 0, 8),
-                 (a[:8], 8, 16)])
+o2 = ExprCompose(a[8:16], a[:8])
 
 l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]]
 l2 = l[::-1]
@@ -56,7 +54,7 @@ print y == y.copy()
 print repr(y), repr(y.copy())
 
 
-z = ExprCompose([(a[5:5 + 8], 0, 8), (b[:16], 8, 24), (x[:8], 24, 32)])
+z = ExprCompose(a[5:5 + 8], b[:16], x[:8])
 print z
 print z.copy()
 print z[:31].copy().visit(replace_expr)
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index aff2d8ca..0bceb8dc 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -672,8 +672,7 @@ def nop():
 
 @sbuild.parse
 def extr(arg1, arg2, arg3, arg4):
-    compose = m2_expr.ExprCompose([(arg2, 0, arg2.size),
-                                   (arg3, arg2.size, arg2.size+arg3.size)])
+    compose = m2_expr.ExprCompose(arg2, arg3)
     arg1 = compose[int(arg4.arg):int(arg4)+arg1.size]
 
 mnemo_func = sbuild.functions
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index 260531ac..c6f3dceb 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -481,7 +481,7 @@ def umull(ir, instr, a, b, c, d):
 
 def umlal(ir, instr, a, b, c, d):
     e = []
-    r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)])
+    r = c.zeroExtend(64) * d.zeroExtend(64) + ExprCompose(a, b)
     e.append(ExprAff(a, r[0:32]))
     e.append(ExprAff(b, r[32:64]))
     # r15/IRDst not allowed as output
@@ -497,7 +497,7 @@ def smull(ir, instr, a, b, c, d):
 
 def smlal(ir, instr, a, b, c, d):
     e = []
-    r = c.signExtend(64) * d.signExtend(64) + ExprCompose([(a, 0, 32), (b, 32, 64)])
+    r = c.signExtend(64) * d.signExtend(64) + ExprCompose(a, b)
     e.append(ExprAff(a, r[0:32]))
     e.append(ExprAff(b, r[32:64]))
     # r15/IRDst not allowed as output
@@ -910,14 +910,14 @@ def bfc(ir, instr, a, b, c):
     out = []
     last = 0
     if start:
-        out.append((a[:start], 0, start))
+        out.append(a[:start])
         last = start
     if stop - start:
-        out.append((ExprInt32(0)[last:stop], last, stop))
+        out.append(ExprInt32(0)[last:stop])
         last = stop
     if last < 32:
-        out.append((a[last:], last, 32))
-    r = ExprCompose(out)
+        out.append(a[last:])
+    r = ExprCompose(*out)
     e.append(ExprAff(a, r))
     dst = None
     if PC in a.get_r():
@@ -927,10 +927,7 @@ def bfc(ir, instr, a, b, c):
 
 def rev(ir, instr, a, b):
     e = []
-    c = ExprCompose([(b[:8],      24, 32),
-                     (b[8:16],    16, 24),
-                     (b[16:24],   8, 16),
-                     (b[24:32],   0, 8)])
+    c = ExprCompose(b[24:32], b[16:24], b[8:16], b[:8])
     e.append(ExprAff(a, c))
     return e
 
@@ -1225,8 +1222,7 @@ class ir_arml(ir):
         # ir = get_mnemo_expr(self, self.name.lower(), *args)
         if len(args) and isinstance(args[-1], ExprOp):
             if args[-1].op == 'rrx':
-                args[-1] = ExprCompose(
-                    [(args[-1].args[0][1:], 0, 31), (cf, 31, 32)])
+                args[-1] = ExprCompose(args[-1].args[0][1:], cf)
             elif (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>'] and
                   isinstance(args[-1].args[-1], ExprId)):
                 args[-1] = ExprOp(args[-1].op,
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index d03772ca..dea822b4 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -99,7 +99,7 @@ def bne(arg1, arg2, arg3):
 def lui(arg1, arg2):
     """The immediate value @arg2 is shifted left 16 bits and stored in the
     register @arg1. The lower 16 bits are zeroes."""
-    arg1 = ExprCompose([(i16(0), 0, 16), (arg2[:16], 16, 32)])
+    arg1 = ExprCompose(i16(0), arg2[:16])
 
 @sbuild.parse
 def nop():
@@ -251,10 +251,7 @@ def bgtz(arg1, arg2):
 
 @sbuild.parse
 def wsbh(arg1, arg2):
-    arg1 = ExprCompose([(arg2[8:16],  0, 8),
-                        (arg2[0:8]  , 8, 16),
-                        (arg2[24:32], 16, 24),
-                        (arg2[16:24], 24, 32)])
+    arg1 = ExprCompose(arg2[8:16], arg2[0:8], arg2[24:32], arg2[16:24])
 
 @sbuild.parse
 def rotr(arg1, arg2, arg3):
diff --git a/miasm2/arch/msp430/sem.py b/miasm2/arch/msp430/sem.py
index 169a631f..a99e500c 100644
--- a/miasm2/arch/msp430/sem.py
+++ b/miasm2/arch/msp430/sem.py
@@ -250,8 +250,7 @@ def call(ir, instr, a):
 def swpb(ir, instr, a):
     e = []
     x, y = a[:8], a[8:16]
-    e.append(ExprAff(a, ExprCompose([(y, 0, 8),
-                                     (x, 8, 16)])))
+    e.append(ExprAff(a, ExprCompose(y, x)))
     return e, []
 
 
@@ -330,8 +329,7 @@ def jmp(ir, instr, a):
 
 def rrc_w(ir, instr, a):
     e = []
-    c = ExprCompose([(a[1:16], 0, 15),
-                   (cf, 15, 16)])
+    c = ExprCompose(a[1:16], cf)
     e.append(ExprAff(a, c))
     e.append(ExprAff(cf, a[:1]))
     # e += update_flag_zn_r(c)
@@ -347,8 +345,7 @@ def rrc_w(ir, instr, a):
 
 def rra_w(ir, instr, a):
     e = []
-    c = ExprCompose([(a[1:16], 0, 15),
-                   (a[15:16], 15, 16)])
+    c = ExprCompose(a[1:16], a[15:16])
     e.append(ExprAff(a, c))
     # TODO: error in disasm microcorruption?
     # e.append(ExprAff(cf, a[:1]))
@@ -406,18 +403,7 @@ mnemo_func = {
 }
 
 
-composed_sr = ExprCompose([
-    (cf,   0,  1),
-    (zf,   1,  2),
-    (nf,   2,  3),
-    (gie,  3,  4),
-    (cpuoff,  4,  5),
-    (osc,  5,  6),
-    (scg0, 6,  7),
-    (scg1, 7,  8),
-    (of, 8,  9),
-    (res, 9, 16),
-])
+composed_sr = ExprCompose(cf, zf, nf, gie, cpuoff, osc, scg0, scg1, of, res)
 
 
 def ComposeExprAff(dst, src):
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 69c21ac8..5dc49efc 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -331,9 +331,7 @@ def xadd(ir, instr, a, b):
 
 def adc(ir, instr, a, b):
     e = []
-    c = a + (b + m2_expr.ExprCompose([(m2_expr.ExprInt(0, a.size - 1),
-                                       1, a.size),
-                                      (cf, 0, 1)]))
+    c = a + (b + m2_expr.ExprCompose(cf, m2_expr.ExprInt(0, a.size - 1)))
     e += update_flag_arith(c)
     e += update_flag_af(a, b, c)
     e += update_flag_add(a, b, c)
@@ -355,9 +353,7 @@ def sub(ir, instr, a, b):
 
 def sbb(ir, instr, a, b):
     e = []
-    c = a - (b + m2_expr.ExprCompose([(m2_expr.ExprInt(0, a.size - 1),
-                                       1, a.size),
-                                      (cf, 0, 1)]))
+    c = a - (b + m2_expr.ExprCompose(cf, m2_expr.ExprInt(0, a.size - 1)))
     e += update_flag_arith(c)
     e += update_flag_af(a, b, c)
     e += update_flag_sub(a, b, c)
@@ -898,25 +894,12 @@ def setalc(ir, instr):
 def bswap(ir, instr, a):
     e = []
     if a.size == 16:
-        c = m2_expr.ExprCompose([(a[:8],        8, 16),
-                                 (a[8:16],      0,  8),
-                                 ])
+        c = m2_expr.ExprCompose(a[8:16], a[:8])
     elif a.size == 32:
-        c = m2_expr.ExprCompose([(a[:8],      24, 32),
-                                 (a[8:16],    16, 24),
-                                 (a[16:24],   8, 16),
-                                 (a[24:32],   0, 8),
-                                 ])
+        c = m2_expr.ExprCompose(a[24:32], a[16:24], a[8:16], a[:8])
     elif a.size == 64:
-        c = m2_expr.ExprCompose([(a[:8],      56, 64),
-                                 (a[8:16],    48, 56),
-                                 (a[16:24],   40, 48),
-                                 (a[24:32],   32, 40),
-                                 (a[32:40],   24, 32),
-                                 (a[40:48],   16, 24),
-                                 (a[48:56],    8, 16),
-                                 (a[56:64],    0, 8),
-                                 ])
+        c = m2_expr.ExprCompose(a[56:64], a[48:56], a[40:48], a[32:40],
+                                a[24:32], a[16:24], a[8:16], a[:8])
     else:
         raise ValueError('the size DOES matter')
     e.append(m2_expr.ExprAff(a, c))
@@ -986,24 +969,18 @@ def scas(ir, instr, size):
 def compose_eflag(s=32):
     args = []
 
-    regs = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(
-        0), af, m2_expr.ExprInt1(0), zf, nf, tf, i_f, df, of]
-    for i in xrange(len(regs)):
-        args.append((regs[i], i, i + 1))
-
-    args.append((iopl, 12, 14))
+    args = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af,
+            m2_expr.ExprInt1(0), zf, nf, tf, i_f, df, of, iopl]
 
     if s == 32:
-        regs = [nt, m2_expr.ExprInt1(0), rf, vm, ac, vif, vip, i_d]
+        args += [nt, m2_expr.ExprInt1(0), rf, vm, ac, vif, vip, i_d]
     elif s == 16:
-        regs = [nt, m2_expr.ExprInt1(0)]
+        args += [nt, m2_expr.ExprInt1(0)]
     else:
         raise ValueError('unk size')
-    for i in xrange(len(regs)):
-        args.append((regs[i], i + 14, i + 15))
     if s == 32:
-        args.append((m2_expr.ExprInt(0, 10), 22, 32))
-    return m2_expr.ExprCompose(args)
+        args.append(m2_expr.ExprInt(0, 10))
+    return m2_expr.ExprCompose(*args)
 
 
 def pushfd(ir, instr):
@@ -1426,8 +1403,7 @@ def div(ir, instr, a):
         b = mRAX[instr.mode][:16]
     elif size in [16, 32, 64]:
         s1, s2 = mRDX[size], mRAX[size]
-        b = m2_expr.ExprCompose([(s2, 0, size),
-                                 (s1, size, size * 2)])
+        b = m2_expr.ExprCompose(s2, s1)
     else:
         raise ValueError('div arg not impl', a)
 
@@ -1436,8 +1412,7 @@ def div(ir, instr, a):
 
     # if 8 bit div, only ax is affected
     if size == 8:
-        e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose([(c_d[:8], 0, 8),
-                                                         (c_r[:8], 8, 16)])))
+        e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose(c_d[:8], c_r[:8])))
     else:
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
@@ -1454,8 +1429,7 @@ def idiv(ir, instr, a):
         b = mRAX[instr.mode][:16]
     elif size in [16, 32, 64]:
         s1, s2 = mRDX[size], mRAX[size]
-        b = m2_expr.ExprCompose([(s2, 0, size),
-                                 (s1, size, size * 2)])
+        b = m2_expr.ExprCompose(s2, s1)
     else:
         raise ValueError('div arg not impl', a)
 
@@ -1464,8 +1438,7 @@ def idiv(ir, instr, a):
 
     # if 8 bit div, only ax is affected
     if size == 8:
-        e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose([(c_d[:8], 0, 8),
-                                                         (c_r[:8], 8, 16)])))
+        e.append(m2_expr.ExprAff(b, m2_expr.ExprCompose(c_d[:8], c_r[:8])))
     else:
         e.append(m2_expr.ExprAff(s1, c_r[:size]))
         e.append(m2_expr.ExprAff(s2, c_d[:size]))
@@ -2192,14 +2165,10 @@ def fyl2x(ir, instr):
 def fnstenv(ir, instr, a):
     e = []
     # XXX TODO tag word, ...
-    status_word = m2_expr.ExprCompose([(m2_expr.ExprInt8(0), 0, 8),
-                                       (float_c0,           8, 9),
-                                       (float_c1,           9, 10),
-                                       (float_c2,           10, 11),
-                                       (float_stack_ptr,    11, 14),
-                                       (float_c3,           14, 15),
-                                       (m2_expr.ExprInt1(0), 15, 16),
-                                       ])
+    status_word = m2_expr.ExprCompose(m2_expr.ExprInt8(0),
+                                      float_c0, float_c1, float_c2,
+                                      float_stack_ptr, float_c3,
+                                      m2_expr.ExprInt1(0))
 
     s = instr.mode
     # The behaviour in 64bit is identical to 32 bit
@@ -2497,15 +2466,15 @@ def fabs(ir, instr):
 def fnstsw(ir, instr, dst):
     args = [
         # Exceptions -> 0
-        (m2_expr.ExprInt8(0), 0, 8),
-        (float_c0,           8, 9),
-        (float_c1,           9, 10),
-        (float_c2,           10, 11),
-        (float_stack_ptr,    11, 14),
-        (float_c3,           14, 15),
+        m2_expr.ExprInt8(0),
+        float_c0,
+        float_c1,
+        float_c2,
+        float_stack_ptr,
+        float_c3,
         # B: FPU is not busy -> 0
-        (m2_expr.ExprInt1(0), 15, 16)]
-    e = [m2_expr.ExprAff(dst, m2_expr.ExprCompose(args))]
+        m2_expr.ExprInt1(0)]
+    e = [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*args))]
     return e, []
 
 
@@ -2656,11 +2625,9 @@ def das(ir, instr):
 def aam(ir, instr, a):
     e = []
     tempAL = mRAX[instr.mode][0:8]
-    newEAX = m2_expr.ExprCompose([
-        (tempAL % a,           0,  8),
-                        (tempAL / a,           8,  16),
-                        (mRAX[instr.mode][16:], 16, mRAX[instr.mode].size),
-    ])
+    newEAX = m2_expr.ExprCompose(tempAL % a,
+                                 tempAL / a,
+                                 mRAX[instr.mode][16:])
     e += [m2_expr.ExprAff(mRAX[instr.mode], newEAX)]
     e += update_flag_arith(newEAX)
     e.append(m2_expr.ExprAff(af, m2_expr.ExprInt1(0)))
@@ -2671,12 +2638,9 @@ def aad(ir, instr, a):
     e = []
     tempAL = mRAX[instr.mode][0:8]
     tempAH = mRAX[instr.mode][8:16]
-    newEAX = m2_expr.ExprCompose([
-        ((tempAL + (tempAH * a)) & m2_expr.ExprInt8(0xFF), 0,  8),
-            (m2_expr.ExprInt8(0),                              8,  16),
-            (mRAX[instr.mode][16:],
-             16, mRAX[instr.mode].size),
-    ])
+    newEAX = m2_expr.ExprCompose((tempAL + (tempAH * a)) & m2_expr.ExprInt8(0xFF),
+                                 m2_expr.ExprInt8(0),
+                                 mRAX[instr.mode][16:])
     e += [m2_expr.ExprAff(mRAX[instr.mode], newEAX)]
     e += update_flag_arith(newEAX)
     e.append(m2_expr.ExprAff(af, m2_expr.ExprInt1(0)))
@@ -2908,9 +2872,8 @@ def l_outs(ir, instr, size):
 
 def xlat(ir, instr):
     e = []
-    a = m2_expr.ExprCompose([(m2_expr.ExprInt(0, 24), 8, 32),
-                             (mRAX[instr.mode][0:8], 0, 8)])
-    b = m2_expr.ExprMem(m2_expr.ExprOp('+', mRBX[instr.mode], a), 8)
+    a = mRAX[instr.mode][0:8].zeroExtend(mRBX[instr.mode].size)
+    b = m2_expr.ExprMem(mRBX[instr.mode] + a, 8)
     e.append(m2_expr.ExprAff(mRAX[instr.mode][0:8], b))
     return e, []
 
@@ -3073,13 +3036,10 @@ def lgs(ir, instr, a, b):
 
 def lahf(ir, instr):
     e = []
-    args = []
-    regs = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af,
+    args = [cf, m2_expr.ExprInt1(1), pf, m2_expr.ExprInt1(0), af,
             m2_expr.ExprInt1(0), zf, nf]
-    for i in xrange(len(regs)):
-        args.append((regs[i], i, i + 1))
     e.append(
-        m2_expr.ExprAff(mRAX[instr.mode][8:16], m2_expr.ExprCompose(args)))
+        m2_expr.ExprAff(mRAX[instr.mode][8:16], m2_expr.ExprCompose(*args)))
     return e, []
 
 
@@ -3128,11 +3088,9 @@ def l_str(ir, instr, a):
 def movd(ir, instr, a, b):
     e = []
     if a in regs_mm_expr:
-        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32),
-                                                         (m2_expr.ExprInt32(0), 32, 64)])))
+        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt32(0))))
     elif a in regs_xmm_expr:
-        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32),
-                                                         (m2_expr.ExprInt(0, 96), 32, 128)])))
+        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt(0, 96))))
     else:
         e.append(m2_expr.ExprAff(a, b[:32]))
     return e, []
@@ -3187,8 +3145,7 @@ def wrmsr(ir, instr):
     msr_addr = m2_expr.ExprId('MSR') + m2_expr.ExprInt32(
         8) * mRCX[instr.mode][:32]
     e = []
-    src = m2_expr.ExprCompose([(mRAX[instr.mode][:32], 0, 32),
-                               (mRDX[instr.mode][:32], 32, 64)])
+    src = m2_expr.ExprCompose(mRAX[instr.mode][:32], mRDX[instr.mode][:32])
     e.append(m2_expr.ExprAff(m2_expr.ExprMem(msr_addr, 64), src))
     return e, []
 
@@ -3216,17 +3173,14 @@ def vec_vertical_sem(op, elt_size, reg_size, a, b):
     assert(reg_size % elt_size == 0)
     n = reg_size / elt_size
     if op == '-':
-        ops = [(
+        ops = [
             (a[i * elt_size:(i + 1) * elt_size]
-             - b[i * elt_size:(i + 1) * elt_size]),
-               i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)]
+             - b[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)]
     else:
-        ops = [(m2_expr.ExprOp(op, a[i * elt_size:(i + 1) * elt_size],
-                               b[i * elt_size:(i + 1) * elt_size]),
-                i * elt_size,
-                (i + 1) * elt_size) for i in xrange(0, n)]
+        ops = [m2_expr.ExprOp(op, a[i * elt_size:(i + 1) * elt_size],
+                              b[i * elt_size:(i + 1) * elt_size]) for i in xrange(0, n)]
 
-    return m2_expr.ExprCompose(ops)
+    return m2_expr.ExprCompose(*ops)
 
 
 def float_vec_vertical_sem(op, elt_size, reg_size, a, b):
@@ -3236,24 +3190,22 @@ def float_vec_vertical_sem(op, elt_size, reg_size, a, b):
     x_to_int, int_to_x = {32: ('float_to_int_%d', 'int_%d_to_float'),
                           64: ('double_to_int_%d', 'int_%d_to_double')}[elt_size]
     if op == '-':
-        ops = [(m2_expr.ExprOp(x_to_int % elt_size,
-                               m2_expr.ExprOp(int_to_x % elt_size, a[i * elt_size:(i + 1) * elt_size]) -
-                               m2_expr.ExprOp(
-                                   int_to_x % elt_size, b[i * elt_size:(
-                                       i + 1) * elt_size])),
-                i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)]
+        ops = [m2_expr.ExprOp(x_to_int % elt_size,
+                              m2_expr.ExprOp(int_to_x % elt_size, a[i * elt_size:(i + 1) * elt_size]) -
+                              m2_expr.ExprOp(
+                                  int_to_x % elt_size, b[i * elt_size:(
+                                      i + 1) * elt_size])) for i in xrange(0, n)]
     else:
-        ops = [(m2_expr.ExprOp(x_to_int % elt_size,
-                               m2_expr.ExprOp(op,
-                                              m2_expr.ExprOp(
-                                                  int_to_x % elt_size, a[i * elt_size:(
-                                                      i + 1) * elt_size]),
-                                              m2_expr.ExprOp(
-                                                  int_to_x % elt_size, b[i * elt_size:(
-                                                      i + 1) * elt_size]))),
-                i * elt_size, (i + 1) * elt_size) for i in xrange(0, n)]
+        ops = [m2_expr.ExprOp(x_to_int % elt_size,
+                              m2_expr.ExprOp(op,
+                                             m2_expr.ExprOp(
+                                                 int_to_x % elt_size, a[i * elt_size:(
+                                                     i + 1) * elt_size]),
+                                             m2_expr.ExprOp(
+                                                 int_to_x % elt_size, b[i * elt_size:(
+                                                     i + 1) * elt_size]))) for i in xrange(0, n)]
 
-    return m2_expr.ExprCompose(ops)
+    return m2_expr.ExprCompose(*ops)
 
 
 def __vec_vertical_instr_gen(op, elt_size, sem):
@@ -3558,8 +3510,7 @@ def movss(ir, instr, a, b):
         e.append(m2_expr.ExprAff(a, b[:32]))
     else:
         # Source Mem Destination XMM
-        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose([(b, 0, 32),
-                                                         (m2_expr.ExprInt(0, 96), 32, 128)])))
+        e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(b, m2_expr.ExprInt(0, 96))))
     return e, []
 
 
@@ -3624,19 +3575,18 @@ def ps_rl_ll(ir, instr, a, b, op, size):
 
     slices = []
     for i in xrange(0, a.size, size):
-        slices.append((m2_expr.ExprOp(op, a[i:i + size], count[:size]),
-                       i, i + size))
+        slices.append(m2_expr.ExprOp(op, a[i:i + size], count[:size]))
 
     if isinstance(test, m2_expr.ExprInt):
         if int(test) == 0:
-            return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices))], []
+            return [m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(*slices))], []
         else:
             return [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size))], []
 
     e_zero = [m2_expr.ExprAff(a, m2_expr.ExprInt(0, a.size)),
               m2_expr.ExprAff(ir.IRDst, lbl_next)]
     e_do = []
-    e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(slices)))
+    e.append(m2_expr.ExprAff(a[0:a.size], m2_expr.ExprCompose(*slices)))
     e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_next))
     return e, [irbloc(lbl_do.name, [e_do]), irbloc(lbl_zero.name, [e_zero])]
 
@@ -3759,11 +3709,9 @@ def punpck(ir, instr, a, b, size, off):
     e = []
     slices = []
     for i in xrange(a.size / (2 * size)):
-        src1 = a[size * i + off: size * i + off + size]
-        src2 = b[size * i + off: size * i + off + size]
-        slices.append((src1, size * 2 * i, size * 2 * i + size))
-        slices.append((src2, size * (2 * i + 1), size * (2 * i + 1) + size))
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(slices)))
+        slices.append(a[size * i + off: size * i + off + size])
+        slices.append(b[size * i + off: size * i + off + size])
+    e.append(m2_expr.ExprAff(a, m2_expr.ExprCompose(*slices)))
     return e, []
 
 
@@ -3861,36 +3809,28 @@ def pextrq(ir, instr, a, b, c):
 
 def unpckhps(ir, instr, a, b):
     e = []
-    src = m2_expr.ExprCompose([(a[64:96], 0, 32),
-                               (b[64:96], 32, 64),
-                               (a[96:128], 64, 96),
-                               (b[96:128], 96, 128)])
+    src = m2_expr.ExprCompose(a[64:96], b[64:96], a[96:128], b[96:128])
     e.append(m2_expr.ExprAff(a, src))
     return e, []
 
 
 def unpckhpd(ir, instr, a, b):
     e = []
-    src = m2_expr.ExprCompose([(a[64:128], 0, 64),
-                               (b[64:128], 64, 128)])
+    src = m2_expr.ExprCompose(a[64:128], b[64:128])
     e.append(m2_expr.ExprAff(a, src))
     return e, []
 
 
 def unpcklps(ir, instr, a, b):
     e = []
-    src = m2_expr.ExprCompose([(a[0:32], 0, 32),
-                               (b[0:32], 32, 64),
-                               (a[32:64], 64, 96),
-                               (b[32:64], 96, 128)])
+    src = m2_expr.ExprCompose(a[0:32], b[0:32], a[32:64], b[32:64])
     e.append(m2_expr.ExprAff(a, src))
     return e, []
 
 
 def unpcklpd(ir, instr, a, b):
     e = []
-    src = m2_expr.ExprCompose([(a[0:64], 0, 64),
-                               (b[0:64], 64, 128)])
+    src = m2_expr.ExprCompose(a[0:64], b[0:64])
     e.append(m2_expr.ExprAff(a, src))
     return e, []
 
@@ -3940,10 +3880,9 @@ def sqrt_gen(ir, instr, a, b, size):
     e = []
     out = []
     for i in b.size / size:
-        out.append((m2_expr.ExprOp('fsqrt' % size,
-                                   b[i * size: (i + 1) * size]),
-                    i * size, (i + 1) * size))
-    src = m2_expr.ExprCompose(out)
+        out.append(m2_expr.ExprOp('fsqrt' % size,
+                                  b[i * size: (i + 1) * size]))
+    src = m2_expr.ExprCompose(*out)
     e.append(m2_expr.ExprAff(a, src))
     return e, []
 
@@ -3976,8 +3915,8 @@ def pmovmskb(ir, instr, a, b):
     e = []
     out = []
     for i in xrange(b.size / 8):
-        out.append((b[8 * i + 7:8 * (i + 1)], i, i + 1))
-    src = m2_expr.ExprCompose(out)
+        out.append(b[8 * i + 7:8 * (i + 1)])
+    src = m2_expr.ExprCompose(*out)
     e.append(m2_expr.ExprAff(a, src.zeroExtend(a.size)))
     return e, []
 
diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py
index 7f80b64e..27401049 100644
--- a/miasm2/core/sembuilder.py
+++ b/miasm2/core/sembuilder.py
@@ -16,7 +16,7 @@ class MiasmTransformer(ast.NodeTransformer):
     X if Y else Z -> ExprCond(Y, X, Z)
     'X'(Y)        -> ExprOp('X', Y)
     ('X' % Y)(Z)  -> ExprOp('X' % Y, Z)
-    {a, b}        -> ExprCompose([(a, 0, a.size), (b, a.size, a.size + b.size)])
+    {a, b}        -> ExprCompose(((a, 0, a.size), (b, a.size, a.size + b.size)))
     """
 
     # Parsers
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index d51f0bdb..d18bc751 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -322,12 +322,10 @@ class Expr(object):
         if self.size == size:
             return self
         ad_size = size - self.size
-        c = ExprCompose([(self, 0, self.size),
-                         (ExprCond(self.msb(),
-                                   ExprInt(size2mask(ad_size), ad_size),
-                                   ExprInt(0, ad_size)),
-                          self.size, size)
-                         ])
+        c = ExprCompose(self,
+                        ExprCond(self.msb(),
+                                 ExprInt(size2mask(ad_size), ad_size),
+                                 ExprInt(0, ad_size)))
         return c
 
     def graph_recursive(self, graph):
@@ -1056,25 +1054,33 @@ class ExprSlice(Expr):
 class ExprCompose(Expr):
 
     """
-    Compose is like a hambuger.
-    It's arguments are tuple of:  (Expression, start, stop)
-    start and stop are intergers, determining Expression position in the compose.
-
-    Burger Example:
-    ExprCompose([(salad, 0, 3), (cheese, 3, 10), (beacon, 10, 16)])
-    In the example, salad.size == 3.
+    Compose is like a hambuger. It concatenate Expressions
     """
 
     __slots__ = Expr.__slots__ + ["__args"]
 
-    def __init__(self, args):
+    def __init__(self, *args):
         """Create an ExprCompose
         The ExprCompose is contiguous and starts at 0
-        @args: tuple(Expr, int, int)
+        @args: [Expr, Expr, ...]
+        DEPRECATED:
+        @args: [(Expr, int, int), (Expr, int, int), ...]
         """
 
         super(ExprCompose, self).__init__()
 
+        is_new_style = args and isinstance(args[0], Expr)
+        if is_new_style:
+            new_args = []
+            index = 0
+            for arg in args:
+                new_args.append((arg, index, index + arg.size))
+                index += arg.size
+            args = new_args
+        else:
+            assert len(args) == 1
+            args = args[0]
+
         last_stop = 0
         args = sorted(args, key=itemgetter(1))
         for e, start, stop in args:
@@ -1106,12 +1112,15 @@ class ExprCompose(Expr):
     def __setstate__(self, state):
         self.__init__(state)
 
-    def __new__(cls, args):
+    def __new__(cls, *args):
+        is_new_style = args and isinstance(args[0], Expr)
+        if not is_new_style:
+            assert len(args) == 1
+            args = args[0]
         return Expr.get_object(cls, tuple(args))
 
     def __str__(self):
-        return '{' + ', '.join(['%s,%d,%d' %
-                                (str(arg[0]), arg[1], arg[2]) for arg in self.__args]) + '}'
+        return '{' + ', '.join([str(arg[0]) for arg in self.__args]) + '}'
 
     def get_r(self, mem_read=False, cst_read=False):
         return reduce(lambda elements, arg:
@@ -1127,7 +1136,7 @@ class ExprCompose(Expr):
         return hash(tuple(h_args))
 
     def _exprrepr(self):
-        return "%s(%r)" % (self.__class__.__name__, self.__args)
+        return "%s([%r])" % (self.__class__.__name__, self.__args)
 
     def __contains__(self, e):
         if self == e:
diff --git a/miasm2/ir/translators/miasm.py b/miasm2/ir/translators/miasm.py
index ef91cfb1..515148ee 100644
--- a/miasm2/ir/translators/miasm.py
+++ b/miasm2/ir/translators/miasm.py
@@ -27,9 +27,9 @@ class TranslatorMiasm(Translator):
                                    ", ".join(map(self.from_expr, expr.args)))
 
     def from_ExprCompose(self, expr):
-        args = ["(%s, %d, %d)" % (self.from_expr(arg), start, stop)
-                for arg, start, stop in expr.args]
-        return "ExprCompose([%s])" % ", ".join(args)
+        args = ["%s" % self.from_expr(arg)
+                for arg, _, _ in expr.args]
+        return "ExprCompose(%s)" % ", ".join(args)
 
     def from_ExprAff(self, expr):
         return "ExprAff(%s, %s)" % (self.from_expr(expr.dst),
diff --git a/test/arch/arm/sem.py b/test/arch/arm/sem.py
index cefbe76a..8fc609fb 100644
--- a/test/arch/arm/sem.py
+++ b/test/arch/arm/sem.py
@@ -285,7 +285,7 @@ class TestARMSemantic(unittest.TestCase):
         self.assertEqual(compute('AND                R4,    R4,   R5    LSR 2 ',  {R4: 0xFFFFFFFF, R5: 0x80000041, }), {R4: 0x20000010, R5: 0x80000041, })
         self.assertEqual(compute('AND                R4,    R4,   R5    ASR 3 ',  {R4: 0xF00000FF, R5: 0x80000081, }), {R4: 0xF0000010, R5: 0x80000081, })
         self.assertEqual(compute('AND                R4,    R4,   R5    ROR 4 ',  {R4: 0xFFFFFFFF, R5: 0x000000FF, }), {R4: 0xF000000F, R5: 0x000000FF, })
-        self.assertEqual(compute('AND                R4,    R4,   R5    RRX   ',  {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose([(ExprInt(0x80, 31),0,31), (cf_init,31,32)]), R5: 0x00000101, })
+        self.assertEqual(compute('AND                R4,    R4,   R5    RRX   ',  {R4: 0xFFFFFFFF, R5: 0x00000101, }), {R4: ExprCompose(ExprInt(0x80, 31), cf_init), R5: 0x00000101, })
 
         # §A8.8.15:                AND{S}{<c>}{<q>} {<Rd>,} <Rn>, <Rm>, <type> <Rs>
         self.assertEqual(compute('AND                R4,    R6,   R4    LSL R5',  {R4: 0x00000001, R5: 0x00000004, R6: -1, }), {R4: 0x00000010, R5: 0x00000004, R6: 0xFFFFFFFF, })
diff --git a/test/expression/expression.py b/test/expression/expression.py
index 90236744..847ba7eb 100644
--- a/test/expression/expression.py
+++ b/test/expression/expression.py
@@ -30,10 +30,10 @@ for expr in [
         A + cst1,
         A + ExprCond(cond1, cst1, cst2),
         ExprCond(cond1, cst1, cst2) + ExprCond(cond2, cst3, cst4),
-        ExprCompose([(A, 0, 32), (cst1, 32, 64)]),
-        ExprCompose([(ExprCond(cond1, cst1, cst2), 0, 32), (A, 32, 64)]),
-        ExprCompose([(ExprCond(cond1, cst1, cst2), 0, 32),
-                     (ExprCond(cond2, cst3, cst4), 32, 64)]),
+        ExprCompose(A, cst1),
+        ExprCompose(ExprCond(cond1, cst1, cst2), A),
+        ExprCompose(ExprCond(cond1, cst1, cst2),
+                    ExprCond(cond2, cst3, cst4)),
         ExprCond(ExprCond(cond1, cst1, cst2), cst3, cst4),
 ]:
     print "*" * 80
diff --git a/test/expression/expression_helper.py b/test/expression/expression_helper.py
index 514a9a51..a3a8fba4 100644
--- a/test/expression/expression_helper.py
+++ b/test/expression/expression_helper.py
@@ -16,11 +16,10 @@ class TestExpressionExpressionHelper(unittest.TestCase):
         ebx = m2_expr.ExprId("EBX")
         ax = eax[0:16]
         expr = eax + ebx
-        expr = m2_expr.ExprCompose([(ax, 0, 16), (expr[16:32], 16, 32)])
+        expr = m2_expr.ExprCompose(ax, expr[16:32])
         expr2 = m2_expr.ExprMem((eax + ebx) ^ (eax), size=16)
         expr2 = expr2 | ax | expr2 | cst
-        exprf = expr - expr + m2_expr.ExprCompose([(expr2, 0, 16),
-                                                   (cst, 16, 32)])
+        exprf = expr - expr + m2_expr.ExprCompose(expr2, cst)
 
         # Identify variables
         vi = Variables_Identifier(exprf)
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 99cc7c35..bf658a30 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -24,11 +24,9 @@ i2 = ExprInt(uint32(0x2))
 icustom = ExprInt(uint32(0x12345678))
 cc = ExprCond(a, b, c)
 
-o = ExprCompose([(a[:8], 8, 16),
-                 (a[8:16], 0, 8)])
+o = ExprCompose(a[8:16], a[:8])
 
-o2 = ExprCompose([(a[8:16], 0, 8),
-                 (a[:8], 8, 16)])
+o2 = ExprCompose(a[8:16], a[:8])
 
 l = [a[:8], b[:8], c[:8], m[:8], s, i1[:8], i2[:8], o[:8]]
 l2 = l[::-1]
@@ -93,11 +91,11 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
            (a[8:16][:8], a[8:16]),
            (a[8:32][:8], a[8:16]),
            (a[:16][8:16], a[8:16]),
-           (ExprCompose([(a, 0, 32)]), a),
-           (ExprCompose([(a[:16], 0, 16)]), a[:16]),
-           (ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]),
-            ExprCompose([(a[:16], 0, 16), (a[:16], 16, 32)]),),
-           (ExprCompose([(a[:16], 0, 16), (a[16:32], 16, 32)]), a),
+           (ExprCompose(a), a),
+           (ExprCompose(a[:16]), a[:16]),
+           (ExprCompose(a[:16], a[:16]),
+            ExprCompose(a[:16], a[:16]),),
+           (ExprCompose(a[:16], a[16:32]), a),
 
            (ExprMem(a)[:32], ExprMem(a)),
            (ExprMem(a)[:16], ExprMem(a, size=16)),
@@ -106,14 +104,12 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
            (ExprCond(ExprInt32(0), b, a), a),
 
            (ExprInt32(0x80000000)[31:32], ExprInt1(1)),
-           (ExprCompose([
-               (ExprInt16(0x1337)[
-                   :8], 0, 8), (ExprInt16(0x1337)[8:16], 8, 16)]),
+           (ExprCompose(ExprInt16(0x1337)[:8], ExprInt16(0x1337)[8:16]),
             ExprInt16(0x1337)),
 
-           (ExprCompose([(ExprInt32(0x1337beef)[8:16], 8, 16),
-                        (ExprInt32(0x1337beef)[:8], 0, 8),
-                        (ExprInt32(0x1337beef)[16:32], 16, 32)]),
+           (ExprCompose(ExprInt32(0x1337beef)[:8],
+                        ExprInt32(0x1337beef)[8:16],
+                        ExprInt32(0x1337beef)[16:32]),
             ExprInt32(0x1337BEEF)),
            (ExprCond(a,
                      ExprCond(a,
@@ -122,9 +118,9 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
                      d), ExprCond(a, b, d)),
            ((a & b & ExprInt32(0x12))[31:32], ExprInt1(0)),
 
-           (ExprCompose([
-               (ExprCond(a, ExprInt16(0x10), ExprInt16(0x20)), 0, 16),
-    (ExprInt16(0x1337), 16, 32)]),
+           (ExprCompose(
+               ExprCond(a, ExprInt16(0x10), ExprInt16(0x20)),
+               ExprInt16(0x1337)),
                ExprCond(a, ExprInt32(0x13370010), ExprInt32(0x13370020))),
     (ExprCond(ExprCond(a, ExprInt1(0), ExprInt1(1)), b, c),
      ExprCond(a, c, b)),
@@ -167,103 +163,99 @@ to_test = [(ExprInt32(1) - ExprInt32(1), ExprInt32(0)),
     (ExprOp('-', ExprInt8(1), ExprInt8(0)),
      ExprInt8(1)),
 
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x20),
-     ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x10),
-     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x30),
-     ExprCompose([(ExprInt(0, 48), 0, 48), (a[:0x10], 48, 64)])),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x11),
-     ExprCompose([(ExprInt(0, 0x11), 0, 0x11), (a, 0x11, 0x31), (ExprInt(0, 0xF), 0x31, 0x40)])),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x40),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x20),
+     ExprCompose(ExprInt32(0), a)),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x10),
+     ExprCompose(ExprInt16(0), a, ExprInt16(0))),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x30),
+     ExprCompose(ExprInt(0, 48), a[:0x10])),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x11),
+     ExprCompose(ExprInt(0, 0x11), a, ExprInt(0, 0xF))),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x40),
      ExprInt64(0)),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) << ExprInt64(0x50),
+    (ExprCompose(a, ExprInt32(0)) << ExprInt64(0x50),
      ExprInt64(0)),
 
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x20),
-     ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)])),
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x10),
-     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (ExprInt16(0), 48, 64)])),
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x30),
-     ExprCompose([(a[0x10:], 0, 16), (ExprInt(0, 48), 16, 64)])),
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x11),
-     ExprCompose([(ExprInt(0, 0xf), 0, 0xf), (a, 0xf, 0x2f), (ExprInt(0, 0x11), 0x2f, 0x40)])),
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x40),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x20),
+     ExprCompose(a, ExprInt32(0))),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x10),
+     ExprCompose(ExprInt16(0), a, ExprInt16(0))),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x30),
+     ExprCompose(a[0x10:], ExprInt(0, 48))),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x11),
+     ExprCompose(ExprInt(0, 0xf), a, ExprInt(0, 0x11))),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x40),
      ExprInt64(0)),
-    (ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)]) >> ExprInt64(0x50),
+    (ExprCompose(ExprInt32(0), a) >> ExprInt64(0x50),
      ExprInt64(0)),
 
 
-    (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x20),
-     ExprCompose([(ExprInt32(0), 0, 32), (a, 32, 64)])),
-    (ExprCompose([(a, 0, 32), (b, 32, 64)]) << ExprInt64(0x10),
-     ExprCompose([(ExprInt16(0), 0, 16), (a, 16, 48), (b[:16], 48, 64)])),
+    (ExprCompose(a, b) << ExprInt64(0x20),
+     ExprCompose(ExprInt32(0), a)),
+    (ExprCompose(a, b) << ExprInt64(0x10),
+     ExprCompose(ExprInt16(0), a, b[:16])),
 
-    (ExprCompose([(a, 0, 32), (b, 32, 64)]) | ExprCompose([(c, 0, 32), (d, 32, 64)]),
-     ExprCompose([(a|c, 0, 32), (b|d, 32, 64)])),
-    (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (d, 32, 64)]),
-     ExprCompose([(a, 0, 32), (d, 32, 64)])),
-    (ExprCompose([(f[:32], 0, 32), (ExprInt32(0), 32, 64)]) | ExprCompose([(ExprInt32(0), 0, 32), (f[32:], 32, 64)]),
+    (ExprCompose(a, b) | ExprCompose(c, d),
+     ExprCompose(a|c, b|d)),
+    (ExprCompose(a, ExprInt32(0)) | ExprCompose(ExprInt32(0), d),
+     ExprCompose(a, d)),
+    (ExprCompose(f[:32], ExprInt32(0)) | ExprCompose(ExprInt32(0), f[32:]),
      f),
-    ((ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) * ExprInt64(0x123))[32:64],
-     (ExprCompose([(a, 0, 32), (ExprInt32(0), 32, 64)]) * ExprInt64(0x123))[32:64]),
+    ((ExprCompose(a, ExprInt32(0)) * ExprInt64(0x123))[32:64],
+     (ExprCompose(a, ExprInt32(0)) * ExprInt64(0x123))[32:64]),
 
     (ExprInt32(0x12),
      ExprInt32(0x12L)),
 
 
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[:16],
+    (ExprCompose(a, b, c)[:16],
      a[:16]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[16:32],
+    (ExprCompose(a, b, c)[16:32],
      a[16:]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[32:48],
+    (ExprCompose(a, b, c)[32:48],
      b[:16]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[48:64],
+    (ExprCompose(a, b, c)[48:64],
      b[16:]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[64:80],
+    (ExprCompose(a, b, c)[64:80],
      c[:16]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[80:],
+    (ExprCompose(a, b, c)[80:],
      c[16:]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[80:82],
+    (ExprCompose(a, b, c)[80:82],
      c[16:18]),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[16:48],
-     ExprCompose(((a[16:], 0, 16), (b[:16], 16, 32)))),
-    (ExprCompose(((a, 0, 32), (b, 32, 64), (c, 64, 96)))[48:80],
-     ExprCompose(((b[16:], 0, 16), (c[:16], 16, 32)))),
-
-    (ExprCompose(((a[0:8], 0, 8),
-                  (b[8:16], 8, 16),
-                  (ExprInt(uint48(0x0L)), 16, 64)))[12:32],
-     ExprCompose(((b[12:16], 0, 4), (ExprInt(uint16(0)), 4, 20)))
+    (ExprCompose(a, b, c)[16:48],
+     ExprCompose(a[16:], b[:16])),
+    (ExprCompose(a, b, c)[48:80],
+     ExprCompose(b[16:], c[:16])),
+
+    (ExprCompose(a[0:8], b[8:16], ExprInt(uint48(0x0L)))[12:32],
+     ExprCompose(b[12:16], ExprInt(uint16(0)))
        ),
 
-    (ExprCompose(((ExprCompose(((a[:8], 0, 8),
-                                (ExprInt(uint56(0x0L)), 8, 64)))[8:32]
-                   &
-                   ExprInt(uint24(0x1L)), 0, 24),
-                  (ExprInt(uint40(0x0L)), 24, 64))),
+    (ExprCompose(ExprCompose(a[:8], ExprInt(uint56(0x0L)))[8:32]
+                  &
+                  ExprInt(uint24(0x1L)),
+                  ExprInt(uint40(0x0L))),
      ExprInt64(0)),
 
-    (ExprCompose(((ExprCompose(((a[:8], 0, 8),
-                                (ExprInt(uint56(0x0L)), 8, 64)))[:8]
-                   &
-                   ExprInt(uint8(0x1L)), 0, 8),
-                  (ExprInt(uint56(0x0L)), 8, 64))),
-     ExprCompose(((a[:8]&ExprInt8(1), 0, 8), (ExprInt(uint56(0)), 8, 64)))),
-
-    (ExprCompose(((ExprCompose(((a[:8], 0, 8),
-                                (ExprInt(uint56(0x0L)), 8, 64)))[:32]
-                   &
-                   ExprInt(uint32(0x1L)), 0, 32),
-                  (ExprInt(uint32(0x0L)), 32, 64))),
-     ExprCompose(((ExprCompose(((ExprSlice(a, 0, 8), 0, 8),
-                                (ExprInt(uint24(0x0L)), 8, 32)))
-                   &
-                   ExprInt(uint32(0x1L)), 0, 32),
-                  (ExprInt(uint32(0x0L)), 32, 64)))
+    (ExprCompose(ExprCompose(a[:8], ExprInt(uint56(0x0L)))[:8]
+                 &
+                 ExprInt(uint8(0x1L)),
+                 (ExprInt(uint56(0x0L)))),
+     ExprCompose(a[:8]&ExprInt8(1), ExprInt(uint56(0)))),
+
+    (ExprCompose(ExprCompose(a[:8],
+                             ExprInt(uint56(0x0L)))[:32]
+                 &
+                 ExprInt(uint32(0x1L)),
+                 ExprInt(uint32(0x0L))),
+     ExprCompose(ExprCompose(ExprSlice(a, 0, 8),
+                             ExprInt(uint24(0x0L)))
+                 &
+                 ExprInt(uint32(0x1L)),
+                 ExprInt(uint32(0x0L)))
        ),
-    (ExprCompose([(a[:16], 0, 16), (b[:16], 16, 32)])[8:32],
-     ExprCompose([(a[8:16], 0, 8), (b[:16], 8, 24)])),
+    (ExprCompose(a[:16], b[:16])[8:32],
+     ExprCompose(a[8:16], b[:16])),
     ((a >> ExprInt32(16))[:16],
      a[16:32]),
     ((a >> ExprInt32(16))[8:16],
@@ -410,10 +402,10 @@ match_tests = [
     (MatchExpr(ExprCond(x, y, z),
                ExprCond(a, b, c), [a, b, c]),
      {a: x, b: y, c: z}),
-    (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]), a, [a]),
-     {a: ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)])}),
-    (MatchExpr(ExprCompose([(x[:8], 0, 8), (y[:8], 8, 16)]),
-               ExprCompose([(a[:8], 0, 8), (b[:8], 8, 16)]), [a, b]),
+    (MatchExpr(ExprCompose(x[:8], y[:8]), a, [a]),
+     {a: ExprCompose(x[:8], y[:8])}),
+    (MatchExpr(ExprCompose(x[:8], y[:8]),
+               ExprCompose(a[:8], b[:8]), [a, b]),
      {a: x, b: y}),
     (MatchExpr(e1, e2, [b]), {b: ExprInt32(0x10)}),
     (MatchExpr(e3,
diff --git a/test/ir/symbexec.py b/test/ir/symbexec.py
index 19cc47db..6df0bbc3 100644
--- a/test/ir/symbexec.py
+++ b/test/ir/symbexec.py
@@ -43,12 +43,12 @@ class TestSymbExec(unittest.TestCase):
         self.assertEqual(e.eval_expr(ExprMem(addr1 - addr1)), id_x)
         self.assertEqual(e.eval_expr(ExprMem(addr1, 8)), id_y)
         self.assertEqual(e.eval_expr(ExprMem(addr1 + addr1)), ExprCompose(
-            [(id_x[16:32], 0, 16), (ExprMem(ExprInt32(4), 16), 16, 32)]))
+            id_x[16:32], ExprMem(ExprInt32(4), 16)))
         self.assertEqual(e.eval_expr(mem8), ExprCompose(
-            [(id_x[0:24], 0, 24), (ExprMem(ExprInt32(11), 8), 24, 32)]))
+            id_x[0:24], ExprMem(ExprInt32(11), 8)))
         self.assertEqual(e.eval_expr(mem40v), id_x[:8])
         self.assertEqual(e.eval_expr(mem50w), ExprCompose(
-            [(id_y, 0, 8), (ExprMem(ExprInt32(51), 8), 8, 16)]))
+            id_y, ExprMem(ExprInt32(51), 8)))
         self.assertEqual(e.eval_expr(mem20), mem20)
         e.func_read = lambda x: x
         self.assertEqual(e.eval_expr(mem20), mem20)
diff --git a/test/ir/translators/z3_ir.py b/test/ir/translators/z3_ir.py
index e080c7f5..5fcfe25e 100644
--- a/test/ir/translators/z3_ir.py
+++ b/test/ir/translators/z3_ir.py
@@ -114,7 +114,7 @@ check_interp(model[memb.get_mem_array(32)],
              [(0xdeadbeef, 0), (0xdeadbeef + 3, 2)])
 
 # --------------------------------------------------------------------------
-e5 = ExprSlice(ExprCompose(((e, 0, 32), (four, 32, 64))), 0, 32) * five
+e5 = ExprSlice(ExprCompose(e, four), 0, 32) * five
 ez3 = Translator.to_language('z3').from_expr(e5)
 
 z3_e5 = z3.Extract(31, 0, z3.Concat(z3_four, z3_e)) * z3_five