about summary refs log tree commit diff stats
path: root/miasm2
diff options
context:
space:
mode:
Diffstat (limited to 'miasm2')
-rw-r--r--miasm2/arch/aarch64/sem.py2
-rw-r--r--miasm2/arch/arm/sem.py2
-rw-r--r--miasm2/arch/mips32/sem.py4
-rw-r--r--miasm2/arch/ppc/sem.py2
-rw-r--r--miasm2/arch/x86/sem.py4
-rw-r--r--miasm2/expression/expression_helper.py2
-rw-r--r--miasm2/expression/simplifications.py10
-rw-r--r--miasm2/expression/simplifications_common.py423
-rw-r--r--miasm2/ir/translators/C.py2
-rw-r--r--miasm2/ir/translators/smt2.py4
-rw-r--r--miasm2/ir/translators/z3_ir.py10
-rw-r--r--miasm2/jitter/bn.c6
-rw-r--r--miasm2/jitter/bn.h4
-rw-r--r--miasm2/jitter/jitcore.py12
-rw-r--r--miasm2/jitter/jitcore_python.py209
-rw-r--r--miasm2/jitter/llvmconvert.py8
-rw-r--r--miasm2/jitter/op_semantics.c18
-rw-r--r--miasm2/jitter/op_semantics.h24
18 files changed, 539 insertions, 207 deletions
diff --git a/miasm2/arch/aarch64/sem.py b/miasm2/arch/aarch64/sem.py
index f22f0c07..e4702a4f 100644
--- a/miasm2/arch/aarch64/sem.py
+++ b/miasm2/arch/aarch64/sem.py
@@ -809,7 +809,7 @@ def udiv(arg1, arg2, arg3):
 @sbuild.parse
 def sdiv(arg1, arg2, arg3):
     if arg3:
-        arg1 = ExprOp('idiv', arg2, arg3)
+        arg1 = ExprOp('sdiv', arg2, arg3)
     else:
         exception_flags = ExprInt(EXCEPT_DIV_BY_ZERO,
                                           exception_flags.size)
diff --git a/miasm2/arch/arm/sem.py b/miasm2/arch/arm/sem.py
index b5ab60d0..64403206 100644
--- a/miasm2/arch/arm/sem.py
+++ b/miasm2/arch/arm/sem.py
@@ -592,7 +592,7 @@ def sdiv(ir, instr, a, b, c=None):
 
 
 
-    r = ExprOp("idiv", b, c)
+    r = ExprOp("sdiv", b, c)
     do_div = []
     do_div.append(ExprAssign(a, r))
     dst = get_dst(a)
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index a57d2200..62a85355 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -393,8 +393,8 @@ def multu(arg1, arg2):
 @sbuild.parse
 def div(arg1, arg2):
     """Divide (signed) @arg1 by @arg2 and stores the remaining/result in $R_HI/$R_LO"""
-    R_LO = ExprOp('idiv' ,arg1, arg2)
-    R_HI = ExprOp('imod', arg1, arg2)
+    R_LO = ExprOp('sdiv' ,arg1, arg2)
+    R_HI = ExprOp('smod', arg1, arg2)
 
 @sbuild.parse
 def divu(arg1, arg2):
diff --git a/miasm2/arch/ppc/sem.py b/miasm2/arch/ppc/sem.py
index 969a8002..44895624 100644
--- a/miasm2/arch/ppc/sem.py
+++ b/miasm2/arch/ppc/sem.py
@@ -165,7 +165,7 @@ def mn_do_div(ir, instr, rd, ra, rb):
     if has_u:
         op = 'udiv'
     else:
-        op = 'idiv'
+        op = 'sdiv'
 
     rvalue = ExprOp(op, ra, rb)
 
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 244aff30..e01adcbc 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -1754,8 +1754,8 @@ def idiv(ir, instr, src1):
     else:
         raise ValueError('div arg not impl', src1)
 
-    c_d = m2_expr.ExprOp('idiv', src2, src1.signExtend(src2.size))
-    c_r = m2_expr.ExprOp('imod', src2, src1.signExtend(src2.size))
+    c_d = m2_expr.ExprOp('sdiv', src2, src1.signExtend(src2.size))
+    c_r = m2_expr.ExprOp('smod', src2, src1.signExtend(src2.size))
 
     # if 8 bit div, only ax is affected
     if size == 8:
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index c503ebfc..8065df9b 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -80,7 +80,7 @@ def merge_sliceto_slice(expr):
 
 op_propag_cst = ['+', '*', '^', '&', '|', '>>',
                  '<<', "a>>", ">>>", "<<<",
-                 "/", "%", 'idiv', 'imod', 'umod', 'udiv','**']
+                 "/", "%", 'sdiv', 'smod', 'umod', 'udiv','**']
 
 
 def is_pure_int(e):
diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py
index 3f50fc1a..8ea9c41f 100644
--- a/miasm2/expression/simplifications.py
+++ b/miasm2/expression/simplifications.py
@@ -49,24 +49,32 @@ class ExpressionSimplifier(object):
             simplifications_common.simp_ext_eq_ext,
 
             simplifications_common.simp_cmp_int,
+            simplifications_common.simp_sign_inf_zeroext,
             simplifications_common.simp_cmp_int_int,
             simplifications_common.simp_ext_cst,
+            simplifications_common.simp_zeroext_and_cst_eq_cst,
+            simplifications_common.simp_test_signext_inf,
+            simplifications_common.simp_test_zeroext_inf,
 
         ],
 
         m2_expr.ExprSlice: [
             simplifications_common.simp_slice,
             simplifications_common.simp_slice_of_ext,
+            simplifications_common.simp_slice_of_op_ext,
         ],
         m2_expr.ExprCompose: [simplifications_common.simp_compose],
         m2_expr.ExprCond: [
             simplifications_common.simp_cond,
+            simplifications_common.simp_cond_zeroext,
             # CC op
             simplifications_common.simp_cond_flag,
             simplifications_common.simp_cmp_int_arg,
 
             simplifications_common.simp_cond_eq_zero,
-
+            simplifications_common.simp_x_and_cst_eq_cst,
+            simplifications_common.simp_cond_logic_ext,
+            simplifications_common.simp_cond_sign_bit,
         ],
         m2_expr.ExprMem: [simplifications_common.simp_mem],
 
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index 6f0eb34a..f7171091 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -73,12 +73,12 @@ def simp_cst_propagation(e_s, expr):
                 out = int1.arg / int2.arg
             elif op_name == '%':
                 out = int1.arg % int2.arg
-            elif op_name == 'idiv':
+            elif op_name == 'sdiv':
                 assert int2.arg.arg
                 tmp1 = mod_size2int[int1.arg.size](int1.arg)
                 tmp2 = mod_size2int[int2.arg.size](int2.arg)
                 out = mod_size2uint[int1.arg.size](tmp1 / tmp2)
-            elif op_name == 'imod':
+            elif op_name == 'smod':
                 assert int2.arg.arg
                 tmp1 = mod_size2int[int1.arg.size](int1.arg)
                 tmp2 = mod_size2int[int2.arg.size](int2.arg)
@@ -143,7 +143,7 @@ def simp_cst_propagation(e_s, expr):
 
     # op A => A
     if op_name in ['+', '*', '^', '&', '|', '>>', '<<',
-              'a>>', '<<<', '>>>', 'idiv', 'imod', 'umod', 'udiv'] and len(args) == 1:
+              'a>>', '<<<', '>>>', 'sdiv', 'smod', 'umod', 'udiv'] and len(args) == 1:
         return args[0]
 
     # A-B => A + (-B)
@@ -382,7 +382,7 @@ def simp_cst_propagation(e_s, expr):
     return ExprOp(op_name, *args)
 
 
-def simp_cond_op_int(e_s, expr):
+def simp_cond_op_int(_, expr):
     "Extract conditions from operations"
 
 
@@ -606,10 +606,11 @@ def simp_compose(e_s, expr):
     return ExprCompose(*args)
 
 
-def simp_cond(e_s, expr):
-    "Common simplifications on ExprCond"
-    # eval exprcond src1/src2 with satifiable/unsatisfiable condition
-    # propagation
+def simp_cond(_, expr):
+    """
+    Common simplifications on ExprCond.
+    Eval exprcond src1/src2 with satifiable/unsatisfiable condition propagation
+    """
     if (not expr.cond.is_int()) and expr.cond.size == 1:
         src1 = expr.src1.replace_expr({expr.cond: ExprInt(1, 1)})
         src2 = expr.src2.replace_expr({expr.cond: ExprInt(0, 1)})
@@ -666,10 +667,11 @@ def simp_cond(e_s, expr):
     return expr
 
 
-def simp_mem(e_s, expr):
-    "Common simplifications on ExprMem"
-
-    # @32[x?a:b] => x?@32[a]:@32[b]
+def simp_mem(_, expr):
+    """
+    Common simplifications on ExprMem:
+    @32[x?a:b] => x?@32[a]:@32[b]
+    """
     if expr.ptr.is_cond():
         cond = expr.ptr
         ret = ExprCond(cond.cond,
@@ -682,6 +684,15 @@ def simp_mem(e_s, expr):
 
 
 def test_cc_eq_args(expr, *sons_op):
+    """
+    Return True if expression's arguments match the list in sons_op, and their
+    sub arguments are identical. Ex:
+    CC_S<=(
+              FLAG_SIGN_SUB(A, B),
+              FLAG_SUB_OF(A, B),
+              FLAG_EQ_CMP(A, B)
+    )
+    """
     if not expr.is_op():
         return False
     if len(expr.args) != len(sons_op):
@@ -694,7 +705,11 @@ def test_cc_eq_args(expr, *sons_op):
     return len(all_args) == 1
 
 
-def simp_cc_conds(expr_simp, expr):
+def simp_cc_conds(_, expr):
+    """
+    High level simplifications. Example:
+    CC_U<(FLAG_SUB_CF(A, B) => A <u B
+    """
     if (expr.is_op("CC_U>=") and
           test_cc_eq_args(
               expr,
@@ -702,8 +717,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_INF_UNSIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1))
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size))
 
     elif (expr.is_op("CC_U<") and
           test_cc_eq_args(
@@ -726,8 +741,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_INF_SIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_EQ") and
@@ -746,8 +761,8 @@ def simp_cc_conds(expr_simp, expr):
         arg = expr.args[0].args[0]
         expr = ExprCond(
             ExprOp(TOK_EQUAL,arg, ExprInt(0, arg.size)),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
     elif (expr.is_op("CC_NE") and
           test_cc_eq_args(
@@ -756,8 +771,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_EQUAL, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_EQ") and
@@ -781,8 +796,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp("&", *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_S>") and
@@ -794,8 +809,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_S>") and
@@ -806,8 +821,8 @@ def simp_cc_conds(expr_simp, expr):
           expr.args[1].is_int(0)):
         expr = ExprCond(
             ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
 
@@ -820,8 +835,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_INF_SIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_S<") and
@@ -865,8 +880,8 @@ def simp_cc_conds(expr_simp, expr):
           )):
         expr = ExprCond(
             ExprOp(TOK_INF_EQUAL_UNSIGNED, *expr.args[0].args),
-            ExprInt(0, 1),
-            ExprInt(1, 1)
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size)
         )
 
     elif (expr.is_op("CC_S<") and
@@ -882,8 +897,8 @@ def simp_cc_conds(expr_simp, expr):
 
 
 
-def simp_cond_flag(expr_simp, expr):
-    # FLAG_EQ_CMP(X, Y)?A:B => (X == Y)?A:B
+def simp_cond_flag(_, expr):
+    """FLAG_EQ_CMP(X, Y)?A:B => (X == Y)?A:B"""
     cond = expr.cond
     if cond.is_op("FLAG_EQ_CMP"):
         return ExprCond(ExprOp(TOK_EQUAL, *cond.args), expr.src1, expr.src2)
@@ -891,8 +906,10 @@ def simp_cond_flag(expr_simp, expr):
 
 
 def simp_cmp_int(expr_simp, expr):
-    # ({X, 0} == int) => X == int[:]
-    # X + int1 == int2 => X == int2-int1
+    """
+    ({X, 0} == int) => X == int[:]
+    X + int1 == int2 => X == int2-int1
+    """
     if (expr.is_op(TOK_EQUAL) and
           expr.args[1].is_int() and
           expr.args[0].is_compose() and
@@ -931,7 +948,7 @@ def simp_cmp_int(expr_simp, expr):
 
 
 
-def simp_cmp_int_arg(expr_simp, expr):
+def simp_cmp_int_arg(_, expr):
     """
     (0x10 <= R0) ? A:B
     =>
@@ -971,10 +988,8 @@ def simp_cmp_int_arg(expr_simp, expr):
     return ExprCond(ExprOp(op, arg1, arg2), src1, src2)
 
 
-
-
-def simp_subwc_cf(expr_s, expr):
-    # SUBWC_CF(A, B, SUB_CF(C, D)) => SUB_CF({A, C}, {B, D})
+def simp_subwc_cf(_, expr):
+    """SUBWC_CF(A, B, SUB_CF(C, D)) => SUB_CF({A, C}, {B, D})"""
     if not expr.is_op('FLAG_SUBWC_CF'):
         return expr
     op3 = expr.args[2]
@@ -987,8 +1002,8 @@ def simp_subwc_cf(expr_s, expr):
     return ExprOp("FLAG_SUB_CF", op1, op2)
 
 
-def simp_subwc_of(expr_s, expr):
-    # SUBWC_OF(A, B, SUB_CF(C, D)) => SUB_OF({A, C}, {B, D})
+def simp_subwc_of(_, expr):
+    """SUBWC_OF(A, B, SUB_CF(C, D)) => SUB_OF({A, C}, {B, D})"""
     if not expr.is_op('FLAG_SUBWC_OF'):
         return expr
     op3 = expr.args[2]
@@ -1001,8 +1016,8 @@ def simp_subwc_of(expr_s, expr):
     return ExprOp("FLAG_SUB_OF", op1, op2)
 
 
-def simp_sign_subwc_cf(expr_s, expr):
-    # SIGN_SUBWC(A, B, SUB_CF(C, D)) => SIGN_SUB({A, C}, {B, D})
+def simp_sign_subwc_cf(_, expr):
+    """SIGN_SUBWC(A, B, SUB_CF(C, D)) => SIGN_SUB({A, C}, {B, D})"""
     if not expr.is_op('FLAG_SIGN_SUBWC'):
         return expr
     op3 = expr.args[2]
@@ -1014,8 +1029,8 @@ def simp_sign_subwc_cf(expr_s, expr):
 
     return ExprOp("FLAG_SIGN_SUB", op1, op2)
 
-def simp_double_zeroext(expr_s, expr):
-    # A.zeroExt(X).zeroExt(Y) => A.zeroExt(Y)
+def simp_double_zeroext(_, expr):
+    """A.zeroExt(X).zeroExt(Y) => A.zeroExt(Y)"""
     if not (expr.is_op() and expr.op.startswith("zeroExt")):
         return expr
     arg1 = expr.args[0]
@@ -1024,8 +1039,8 @@ def simp_double_zeroext(expr_s, expr):
     arg2 = arg1.args[0]
     return ExprOp(expr.op, arg2)
 
-def simp_double_signext(expr_s, expr):
-    # A.signExt(X).signExt(Y) => A.signExt(Y)
+def simp_double_signext(_, expr):
+    """A.signExt(X).signExt(Y) => A.signExt(Y)"""
     if not (expr.is_op() and expr.op.startswith("signExt")):
         return expr
     arg1 = expr.args[0]
@@ -1034,8 +1049,8 @@ def simp_double_signext(expr_s, expr):
     arg2 = arg1.args[0]
     return ExprOp(expr.op, arg2)
 
-def simp_zeroext_eq_cst(expr_s, expr):
-    # A.zeroExt(X) == int => A == int[:A.size]
+def simp_zeroext_eq_cst(_, expr):
+    """A.zeroExt(X) == int => A == int[:A.size]"""
     if not expr.is_op(TOK_EQUAL):
         return expr
     arg1, arg2 = expr.args
@@ -1046,12 +1061,31 @@ def simp_zeroext_eq_cst(expr_s, expr):
     src = arg1.args[0]
     if int(arg2) > (1 << src.size):
         # Always false
-        return ExprInt(0, 1)
+        return ExprInt(0, expr.size)
     return ExprOp(TOK_EQUAL, src, ExprInt(int(arg2), src.size))
 
-def simp_ext_eq_ext(expr_s, expr):
-    # A.zeroExt(X) == B.zeroExt(X) => A == B
-    # A.signExt(X) == B.signExt(X) => A == B
+def simp_cond_zeroext(_, expr):
+    """
+    X.zeroExt()?(A:B) => X ? A:B
+    X.signExt()?(A:B) => X ? A:B
+    """
+    if not (
+            expr.cond.is_op() and
+            (
+                expr.cond.op.startswith("zeroExt") or
+                expr.cond.op.startswith("signExt")
+            )
+    ):
+        return expr
+
+    ret = ExprCond(expr.cond.args[0], expr.src1, expr.src2)
+    return ret
+
+def simp_ext_eq_ext(_, expr):
+    """
+    A.zeroExt(X) == B.zeroExt(X) => A == B
+    A.signExt(X) == B.signExt(X) => A == B
+    """
     if not expr.is_op(TOK_EQUAL):
         return expr
     arg1, arg2 = expr.args
@@ -1064,8 +1098,8 @@ def simp_ext_eq_ext(expr_s, expr):
         return expr
     return ExprOp(TOK_EQUAL, arg1.args[0], arg2.args[0])
 
-def simp_cond_eq_zero(expr_s, expr):
-    # (X == 0)?(A:B) => X?(B:A)
+def simp_cond_eq_zero(_, expr):
+    """(X == 0)?(A:B) => X?(B:A)"""
     cond = expr.cond
     if not cond.is_op(TOK_EQUAL):
         return expr
@@ -1075,13 +1109,122 @@ def simp_cond_eq_zero(expr_s, expr):
     new_expr = ExprCond(arg1, expr.src2, expr.src1)
     return new_expr
 
+def simp_sign_inf_zeroext(expr_s, expr):
+    """
+    /!\ Ensure before: X.zeroExt(X.size) => X
+
+    X.zeroExt() <s 0 => 0
+    X.zeroExt() <=s 0 => X == 0
 
-def simp_cmp_int_int(expr_s, expr):
-    # IntA <s IntB => int
-    # IntA <u IntB => int
-    # IntA <=s IntB => int
-    # IntA <=u IntB => int
-    # IntA == IntB => int
+    X.zeroExt() <s cst => X.zeroExt() <u cst (cst positive)
+    X.zeroExt() <=s cst => X.zeroExt() <=u cst (cst positive)
+
+    X.zeroExt() <s cst => 0 (cst negative)
+    X.zeroExt() <=s cst => 0 (cst negative)
+
+    """
+    if not (expr.is_op(TOK_INF_SIGNED) or expr.is_op(TOK_INF_EQUAL_SIGNED)):
+        return expr
+    arg1, arg2 = expr.args
+    if not arg2.is_int():
+        return expr
+    if not (arg1.is_op() and arg1.op.startswith("zeroExt")):
+        return expr
+    src = arg1.args[0]
+    assert src.size < arg1.size
+
+    # If cst is zero
+    if arg2.is_int(0):
+        if expr.is_op(TOK_INF_SIGNED):
+            # X.zeroExt() <s 0 => 0
+            return ExprInt(0, expr.size)
+        else:
+            # X.zeroExt() <=s 0 => X == 0
+            return ExprOp(TOK_EQUAL, src, ExprInt(0, src.size))
+
+    # cst is not zero
+    cst = int(arg2)
+    if cst & (1 << (arg2.size - 1)):
+        # cst is negative
+        return ExprInt(0, expr.size)
+    # cst is positive
+    if expr.is_op(TOK_INF_SIGNED):
+        # X.zeroExt() <s cst => X.zeroExt() <u cst (cst positive)
+        return ExprOp(TOK_INF_UNSIGNED, src, expr_s(arg2[:src.size]))
+    # X.zeroExt() <=s cst => X.zeroExt() <=u cst (cst positive)
+    return ExprOp(TOK_INF_EQUAL_UNSIGNED, src, expr_s(arg2[:src.size]))
+
+
+def simp_zeroext_and_cst_eq_cst(expr_s, expr):
+    """
+    A.zeroExt(X) & ... & int == int => A & ... & int[:A.size] == int[:A.size]
+    """
+    if not expr.is_op(TOK_EQUAL):
+        return expr
+    arg1, arg2 = expr.args
+    if not arg2.is_int():
+        return expr
+    if not arg1.is_op('&'):
+        return expr
+    is_ok = True
+    sizes = set()
+    for arg in arg1.args:
+        if arg.is_int():
+            continue
+        if (arg.is_op() and
+            arg.op.startswith("zeroExt")):
+            sizes.add(arg.args[0].size)
+            continue
+        is_ok = False
+        break
+    if not is_ok:
+        return expr
+    if len(sizes) != 1:
+        return expr
+    size = list(sizes)[0]
+    if int(arg2) > ((1 << size) - 1):
+        return expr
+    args = [expr_s(arg[:size]) for arg in arg1.args]
+    left = ExprOp('&', *args)
+    right = expr_s(arg2[:size])
+    ret = ExprOp(TOK_EQUAL, left, right)
+    return ret
+
+
+def test_one_bit_set(arg):
+    """
+    Return True if arg has form 1 << X
+    """
+    return arg != 0  and ((arg & (arg - 1)) == 0)
+
+def simp_x_and_cst_eq_cst(_, expr):
+    """
+    (x & ... & onebitmask == onebitmask) ? A:B => (x & ... & onebitmask) ? A:B
+    """
+    cond = expr.cond
+    if not cond.is_op(TOK_EQUAL):
+        return expr
+    arg1, mask2 = cond.args
+    if not mask2.is_int():
+        return expr
+    if not test_one_bit_set(int(mask2)):
+        return expr
+    if not arg1.is_op('&'):
+        return expr
+    mask1 = arg1.args[-1]
+    if mask1 != mask2:
+        return expr
+    cond = ExprOp('&', *arg1.args)
+    return ExprCond(cond, expr.src1, expr.src2)
+
+def simp_cmp_int_int(_, expr):
+    """
+    IntA <s IntB => int
+    IntA <u IntB => int
+    IntA <=s IntB => int
+    IntA <=u IntB => int
+    IntA == IntB => int
+    """
     if expr.op not in [
             TOK_EQUAL,
             TOK_INF_SIGNED, TOK_INF_UNSIGNED,
@@ -1094,8 +1237,7 @@ def simp_cmp_int_int(expr_s, expr):
     if expr.is_op(TOK_EQUAL):
         if int_a == int_b:
             return ExprInt(1, 1)
-        else:
-            return ExprInt(0, 1)
+        return ExprInt(0, expr.size)
 
     if expr.op in [TOK_INF_SIGNED, TOK_INF_EQUAL_SIGNED]:
         int_a = int(mod_size2int[int_a.size](int(int_a)))
@@ -1116,9 +1258,11 @@ def simp_cmp_int_int(expr_s, expr):
     return ExprInt(ret, 1)
 
 
-def simp_ext_cst(expr_s, expr):
-    # Int.zeroExt(X) => Int
-    # Int.signExt(X) => Int
+def simp_ext_cst(_, expr):
+    """
+    Int.zeroExt(X) => Int
+    Int.signExt(X) => Int
+    """
     if not (expr.op.startswith("zeroExt") or expr.op.startswith("signExt")):
         return expr
     arg = expr.args[0]
@@ -1132,31 +1276,150 @@ def simp_ext_cst(expr_s, expr):
     return ret
 
 
-def simp_slice_of_ext(expr_s, expr):
-    # zeroExt(X)[0:size(X)] => X
-    if expr.start != 0:
-        return expr
+def simp_slice_of_ext(_, expr):
+    """
+    C.zeroExt(X)[A:B] => 0 if A >= size(C)
+    C.zeroExt(X)[A:B] => C[A:B] if B <= size(C)
+    A.zeroExt(X)[0:Y] => A.zeroExt(Y)
+    """
     if not expr.arg.is_op():
         return expr
     if not expr.arg.op.startswith("zeroExt"):
         return expr
     arg = expr.arg.args[0]
-    if arg.size != expr.size:
+
+    if expr.start >= arg.size:
+        # C.zeroExt(X)[A:B] => 0 if A >= size(C)
+        return ExprInt(0, expr.size)
+    if expr.stop <= arg.size:
+        # C.zeroExt(X)[A:B] => C[A:B] if B <= size(C)
+        return arg[expr.start:expr.stop]
+    if expr.start == 0:
+        # A.zeroExt(X)[0:Y] => A.zeroExt(Y)
+        return arg.zeroExtend(expr.stop)
+    return expr
+
+def simp_slice_of_op_ext(expr_s, expr):
+    """(X.zeroExt() + ... + Int)[0:8] => X + ... + int[:]"""
+    if expr.start != 0:
+        return expr
+    src = expr.arg
+    if not src.is_op("+"):
+        return expr
+    is_ok = True
+    for arg in src.args:
+        if arg.is_int():
+            continue
+        if (arg.is_op() and
+            arg.op.startswith("zeroExt") and
+            arg.args[0].size == expr.stop):
+            continue
+        is_ok = False
+        break
+    if not is_ok:
+        return expr
+    args = [expr_s(arg[:expr.stop]) for arg in src.args]
+    return ExprOp("+", *args)
+
+
+def simp_cond_logic_ext(expr_s, expr):
+    """(X.zeroExt() + ... + Int) ? A:B => X + ... + int[:] ? A:B"""
+    cond = expr.cond
+    if not cond.is_op():
+        return expr
+    if cond.op not in ["&", "^", "|"]:
+        return expr
+    is_ok = True
+    sizes = set()
+    for arg in cond.args:
+        if arg.is_int():
+            continue
+        if (arg.is_op() and
+            arg.op.startswith("zeroExt")):
+            sizes.add(arg.args[0].size)
+            continue
+        is_ok = False
+        break
+    if not is_ok:
+        return expr
+    if len(sizes) != 1:
+        return expr
+    size = list(sizes)[0]
+    args = [expr_s(arg[:size]) for arg in cond.args]
+    cond = ExprOp(cond.op, *args)
+    return ExprCond(cond, expr.src1, expr.src2)
+
+
+def simp_cond_sign_bit(_, expr):
+    """(a & .. & 0x80000000) ? A:B => (a & ...) <s 0 ? A:B"""
+    cond = expr.cond
+    if not cond.is_op('&'):
+        return expr
+    last = cond.args[-1]
+    if not last.is_int(1 << (last.size - 1)):
+        return expr
+    zero = ExprInt(0, expr.cond.size)
+    if len(cond.args) == 2:
+        args = [cond.args[0], zero]
+    else:
+        args = [ExprOp('&', *list(cond.args[:-1])), zero]
+    cond = ExprOp(TOK_INF_SIGNED, *args)
+    return ExprCond(cond, expr.src1, expr.src2)
+
+
+def simp_test_signext_inf(expr_s, expr):
+    """A.signExt() <s int => A <s int[:]"""
+    if not (expr.is_op(TOK_INF_SIGNED) or expr.is_op(TOK_INF_EQUAL_SIGNED)):
+        return expr
+    arg, cst = expr.args
+    if not (arg.is_op() and arg.op.startswith("signExt")):
         return expr
-    return arg
+    if not cst.is_int():
+        return expr
+    base = arg.args[0]
+    tmp = int(mod_size2int[cst.size](int(cst)))
+    if -(1 << (base.size - 1)) <= tmp < (1 << (base.size - 1)):
+        # Can trunc integer
+        return ExprOp(expr.op, base, expr_s(cst[:base.size]))
+    if (tmp >= (1 << (base.size - 1)) or
+        tmp < -(1 << (base.size - 1)) ):
+        return ExprInt(1, 1)
+    return expr
 
-def simp_add_multiple(expr_s, expr):
-    # X + X => 2 * X
-    # X + X * int1 => X * (1 + int1)
-    # X * int1 + (- X) => X * (int1 - 1)
-    # X + (X << int1) => X * (1 + 2 ** int1)
-    # Correct even if addition overflow/underflow
+
+def simp_test_zeroext_inf(expr_s, expr):
+    """A.zeroExt() <u int => A <u int[:]"""
+    if not (expr.is_op(TOK_INF_UNSIGNED) or expr.is_op(TOK_INF_EQUAL_UNSIGNED)):
+        return expr
+    arg, cst = expr.args
+    if not (arg.is_op() and arg.op.startswith("zeroExt")):
+        return expr
+    if not cst.is_int():
+        return expr
+    base = arg.args[0]
+    tmp = int(mod_size2uint[cst.size](int(cst)))
+    if 0 <= tmp < (1 << base.size):
+        # Can trunc integer
+        return ExprOp(expr.op, base, expr_s(cst[:base.size]))
+    if tmp >= (1 << base.size):
+        return ExprInt(1, 1)
+    return expr
+
+
+def simp_add_multiple(_, expr):
+    """
+    X + X => 2 * X
+    X + X * int1 => X * (1 + int1)
+    X * int1 + (- X) => X * (int1 - 1)
+    X + (X << int1) => X * (1 + 2 ** int1)
+    Correct even if addition overflow/underflow
+    """
     if not expr.is_op('+'):
         return expr
 
     # Extract each argument and its counter
     operands = {}
-    for i, arg in enumerate(expr.args):
+    for arg in expr.args:
         if arg.is_op('*') and arg.args[1].is_int():
             base_expr, factor = arg.args
             operands[base_expr] = operands.get(base_expr, 0) + int(factor)
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index a5453745..a239383b 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -372,7 +372,7 @@ class TranslatorC(Translator):
 
 
 
-            elif expr.op in ['idiv', 'imod']:
+            elif expr.op in ['sdiv', 'smod']:
                 arg0 = self.from_expr(expr.args[0])
                 arg1 = self.from_expr(expr.args[1])
 
diff --git a/miasm2/ir/translators/smt2.py b/miasm2/ir/translators/smt2.py
index eda24bb7..81d86798 100644
--- a/miasm2/ir/translators/smt2.py
+++ b/miasm2/ir/translators/smt2.py
@@ -198,13 +198,13 @@ class TranslatorSMT2(Translator):
                     res = bvmul(res, arg)
                 elif expr.op == "/":
                     res = bvsdiv(res, arg)
-                elif expr.op == "idiv":
+                elif expr.op == "sdiv":
                     res = bvsdiv(res, arg)
                 elif expr.op == "udiv":
                     res = bvudiv(res, arg)
                 elif expr.op == "%":
                     res = bvsmod(res, arg)
-                elif expr.op == "imod":
+                elif expr.op == "smod":
                     res = bvsmod(res, arg)
                 elif expr.op == "umod":
                     res = bvurem(res, arg)
diff --git a/miasm2/ir/translators/z3_ir.py b/miasm2/ir/translators/z3_ir.py
index d43468ef..2572ac74 100644
--- a/miasm2/ir/translators/z3_ir.py
+++ b/miasm2/ir/translators/z3_ir.py
@@ -171,7 +171,7 @@ class TranslatorZ3(Translator):
     def _abs(self, z3_value):
         return z3.If(z3_value >= 0,z3_value,-z3_value)
 
-    def _idivC(self, num, den):
+    def _sdivC(self, num, den):
         """Divide (signed) @num by @den (z3 values) as C would
         See modint.__div__ for implementation choice
         """
@@ -197,12 +197,12 @@ class TranslatorZ3(Translator):
                     res = z3.RotateLeft(res, arg)
                 elif expr.op == ">>>":
                     res = z3.RotateRight(res, arg)
-                elif expr.op == "idiv":
-                    res = self._idivC(res, arg)
+                elif expr.op == "sdiv":
+                    res = self._sdivC(res, arg)
                 elif expr.op == "udiv":
                     res = z3.UDiv(res, arg)
-                elif expr.op == "imod":
-                    res = res - (arg * (self._idivC(res, arg)))
+                elif expr.op == "smod":
+                    res = res - (arg * (self._sdivC(res, arg)))
                 elif expr.op == "umod":
                     res = z3.URem(res, arg)
                 elif expr.op == "==":
diff --git a/miasm2/jitter/bn.c b/miasm2/jitter/bn.c
index 96e66f4d..c621d102 100644
--- a/miasm2/jitter/bn.c
+++ b/miasm2/jitter/bn.c
@@ -796,7 +796,7 @@ int bignum_cnttrailzeros(bn_t n, int size)
 
 
 
-bn_t bignum_idiv(bn_t a, bn_t b, int size)
+bn_t bignum_sdiv(bn_t a, bn_t b, int size)
 {
 	require(size, "size must be greater than 0");
 	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
@@ -832,14 +832,14 @@ bn_t bignum_idiv(bn_t a, bn_t b, int size)
 
 
 
-bn_t bignum_imod(bn_t a, bn_t b, int size)
+bn_t bignum_smod(bn_t a, bn_t b, int size)
 {
 	require(size, "size must be greater than 0");
 	require(size <= BN_BIT_SIZE, "size must be below bignum max size");
 
 	bn_t c;
 
-	c = bignum_idiv(a, b, size);
+	c = bignum_sdiv(a, b, size);
 	c = bignum_mul(c, b);
 	c = bignum_sub(a, c);
 	c = bignum_mask(c, size);
diff --git a/miasm2/jitter/bn.h b/miasm2/jitter/bn.h
index 67d20a77..f0a13b53 100644
--- a/miasm2/jitter/bn.h
+++ b/miasm2/jitter/bn.h
@@ -116,8 +116,8 @@ _MIASM_EXPORT bn_t bignum_sub(bn_t a, bn_t b); /* c = a - b */
 _MIASM_EXPORT bn_t bignum_mul(bn_t a, bn_t b); /* c = a * b */
 _MIASM_EXPORT bn_t bignum_udiv(bn_t a, bn_t b); /* c = a / b */
 _MIASM_EXPORT bn_t bignum_umod(bn_t a, bn_t b); /* c = a % b */
-_MIASM_EXPORT bn_t bignum_idiv(bn_t a, bn_t b, int size);
-_MIASM_EXPORT bn_t bignum_imod(bn_t a, bn_t b, int size);
+_MIASM_EXPORT bn_t bignum_sdiv(bn_t a, bn_t b, int size);
+_MIASM_EXPORT bn_t bignum_smod(bn_t a, bn_t b, int size);
 //void bignum_udivmod(struct bn* a, struct bn* b, struct bn* c, struct bn* d); /* c = a/b, d = a%b */
 
 
diff --git a/miasm2/jitter/jitcore.py b/miasm2/jitter/jitcore.py
index fc5cf35e..78e27244 100644
--- a/miasm2/jitter/jitcore.py
+++ b/miasm2/jitter/jitcore.py
@@ -114,21 +114,11 @@ class JitCore(object):
         for a, b in self.blocks_mem_interval:
             vm.add_code_bloc(a, b + 1)
 
-    def jit_irblocks(self, label, irblocks):
-        """JiT a group of irblocks.
-        @label: the label of the irblocks
-        @irblocks: a group of irblocks
-        """
-
-        raise NotImplementedError("Abstract class")
-
     def add_block(self, block):
         """Add a block to JiT and JiT it.
         @block: asm_bloc to add
         """
-        irblocks = self.ir_arch.add_asmblock_to_ircfg(block, self.ircfg, gen_pc_updt = True)
-        block.blocks = irblocks
-        self.jit_irblocks(block.loc_key, irblocks)
+        raise NotImplementedError("Abstract class")
 
     def disasm_and_jit_block(self, addr, vm):
         """Disassemble a new block and JiT it
diff --git a/miasm2/jitter/jitcore_python.py b/miasm2/jitter/jitcore_python.py
index 0b1f5809..fdd5c2ae 100644
--- a/miasm2/jitter/jitcore_python.py
+++ b/miasm2/jitter/jitcore_python.py
@@ -1,5 +1,5 @@
 import miasm2.jitter.jitcore as jitcore
-import miasm2.expression.expression as m2_expr
+from miasm2.expression.expression import ExprInt, ExprLoc
 import miasm2.jitter.csts as csts
 from miasm2.expression.simplifications import expr_simp_explicit
 from miasm2.jitter.emulatedsymbexec import EmulatedSymbExec
@@ -36,12 +36,38 @@ class JitCore_Python(jitcore.JitCore):
         "Preload symbols according to current architecture"
         self.symbexec.reset_regs()
 
-    def jit_irblocks(self, loc_key, irblocks):
-        """Create a python function corresponding to an irblocks' group.
-        @loc_key: the loc_key of the irblocks
-        @irblocks: a group of irblocks
+    def arch_specific(self):
+        """Return arch specific information for the current architecture"""
+        arch = self.ir_arch.arch
+        has_delayslot = False
+        if arch.name == "mips32":
+            from miasm2.arch.mips32.jit import mipsCGen
+            cgen_class = mipsCGen
+            has_delayslot = True
+        elif arch.name == "arm":
+            from miasm2.arch.arm.jit import arm_CGen
+            cgen_class = arm_CGen
+        else:
+            from miasm2.jitter.codegen import CGen
+            cgen_class = CGen
+        return cgen_class(self.ir_arch), has_delayslot
+
+    def add_block(self, asmblock):
+        """Create a python function corresponding to an AsmBlock
+        @asmblock: AsmBlock
         """
 
+        # TODO: merge duplicate code with CGen, llvmconvert
+        codegen, has_delayslot = self.arch_specific()
+        irblocks_list = codegen.block2assignblks(asmblock)
+        instr_offsets = [line.offset for line in asmblock.lines]
+
+        loc_db = self.ir_arch.loc_db
+        local_loc_keys = []
+        for irblocks in irblocks_list:
+            for irblock in irblocks:
+                local_loc_keys.append(irblock.loc_key)
+
         def myfunc(cpu):
             """Execute the function according to cpu and vmmngr states
             @cpu: JitCpu instance
@@ -49,86 +75,131 @@ class JitCore_Python(jitcore.JitCore):
             # Get virtual memory handler
             vmmngr = cpu.vmmngr
 
-            # Keep current location in irblocks
-            cur_loc_key = loc_key
-
-            # Required to detect new instructions
-            offsets_jitted = set()
-
-            # Get exec engine
+            # Get execution engine (EmulatedSymbExec instance)
             exec_engine = self.symbexec
-            expr_simp = exec_engine.expr_simp
 
-            # For each irbloc inside irblocks
-            while True:
-                # Get the current bloc
-                for irb in irblocks:
-                    if irb.loc_key == cur_loc_key:
-                        break
+            # Refresh CPU values according to @cpu instance
+            exec_engine.update_engine_from_cpu()
 
-                else:
-                    raise RuntimeError("Irblocks must end with returning an "
-                                       "ExprInt instance")
-
-                # Refresh CPU values according to @cpu instance
-                exec_engine.update_engine_from_cpu()
-
-                # Execute current ir bloc
-                for assignblk in irb:
-                    instr = assignblk.instr
-                    # For each new instruction (in assembly)
-                    if instr is not None and instr.offset not in offsets_jitted:
-                        # Test exceptions
-                        vmmngr.check_invalid_code_blocs()
-                        vmmngr.check_memory_breakpoint()
-                        if vmmngr.get_exception():
-                            exec_engine.update_cpu_from_engine()
-                            return instr.offset
+            # Get initial loc_key
+            cur_loc_key = asmblock.loc_key
 
-                        offsets_jitted.add(instr.offset)
+            # Update PC helper
+            update_pc = lambda value: setattr(cpu, self.ir_arch.pc.name, value)
 
-                        # Log registers values
-                        if self.log_regs:
-                            exec_engine.update_cpu_from_engine()
-                            exec_engine.cpu.dump_gpregs_with_attrib(self.ir_arch.attrib)
+            while True:
+                # Retrieve the expected irblock
+                for instr, irblocks in zip(asmblock.lines, irblocks_list):
+                    for index, irblock in enumerate(irblocks):
+                        if irblock.loc_key == cur_loc_key:
+                            break
+                    else:
+                        continue
+                    break
+                else:
+                    raise RuntimeError("Unable to find the block for %r" % cur_loc_key)
+
+                instr_attrib, irblocks_attributes = codegen.get_attributes(
+                    instr, irblocks, self.log_mn, self.log_regs
+                )
+                irblock_attributes = irblocks_attributes[index]
+
+                # Do IRBlock
+                new_irblock = self.ir_arch.irbloc_fix_regs_for_mode(
+                    irblock, self.ir_arch.attrib
+                )
+                if index == 0:
+                    # Pre code
+                    if instr_attrib.log_mn:
+                        print "%.8X %s" % (
+                            instr_attrib.instr.offset,
+                            instr_attrib.instr.to_string(loc_db)
+                        )
+
+                # Exec IRBlock
+                instr = instr_attrib.instr
+
+                for index, assignblk in enumerate(irblock):
+                    attributes = irblock_attributes[index]
 
-                        # Log instruction
-                        if self.log_mn:
-                            print "%08x %s" % (instr.offset, instr)
+                    # Eval current instruction (in IR)
+                    exec_engine.eval_updt_assignblk(assignblk)
 
-                        # Check for exception
-                        if (vmmngr.get_exception() != 0 or
-                            cpu.get_exception() != 0):
-                            exec_engine.update_cpu_from_engine()
+                    # Check memory access / write exception
+                    # TODO: insert a check between memory reads and writes
+                    if attributes.mem_read or attributes.mem_write:
+                        # Restricted exception
+                        flag = ~csts.EXCEPT_CODE_AUTOMOD & csts.EXCEPT_DO_NOT_UPDATE_PC
+                        if (vmmngr.get_exception() & flag != 0):
+                            # Do not update registers
+                            update_pc(instr.offset)
                             return instr.offset
 
-                    # Eval current instruction (in IR)
-                    exec_engine.eval_updt_assignblk(assignblk)
-                    # Check for exceptions which do not update PC
+                    # Update registers values
                     exec_engine.update_cpu_from_engine()
-                    if (vmmngr.get_exception() & csts.EXCEPT_DO_NOT_UPDATE_PC != 0 or
-                        cpu.get_exception() > csts.EXCEPT_NUM_UPDT_EIP):
-                        return instr.offset
-
-                vmmngr.check_invalid_code_blocs()
-                vmmngr.check_memory_breakpoint()
 
-                # Get next bloc address
-                ad = expr_simp(exec_engine.eval_expr(self.ir_arch.IRDst))
+                    # Check post assignblk exception flags
+                    if attributes.set_exception:
+                        # Restricted exception
+                        if cpu.get_exception() > csts.EXCEPT_NUM_UPDT_EIP:
+                            # Update PC
+                            update_pc(instr.offset)
+                            return instr.offset
 
-                # Updates @cpu instance according to new CPU values
-                exec_engine.update_cpu_from_engine()
+                dst = exec_engine.eval_expr(self.ir_arch.IRDst)
+                if dst.is_int():
+                    loc_key = loc_db.get_or_create_offset_location(int(dst))
+                    dst = ExprLoc(loc_key, dst.size)
+
+                assert dst.is_loc()
+                loc_key = dst.loc_key
+                offset = loc_db.get_location_offset(loc_key)
+                if offset is None:
+                    # Avoid checks on generated label
+                    cur_loc_key = loc_key
+                    continue
+
+                if instr_attrib.log_regs:
+                    update_pc(offset)
+                    cpu.dump_gpregs_with_attrib(self.ir_arch.attrib)
+
+                # Post-instr checks
+                if instr_attrib.mem_read | instr_attrib.mem_write:
+                    vmmngr.check_memory_breakpoint()
+                    vmmngr.check_invalid_code_blocs()
+                    if vmmngr.get_exception():
+                        update_pc(offset)
+                        return offset
+
+                if instr_attrib.set_exception:
+                    if cpu.get_exception():
+                        update_pc(offset)
+                        return offset
+
+                if instr_attrib.mem_read | instr_attrib.mem_write:
+                    vmmngr.reset_memory_access()
 
                 # Manage resulting address
-                if isinstance(ad, m2_expr.ExprInt):
-                    return ad.arg.arg
-                elif isinstance(ad, m2_expr.ExprLoc):
-                    cur_loc_key = ad.loc_key
-                else:
-                    raise NotImplementedError("Type not handled: %s" % ad)
+                if (loc_key in local_loc_keys and
+                    offset > instr.offset):
+                    # Forward local jump
+                    # Note: a backward local jump has to be promoted to extern,
+                    # for max_exec_per_call support
+                    cur_loc_key = loc_key
+                    continue
+
+                # Delay slot
+                if has_delayslot:
+                    delay_slot_set = exec_engine.eval_expr(codegen.delay_slot_set)
+                    if delay_slot_set.is_int() and int(delay_slot_set) != 0:
+                        return int(exec_engine.eval_expr(codegen.delay_slot_dst))
+
+                # Extern of asmblock, must have an offset
+                assert offset is not None
+                return offset
 
         # Associate myfunc with current loc_key
-        offset = self.ir_arch.loc_db.get_location_offset(loc_key)
+        offset = loc_db.get_location_offset(asmblock.loc_key)
         assert offset is not None
         self.offset_to_jitted_func[offset] = myfunc
 
diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py
index 37ce8d52..41461c3a 100644
--- a/miasm2/jitter/llvmconvert.py
+++ b/miasm2/jitter/llvmconvert.py
@@ -874,15 +874,15 @@ class LLVMFunction(object):
                 self.update_cache(expr, ret)
                 return ret
 
-            if op in ["imod", "idiv", "umod", "udiv"]:
+            if op in ["smod", "sdiv", "umod", "udiv"]:
                 assert len(expr.args) == 2
 
                 arg_b = self.add_ir(expr.args[1])
                 arg_a = self.add_ir(expr.args[0])
 
-                if op == "imod":
+                if op == "smod":
                     callback = builder.srem
-                elif op == "idiv":
+                elif op == "sdiv":
                     callback = builder.sdiv
                 elif op == "umod":
                     callback = builder.urem
@@ -1297,7 +1297,7 @@ class LLVMFunction(object):
             # Update PC for dump_gpregs
             PC = self.llvm_context.PC
             t_size = LLVMType.IntType(PC.size)
-            dst = self.builder.zext(t_size(pc_value), LLVMType.IntType(PC.size))
+            dst = self.builder.zext(t_size(pc_value), t_size)
             self.affect(dst, PC)
 
             fc_ptr = self.mod.get_global(self.llvm_context.logging_func)
diff --git a/miasm2/jitter/op_semantics.c b/miasm2/jitter/op_semantics.c
index 091da87f..46e6cca1 100644
--- a/miasm2/jitter/op_semantics.c
+++ b/miasm2/jitter/op_semantics.c
@@ -738,12 +738,12 @@ UMOD(16)
 UMOD(32)
 UMOD(64)
 
-IDIV(8)
-IDIV(16)
-IDIV(32)
-IDIV(64)
-
-IMOD(8)
-IMOD(16)
-IMOD(32)
-IMOD(64)
+SDIV(8)
+SDIV(16)
+SDIV(32)
+SDIV(64)
+
+SMOD(8)
+SMOD(16)
+SMOD(32)
+SMOD(64)
diff --git a/miasm2/jitter/op_semantics.h b/miasm2/jitter/op_semantics.h
index 921c9b9e..690cfb35 100644
--- a/miasm2/jitter/op_semantics.h
+++ b/miasm2/jitter/op_semantics.h
@@ -66,8 +66,8 @@ _MIASM_EXPORT unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 	}
 
 
-#define IDIV(sizeA)						\
-	int ## sizeA ## _t idiv ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
+#define SDIV(sizeA)						\
+	int ## sizeA ## _t sdiv ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
 	{								\
 		int ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -79,8 +79,8 @@ _MIASM_EXPORT unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 	}
 
 
-#define IMOD(sizeA)						\
-	int ## sizeA ## _t imod ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
+#define SMOD(sizeA)						\
+	int ## sizeA ## _t smod ## sizeA (int ## sizeA ## _t a, int ## sizeA ## _t b) \
 	{								\
 		int ## sizeA ## _t r;					\
 		if (b == 0) {						\
@@ -93,23 +93,23 @@ _MIASM_EXPORT unsigned int cnttrailzeros(uint64_t size, uint64_t src);
 
 _MIASM_EXPORT uint64_t udiv64(uint64_t a, uint64_t b);
 _MIASM_EXPORT uint64_t umod64(uint64_t a, uint64_t b);
-_MIASM_EXPORT int64_t idiv64(int64_t a, int64_t b);
-_MIASM_EXPORT int64_t imod64(int64_t a, int64_t b);
+_MIASM_EXPORT int64_t sdiv64(int64_t a, int64_t b);
+_MIASM_EXPORT int64_t smod64(int64_t a, int64_t b);
 
 _MIASM_EXPORT uint32_t udiv32(uint32_t a, uint32_t b);
 _MIASM_EXPORT uint32_t umod32(uint32_t a, uint32_t b);
-_MIASM_EXPORT int32_t idiv32(int32_t a, int32_t b);
-_MIASM_EXPORT int32_t imod32(int32_t a, int32_t b);
+_MIASM_EXPORT int32_t sdiv32(int32_t a, int32_t b);
+_MIASM_EXPORT int32_t smod32(int32_t a, int32_t b);
 
 _MIASM_EXPORT uint16_t udiv16(uint16_t a, uint16_t b);
 _MIASM_EXPORT uint16_t umod16(uint16_t a, uint16_t b);
-_MIASM_EXPORT int16_t idiv16(int16_t a, int16_t b);
-_MIASM_EXPORT int16_t imod16(int16_t a, int16_t b);
+_MIASM_EXPORT int16_t sdiv16(int16_t a, int16_t b);
+_MIASM_EXPORT int16_t smod16(int16_t a, int16_t b);
 
 _MIASM_EXPORT uint8_t udiv8(uint8_t a, uint8_t b);
 _MIASM_EXPORT uint8_t umod8(uint8_t a, uint8_t b);
-_MIASM_EXPORT int8_t idiv8(int8_t a, int8_t b);
-_MIASM_EXPORT int8_t imod8(int8_t a, int8_t b);
+_MIASM_EXPORT int8_t sdiv8(int8_t a, int8_t b);
+_MIASM_EXPORT int8_t smod8(int8_t a, int8_t b);
 
 _MIASM_EXPORT unsigned int x86_cpuid(unsigned int a, unsigned int reg_num);