diff options
| author | Ajax <commial@gmail.com> | 2018-02-09 14:51:30 +0100 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2018-02-09 17:36:31 +0100 |
| commit | 971b683a5f068068a2d775d5807deacd13918cf9 (patch) | |
| tree | 88f1d24475dbcbd6f4d06d07910b156e6e98a9e6 | |
| parent | 8d6b88e240f860b5d41244b5d1f16ea88a2d1cb0 (diff) | |
| download | miasm-971b683a5f068068a2d775d5807deacd13918cf9.tar.gz miasm-971b683a5f068068a2d775d5807deacd13918cf9.zip | |
Add MASKMOVQ/MASKMOVDQU instruction
| -rw-r--r-- | miasm2/arch/x86/arch.py | 6 | ||||
| -rw-r--r-- | miasm2/arch/x86/sem.py | 49 | ||||
| -rw-r--r-- | test/arch/x86/arch.py | 5 |
3 files changed, 59 insertions, 1 deletions
diff --git a/miasm2/arch/x86/arch.py b/miasm2/arch/x86/arch.py index 4707fde3..40cd4e9c 100644 --- a/miasm2/arch/x86/arch.py +++ b/miasm2/arch/x86/arch.py @@ -4548,6 +4548,12 @@ addop("pavgw", [bs8(0x0f), bs8(0xe3), no_xmm_pref] + addop("pavgw", [bs8(0x0f), bs8(0xe3), pref_66] + rmmod(xmm_reg, rm_arg_xmm_m128)) +addop("maskmovq", [bs8(0x0f), bs8(0xf7), no_xmm_pref] + + rmmod(mm_reg, rm_arg_mm_reg)) +addop("maskmovdqu", [bs8(0x0f), bs8(0xf7), pref_66] + + rmmod(xmm_reg, rm_arg_xmm_reg)) + + 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 5a0f1b6b..becee84e 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -4401,6 +4401,52 @@ paddsb = vec_vertical_instr('+', 8, _saturation_add_signed) paddsw = vec_vertical_instr('+', 16, _saturation_add_signed) +# Others SSE operations + +def maskmovq(ir, instr, src, mask): + lbl_next = m2_expr.ExprId(ir.get_next_label(instr), ir.IRDst.size) + blks = [] + + # For each possibility, check if a write is necessary + check_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + for _ in xrange(0, mask.size, 8)] + # If the write has to be done, do it (otherwise, nothing happen) + write_labels = [m2_expr.ExprId(ir.gen_label(), ir.IRDst.size) + for _ in xrange(0, mask.size, 8)] + + # Build check blocks + for i, start in enumerate(xrange(0, mask.size, 8)): + bit = mask[start + 7: start + 8] + cur_label = check_labels[i] + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + write_label = write_labels[i] + check = m2_expr.ExprAff(ir.IRDst, + m2_expr.ExprCond(bit, + write_label, + next_check_label)) + blks.append(IRBlock(cur_label.name, [AssignBlock([check], instr)])) + + # Build write blocks + dst_addr = mRDI[instr.mode] + for i, start in enumerate(xrange(0, mask.size, 8)): + bit = mask[start + 7: start + 8] + cur_label = write_labels[i] + next_check_label = check_labels[i + 1] if (i + 1) < len(check_labels) else lbl_next + write_addr = dst_addr + m2_expr.ExprInt(i, dst_addr.size) + + # @8[DI/EDI/RDI + i] = src[byte i] + write_mem = m2_expr.ExprAff(m2_expr.ExprMem(write_addr, 8), + src[start: start + 8]) + jump = m2_expr.ExprAff(ir.IRDst, next_check_label) + blks.append(IRBlock(cur_label.name, [AssignBlock([write_mem, jump], instr)])) + + # If mask is null, bypass all + e = [m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(mask, + check_labels[0], + lbl_next))] + return e, blks + + mnemo_func = {'mov': mov, 'xchg': xchg, 'movzx': movzx, @@ -4936,7 +4982,8 @@ mnemo_func = {'mov': mov, "paddsw": paddsw, "smsw": smsw, - + "maskmovq": maskmovq, + "maskmovdqu": maskmovq, } diff --git a/test/arch/x86/arch.py b/test/arch/x86/arch.py index 68bc1304..f491c19a 100644 --- a/test/arch/x86/arch.py +++ b/test/arch/x86/arch.py @@ -3069,6 +3069,11 @@ reg_tests = [ "0fe3d9"), (m32, "00000000 PAVGW XMM0, XMM6", "660fe3c6"), + + (m32, "00000000 MASKMOVQ MM2, MM3", + "0ff7d3"), + (m32, "00000000 MASKMOVDQU XMM4, XMM5", + "660ff7e5"), ] |