From 9b965525afced37e99543e3a412218207a41e793 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 23 May 2020 19:37:58 -0700 Subject: add SHA, BMI1, and BMI2, complete XSAVE extension support additionally: cmpcxchg{8,16}b, rdrand, rdseed, rdpid, {rd,wr}{fs,gs}base --- test/protected_mode/mod.rs | 92 +++++++++++++++++++++++++++++++++++++----- test/protected_mode/operand.rs | 3 +- 2 files changed, 82 insertions(+), 13 deletions(-) (limited to 'test/protected_mode') diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs index 9fc603d..fc1db2d 100644 --- a/test/protected_mode/mod.rs +++ b/test/protected_mode/mod.rs @@ -482,14 +482,14 @@ fn test_0f01() { test_display(&[0x0f, 0x01, 0xd5], "xend"); test_display(&[0x0f, 0x01, 0xd6], "xtest"); test_display(&[0x0f, 0x01, 0xd7], "enclu"); - test_invalid(&[0x0f, 0x01, 0xd8]); - test_invalid(&[0x0f, 0x01, 0xd9]); - test_invalid(&[0x0f, 0x01, 0xda]); - test_invalid(&[0x0f, 0x01, 0xdb]); - test_invalid(&[0x0f, 0x01, 0xdc]); - test_invalid(&[0x0f, 0x01, 0xdd]); - test_invalid(&[0x0f, 0x01, 0xde]); - test_invalid(&[0x0f, 0x01, 0xdf]); + test_display(&[0x0f, 0x01, 0xd8], "vmrun eax"); + test_display(&[0x0f, 0x01, 0xd9], "vmmcall"); + test_display(&[0x0f, 0x01, 0xda], "vmload eax"); + test_display(&[0x0f, 0x01, 0xdb], "vmsave eax"); + test_display(&[0x0f, 0x01, 0xdc], "stgi"); + test_display(&[0x0f, 0x01, 0xdd], "clgi"); + test_display(&[0x0f, 0x01, 0xde], "skinit eax"); + test_display(&[0x0f, 0x01, 0xdf], "invlpga eax, ecx"); test_display(&[0x0f, 0x01, 0xee], "rdpkru"); test_display(&[0x0f, 0x01, 0xef], "wrpkru"); test_display(&[0x0f, 0x01, 0xf8], "swapgs"); @@ -716,7 +716,68 @@ fn test_bmi1() { test_display_under(&bmi1, &[0x0f, 0xbc, 0xd3], "tzcnt edx, ebx"); test_display_under(&no_bmi1, &[0x0f, 0xbc, 0xd3], "bsf edx, ebx"); - test_display_under(&bmi1, &[0xf3, 0x0f, 0xb8, 0xc1], "popcnt eax, ecx"); + // from the intel manual [`ANDN`, though this is true for `BMI1` generally]: + // ``` + // VEX.W1 is ignored in non-64-bit modes. + // ``` + + // just 0f38 + test_display_under(&bmi1, &[0xc4, 0xe2, 0x60, 0xf2, 0x01], "andn eax, ebx, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0xe0, 0xf2, 0x01], "andn eax, ebx, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0x78, 0xf3, 0x09], "blsr eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0xf8, 0xf3, 0x09], "blsr eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0x78, 0xf3, 0x11], "blsmsk eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0xf8, 0xf3, 0x11], "blsmsk eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0x78, 0xf3, 0x19], "blsi eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0xf8, 0xf3, 0x19], "blsi eax, [ecx]"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0x60, 0xf7, 0x01], "bextr eax, [ecx], ebx"); + test_display_under(&bmi1, &[0xc4, 0xe2, 0xe0, 0xf7, 0x01], "bextr eax, [ecx], ebx"); +} + +#[test] +fn test_bmi2() { + let bmi2 = InstDecoder::minimal().with_bmi2(); + + // from the intel manual [`PDEP`, though this is true for `BMI2` generally]: + // ``` + // VEX.W1 is ignored in non-64-bit modes. + // ``` + + // f2 0f3a + test_display_under(&bmi2, &[0xc4, 0xe3, 0x7b, 0xf0, 0x01, 0x05], "rorx eax, [ecx], 0x5"); + test_display_under(&bmi2, &[0xc4, 0xe3, 0xfb, 0xf0, 0x01, 0x05], "rorx eax, [ecx], 0x5"); + + // f2 0f38 map + test_display_under(&bmi2, &[0xc4, 0xe2, 0x63, 0xf5, 0x07], "pdep eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe3, 0xf5, 0x07], "pdep eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0x63, 0xf6, 0x07], "mulx eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe3, 0xf6, 0x07], "mulx eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0x63, 0xf7, 0x01], "shrx eax, [ecx], ebx"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe3, 0xf7, 0x01], "shrx eax, [ecx], ebx"); + + // f3 0f38 map + test_display_under(&bmi2, &[0xc4, 0xe2, 0x62, 0xf5, 0x07], "pext eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe2, 0xf5, 0x07], "pext eax, ebx, [edi]"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0x62, 0xf7, 0x01], "sarx eax, [ecx], ebx"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe2, 0xf7, 0x01], "sarx eax, [ecx], ebx"); + + // just 0f38 + test_display_under(&bmi2, &[0xc4, 0xe2, 0x60, 0xf5, 0x07], "bzhi eax, [edi], ebx"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe0, 0xf5, 0x07], "bzhi eax, [edi], ebx"); + + // 66 0f38 + test_display_under(&bmi2, &[0xc4, 0xe2, 0x61, 0xf7, 0x01], "shlx eax, [ecx], ebx"); + test_display_under(&bmi2, &[0xc4, 0xe2, 0xe1, 0xf7, 0x01], "shlx eax, [ecx], ebx"); +} + +#[test] +fn test_popcnt() { + let popcnt = InstDecoder::minimal().with_popcnt(); + let intel_popcnt = InstDecoder::minimal().with_intel_quirks().with_sse4_2(); + let no_popcnt = InstDecoder::minimal(); + test_display_under(&popcnt, &[0xf3, 0x0f, 0xb8, 0xc1], "popcnt eax, ecx"); + test_display_under(&intel_popcnt, &[0xf3, 0x0f, 0xb8, 0xc1], "popcnt eax, ecx"); + test_invalid_under(&no_popcnt, &[0xf3, 0x0f, 0xb8, 0xc1]); } #[test] @@ -768,6 +829,15 @@ fn test_misc() { // test_invalid(&[0x66, 0x0f, 0xc7, 0x03]); test_display(&[0x66, 0x0f, 0xc7, 0x33], "vmclear [ebx]"); test_display(&[0xf3, 0x0f, 0xc7, 0x33], "vmxon [ebx]"); + + test_display(&[0xf3, 0x0f, 0xae, 0xc4], "rdfsbase esp"); + test_display(&[0xf3, 0x0f, 0xae, 0xcc], "rdgsbase esp"); + test_display(&[0xf3, 0x0f, 0xae, 0xd4], "wrfsbase esp"); + test_display(&[0xf3, 0x0f, 0xae, 0xdc], "wrgsbase esp"); + test_display(&[0x66, 0x0f, 0xae, 0x3f], "clflushopt [edi]"); // or clflush without 66 + test_invalid(&[0x66, 0x0f, 0xae, 0xff]); + test_display(&[0x66, 0x0f, 0xae, 0x37], "clwb [edi]"); + test_invalid(&[0x66, 0x0f, 0xae, 0xf7]); } #[test] @@ -1075,8 +1145,8 @@ fn test_movbe() { #[test] fn test_tsx() { test_display(&[0xc6, 0xf8, 0x10], "xabort 0x10"); - test_display(&[0xc7, 0xf8, 0x10, 0x12, 0x34, 0x56, 0x78], "xbegin 0x78563412"); - test_display(&[0x66, 0xc7, 0xf8, 0x10, 0x12, 0x34], "xbegin 0x3412"); + test_display(&[0xc7, 0xf8, 0x10, 0x12, 0x34, 0x56], "xbegin $+0x56341210"); + test_display(&[0x66, 0xc7, 0xf8, 0x10, 0x12], "xbegin $+0x1210"); test_display(&[0x0f, 0x01, 0xd5], "xend"); test_display(&[0x0f, 0x01, 0xd6], "xtest"); } diff --git a/test/protected_mode/operand.rs b/test/protected_mode/operand.rs index 8fda181..8ffd446 100644 --- a/test/protected_mode/operand.rs +++ b/test/protected_mode/operand.rs @@ -1,5 +1,4 @@ -use yaxpeax_arch::{Decoder, LengthedInstruction}; -use yaxpeax_x86::protected_mode::{DecodeError, InstDecoder, Opcode, Operand, RegSpec}; +use yaxpeax_x86::protected_mode::{Operand, RegSpec}; #[test] fn register_widths() { -- cgit v1.1