about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/mep/sem.py7
-rw-r--r--miasm2/arch/mips32/ira.py106
-rw-r--r--miasm2/arch/mips32/regs.py1
-rw-r--r--miasm2/arch/mips32/sem.py53
-rw-r--r--miasm2/expression/expression.py14
-rw-r--r--miasm2/expression/expression_helper.py2
-rw-r--r--miasm2/expression/simplifications.py3
-rw-r--r--miasm2/expression/simplifications_common.py111
-rw-r--r--miasm2/expression/simplifications_explicit.py11
-rw-r--r--miasm2/ir/translators/C.py5
-rw-r--r--test/arch/mep/ir/test_divide.py24
-rw-r--r--test/expression/simplifications.py9
-rwxr-xr-xtest/ir/ir2C.py4
13 files changed, 224 insertions, 126 deletions
diff --git a/miasm2/arch/mep/sem.py b/miasm2/arch/mep/sem.py
index e1d4c5fa..e779b970 100644
--- a/miasm2/arch/mep/sem.py
+++ b/miasm2/arch/mep/sem.py
@@ -912,7 +912,12 @@ def div(rn, rm):
 
     # Check if both numbers are positive or negative
     are_both_neg = sign_rn & sign_rm
-    are_both_pos = "=="(are_both_neg, sign_mask)
+    are_both_pos = ExprCond(
+        are_both_neg - sign_mask,
+        ExprInt(0, are_both_neg.size),
+        ExprInt(1, are_both_neg.size)
+    )
+
 
     # Invert both numbers
     rn_inv = ~rn + i32(1)
diff --git a/miasm2/arch/mips32/ira.py b/miasm2/arch/mips32/ira.py
index def75750..4c4a33d8 100644
--- a/miasm2/arch/mips32/ira.py
+++ b/miasm2/arch/mips32/ira.py
@@ -1,7 +1,7 @@
 #-*- coding:utf-8 -*-
 
-from miasm2.expression.expression import ExprAff, ExprInt, ExprId
-from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
+from miasm2.expression.expression import ExprAff, ExprOp
+from miasm2.ir.ir import IRBlock, AssignBlock
 from miasm2.ir.analysis import ira
 from miasm2.arch.mips32.sem import ir_mips32l, ir_mips32b
 
@@ -10,41 +10,73 @@ class ir_a_mips32l(ir_mips32l, ira):
         ir_mips32l.__init__(self, loc_db)
         self.ret_reg = self.arch.regs.V0
 
-    def post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks):
-        IntermediateRepresentation.post_add_asmblock_to_ircfg(self, block, ircfg, ir_blocks)
-        new_irblocks = []
-        for irb in ir_blocks:
-            pc_val = None
-            lr_val = None
-            for assignblk in irb:
-                pc_val = assignblk.get(self.arch.regs.PC, pc_val)
-                lr_val = assignblk.get(self.arch.regs.RA, lr_val)
-
-            if pc_val is None or lr_val is None:
-                new_irblocks.append(irb)
-                continue
-            if lr_val.is_loc():
-                offset = self.loc_db.get_location_offset(lr_val.loc_key)
-                if offset is not None:
-                    lr_val = ExprInt(offset, 32)
-            if not lr_val.is_int():
-                continue
-
-            instr = block.lines[-2]
-            if int(lr_val) != instr.offset + 8:
-                raise ValueError("Wrong arg")
-
-            # CALL
-            lbl = block.get_next()
-            new_lbl = self.gen_label()
-            call_assignblks, extra_irblocks = self.call_effects(pc_val, instr)
-            ir_blocks += extra_irblocks
-            irs.append(AssignBlock([ExprAff(self.IRDst,
-                                            ExprId(lbl, size=self.pc.size))],
-                                   instr))
-            new_irblocks.append(IRBlock(new_lbl, call_assignblks))
-            new_irblocks.append(irb.set_dst(ExprId(new_lbl, size=self.pc.size)))
-        return new_irblocks
+    def call_effects(self, ad, instr):
+        call_assignblk = AssignBlock(
+            [
+                ExprAff(
+                    self.ret_reg,
+                    ExprOp(
+                        'call_func_ret',
+                        ad,
+                        self.arch.regs.A0,
+                        self.arch.regs.A1,
+                        self.arch.regs.A2,
+                        self.arch.regs.A3,
+                    )
+                ),
+            ],
+            instr
+        )
+
+        return [call_assignblk], []
+
+
+    def add_asmblock_to_ircfg(self, block, ircfg, gen_pc_updt=False):
+        """
+        Add a native block to the current IR
+        @block: native assembly block
+        @ircfg: IRCFG instance
+        @gen_pc_updt: insert PC update effects between instructions
+        """
+        loc_key = block.loc_key
+        ir_blocks_all = []
+
+        assignments = []
+        for index, instr in enumerate(block.lines):
+            if loc_key is None:
+                assignments = []
+                loc_key = self.get_loc_key_for_instr(instr)
+            if instr.is_subcall():
+                assert index == len(block.lines) - 2
+
+                # Add last instruction first (before call)
+                split = self.add_instr_to_current_state(
+                    block.lines[-1], block, assignments,
+                    ir_blocks_all, gen_pc_updt
+                )
+                assert not split
+                # Add call effects after the delay splot
+                split = self.add_instr_to_current_state(
+                    instr, block, assignments,
+                    ir_blocks_all, gen_pc_updt
+                )
+                assert split
+                break
+            split = self.add_instr_to_current_state(
+                instr, block, assignments,
+                ir_blocks_all, gen_pc_updt
+            )
+            if split:
+                ir_blocks_all.append(IRBlock(loc_key, assignments))
+                loc_key = None
+                assignments = []
+        if loc_key is not None:
+            ir_blocks_all.append(IRBlock(loc_key, assignments))
+
+        new_ir_blocks_all = self.post_add_asmblock_to_ircfg(block, ircfg, ir_blocks_all)
+        for irblock in new_ir_blocks_all:
+            ircfg.add_irblock(irblock)
+        return new_ir_blocks_all
 
     def get_out_regs(self, _):
         return set([self.ret_reg, self.sp])
diff --git a/miasm2/arch/mips32/regs.py b/miasm2/arch/mips32/regs.py
index 7ff949f2..ddaaff79 100644
--- a/miasm2/arch/mips32/regs.py
+++ b/miasm2/arch/mips32/regs.py
@@ -24,6 +24,7 @@ regs32_str = ["ZERO", 'AT', 'V0', 'V1'] +\
     ['GP', 'SP', 'FP', 'RA']
 
 regs32_expr = [ExprId(x, 32) for x in regs32_str]
+ZERO = regs32_expr[0]
 
 regs_flt_str = ['F%d'%i for i in xrange(0x20)]
 
diff --git a/miasm2/arch/mips32/sem.py b/miasm2/arch/mips32/sem.py
index acf7370f..92001280 100644
--- a/miasm2/arch/mips32/sem.py
+++ b/miasm2/arch/mips32/sem.py
@@ -1,16 +1,20 @@
 import miasm2.expression.expression as m2_expr
 from miasm2.ir.ir import IntermediateRepresentation, IRBlock, AssignBlock
 from miasm2.arch.mips32.arch import mn_mips32
-from miasm2.arch.mips32.regs import R_LO, R_HI, PC, RA, exception_flags
+from miasm2.arch.mips32.regs import R_LO, R_HI, PC, RA, ZERO, exception_flags
 from miasm2.core.sembuilder import SemBuilder
 from miasm2.jitter.csts import EXCEPT_DIV_BY_ZERO
 
 
 # SemBuilder context
-ctx = {"R_LO": R_LO,
-       "R_HI": R_HI,
-       "PC": PC,
-       "RA": RA}
+ctx = {
+    "R_LO": R_LO,
+    "R_HI": R_HI,
+    "PC": PC,
+    "RA": RA,
+    "m2_expr": m2_expr
+}
+
 sbuild = SemBuilder(ctx)
 
 
@@ -76,7 +80,7 @@ def lb(arg1, arg2):
 @sbuild.parse
 def beq(arg1, arg2, arg3):
     "Branches on @arg3 if the quantities of two registers @arg1, @arg2 are eq"
-    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1 - arg2 else arg3
+    dst = arg3 if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst
     ir.IRDst = dst
 
@@ -84,7 +88,7 @@ def beq(arg1, arg2, arg3):
 def bgez(arg1, arg2):
     """Branches on @arg2 if the quantities of register @arg1 is greater than or
     equal to zero"""
-    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if arg1.msb() else arg2
+    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else arg2
     PC = dst
     ir.IRDst = dst
 
@@ -92,7 +96,7 @@ def bgez(arg1, arg2):
 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 ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
+    dst = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if ExprOp(m2_expr.TOK_EQUAL, arg1, arg2) else arg3
     PC = dst
     ir.IRDst = dst
 
@@ -143,15 +147,24 @@ def mul(arg1, arg2, arg3):
 
 @sbuild.parse
 def sltu(arg1, arg2, arg3):
-    """If @arg3 is less than @arg2 (unsigned), @arg1 is set to one. It gets zero
+    """If @arg2 is less than @arg3 (unsigned), @arg1 is set to one. It gets zero
     otherwise."""
-    arg1 = (((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))) ^ arg2 ^ arg3).msb().zeroExtend(32)
+    arg1 = ExprCond(
+        ExprOp(m2_expr.TOK_INF_UNSIGNED, arg2, arg3),
+        ExprInt(1, arg1.size),
+        ExprInt(0, arg1.size)
+    )
 
 @sbuild.parse
 def slt(arg1, arg2, arg3):
-    """If @arg3 is less than @arg2 (signed), @arg1 is set to one. It gets zero
+    """If @arg2 is less than @arg3 (signed), @arg1 is set to one. It gets zero
     otherwise."""
-    arg1 = ((arg2 - arg3) ^ ((arg2 ^ arg3) & ((arg2 - arg3) ^ arg2))).msb().zeroExtend(32)
+    arg1 = ExprCond(
+        ExprOp(m2_expr.TOK_INF_SIGNED, arg2, arg3),
+        ExprInt(1, arg1.size),
+        ExprInt(0, arg1.size)
+    )
+
 
 @sbuild.parse
 def l_sub(arg1, arg2, arg3):
@@ -230,14 +243,14 @@ def seh(arg1, arg2):
 @sbuild.parse
 def bltz(arg1, arg2):
     """Branches on @arg2 if the register @arg1 is less than zero"""
-    dst_o = arg2 if arg1.msb() else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
+    dst_o = arg2 if ExprOp(m2_expr.TOK_INF_SIGNED, arg1, ExprInt(0, arg1.size)) else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst_o
     ir.IRDst = dst_o
 
 @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()
+    cond = ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size))
     dst_o = arg2 if cond else ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size)
     PC = dst_o
     ir.IRDst = dst_o
@@ -245,7 +258,7 @@ def blez(arg1, arg2):
 @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()
+    cond =  ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1, ExprInt(0, arg1.size))
     dst_o = ExprLoc(ir.get_next_break_loc_key(instr), ir.IRDst.size) if cond else arg2
     PC = dst_o
     ir.IRDst = dst_o
@@ -480,12 +493,15 @@ class ir_mips32l(IntermediateRepresentation):
         args = instr.args
         instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
 
-        pc_fixed = {self.pc: m2_expr.ExprInt(instr.offset + 4, 32)}
+        fixed_regs = {
+            self.pc: m2_expr.ExprInt(instr.offset + 4, 32),
+            ZERO: m2_expr.ExprInt(0, 32)
+        }
 
-        instr_ir = [m2_expr.ExprAff(expr.dst, expr.src.replace_expr(pc_fixed))
+        instr_ir = [m2_expr.ExprAff(expr.dst, expr.src.replace_expr(fixed_regs))
                     for expr in instr_ir]
 
-        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(pc_fixed))
+        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fixed_regs))
                         for irblock in extra_ir]
         return instr_ir, new_extra_ir
 
@@ -497,6 +513,7 @@ class ir_mips32l(IntermediateRepresentation):
 
 class ir_mips32b(ir_mips32l):
     def __init__(self, loc_db=None):
+        self.addrsize = 32
         IntermediateRepresentation.__init__(self, mn_mips32, 'b', loc_db)
         self.pc = mn_mips32.getpc()
         self.sp = mn_mips32.getsp()
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index 954ba00a..ec423f83 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -1009,7 +1009,7 @@ class ExprOp(Expr):
 
         # Set size for special cases
         if self._op in [
-                '==', 'parity', 'fcom_c0', 'fcom_c1', 'fcom_c2', 'fcom_c3',
+                TOK_EQUAL, 'parity', 'fcom_c0', 'fcom_c1', 'fcom_c2', 'fcom_c3',
                 'fxam_c0', 'fxam_c1', 'fxam_c2', 'fxam_c3',
                 "access_segment_ok", "load_segment_limit_ok", "bcdadd_cf",
                 "ucomiss_zf", "ucomiss_pf", "ucomiss_cf",
@@ -1102,9 +1102,15 @@ class ExprOp(Expr):
         return self._op.startswith('call')
 
     def is_infix(self):
-        return self._op in [ '-', '+', '*', '^', '&', '|', '>>', '<<',
-                             'a>>', '>>>', '<<<', '/', '%', '**',
-                             '<u', '<s', '<=u', '<=s', '==' ]
+        return self._op in [
+            '-', '+', '*', '^', '&', '|', '>>', '<<',
+            'a>>', '>>>', '<<<', '/', '%', '**',
+            TOK_INF_UNSIGNED,
+            TOK_INF_SIGNED,
+            TOK_INF_EQUAL_UNSIGNED,
+            TOK_INF_EQUAL_SIGNED,
+            TOK_EQUAL
+        ]
 
     def is_associative(self):
         "Return True iff current operation is associative"
diff --git a/miasm2/expression/expression_helper.py b/miasm2/expression/expression_helper.py
index bb0d5adf..5de9e04f 100644
--- a/miasm2/expression/expression_helper.py
+++ b/miasm2/expression/expression_helper.py
@@ -512,7 +512,7 @@ class CondConstraint(object):
 class CondConstraintZero(CondConstraint):
 
     """Stand for a constraint like 'A == 0'"""
-    operator = "=="
+    operator = m2_expr.TOK_EQUAL
 
     def to_constraint(self):
         return m2_expr.ExprAff(self.expr, m2_expr.ExprInt(0, self.expr.size))
diff --git a/miasm2/expression/simplifications.py b/miasm2/expression/simplifications.py
index d3628ae8..e090d806 100644
--- a/miasm2/expression/simplifications.py
+++ b/miasm2/expression/simplifications.py
@@ -56,6 +56,9 @@ class ExpressionSimplifier(object):
             simplifications_common.simp_cond_flag,
             simplifications_common.simp_cond_int,
             simplifications_common.simp_cmp_int_arg,
+
+            simplifications_common.simp_cond_eq_zero,
+
         ],
         m2_expr.ExprMem: [simplifications_common.simp_mem],
 
diff --git a/miasm2/expression/simplifications_common.py b/miasm2/expression/simplifications_common.py
index b01b1d1d..e7dacc91 100644
--- a/miasm2/expression/simplifications_common.py
+++ b/miasm2/expression/simplifications_common.py
@@ -4,8 +4,11 @@
 
 
 from miasm2.expression.modint import mod_size2int, mod_size2uint
-from miasm2.expression.expression import ExprInt, ExprSlice, ExprMem, ExprCond, ExprOp, ExprCompose
-from miasm2.expression.expression_helper import parity, op_propag_cst, merge_sliceto_slice
+from miasm2.expression.expression import ExprInt, ExprSlice, ExprMem, \
+    ExprCond, ExprOp, ExprCompose, TOK_INF_SIGNED, TOK_INF_UNSIGNED, \
+    TOK_INF_EQUAL_SIGNED, TOK_INF_EQUAL_UNSIGNED, TOK_EQUAL
+from miasm2.expression.expression_helper import parity, op_propag_cst, \
+    merge_sliceto_slice
 
 
 def simp_cst_propagation(e_s, expr):
@@ -692,7 +695,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SUB_CF"
           )):
         expr = ExprCond(
-            ExprOp("<u", *expr.args[0].args),
+            ExprOp(TOK_INF_UNSIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1))
 
@@ -701,14 +704,14 @@ def simp_cc_conds(expr_simp, expr):
               expr,
               "FLAG_SUB_CF"
           )):
-        expr = ExprOp("<u", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_UNSIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_NEG") and
           test_cc_eq_args(
               expr,
               "FLAG_SIGN_SUB"
           )):
-        expr = ExprOp("<s", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_SIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_POS") and
           test_cc_eq_args(
@@ -716,7 +719,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SIGN_SUB"
           )):
         expr = ExprCond(
-            ExprOp("<s", *expr.args[0].args),
+            ExprOp(TOK_INF_SIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -727,7 +730,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_EQ"
           )):
         arg = expr.args[0].args[0]
-        expr = ExprOp("==", arg, ExprInt(0, arg.size))
+        expr = ExprOp(TOK_EQUAL, arg, ExprInt(0, arg.size))
 
     elif (expr.is_op("CC_NE") and
           test_cc_eq_args(
@@ -736,7 +739,7 @@ def simp_cc_conds(expr_simp, expr):
           )):
         arg = expr.args[0].args[0]
         expr = ExprCond(
-            ExprOp("==",arg, ExprInt(0, arg.size)),
+            ExprOp(TOK_EQUAL,arg, ExprInt(0, arg.size)),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -746,7 +749,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_EQ_CMP"
           )):
         expr = ExprCond(
-            ExprOp("==", *expr.args[0].args),
+            ExprOp(TOK_EQUAL, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -756,7 +759,7 @@ def simp_cc_conds(expr_simp, expr):
               expr,
               "FLAG_EQ_CMP"
           )):
-        expr = ExprOp("==", *expr.args[0].args)
+        expr = ExprOp(TOK_EQUAL, *expr.args[0].args)
 
     elif (expr.is_op("CC_NE") and
           test_cc_eq_args(
@@ -784,7 +787,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_EQ_CMP",
           )):
         expr = ExprCond(
-            ExprOp("<=s", *expr.args[0].args),
+            ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -796,7 +799,7 @@ def simp_cc_conds(expr_simp, expr):
           expr.args[0].args == expr.args[2].args and
           expr.args[1].is_int(0)):
         expr = ExprCond(
-            ExprOp("<=s", *expr.args[0].args),
+            ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -810,7 +813,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SUB_OF"
           )):
         expr = ExprCond(
-            ExprOp("<s", *expr.args[0].args),
+            ExprOp(TOK_INF_SIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -821,7 +824,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SIGN_SUB",
               "FLAG_SUB_OF"
           )):
-        expr = ExprOp("<s", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_SIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_S<=") and
           test_cc_eq_args(
@@ -830,7 +833,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SUB_OF",
               "FLAG_EQ_CMP",
           )):
-        expr = ExprOp("<=s", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_S<=") and
           len(expr.args) == 3 and
@@ -838,7 +841,7 @@ def simp_cc_conds(expr_simp, expr):
           expr.args[2].is_op("FLAG_EQ_CMP") and
           expr.args[0].args == expr.args[2].args and
           expr.args[1].is_int(0)):
-        expr = ExprOp("<=s", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_EQUAL_SIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_U<=") and
           test_cc_eq_args(
@@ -846,7 +849,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_SUB_CF",
               "FLAG_EQ_CMP",
           )):
-        expr = ExprOp("<=u", *expr.args[0].args)
+        expr = ExprOp(TOK_INF_EQUAL_UNSIGNED, *expr.args[0].args)
 
     elif (expr.is_op("CC_U>") and
           test_cc_eq_args(
@@ -855,7 +858,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_EQ_CMP",
           )):
         expr = ExprCond(
-            ExprOp("<=u", *expr.args[0].args),
+            ExprOp(TOK_INF_EQUAL_UNSIGNED, *expr.args[0].args),
             ExprInt(0, 1),
             ExprInt(1, 1)
         )
@@ -867,7 +870,7 @@ def simp_cc_conds(expr_simp, expr):
               "FLAG_ADD_OF"
           )):
         arg0, arg1 = expr.args[0].args
-        expr = ExprOp("<s", arg0, -arg1)
+        expr = ExprOp(TOK_INF_SIGNED, arg0, -arg1)
 
     return expr
 
@@ -877,12 +880,12 @@ def simp_cond_flag(expr_simp, 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("==", *cond.args), expr.src1, expr.src2)
+        return ExprCond(ExprOp(TOK_EQUAL, *cond.args), expr.src1, expr.src2)
     return expr
 
 
 def simp_cond_int(expr_simp, expr):
-    if (expr.cond.is_op('==') and
+    if (expr.cond.is_op(TOK_EQUAL) and
           expr.cond.args[1].is_int() and
           expr.cond.args[0].is_compose() and
           len(expr.cond.args[0].args) == 2 and
@@ -891,9 +894,20 @@ def simp_cond_int(expr_simp, expr):
         src = expr.cond.args[0].args[0]
         int_val = int(expr.cond.args[1])
         new_int = ExprInt(int_val, src.size)
-        expr = expr_simp(ExprCond(ExprOp("==", src, new_int), expr.src1, expr.src2))
+        expr = expr_simp(
+            ExprCond(
+                ExprOp(TOK_EQUAL, src, new_int),
+                expr.src1,
+                expr.src2)
+        )
     elif (expr.cond.is_op() and
-          expr.cond.op in ['==', '<s', '<=s', '<u', '<=u'] and
+          expr.cond.op in [
+              TOK_EQUAL,
+              TOK_INF_SIGNED,
+              TOK_INF_EQUAL_SIGNED,
+              TOK_INF_UNSIGNED,
+              TOK_INF_EQUAL_UNSIGNED
+          ] and
           expr.cond.args[1].is_int() and
           expr.cond.args[0].is_op("+") and
           expr.cond.args[0].args[-1].is_int()):
@@ -905,7 +919,12 @@ def simp_cond_int(expr_simp, expr):
         else:
             left = ExprOp('+', *left)
         new_int = expr_simp(right - int_diff)
-        expr = expr_simp(ExprCond(ExprOp(expr.cond.op, left, new_int), expr.src1, expr.src2))
+        expr = expr_simp(
+            ExprCond(
+                ExprOp(expr.cond.op, left, new_int),
+                expr.src1,
+                expr.src2)
+        )
     return expr
 
 
@@ -920,7 +939,13 @@ def simp_cmp_int_arg(expr_simp, expr):
     if not cond.is_op():
         return expr
     op = cond.op
-    if op not in ['==', '<s', '<=s', '<u', '<=u']:
+    if op not in [
+            TOK_EQUAL,
+            TOK_INF_SIGNED,
+            TOK_INF_EQUAL_SIGNED,
+            TOK_INF_UNSIGNED,
+            TOK_INF_EQUAL_UNSIGNED
+    ]:
         return expr
     arg1, arg2 = cond.args
     if arg2.is_int():
@@ -928,19 +953,19 @@ def simp_cmp_int_arg(expr_simp, expr):
     if not arg1.is_int():
         return expr
     src1, src2 = expr.src1, expr.src2
-    if op == "==":
-        return ExprCond(ExprOp('==', arg2, arg1), src1, src2)
+    if op == TOK_EQUAL:
+        return ExprCond(ExprOp(TOK_EQUAL, arg2, arg1), src1, src2)
 
     arg1, arg2 = arg2, arg1
     src1, src2 = src2, src1
-    if op == '<s':
-        op = '<=s'
-    elif op == '<=s':
-        op = '<s'
-    elif op == '<u':
-        op = '<=u'
-    elif op == '<=u':
-        op = '<u'
+    if op == TOK_INF_SIGNED:
+        op = TOK_INF_EQUAL_SIGNED
+    elif op == TOK_INF_EQUAL_SIGNED:
+        op = TOK_INF_SIGNED
+    elif op == TOK_INF_UNSIGNED:
+        op = TOK_INF_EQUAL_UNSIGNED
+    elif op == TOK_INF_EQUAL_UNSIGNED:
+        op = TOK_INF_UNSIGNED
     return ExprCond(ExprOp(op, arg1, arg2), src1, src2)
 
 
@@ -1009,7 +1034,7 @@ def simp_double_signext(expr_s, expr):
 
 def simp_zeroext_eq_cst(expr_s, expr):
     # A.zeroExt(X) == int => A == int[:A.size]
-    if not expr.is_op("=="):
+    if not expr.is_op(TOK_EQUAL):
         return expr
     arg1, arg2 = expr.args
     if not arg2.is_int():
@@ -1020,4 +1045,16 @@ def simp_zeroext_eq_cst(expr_s, expr):
     if int(arg2) > (1 << src.size):
         # Always false
         return ExprInt(0, 1)
-    return ExprOp("==", src, ExprInt(int(arg2), src.size))
+    return ExprOp(TOK_EQUAL, src, ExprInt(int(arg2), src.size))
+
+
+def simp_cond_eq_zero(expr_s, expr):
+    # (X == 0)?(A:B) => X?(B:A)
+    cond = expr.cond
+    if not cond.is_op(TOK_EQUAL):
+        return expr
+    arg1, arg2 = cond.args
+    if not arg2.is_int(0):
+        return expr
+    new_expr = ExprCond(arg1, expr.src2, expr.src1)
+    return new_expr
diff --git a/miasm2/expression/simplifications_explicit.py b/miasm2/expression/simplifications_explicit.py
index 54e9efc2..4c5dde3e 100644
--- a/miasm2/expression/simplifications_explicit.py
+++ b/miasm2/expression/simplifications_explicit.py
@@ -1,5 +1,6 @@
 from miasm2.expression.modint import size2mask
-from miasm2.expression.expression import ExprInt, ExprCond, ExprCompose
+from miasm2.expression.expression import ExprInt, ExprCond, ExprCompose, \
+    TOK_EQUAL
 
 
 def simp_ext(_, expr):
@@ -154,5 +155,13 @@ def simp_flags(_, expr):
         op_nf, = args
         return ~op_nf
 
+    elif expr.is_op(TOK_EQUAL):
+        arg1, arg2 = args
+        return ExprCond(
+            arg1 - arg2,
+            ExprInt(0, expr.size),
+            ExprInt(1, expr.size),
+        )
+
     return expr
 
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index 89a2ac84..01aa7d7a 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -1,6 +1,7 @@
 from miasm2.ir.translators.translator import Translator
 from miasm2.expression.modint import size2mask
-from miasm2.expression.expression import ExprInt, ExprCond, ExprCompose
+from miasm2.expression.expression import ExprInt, ExprCond, ExprCompose, \
+    TOK_EQUAL
 
 def int_size_to_bn(value, size):
     if size < 32:
@@ -243,7 +244,7 @@ class TranslatorC(Translator):
                 raise NotImplementedError('Unknown op: %r' % expr.op)
 
         elif len(expr.args) == 2:
-            if expr.op == "==":
+            if expr.op == TOK_EQUAL:
                 return '(((%s&%s) == (%s&%s))?1:0)' % (
                     self.from_expr(expr.args[0]),
                     self._size2mask(expr.args[0].size),
diff --git a/test/arch/mep/ir/test_divide.py b/test/arch/mep/ir/test_divide.py
index 04d5f6c5..a63d0c5e 100644
--- a/test/arch/mep/ir/test_divide.py
+++ b/test/arch/mep/ir/test_divide.py
@@ -39,33 +39,21 @@ class TestDivide:
         exec_instruction("DIV R0, R1",
                          [(ExprId("R0", 32), ExprInt(4, 32)),
                           (ExprId("R1", 32), ExprInt(2, 32))],
-                         [(ExprId("HI", 32), ExprCond(ExprOp("==",
-                                                             ExprInt(0, 32),
-                                                             ExprInt(0x80000000, 32)),
-                                                      ExprInt(0, 32),
-                                                      ExprInt(0xFFFFFFFC, 32))),
-                          (ExprId("LO", 32), ExprCond(ExprOp("==",
-                                                             ExprInt(0, 32),
-                                                             ExprInt(0x80000000, 32)),
-                                                       ExprInt(2, 32),
-                                                       ExprInt(0, 32)))])
+                         [(ExprId("HI", 32), ExprInt(0xFFFFFFFC, 32)),
+                          (ExprId("LO", 32), ExprInt(0, 32))])
 
         # Negative & positive numbers
         exec_instruction("DIV R0, R1",
                          [(ExprId("R0", 32), ExprInt(-5, 32)),
                           (ExprId("R1", 32), ExprInt(2, 32))],
-                         [(ExprId("HI", 32), ExprCond(ExprOp("==", ExprInt(0, 32), ExprInt(0x80000000, 32)),
-                                                      ExprInt(1, 32), ExprInt(0xFFFFFFFF, 32))),
-                          (ExprId("LO", 32), ExprCond(ExprOp("==", ExprInt(0, 32), ExprInt(0x80000000, 32)),
-                                                      ExprInt(0x7FFFFFFD, 32), ExprInt(0xFFFFFFFE, 32)))])
+                         [(ExprId("HI", 32), ExprInt(0xFFFFFFFF, 32)),
+                          (ExprId("LO", 32), ExprInt(0xFFFFFFFE, 32))])
 
         exec_instruction("DIV R0, R1",
                          [(ExprId("R0", 32), ExprInt(5, 32)),
                           (ExprId("R1", 32), ExprInt(-2, 32))],
-                         [(ExprId("HI", 32), ExprCond(ExprOp("==", ExprInt(0, 32), ExprInt(0x80000000, 32)),
-                                                      ExprInt(5, 32), ExprInt(0xFFFFFFFF, 32))),
-                          (ExprId("LO", 32), ExprCond(ExprOp("==", ExprInt(0, 32), ExprInt(0x80000000, 32)),
-                                                      ExprInt(0, 32), ExprInt(0xFFFFFFFE, 32)))])
+                         [(ExprId("HI", 32), ExprInt(0xFFFFFFFF, 32)),
+                          (ExprId("LO", 32), ExprInt(0xFFFFFFFE, 32))])
 
     def test_divu(self):
         """Test DIVU execution"""
diff --git a/test/expression/simplifications.py b/test/expression/simplifications.py
index 1d91f109..046c948e 100644
--- a/test/expression/simplifications.py
+++ b/test/expression/simplifications.py
@@ -479,19 +479,18 @@ to_test = [
     (ExprOp_inf_signed(ExprInt(-3, 32), ExprInt(0, 32)), ExprInt(1, 1)),
 ]
 
-expr_simp_cond = ExpressionSimplifier()
-expr_simp_explicit.enable_passes(ExpressionSimplifier.PASS_COND)
+expr_simp.enable_passes(ExpressionSimplifier.PASS_COND)
 
 
 for e_input, e_check in to_test:
     print "#" * 80
-    e_check = expr_simp_explicit(e_check)
-    e_new = expr_simp_explicit(e_input)
+    e_check = expr_simp(e_check)
+    e_new = expr_simp(e_input)
     print "original: ", str(e_input), "new: ", str(e_new)
     rez = e_new == e_check
     if not rez:
         raise ValueError(
-            'bug in expr_simp_explicit simp(%s) is %s and should be %s' % (e_input, e_new, e_check))
+            'bug in expr_simp simp(%s) is %s and should be %s' % (e_input, e_new, e_check))
 
 if args.z3:
     # This check is done on 32 bits, but the size is not use by Miasm formulas, so
diff --git a/test/ir/ir2C.py b/test/ir/ir2C.py
index 375dedb8..6df439c2 100755
--- a/test/ir/ir2C.py
+++ b/test/ir/ir2C.py
@@ -2,7 +2,7 @@
 #-*- coding:utf-8 -*-
 
 import unittest
-
+from miasm2.expression.expression import TOK_EQUAL
 
 class TestIrIr2C(unittest.TestCase):
 
@@ -32,7 +32,7 @@ class TestIrIr2C(unittest.TestCase):
 
         # Binary operators
         self.translationTest(
-            ExprOp('==',      *args[:2]), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)')
+            ExprOp(TOK_EQUAL,      *args[:2]), r'(((0x0&0xffffffff) == (0x1&0xffffffff))?1:0)')
         self.translationTest(
             ExprOp('%',       *args[:2]), r'(((0x0&0xffffffff)%(0x1&0xffffffff))&0xffffffff)')
         self.translationTest(