about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--miasm2/arch/x86/arch.py7
-rw-r--r--miasm2/arch/x86/sem.py44
-rw-r--r--miasm2/expression/expression.py182
-rw-r--r--test/arch/x86/arch.py15
-rw-r--r--test/expression/expr_cmp.py107
-rwxr-xr-xtest/test_all.py1
6 files changed, 351 insertions, 5 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py
index 73c9fc0d..6725f5bc 100644
--- a/miasm2/arch/x86/arch.py
+++ b/miasm2/arch/x86/arch.py
@@ -4254,6 +4254,8 @@ addop("pcmpgtd", [bs8(0x0f), bs8(0x66), no_xmm_pref] +
 addop("pcmpgtd", [bs8(0x0f), bs8(0x66), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm))
 
+addop("pcmpeqq", [bs8(0x0f), bs8(0x38), bs8(0x29), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
+addop("pcmpgtq", [bs8(0x0f), bs8(0x38), bs8(0x37), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
 
 addop("punpckhbw", [bs8(0x0f), bs8(0x68), no_xmm_pref] +
       rmmod(mm_reg, rm_arg_mm))
@@ -4355,6 +4357,11 @@ addop("shufps", [bs8(0x0f), bs8(0xc6), no_xmm_pref] +
 addop("shufpd", [bs8(0x0f), bs8(0xc6), pref_66] +
       rmmod(xmm_reg, rm_arg_xmm) + [u08])
 
+addop("aesenc", [bs8(0x0f), bs8(0x38), bs8(0xdc), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
+addop("aesdec", [bs8(0x0f), bs8(0x38), bs8(0xde), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
+
+addop("aesenclast", [bs8(0x0f), bs8(0x38), bs8(0xdd), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
+addop("aesdeclast", [bs8(0x0f), bs8(0x38), bs8(0xdf), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
 
 mn_x86.bintree = factor_one_bit(mn_x86.bintree)
 # mn_x86.bintree = factor_fields_all(mn_x86.bintree)
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py
index 1fceab30..5d564fb1 100644
--- a/miasm2/arch/x86/sem.py
+++ b/miasm2/arch/x86/sem.py
@@ -3819,25 +3819,53 @@ def pminud(ir, instr, dst, src):
 def pcmpeq(_, instr, dst, src, size):
     e = []
     for i in xrange(0, dst.size, size):
-        test = dst[i:i + size] - src[i:i + size]
+        test = m2_expr.expr_is_equal(dst[i:i + size], src[i:i + size])
         e.append(m2_expr.ExprAff(dst[i:i + size],
                                  m2_expr.ExprCond(test,
-                                                  m2_expr.ExprInt(0, size),
-                                                  m2_expr.ExprInt(-1, size))))
+                                                  m2_expr.ExprInt(-1, size),
+                                                  m2_expr.ExprInt(0, size))))
+    return e, []
+
+
+def pcmpgt(_, instr, dst, src, size):
+    e = []
+    for i in xrange(0, dst.size, size):
+        test = m2_expr.expr_is_signed_greater(dst[i:i + size], src[i:i + size])
+        e.append(m2_expr.ExprAff(dst[i:i + size],
+                                 m2_expr.ExprCond(test,
+                                                  m2_expr.ExprInt(-1, size),
+                                                  m2_expr.ExprInt(0, size))))
     return e, []
 
 
 def pcmpeqb(ir, instr, dst, src):
     return pcmpeq(ir, instr, dst, src, 8)
 
-
 def pcmpeqw(ir, instr, dst, src):
     return pcmpeq(ir, instr, dst, src, 16)
 
-
 def pcmpeqd(ir, instr, dst, src):
     return pcmpeq(ir, instr, dst, src, 32)
 
+def pcmpeqq(ir, instr, dst, src):
+    return pcmpeq(ir, instr, dst, src, 64)
+
+
+
+
+def pcmpgtb(ir, instr, dst, src):
+    return pcmpgt(ir, instr, dst, src, 8)
+
+def pcmpgtw(ir, instr, dst, src):
+    return pcmpgt(ir, instr, dst, src, 16)
+
+def pcmpgtd(ir, instr, dst, src):
+    return pcmpgt(ir, instr, dst, src, 32)
+
+def pcmpgtq(ir, instr, dst, src):
+    return pcmpgt(ir, instr, dst, src, 64)
+
+
 
 def punpck(_, instr, dst, src, size, off):
     e = []
@@ -4504,6 +4532,12 @@ mnemo_func = {'mov': mov,
               "pcmpeqb": pcmpeqb,
               "pcmpeqw": pcmpeqw,
               "pcmpeqd": pcmpeqd,
+              "pcmpeqq": pcmpeqq,
+
+              "pcmpgtb": pcmpgtb,
+              "pcmpgtw": pcmpgtw,
+              "pcmpgtd": pcmpgtd,
+              "pcmpgtq": pcmpgtq,
 
               "punpckhbw": punpckhbw,
               "punpckhwd": punpckhwd,
diff --git a/miasm2/expression/expression.py b/miasm2/expression/expression.py
index b7b90470..591dc024 100644
--- a/miasm2/expression/expression.py
+++ b/miasm2/expression/expression.py
@@ -1538,3 +1538,185 @@ def get_expr_mem(expr):
     ops = set()
     expr.visit(lambda x: visit_getmem(x, ops))
     return ops
+
+
+def _expr_compute_cf(op1, op2):
+    """
+    Get carry flag of @op1 - @op2
+    Ref: x86 cf flag
+    @op1: Expression
+    @op2: Expression
+    """
+    res = op1 - op2
+    cf = (((op1 ^ op2) ^ res) ^ ((op1 ^ res) & (op1 ^ op2))).msb()
+    return cf
+
+def _expr_compute_of(op1, op2):
+    """
+    Get overflow flag of @op1 - @op2
+    Ref: x86 of flag
+    @op1: Expression
+    @op2: Expression
+    """
+    res = op1 - op2
+    of = (((op1 ^ res) & (op1 ^ op2))).msb()
+    return of
+
+def _expr_compute_zf(op1, op2):
+    """
+    Get zero flag of @op1 - @op2
+    @op1: Expression
+    @op2: Expression
+    """
+    res = op1 - op2
+    zf = ExprCond(res,
+                  ExprInt(0, 1),
+                  ExprInt(1, 1))
+    return zf
+
+
+def _expr_compute_nf(op1, op2):
+    """
+    Get negative (or sign) flag of @op1 - @op2
+    @op1: Expression
+    @op2: Expression
+    """
+    res = op1 - op2
+    nf = res.msb()
+    return nf
+
+
+def expr_is_equal(op1, op2):
+    """
+    if op1 == op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    zf = _expr_compute_zf(op1, op2)
+    return zf
+
+
+def expr_is_not_equal(op1, op2):
+    """
+    if op1 != op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    zf = _expr_compute_zf(op1, op2)
+    return ~zf
+
+
+def expr_is_unsigned_greater(op1, op2):
+    """
+    UNSIGNED cmp
+    if op1 > op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    cf = _expr_compute_cf(op1, op2)
+    zf = _expr_compute_zf(op1, op2)
+    return ~(cf | zf)
+
+
+def expr_is_unsigned_greater_or_equal(op1, op2):
+    """
+    Unsigned cmp
+    if op1 >= op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    cf = _expr_compute_cf(op1, op2)
+    return ~cf
+
+
+def expr_is_unsigned_lower(op1, op2):
+    """
+    Unsigned cmp
+    if op1 < op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    cf = _expr_compute_cf(op1, op2)
+    return cf
+
+
+def expr_is_unsigned_lower_or_equal(op1, op2):
+    """
+    Unsigned cmp
+    if op1 <= op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    cf = _expr_compute_cf(op1, op2)
+    zf = _expr_compute_zf(op1, op2)
+    return cf | zf
+
+
+def expr_is_signed_greater(op1, op2):
+    """
+    Signed cmp
+    if op1 > op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    nf = _expr_compute_nf(op1, op2)
+    of = _expr_compute_of(op1, op2)
+    zf = _expr_compute_zf(op1, op2)
+    return ~(zf | (nf ^ of))
+
+
+def expr_is_signed_greater_or_equal(op1, op2):
+    """
+    Signed cmp
+    if op1 > op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    nf = _expr_compute_nf(op1, op2)
+    of = _expr_compute_of(op1, op2)
+    return ~(nf ^ of)
+
+
+def expr_is_signed_lower(op1, op2):
+    """
+    Signed cmp
+    if op1 < op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    nf = _expr_compute_nf(op1, op2)
+    of = _expr_compute_of(op1, op2)
+    return nf ^ of
+
+
+def expr_is_signed_lower_or_equal(op1, op2):
+    """
+    Signed cmp
+    if op1 <= op2:
+       Return ExprInt(1, 1)
+    else:
+       Return ExprInt(0, 1)
+    """
+
+    nf = _expr_compute_nf(op1, op2)
+    of = _expr_compute_of(op1, op2)
+    zf = _expr_compute_zf(op1, op2)
+    return zf | (nf ^ of)
diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py
index 0472e714..76e5a5eb 100644
--- a/test/arch/x86/arch.py
+++ b/test/arch/x86/arch.py
@@ -2793,6 +2793,12 @@ reg_tests = [
     (m64, "00000000    PCMPGTD    XMM3, XMM0",
      "660f66d8"),
 
+    (m32, "00000000    PCMPEQQ    XMM0, XMM5",
+    "660f3829C5"),
+    (m32, "00000000    PCMPGTQ    XMM0, XMM5",
+    "660f3837C5"),
+
+
     (m32, "00000000    PUNPCKHBW  MM2, QWORD PTR [EDX]",
     "0F6812"),
     (m32, "00000000    PUNPCKHBW  XMM2, XMMWORD PTR [EDX]",
@@ -2939,6 +2945,15 @@ reg_tests = [
     (m64, "00000000    SHUFPD     XMM0, XMM6, 0x44",
      "660fc6c644"),
 
+    (m32, "00000000    AESENC     XMM1, XMM2",
+     "660f38dcca"),
+    (m32, "00000000    AESDEC     XMM1, XMM2",
+     "660f38deca"),
+
+    (m32, "00000000    AESENCLAST XMM1, XMM2",
+     "660f38ddca"),
+    (m32, "00000000    AESDECLAST XMM1, XMM2",
+     "660f38dfca"),
 
 ]
 
diff --git a/test/expression/expr_cmp.py b/test/expression/expr_cmp.py
new file mode 100644
index 00000000..b238151d
--- /dev/null
+++ b/test/expression/expr_cmp.py
@@ -0,0 +1,107 @@
+#
+# Expression comparison regression tests  #
+#
+from pdb import pm
+from miasm2.expression.expression import ExprInt, expr_is_unsigned_greater,\
+    expr_is_unsigned_greater_or_equal, expr_is_unsigned_lower,\
+    expr_is_unsigned_lower_or_equal, expr_is_signed_greater,\
+    expr_is_signed_greater_or_equal, expr_is_signed_lower, \
+    expr_is_signed_lower_or_equal, expr_is_equal, expr_is_not_equal
+from miasm2.expression.simplifications import expr_simp
+
+int_0 = ExprInt(0, 32)
+int_1 = ExprInt(1, 32)
+int_m1 = ExprInt(-1, 32)
+int_m2 = ExprInt(-2, 32)
+
+b0 = ExprInt(0, 1)
+b1 = ExprInt(1, 1)
+
+tests = [
+    # unsigned
+    (b1, expr_is_unsigned_greater, int_1, int_0),
+    (b1, expr_is_unsigned_lower, int_0, int_1),
+
+    (b0, expr_is_unsigned_greater, int_0, int_1),
+    (b0, expr_is_unsigned_lower, int_1, int_0),
+
+    (b1, expr_is_unsigned_greater_or_equal, int_1, int_0),
+    (b1, expr_is_unsigned_lower_or_equal, int_0, int_1),
+
+    (b0, expr_is_unsigned_greater_or_equal, int_0, int_1),
+    (b0, expr_is_unsigned_lower_or_equal, int_1, int_0),
+
+    (b1, expr_is_unsigned_greater_or_equal, int_1, int_1),
+    (b1, expr_is_unsigned_lower_or_equal, int_1, int_1),
+
+    (b1, expr_is_unsigned_greater, int_m1, int_0),
+    (b1, expr_is_unsigned_lower, int_0, int_m1),
+
+    (b0, expr_is_unsigned_greater, int_0, int_m1),
+    (b0, expr_is_unsigned_lower, int_m1, int_0),
+
+
+    # signed
+    (b1, expr_is_signed_greater, int_1, int_0),
+    (b1, expr_is_signed_lower, int_0, int_1),
+
+    (b0, expr_is_signed_greater, int_0, int_1),
+    (b0, expr_is_signed_lower, int_1, int_0),
+
+    (b1, expr_is_signed_greater_or_equal, int_1, int_0),
+    (b1, expr_is_signed_lower_or_equal, int_0, int_1),
+
+    (b0, expr_is_signed_greater_or_equal, int_0, int_1),
+    (b0, expr_is_signed_lower_or_equal, int_1, int_0),
+
+    (b1, expr_is_signed_greater_or_equal, int_1, int_1),
+    (b1, expr_is_signed_lower_or_equal, int_1, int_1),
+
+    (b0, expr_is_signed_greater, int_m1, int_0),
+    (b0, expr_is_signed_lower, int_0, int_m1),
+
+    (b1, expr_is_signed_greater, int_0, int_m1),
+    (b1, expr_is_signed_lower, int_m1, int_0),
+
+
+    # greater lesser, neg
+    (b1, expr_is_signed_greater, int_1, int_m1),
+    (b1, expr_is_signed_lower, int_m1, int_1),
+
+    (b0, expr_is_signed_greater, int_m1, int_1),
+    (b0, expr_is_signed_lower, int_1, int_m1),
+
+    (b1, expr_is_signed_greater_or_equal, int_1, int_m1),
+    (b1, expr_is_signed_lower_or_equal, int_m1, int_1),
+
+    (b0, expr_is_signed_greater_or_equal, int_m1, int_1),
+    (b0, expr_is_signed_lower_or_equal, int_1, int_m1),
+
+    (b1, expr_is_signed_greater_or_equal, int_m1, int_m1),
+    (b1, expr_is_signed_lower_or_equal, int_m1, int_m1),
+
+
+    (b1, expr_is_signed_greater, int_m1, int_m2),
+    (b1, expr_is_signed_lower, int_m2, int_m1),
+
+    (b0, expr_is_signed_greater, int_m2, int_m1),
+    (b0, expr_is_signed_lower, int_m1, int_m2),
+
+    (b1, expr_is_signed_greater_or_equal, int_m1, int_m2),
+    (b1, expr_is_signed_lower_or_equal, int_m2, int_m1),
+
+    (b0, expr_is_signed_greater_or_equal, int_m2, int_m1),
+    (b0, expr_is_signed_lower_or_equal, int_m1, int_m2),
+
+    # eq/neq
+    (b1, expr_is_equal, int_1, int_1),
+    (b1, expr_is_not_equal, int_0, int_1),
+
+    (b0, expr_is_equal, int_1, int_0),
+    (b0, expr_is_not_equal, int_0, int_0),
+
+
+]
+
+for result, func, arg1, arg2 in tests:
+    assert result == expr_simp(func(arg1, arg2))
diff --git a/test/test_all.py b/test/test_all.py
index 99b0094e..30408ee2 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -245,6 +245,7 @@ for script in ["modint.py",
                "expression_helper.py",
                "expr_pickle.py",
                "parser.py",
+               "expr_cmp.py",
                ]:
     testset += RegressionTest([script], base_dir="expression")