about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/mips32/sem.py705
-rw-r--r--miasm2/core/sembuilder.py206
-rw-r--r--miasm2/jitter/arch/JitCore_arm.c2
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.c2
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.c2
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c2
-rw-r--r--test/core/sembuilder.py37
7 files changed, 495 insertions, 461 deletions
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index 0d62cc58..7eb9dcae 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -10,356 +10,304 @@ ctx = {"R_LO": R_LO,
        "R_HI": R_HI,
        "PC": PC,
        "RA": RA}
-ctx.update(m2_expr.__dict__)
 sbuild = SemBuilder(ctx)
 
 
 @sbuild.parse
-def addiu(Arg1, Arg2, Arg3):
-    """Adds a register @Arg3 and a sign-extended immediate value @Arg2 and
-    stores the result in a register @Arg1"""
-    Arg1 = Arg2 + Arg3
+def addiu(arg1, arg2, arg3):
+    """Adds a register @arg3 and a sign-extended immediate value @arg2 and
+    stores the result in a register @arg1"""
+    arg1 = arg2 + arg3
 
 @sbuild.parse
-def lw(Arg1, Arg2):
-    "A word is loaded into a register @Arg1 from the specified address @Arg2."
-    Arg1 = Arg2
+def lw(arg1, arg2):
+    "A word is loaded into a register @arg1 from the specified address @arg2."
+    arg1 = arg2
 
 @sbuild.parse
-def sw(Arg1, Arg2):
-    "The contents of @Arg2 is stored at the specified address @Arg1."
-    Arg2 = Arg1
+def sw(arg1, arg2):
+    "The contents of @arg2 is stored at the specified address @arg1."
+    arg2 = arg1
 
 @sbuild.parse
-def jal(Arg1):
-    "Jumps to the calculated address @Arg1 and stores the return address in $RA"
-    PC = Arg1
-    ir.IRDst = Arg1
+def jal(arg1):
+    "Jumps to the calculated address @arg1 and stores the return address in $RA"
+    PC = arg1
+    ir.IRDst = arg1
     RA = ExprId(ir.get_next_break_label(instr))
 
 @sbuild.parse
-def jalr(Arg1, Arg2):
-    """Jump to an address stored in a register @Arg1, and store the return
-    address in another register @Arg2"""
-    PC = Arg1
-    ir.IRDst = Arg1
-    Arg2 = ExprId(ir.get_next_break_label(instr))
+def jalr(arg1, arg2):
+    """Jump to an address stored in a register @arg1, and store the return
+    address in another register @arg2"""
+    PC = arg1
+    ir.IRDst = arg1
+    arg2 = ExprId(ir.get_next_break_label(instr))
 
 @sbuild.parse
-def bal(Arg1):
-    PC = Arg1
-    ir.IRDst = Arg1
+def bal(arg1):
+    PC = arg1
+    ir.IRDst = arg1
     RA = ExprId(ir.get_next_break_label(instr))
 
 @sbuild.parse
-def l_b(Arg1):
-    PC = Arg1
-    ir.IRDst = Arg1
+def l_b(arg1):
+    PC = arg1
+    ir.IRDst = arg1
 
 @sbuild.parse
-def lbu(Arg1, Arg2):
-    """A byte is loaded (unsigned extended) into a register @Arg1 from the
-    specified address @Arg2."""
-    Arg1 = mem8[Arg2.arg].zeroExtend(32)
+def lbu(arg1, arg2):
+    """A byte is loaded (unsigned extended) into a register @arg1 from the
+    specified address @arg2."""
+    arg1 = mem8[arg2.arg].zeroExtend(32)
 
 @sbuild.parse
-def lhu(Arg1, Arg2):
-    """A word is loaded (unsigned extended) into a register @Arg1 from the
-    specified address @Arg2."""
-    Arg1 = mem16[Arg2.arg].zeroExtend(32)
+def lhu(arg1, arg2):
+    """A word is loaded (unsigned extended) into a register @arg1 from the
+    specified address @arg2."""
+    arg1 = mem16[arg2.arg].zeroExtend(32)
 
 @sbuild.parse
-def lb(Arg1, Arg2):
-    "A byte is loaded into a register @Arg1 from the specified address @Arg2."
-    Arg1 = mem8[Arg2.arg].signExtend(32)
+def lb(arg1, arg2):
+    "A byte is loaded into a register @arg1 from the specified address @arg2."
+    arg1 = mem8[arg2.arg].signExtend(32)
 
 @sbuild.parse
-def beq(Arg1, Arg2, Arg3):
-    "Branches on @Arg3 if the quantities of two registers @Arg1, @Arg2 are eq"
-    dst = ExprId(ir.get_next_break_label(instr)) if Arg1 - Arg2 else Arg3
+def beq(arg1, arg2, arg3):
+    "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq"
+    dst = ExprId(ir.get_next_break_label(instr)) if arg1 - arg2 else arg3
     PC = dst
     ir.IRDst = dst
 
 @sbuild.parse
-def bgez(Arg1, Arg2):
-    """Branches on @Arg2 if the quantities of register @Arg1 is greater than or
+def bgez(arg1, arg2):
+    """Branches on @arg2 if the quantities of register @arg1 is greater than or
     equal to zero"""
-    dst = ExprId(ir.get_next_break_label(instr)) if Arg1.msb() else Arg2
+    dst = ExprId(ir.get_next_break_label(instr)) if arg1.msb() else arg2
     PC = dst
     ir.IRDst = dst
 
 @sbuild.parse
-def bne(Arg1, Arg2, Arg3):
-    """Branches on @Arg3 if the quantities of two registers @Arg1, @Arg2 are NOT
+def bne(arg1, arg2, arg3):
+    """Branches on @arg3 if the quantities of two registers @arg1, @arg2 are NOT
     equal"""
-    dst = Arg3 if Arg1 - Arg2 else ExprId(ir.get_next_break_label(instr))
+    dst = arg3 if arg1 - arg2 else ExprId(ir.get_next_break_label(instr))
     PC = dst
     ir.IRDst = dst
 
 @sbuild.parse
-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)])
+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)])
 
 @sbuild.parse
 def nop():
     """Do nothing"""
 
 @sbuild.parse
-def j(Arg1):
-    """Jump to an address @Arg1"""
-    PC = Arg1
-    ir.IRDst = Arg1
+def j(arg1):
+    """Jump to an address @arg1"""
+    PC = arg1
+    ir.IRDst = arg1
 
 @sbuild.parse
-def l_or(Arg1, Arg2, Arg3):
-    """Bitwise logical ors two registers @Arg2, @Arg3 and stores the result in a
-    register @Arg1"""
-    Arg1 = Arg2 | Arg3
+def l_or(arg1, arg2, arg3):
+    """Bitwise logical ors two registers @arg2, @arg3 and stores the result in a
+    register @arg1"""
+    arg1 = arg2 | arg3
 
 @sbuild.parse
-def nor(Arg1, Arg2, Arg3):
-    """Bitwise logical Nors two registers @Arg2, @Arg3 and stores the result in
-    a register @Arg1"""
-    Arg1 = (Arg2 | Arg3) ^ i32(-1)
+def nor(arg1, arg2, arg3):
+    """Bitwise logical Nors two registers @arg2, @arg3 and stores the result in
+    a register @arg1"""
+    arg1 = (arg2 | arg3) ^ i32(-1)
 
 @sbuild.parse
-def l_and(Arg1, Arg2, Arg3):
-    """Bitwise logical ands two registers @Arg2, @Arg3 and stores the result in
-    a register @Arg1"""
-    Arg1 = Arg2 & Arg3
+def l_and(arg1, arg2, arg3):
+    """Bitwise logical ands two registers @arg2, @arg3 and stores the result in
+    a register @arg1"""
+    arg1 = arg2 & arg3
 
-def ext(ir, instr, a, b, c, d):
-    e = []
-    pos = int(c.arg)
-    size = int(d.arg)
-    e.append(m2_expr.ExprAff(a, b[pos:pos+size].zeroExtend(32)))
-    return e, []
+@sbuild.parse
+def ext(arg1, arg2, arg3, arg4):
+    pos = int(arg3.arg)
+    size = int(arg4.arg)
+    arg1 = arg2[pos:pos + size].zeroExtend(32)
 
-def mul(ir, instr, a, b, c):
-    """Multiplies @b by $c and stores the result in @a."""
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('imul', b, c)))
-    return e, []
+@sbuild.parse
+def mul(arg1, arg2, arg3):
+    """Multiplies @arg2 by $arg3 and stores the result in @arg1."""
+    arg1 = 'imul'(arg2, arg3)
 
-def sltu(ir, instr, a, x, y):
-    """If @y is less than @x (unsigned), @a is set to one. It gets zero
+@sbuild.parse
+def sltu(arg1, arg2, arg3):
+    """If @arg3 is less than @arg2 (unsigned), @arg1 is set to one. It gets zero
     otherwise."""
-    e = []
-    value = (((x - y) ^ ((x ^ y) & ((x - y) ^ x))) ^ x ^ y).msb().zeroExtend(32)
-    e.append(m2_expr.ExprAff(a, value))
-    return e, []
+    arg1 = (((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))) ^ arg2 ^ arg3).msb().zeroExtend(32)
 
-def slt(ir, instr, a, x, y):
-    """If @y is less than @x (signed), @a is set to one. It gets zero
+@sbuild.parse
+def slt(arg1, arg2, arg3):
+    """If @arg3 is less than @arg2 (signed), @arg1 is set to one. It gets zero
     otherwise."""
-    e = []
-    value = ((x - y) ^ ((x ^ y) & ((x - y) ^ x))).zeroExtend(32)
-    e.append(m2_expr.ExprAff(a, value))
-    return e, []
-
-def l_sub(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, b-c))
-    return e, []
-
-def sb(ir, instr, a, b):
-    "The least significant byte of @a is stored at the specified address @b."
-    e = []
-    b = m2_expr.ExprMem(b.arg, 8)
-    e.append(m2_expr.ExprAff(b, a[:8]))
-    return e, []
+    arg1 = ((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))).zeroExtend(32)
 
-def sh(ir, instr, a, b):
-    e = []
-    b = m2_expr.ExprMem(b.arg, 16)
-    e.append(m2_expr.ExprAff(b, a[:16]))
-    return e, []
+@sbuild.parse
+def l_sub(arg1, arg2, arg3):
+    arg1 = arg2 - arg3
 
-def movn(ir, instr, a, b, c):
-    lbl_do = m2_expr.ExprId(ir.gen_label(), 32)
-    lbl_skip = m2_expr.ExprId(ir.get_next_instr(instr), 32)
-    e_do = []
-    e_do.append(m2_expr.ExprAff(a, b))
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
-    e = []
-    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(c, lbl_do, lbl_skip)))
+@sbuild.parse
+def sb(arg1, arg2):
+    """The least significant byte of @arg1 is stored at the specified address
+    @arg2."""
+    mem8[arg2.arg] = arg1[:8]
 
-    return e, [irbloc(lbl_do.name, [e_do], [])]
+@sbuild.parse
+def sh(arg1, arg2):
+    mem16[arg2.arg] = arg1[:16]
 
-def movz(ir, instr, a, b, c):
-    lbl_do = m2_expr.ExprId(ir.gen_label(), 32)
-    lbl_skip = m2_expr.ExprId(ir.get_next_instr(instr), 32)
-    e_do = []
-    e_do.append(m2_expr.ExprAff(a, b))
-    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
-    e = []
-    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(c, lbl_skip, lbl_do)))
+@sbuild.parse
+def movn(arg1, arg2, arg3):
+    if arg3:
+        arg1 = arg2
 
-    return e, [irbloc(lbl_do.name, [e_do], [])]
+@sbuild.parse
+def movz(arg1, arg2, arg3):
+    if not arg3:
+        arg1 = arg2
 
-def srl(ir, instr, a, b, c):
-    """Shifts a register value @b right by the shift amount @c and places the
-    value in the destination register @a. Zeroes are shifted in."""
-    e = []
-    e.append(m2_expr.ExprAff(a, b >> c))
-    return e, []
+@sbuild.parse
+def srl(arg1, arg2, arg3):
+    """Shifts arg1 register value @arg2 right by the shift amount @arg3 and
+    places the value in the destination register @arg1.
+    Zeroes are shifted in."""
+    arg1 = arg2 >> arg3
 
-def sra(ir, instr, a, b, c):
-    """Shifts a register value @b right by the shift amount @c and places the
-    value in the destination register @a. The sign bit is shifted in."""
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('a>>', b, c)))
-    return e, []
+@sbuild.parse
+def sra(arg1, arg2, arg3):
+    """Shifts arg1 register value @arg2 right by the shift amount @arg3 and
+    places the value in the destination register @arg1. The sign bit is shifted
+    in."""
+    arg1 = 'a>>'(arg2, arg3)
 
-def srav(ir, instr, a, b, c):
-    e = []
-    value = m2_expr.ExprOp('a>>', b, c&m2_expr.ExprInt32(0x1F))
-    e.append(m2_expr.ExprAff(a, value))
-    return e, []
+@sbuild.parse
+def srav(arg1, arg2, arg3):
+    arg1 = 'a>>'(arg2, arg3 & i32(0x1F))
 
-def sll(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, b<<c))
-    return e, []
+@sbuild.parse
+def sll(arg1, arg2, arg3):
+    arg1 = arg2 << arg3
 
-def srlv(ir, instr, a, b, c):
-    """Shifts a register value @b right by the amount specified in @c and places
-    the value in the destination register @a. Zeroes are shifted in."""
-    e = []
-    e.append(m2_expr.ExprAff(a, b >> (c & m2_expr.ExprInt32(0x1F))))
-    return e, []
+@sbuild.parse
+def srlv(arg1, arg2, arg3):
+    """Shifts a register value @arg2 right by the amount specified in @arg3 and
+    places the value in the destination register @arg1.
+    Zeroes are shifted in."""
+    arg1 = arg2 >> (arg3 & i32(0x1F))
 
-def sllv(ir, instr, a, b, c):
-    """Shifts a register value @b left by the amount specified in @c and places
-    the value in the destination register @a. Zeroes are shifted in."""
-    e = []
-    e.append(m2_expr.ExprAff(a, b << (c & m2_expr.ExprInt32(0x1F))))
-    return e, []
+@sbuild.parse
+def sllv(arg1, arg2, arg3):
+    """Shifts a register value @arg2 left by the amount specified in @arg3 and
+    places the value in the destination register @arg1.
+    Zeroes are shifted in."""
+    arg1 = arg2 << (arg3 & i32(0x1F))
 
-def l_xor(ir, instr, a, b, c):
-    """Exclusive ors two registers @b, @c and stores the result in a register
-    @c"""
-    e = []
-    e.append(m2_expr.ExprAff(a, b^c))
-    return e, []
+@sbuild.parse
+def l_xor(arg1, arg2, arg3):
+    """Exclusive ors two registers @arg2, @arg3 and stores the result in a
+    register @arg3"""
+    arg1 = arg2 ^ arg3
 
-def seb(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(a, b[:8].signExtend(32)))
-    return e, []
+@sbuild.parse
+def seb(arg1, arg2):
+    arg1 = arg2[:8].signExtend(32)
 
-def seh(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(a, b[:16].signExtend(32)))
-    return e, []
+@sbuild.parse
+def seh(arg1, arg2):
+    arg1 = arg2[:16].signExtend(32)
 
-def bltz(ir, instr, a, b):
-    """Branches on @b if the register @a is less than zero"""
-    e = []
-    n = m2_expr.ExprId(ir.get_next_break_label(instr))
-    dst_o = m2_expr.ExprCond(a.msb(), b, n)
-    e = [m2_expr.ExprAff(PC, dst_o),
-         m2_expr.ExprAff(ir.IRDst, dst_o)
-    ]
-    return e, []
+@sbuild.parse
+def bltz(arg1, arg2):
+    """Branches on @arg2 if the register @arg1 is less than zero"""
+    dst_o = arg2 if arg1.msb() else ExprId(ir.get_next_break_label(instr))
+    PC = dst_o
+    ir.IRDst = dst_o
 
-def blez(ir, instr, a, b):
-    """Branches on @b if the register @a is less than or equal to zero"""
-    e = []
-    n = m2_expr.ExprId(ir.get_next_break_label(instr))
-    cond = m2_expr.ExprCond(a, m2_expr.ExprInt1(1),
-                            m2_expr.ExprInt1(0)) | a.msb()
-    dst_o = m2_expr.ExprCond(cond, b, n)
-    e = [m2_expr.ExprAff(PC, dst_o),
-         m2_expr.ExprAff(ir.IRDst, dst_o)
-    ]
-    return e, []
+@sbuild.parse
+def blez(arg1, arg2):
+    """Branches on @arg2 if the register @arg1 is less than or equal to zero"""
+    cond = (i1(1) if arg1 else i1(0)) | arg1.msb()
+    dst_o = arg2 if cond else ExprId(ir.get_next_break_label(instr))
+    PC = dst_o
+    ir.IRDst = dst_o
 
-def bgtz(ir, instr, a, b):
-    """Branches on @b if the register @a is greater than zero"""
-    e = []
-    n = m2_expr.ExprId(ir.get_next_break_label(instr))
-    cond = m2_expr.ExprCond(a, m2_expr.ExprInt1(1),
-                            m2_expr.ExprInt1(0)) | a.msb()
-    dst_o = m2_expr.ExprCond(cond, n, b)
-    e = [m2_expr.ExprAff(PC, dst_o),
-         m2_expr.ExprAff(ir.IRDst, dst_o)
-     ]
-    return e, []
+@sbuild.parse
+def bgtz(arg1, arg2):
+    """Branches on @arg2 if the register @arg1 is greater than zero"""
+    cond = (i1(1) if arg1 else i1(0)) | arg1.msb()
+    dst_o = ExprId(ir.get_next_break_label(instr)) if cond else arg2
+    PC = dst_o
+    ir.IRDst = dst_o
 
-def wsbh(ir, instr, a, b):
-    e = [m2_expr.ExprAff(a, m2_expr.ExprCompose([(b[8:16],  0, 8),
-                                 (b[0:8]  , 8, 16),
-                                 (b[24:32], 16, 24),
-                                 (b[16:24], 24, 32)]))]
-    return e, []
+@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)])
 
-def rotr(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('>>>', b, c)))
-    return e, []
+@sbuild.parse
+def rotr(arg1, arg2, arg3):
+    arg1 = '>>>'(arg2, arg3)
 
-def add_d(ir, instr, a, b, c):
+@sbuild.parse
+def add_d(arg1, arg2, arg3):
     # XXX TODO check
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fadd', b, c)))
-    return e, []
+    arg1 = 'fadd'(arg2, arg3)
 
-def sub_d(ir, instr, a, b, c):
+@sbuild.parse
+def sub_d(arg1, arg2, arg3):
     # XXX TODO check
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fsub', b, c)))
-    return e, []
+    arg1 = 'fsub'(arg2, arg3)
 
-def div_d(ir, instr, a, b, c):
+@sbuild.parse
+def div_d(arg1, arg2, arg3):
     # XXX TODO check
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fdiv', b, c)))
-    return e, []
+    arg1 = 'fdiv'(arg2, arg3)
 
-def mul_d(ir, instr, a, b, c):
+@sbuild.parse
+def mul_d(arg1, arg2, arg3):
     # XXX TODO check
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fmul', b, c)))
-    return e, []
+    arg1 = 'fmul'(arg2, arg3)
 
-def mov_d(ir, instr, a, b):
+@sbuild.parse
+def mov_d(arg1, arg2):
     # XXX TODO check
-    e = []
-    e.append(m2_expr.ExprAff(a, b))
-    return e, []
+    arg1 = arg2
 
-def mfc0(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(a, b))
-    return e, []
+@sbuild.parse
+def mfc0(arg1, arg2):
+    arg1 = arg2
 
-def mfc1(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(a, b))
-    return e, []
+@sbuild.parse
+def mfc1(arg1, arg2):
+    arg1 = arg2
 
-def mtc0(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(b, a))
-    return e, []
+@sbuild.parse
+def mtc0(arg1, arg2):
+    arg2 = arg1
 
-def mtc1(ir, instr, a, b):
-    e = []
-    e.append(m2_expr.ExprAff(b, a))
-    return e, []
+@sbuild.parse
+def mtc1(arg1, arg2):
+    arg2 = arg1
 
-def tlbwi(ir, instr):
-    # TODO XXX
-    e = []
-    return e, []
+@sbuild.parse
+def tlbwi():
+    "TODO XXX"
 
-def tlbp(ir, instr):
-    # TODO XXX
-    e = []
-    return e, []
+@sbuild.parse
+def tlbp():
+    "TODO XXX"
 
 def ins(ir, instr, a, b, c, d):
     e = []
@@ -378,179 +326,106 @@ def ins(ir, instr, a, b, c, d):
     return e, []
 
 
-def lwc1(ir, instr, a, b):
-    e = []
-    src = m2_expr.ExprOp('mem_%.2d_to_single' % b.size, b)
-    e.append(m2_expr.ExprAff(a, src))
-    return e, []
+@sbuild.parse
+def lwc1(arg1, arg2):
+    arg1 = ('mem_%.2d_to_single' % arg2.size)(arg2)
 
-def swc1(ir, instr, a, b):
-    e = []
-    src = m2_expr.ExprOp('single_to_mem_%.2d' % a.size, a)
-    e.append(m2_expr.ExprAff(b, src))
-    return e, []
+@sbuild.parse
+def swc1(arg1, arg2):
+    arg2 = ('single_to_mem_%.2d' % arg1.size)(arg1)
 
-def c_lt_d(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fcomp_lt', b, c)))
-    return e, []
+@sbuild.parse
+def c_lt_d(arg1, arg2, arg3):
+    arg1 = 'fcomp_lt'(arg2, arg3)
 
-def c_eq_d(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fcomp_eq', b, c)))
-    return e, []
+@sbuild.parse
+def c_eq_d(arg1, arg2, arg3):
+    arg1 = 'fcomp_eq'(arg2, arg3)
 
-def c_le_d(ir, instr, a, b, c):
-    e = []
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fcomp_le', b, c)))
-    return e, []
+@sbuild.parse
+def c_le_d(arg1, arg2, arg3):
+    arg1 = 'fcomp_le'(arg2, arg3)
 
-def bc1t(ir, instr, a, b):
-    e = []
-    n = m2_expr.ExprId(ir.get_next_break_label(instr))
-    dst_o = m2_expr.ExprCond(a, b, n)
-    e = [m2_expr.ExprAff(PC, dst_o)]
-    e.append(m2_expr.ExprAff(ir.IRDst, dst_o))
-    return e, []
+@sbuild.parse
+def bc1t(arg1, arg2):
+    dst_o = arg2 if arg1 else ExprId(ir.get_next_break_label(instr))
+    PC = dst_o
+    ir.IRDst = dst_o
 
-def bc1f(ir, instr, a, b):
-    e = []
-    n = m2_expr.ExprId(ir.get_next_break_label(instr))
-    dst_o = m2_expr.ExprCond(a, n, b)
-    e = [m2_expr.ExprAff(PC, dst_o)]
-    e.append(m2_expr.ExprAff(ir.IRDst, dst_o))
-    return e, []
+@sbuild.parse
+def bc1f(arg1, arg2):
+    dst_o = ExprId(ir.get_next_break_label(instr)) if arg1 else arg2
+    PC = dst_o
+    ir.IRDst = dst_o
 
-def cvt_d_w(ir, instr, a, b):
-    e = []
+@sbuild.parse
+def cvt_d_w(arg1, arg2):
     # TODO XXX
-    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('flt_d_w', b)))
-    return e, []
+    arg1 = 'flt_d_w'(arg2)
 
-def mult(ir, instr, a, b):
-    """Multiplies (signed) @a by @b and stores the result in $R_HI:$R_LO"""
-    e = []
-    size = a.size
-    r = a.signExtend(size * 2) * b.signExtend(size * 2)
+@sbuild.parse
+def mult(arg1, arg2):
+    """Multiplies (signed) @arg1 by @arg2 and stores the result in $R_HI:$R_LO"""
+    size = arg1.size
+    result = arg1.signExtend(size * 2) * arg2.signExtend(size * 2)
+    R_LO = result[:32]
+    R_HI = result[32:]
 
-    e.append(m2_expr.ExprAff(R_LO, r[:32]))
-    e.append(m2_expr.ExprAff(R_HI, r[32:]))
-    return e, []
+@sbuild.parse
+def multu(arg1, arg2):
+    """Multiplies (unsigned) @arg1 by @arg2 and stores the result in $R_HI:$R_LO"""
+    size = arg1.size
+    result = arg1.zeroExtend(size * 2) * arg2.zeroExtend(size * 2)
+    R_LO = result[:32]
+    R_HI = result[32:]
 
-def multu(ir, instr, a, b):
-    """Multiplies (unsigned) @a by @b and stores the result in $R_HI:$R_LO"""
-    e = []
-    size = a.size
-    r = a.zeroExtend(size * 2) * b.zeroExtend(size * 2)
+@sbuild.parse
+def mfhi(arg1):
+    "The contents of register $R_HI are moved to the specified register @arg1."
+    arg1 = R_HI
 
-    e.append(m2_expr.ExprAff(R_LO, r[:32]))
-    e.append(m2_expr.ExprAff(R_HI, r[32:]))
-    return e, []
+@sbuild.parse
+def mflo(arg1):
+    "The contents of register R_LO are moved to the specified register @arg1."
+    arg1 = R_LO
 
-def mfhi(ir, instr, a):
-    "The contents of register $R_HI are moved to the specified register @a."
-    e = []
-    e.append(m2_expr.ExprAff(a, R_HI))
-    return e, []
+@sbuild.parse
+def di(arg1):
+    "NOP"
 
-def mflo(ir, instr, a):
-    "The contents of register R_LO are moved to the specified register @a."
-    e = []
-    e.append(m2_expr.ExprAff(a, R_LO))
-    return e, []
+@sbuild.parse
+def ei(arg1):
+    "NOP"
 
-def di(ir, instr, a):
-    return [], []
-
-def ei(ir, instr, a):
-    return [], []
-
-def ehb(ir, instr, a):
-    return [], []
-
-mnemo_func = {
-    "addiu": addiu,
-    "addu": addiu,
-    "lw" : lw,
-    "sw" : sw,
-    "sh" : sh,
-    "sb" : sb,
-    "jalr" : jalr,
-    "jal" : jal,
-    "bal" : bal,
-    "b" : l_b,
-    "lbu" : lbu,
-    "lhu" : lhu,
-    "lb" : lb,
-    "beq" : beq,
-    "bgez" : bgez,
-    "bltz" : bltz,
-    "bgtz" : bgtz,
-    "bne" : bne,
-    "lui" : lui,
-    "nop" : nop,
-    "j" : j,
-    "jr" : j,
-    "ori" : l_or,
-    "or" : l_or,
-    "nor" : nor,
-    "and" : l_and,
-    "andi" : l_and,
-    "ext" : ext,
-    "mul" : mul,
-    "sltu" : sltu,
-    "slt" : slt,
-    "slti" : slt,
-    "sltiu" : sltu,
-    "subu" : l_sub,
-    "movn" : movn,
-    "movz" : movz,
-    "srl" : srl,
-    "sra" : sra,
-    "srav" : srav,
-    "sll" : sll,
-    "srlv" : srlv,
-    "sllv" : sllv,
-    "xori" : l_xor,
-    "xor" : l_xor,
-    "seb" : seb,
-    "seh" : seh,
-    "bltz" : bltz,
-    "blez" : blez,
-    "wsbh" : wsbh,
-    "rotr" : rotr,
-    # "mfc0" : mfc0,
-    # "mfc1" : mfc1,
-    # "mtc0" : mtc0,
-    # "mtc1" : mtc1,
-    "tlbwi" : tlbwi,
-    "tlbp" : tlbp,
-    "ins" : ins,
-
-    "add.d" : add_d,
-    "sub.d" : sub_d,
-    "div.d" : div_d,
-    "mul.d" : mul_d,
-    "mov.d" : mov_d,
-    "lwc1" : lwc1,
-    "swc1" : swc1,
-    "c.lt.d" : c_lt_d,
-    "c.eq.d" : c_eq_d,
-    "c.le.d" : c_le_d,
-    "bc1t" : bc1t,
-    "bc1f" : bc1f,
-    "cvt.d.w":cvt_d_w,
-    "mult" : mult,
-    "multu" : multu,
-
-    "mfhi" : mfhi,
-    "mflo" : mflo,
-
-    "di" : di,
-    "ei" : ei,
-    "ehb" : ehb,
-
-    }
+@sbuild.parse
+def ehb(arg1):
+    "NOP"
+
+mnemo_func = sbuild.functions
+mnemo_func.update({
+        'add.d': add_d,
+        'addu': addiu,
+        'and': l_and,
+        'andi': l_and,
+        'b': l_b,
+        'c.eq.d': c_eq_d,
+        'c.le.d': c_le_d,
+        'c.lt.d': c_lt_d,
+        'cvt.d.w': cvt_d_w,
+        'div.d': div_d,
+        'ins': ins,
+        'jr': j,
+        'mov.d': mov_d,
+        'mul.d': mul_d,
+        'or': l_or,
+        'ori': l_or,
+        'slti': slt,
+        'sltiu': sltu,
+        'sub.d': sub_d,
+        'subu': l_sub,
+        'xor': l_xor,
+        'xori': l_xor,
+})
 
 def get_mnemo_expr(ir, instr, *args):
     instr, extra_ir = mnemo_func[instr.name.lower()](ir, instr, *args)
diff --git a/miasm2/core/sembuilder.py b/miasm2/core/sembuilder.py
index 34271960..985a6a65 100644
--- a/miasm2/core/sembuilder.py
+++ b/miasm2/core/sembuilder.py
@@ -4,6 +4,9 @@ import inspect
 import ast
 import re
 
+import miasm2.expression.expression as m2_expr
+from miasm2.ir.ir import irbloc
+
 
 class MiasmTransformer(ast.NodeTransformer):
     """AST visitor translating DSL to Miasm expression
@@ -11,6 +14,8 @@ class MiasmTransformer(ast.NodeTransformer):
     memX[Y]       -> ExprMem(Y, X)
     iX(Y)         -> ExprIntX(Y)
     X if Y else Z -> ExprCond(Y, X, Z)
+    'X'(Y)        -> ExprOp('X', Y)
+    ('X' % Y)(Z)  -> ExprOp('X' % Y, Z)
     """
 
     # Parsers
@@ -20,23 +25,40 @@ class MiasmTransformer(ast.NodeTransformer):
     # Visitors
 
     def visit_Call(self, node):
-        """iX(Y) -> ExprIntX(Y)"""
-        # Match the function name
-        if not isinstance(node.func, ast.Name):
+        """iX(Y) -> ExprIntX(Y),
+        'X'(Y) -> ExprOp('X', Y), ('X' % Y)(Z) -> ExprOp('X' % Y, Z)"""
+        if isinstance(node.func, ast.Name):
+            # iX(Y) -> ExprIntX(Y)
+            fc_name = node.func.id
+
+            # Match the function name
+            new_name = fc_name
+            integer = self.parse_integer.search(fc_name)
+
+            # Do replacement
+            if integer is not None:
+                new_name = "ExprInt%s" % integer.groups()[0]
+
+            # Replace in the node
+            node.func.id = new_name
+
+        elif (isinstance(node.func, ast.Str) or
+              (isinstance(node.func, ast.BinOp) and
+               isinstance(node.func.op, ast.Mod) and
+               isinstance(node.func.left, ast.Str))):
+            # 'op'(args...) -> ExprOp('op', args...)
+            # ('op' % (fmt))(args...) -> ExprOp('op' % (fmt), args...)
+            op_name = node.func
+
+            # Do replacement
+            node.func = ast.Name(id="ExprOp", ctx=ast.Load())
+            node.args[0:0] = [op_name]
+            node.args = map(self.visit, node.args)
+
+        else:
             # TODO: launch visitor on node
-            return node
-
-        fc_name = node.func.id
-        new_name = fc_name
-        integer = self.parse_integer.search(fc_name)
-
-        # Do replacement
-        if integer is not None:
-            new_name = "ExprInt%s" % integer.groups()[0]
+            pass
 
-        # Replace in the node
-        node.func.id = new_name
-        # TODO: launch visitor on node
         return node
 
     def visit_Subscript(self, node):
@@ -80,22 +102,40 @@ class SemBuilder(object):
         """Create a SemBuilder
         @ctx: context dictionnary used during parsing
         """
-        self.ctx = dict(ctx)
+        # Init
         self.transformer = MiasmTransformer()
-
-    def parse(self, func):
-        """Function decorator, returning a correct method from a pseudo-Python
-        one"""
-
-        # Get the function AST
-        parsed = ast.parse(inspect.getsource(func))
-        fc_ast = parsed.body[0]
-        argument_names = [name.id for name in fc_ast.args.args]
-        body = []
-
-        # AffBlock of the current instruction
-        new_ast = []
-        for statement in fc_ast.body:
+        self._ctx = dict(m2_expr.__dict__)
+        self._ctx["irbloc"] = irbloc
+        self._functions = {}
+
+        # Update context
+        self._ctx.update(ctx)
+
+    @property
+    def functions(self):
+        """Return a dictionnary name -> func of parsed functions"""
+        return self._functions.copy()
+
+    @staticmethod
+    def _create_labels():
+        """Return the AST standing for label creations"""
+        out = ast.parse("lbl_end = ExprId(ir.get_next_instr(instr))").body
+        out += ast.parse("lbl_if = ExprId(ir.gen_label())").body
+        return out
+
+    def _parse_body(self, body, argument_names):
+        """Recursive function transforming a @body to a block expression
+        Return:
+         - AST to append to body (real python statements)
+         - a list of blocks, ie list of affblock, ie list of ExprAff (AST)"""
+
+        # Init
+        ## Real instructions
+        real_body = []
+        ## Final blocks
+        blocks = [[[]]]
+
+        for statement in body:
 
             if isinstance(statement, ast.Assign):
                 src = self.transformer.visit(statement.value)
@@ -103,10 +143,11 @@ class SemBuilder(object):
 
                 if (isinstance(dst, ast.Name) and
                     dst.id not in argument_names and
-                    dst.id not in self.ctx):
+                    dst.id not in self._ctx):
+
                     # Real variable declaration
                     statement.value = src
-                    body.append(statement)
+                    real_body.append(statement)
                     continue
 
                 dst.ctx = ast.Load()
@@ -118,22 +159,112 @@ class SemBuilder(object):
                                starargs=None,
                                kwargs=None)
 
-                new_ast.append(res)
+                blocks[-1][-1].append(res)
 
             elif (isinstance(statement, ast.Expr) and
                   isinstance(statement.value, ast.Str)):
                 # String (docstring, comment, ...) -> keep it
-                body.append(statement)
+                real_body.append(statement)
+
+            elif (isinstance(statement, ast.If) and
+                  not statement.orelse):
+                # Create jumps : ir.IRDst = lbl_if if cond else lbl_end
+                cond = statement.test
+                real_body += self._create_labels()
+
+                lbl_end = ast.Name(id='lbl_end', ctx=ast.Load())
+                lbl_if = ast.Name(id='lbl_if', ctx=ast.Load())
+                dst = ast.Call(func=ast.Name(id='ExprCond',
+                                             ctx=ast.Load()),
+                               args=[cond,
+                                     lbl_if,
+                                     lbl_end],
+                               keywords=[],
+                               starargs=None,
+                               kwargs=None)
+
+                if (isinstance(cond, ast.UnaryOp) and
+                    isinstance(cond.op, ast.Not)):
+                    ## if not cond -> switch exprCond
+                    dst.args[1:] = dst.args[1:][::-1]
+                    dst.args[0] = cond.operand
+
+                IRDst = ast.Attribute(value=ast.Name(id='ir',
+                                                     ctx=ast.Load()),
+                                      attr='IRDst', ctx=ast.Load())
+                blocks[-1][-1].append(ast.Call(func=ast.Name(id='ExprAff',
+                                                             ctx=ast.Load()),
+                                               args=[IRDst, dst],
+                                               keywords=[],
+                                               starargs=None,
+                                               kwargs=None))
+
+                # Create the new blocks
+                sub_blocks, sub_body = self._parse_body(statement.body,
+                                                        argument_names)
+                if len(sub_blocks) > 1:
+                    raise RuntimeError("Imbricated if unimplemented")
+
+                ## Close the last block
+                jmp_end = ast.Call(func=ast.Name(id='ExprAff',
+                                                 ctx=ast.Load()),
+                                   args=[IRDst, lbl_end],
+                                   keywords=[],
+                                   starargs=None,
+                                   kwargs=None)
+                sub_blocks[-1][-1].append(jmp_end)
+                sub_blocks[-1][-1] = ast.List(elts=sub_blocks[-1][-1],
+                                              ctx=ast.Load())
+                sub_blocks[-1] = ast.List(elts=sub_blocks[-1],
+                                          ctx=ast.Load())
+
+                ## Replace the block with a call to 'irbloc'
+                lbl_if_name = ast.Attribute(value=ast.Name(id='lbl_if',
+                                                           ctx=ast.Load()),
+                                            attr='name', ctx=ast.Load())
+
+                sub_blocks[-1] = ast.Call(func=ast.Name(id='irbloc',
+                                                        ctx=ast.Load()),
+                                          args=[lbl_if_name,
+                                                sub_blocks[-1]],
+                                          keywords=[],
+                                          starargs=None,
+                                          kwargs=None)
+                blocks += sub_blocks
+                real_body += sub_body
+
+                # Prepare a new block for following statement
+                blocks.append([[]])
+
             else:
                 # TODO: real var, +=, /=, -=, <<=, >>=, if/else, ...
                 raise RuntimeError("Unimplemented %s" % statement)
 
+        return blocks, real_body
+
+    def parse(self, func):
+        """Function decorator, returning a correct method from a pseudo-Python
+        one"""
+
+        # Get the function AST
+        parsed = ast.parse(inspect.getsource(func))
+        fc_ast = parsed.body[0]
+        argument_names = [name.id for name in fc_ast.args.args]
+
+        # Translate (blocks[0][0] is the current instr)
+        blocks, body = self._parse_body(fc_ast.body, argument_names)
+
         # Build the new function
         fc_ast.args.args[0:0] = [ast.Name(id='ir', ctx=ast.Param()),
                                  ast.Name(id='instr', ctx=ast.Param())]
-        body.append(ast.Return(value=ast.Tuple(elts=[ast.List(elts=new_ast,
+        cur_instr = blocks[0][0]
+        if len(blocks[-1][0]) == 0:
+            ## Last block can be empty
+            blocks.pop()
+        other_blocks = blocks[1:]
+        body.append(ast.Return(value=ast.Tuple(elts=[ast.List(elts=cur_instr,
                                                               ctx=ast.Load()),
-                                                     ast.List(elts=[],
+                                                     ast.List(elts=other_blocks,
                                                               ctx=ast.Load())],
                                                ctx=ast.Load())))
 
@@ -148,8 +279,9 @@ class SemBuilder(object):
         # Compile according to the context
         fixed = ast.fix_missing_locations(ret)
         codeobj = compile(fixed, '<string>', 'exec')
-        ctx = self.ctx.copy()
+        ctx = self._ctx.copy()
         eval(codeobj, ctx)
 
         # Get the function back
+        self._functions[fc_ast.name] = ctx[fc_ast.name]
         return ctx[fc_ast.name]
diff --git a/miasm2/jitter/arch/JitCore_arm.c b/miasm2/jitter/arch/JitCore_arm.c
index 92027c25..b2550194 100644
--- a/miasm2/jitter/arch/JitCore_arm.c
+++ b/miasm2/jitter/arch/JitCore_arm.c
@@ -165,7 +165,7 @@ PyObject* cpu_get_exception(JitCpu* self, PyObject* args)
 
 
 
-void check_automod(JitCpu* jitcpu, uint64_t addr, int size)
+void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 {
 	PyObject *result;
 
diff --git a/miasm2/jitter/arch/JitCore_mips32.c b/miasm2/jitter/arch/JitCore_mips32.c
index 4cd016cf..c8f8fb81 100644
--- a/miasm2/jitter/arch/JitCore_mips32.c
+++ b/miasm2/jitter/arch/JitCore_mips32.c
@@ -209,7 +209,7 @@ PyObject* cpu_get_exception(JitCpu* self, PyObject* args)
 
 
 
-void check_automod(JitCpu* jitcpu, uint64_t addr, int size)
+void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 {
 	PyObject *result;
 
diff --git a/miasm2/jitter/arch/JitCore_msp430.c b/miasm2/jitter/arch/JitCore_msp430.c
index e4f26de1..3a34248a 100644
--- a/miasm2/jitter/arch/JitCore_msp430.c
+++ b/miasm2/jitter/arch/JitCore_msp430.c
@@ -182,7 +182,7 @@ PyObject* cpu_get_exception(JitCpu* self, PyObject* args)
 
 
 
-void check_automod(JitCpu* jitcpu, uint64_t addr, int size)
+void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 {
 	PyObject *result;
 
diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c
index a5bbb7bc..baa66755 100644
--- a/miasm2/jitter/arch/JitCore_x86.c
+++ b/miasm2/jitter/arch/JitCore_x86.c
@@ -307,7 +307,7 @@ IMOD(64)
 
 
 
-void check_automod(JitCpu* jitcpu, uint64_t addr, int size)
+void check_automod(JitCpu* jitcpu, uint64_t addr, uint64_t size)
 {
 	PyObject *result;
 
diff --git a/test/core/sembuilder.py b/test/core/sembuilder.py
index 3c1b7d3f..468e3ef5 100644
--- a/test/core/sembuilder.py
+++ b/test/core/sembuilder.py
@@ -3,7 +3,20 @@ from pdb import pm
 
 from miasm2.core.sembuilder import SemBuilder
 import miasm2.expression.expression as m2_expr
+from miasm2.core.asmbloc import asm_label
 
+# Test classes
+class IR(object):
+
+    IRDst = m2_expr.ExprId("IRDst")
+
+    def get_next_instr(self, _):
+        return asm_label("NEXT")
+
+    def gen_label(self):
+        return asm_label("GEN")
+
+# Test
 sb = SemBuilder(m2_expr.__dict__)
 
 @sb.parse
@@ -13,13 +26,27 @@ def test(Arg1, Arg2, Arg3):
     mem32[Arg1] = Arg2
     mem32[Arg2] = Arg3  + i32(4) - mem32[Arg1]
     Arg3 = Arg3 if Arg2 else i32(0)
-    tmpvar = i32(2)
-    Arg2 = tmpvar
+    tmpvar = 'myop'(i32(2))
+    Arg2 = ('myopsize%d' % Arg1.size)(tmpvar, Arg1)
+
+    if not Arg1:
+        Arg2 = Arg3
 
 a = m2_expr.ExprId('A')
 b = m2_expr.ExprId('B')
 c = m2_expr.ExprId('C')
-ir = None
+ir = IR()
 instr = None
-print test(ir, instr, a, b, c)
-print test.__doc__
+res = test(ir, instr, a, b, c)
+
+print "[+] Returned:"
+print res
+print "[+] DocString:", test.__doc__
+
+print "[+] Cur instr:"
+for statement in res[0]:
+    print statement
+
+print "[+] Blocks:"
+for block in res[1]:
+    print block