diff options
| author | Ajax <commial@gmail.com> | 2018-02-08 12:14:59 +0100 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2018-02-09 17:34:35 +0100 |
| commit | 0c35bb71b6b3f32b2a62618f4b67ef87df81958d (patch) | |
| tree | 1e1612f116e9f298a396890c302562fa88a29ebd | |
| parent | d404b1803c09b61463845fe14feee5324cbdc051 (diff) | |
| download | miasm-0c35bb71b6b3f32b2a62618f4b67ef87df81958d.tar.gz miasm-0c35bb71b6b3f32b2a62618f4b67ef87df81958d.zip | |
Add PACKSSWB instruction
0F 63 /r PACKSSWB mm1, mm2/m64 66 0F 63 /r PACKSSWB xmm1, xmm2/m128
| -rw-r--r-- | miasm2/arch/x86/arch.py | 5 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 50 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 4 |
3 files changed, 59 insertions, 0 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 13c06ae6..2196e5ef 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -4453,6 +4453,11 @@ addop("aesdec", [bs8(0x0f), bs8(0x38), bs8(0xde), pref_66] + rmmod(xmm_reg, rm_a 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)) +addop("packsswb", [bs8(0x0f), bs8(0x63), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_m64)) +addop("packsswb", [bs8(0x0f), bs8(0x63), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_m128)) + 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 deebba8c..635206b6 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -4173,6 +4173,54 @@ def palignr(ir, instr, dst, src, imm): return [m2_expr.ExprAff(dst, result)], [] +def _signed_saturation(expr, dst_size): + """Saturate the expr @expr for @dst_size bit + Signed saturation return MAX_INT / MIN_INT or value depending on the value + """ + assert expr.size > dst_size + + median = 1 << (dst_size - 1) + min_int = m2_expr.ExprInt(- median, dst_size) + max_int = m2_expr.ExprInt(median - 1, dst_size) + signed = expr.msb() + value_unsigned = expr ^ expr.mask + m2_expr.ExprInt(1, expr.size) + # Re-use the sign bit + value = m2_expr.ExprCompose(expr[:dst_size - 1], signed) + + # Bit hack: to avoid a double signed comparison, use mask + # ie., in unsigned, 0xXY > 0x0f iff X is not null + + # if expr >s 0 + # if expr[dst_size:] > 0: # bigger than max_int + # -> max_int + # else + # -> value + # else # negative + # if expr[dst_size:-1] > 0: # smaller than min_int + # -> value + # else + # -> min_int + + return m2_expr.ExprCond( + signed, + m2_expr.ExprCond(value_unsigned[dst_size:], + min_int, + value), + m2_expr.ExprCond(expr[dst_size:], + max_int, + value), + ) + + +def packsswb(ir, instr, dst, src): + out = [] + for source in [dst, src]: + for start in xrange(0, dst.size, 16): + out.append(_signed_saturation(source[start:start + 16], 8)) + return [m2_expr.ExprAff(dst, m2_expr.ExprCompose(*out))], [] + + + mnemo_func = {'mov': mov, 'xchg': xchg, 'movzx': movzx, @@ -4670,6 +4718,8 @@ mnemo_func = {'mov': mov, "pmovmskb": pmovmskb, + "packsswb": packsswb, + "smsw": smsw, } diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index d3b2964c..b9bfec74 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -2970,6 +2970,10 @@ reg_tests = [ (m64, "00000000 BNDMOV BND3, XMMWORD PTR [RSP + 0xB0]", "660f1a9c24b0000000"), + (m32, "00000000 PACKSSWB MM7, MM0", + "0f63f8"), + (m32, "00000000 PACKSSWB XMM0, XMM5", + "660f63c5"), ] |