aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2020-05-23 19:37:58 -0700
committeriximeow <me@iximeow.net>2020-05-23 19:37:58 -0700
commit9b965525afced37e99543e3a412218207a41e793 (patch)
treed82cb429eb2b7f230249769f935bc24d60a6158f /test
parenta0fd5a24cb0aa0b697f680c451d928cefe8323b4 (diff)
add SHA, BMI1, and BMI2, complete XSAVE extension support
additionally: cmpcxchg{8,16}b, rdrand, rdseed, rdpid, {rd,wr}{fs,gs}base
Diffstat (limited to 'test')
-rw-r--r--test/long_mode/mod.rs122
-rw-r--r--test/long_mode/operand.rs3
-rw-r--r--test/protected_mode/mod.rs92
-rw-r--r--test/protected_mode/operand.rs3
4 files changed, 187 insertions, 33 deletions
diff --git a/test/long_mode/mod.rs b/test/long_mode/mod.rs
index b37581e..f6f02a1 100644
--- a/test/long_mode/mod.rs
+++ b/test/long_mode/mod.rs
@@ -62,6 +62,7 @@ fn test_mmx() {
test_display(&[0x4f, 0x0f, 0xd1, 0x00], "psrlw mm0, [r8]");
test_invalid(&[0x4f, 0x0f, 0xd7, 0x00]);
test_display(&[0x4f, 0x0f, 0xd7, 0xcf], "pmovmskb r9d, mm7");
+ test_display(&[0x0f, 0x3a, 0x0f, 0xc1, 0x23], "palignr mm0, mm1, 0x23");
}
#[test]
@@ -510,14 +511,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 rax");
+ test_display(&[0x0f, 0x01, 0xd9], "vmmcall");
+ test_display(&[0x0f, 0x01, 0xda], "vmload rax");
+ test_display(&[0x0f, 0x01, 0xdb], "vmsave rax");
+ 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 rax, ecx");
test_display(&[0x0f, 0x01, 0xee], "rdpkru");
test_display(&[0x0f, 0x01, 0xef], "wrpkru");
test_display(&[0x0f, 0x01, 0xf8], "swapgs");
@@ -771,8 +772,59 @@ fn test_bmi1() {
test_display_under(&bmi1, &[0x41, 0x0f, 0xbc, 0xd3], "tzcnt edx, r11d");
test_display_under(&no_bmi1, &[0x41, 0x0f, 0xbc, 0xd3], "bsf edx, r11d");
- test_display_under(&bmi1, &[0xf3, 0x0f, 0xb8, 0xc1], "popcnt eax, ecx");
- test_display_under(&bmi1, &[0xf3, 0x4f, 0x0f, 0xb8, 0xc1], "popcnt r8, r9");
+ // just 0f38
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0x60, 0xf2, 0x01], "andn eax, ebx, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0xe0, 0xf2, 0x01], "andn rax, rbx, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0x78, 0xf3, 0x09], "blsr eax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0xf8, 0xf3, 0x09], "blsr rax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0x78, 0xf3, 0x11], "blsmsk eax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0xf8, 0xf3, 0x11], "blsmsk rax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0x78, 0xf3, 0x19], "blsi eax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0xf8, 0xf3, 0x19], "blsi rax, [r9]");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0x60, 0xf7, 0x01], "bextr eax, [r9], ebx");
+ test_display_under(&bmi1, &[0xc4, 0xc2, 0xe0, 0xf7, 0x01], "bextr rax, [r9], rbx");
+}
+
+#[test]
+fn test_bmi2() {
+ let bmi2 = InstDecoder::minimal().with_bmi2();
+ // f2 0f3a
+ test_display_under(&bmi2, &[0xc4, 0xc3, 0x7b, 0xf0, 0x01, 0x05], "rorx eax, [r9], 0x5");
+ test_display_under(&bmi2, &[0xc4, 0xc3, 0xfb, 0xf0, 0x01, 0x05], "rorx rax, [r9], 0x5");
+
+ // f2 0f38 map
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0x63, 0xf5, 0x07], "pdep eax, ebx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0xe3, 0xf5, 0x07], "pdep rax, rbx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0x63, 0xf6, 0x07], "mulx eax, ebx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0xe3, 0xf6, 0x07], "mulx rax, rbx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0x63, 0xf7, 0x01], "shrx eax, [r9], ebx");
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0xe3, 0xf7, 0x01], "shrx rax, [r9], rbx");
+
+ // f3 0f38 map
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0x62, 0xf5, 0x07], "pext eax, ebx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0xe2, 0xf5, 0x07], "pext rax, rbx, [rdi]");
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0x62, 0xf7, 0x01], "sarx eax, [r9], ebx");
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0xe2, 0xf7, 0x01], "sarx rax, [r9], rbx");
+
+ // just 0f38
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0x60, 0xf5, 0x07], "bzhi eax, [rdi], ebx");
+ test_display_under(&bmi2, &[0xc4, 0xe2, 0xe0, 0xf5, 0x07], "bzhi rax, [rdi], rbx");
+
+ // 66 0f38
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0x61, 0xf7, 0x01], "shlx eax, [r9], ebx");
+ test_display_under(&bmi2, &[0xc4, 0xc2, 0xe1, 0xf7, 0x01], "shlx rax, [r9], rbx");
+}
+
+#[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_display_under(&popcnt, &[0xf3, 0x4f, 0x0f, 0xb8, 0xc1], "popcnt r8, r9");
+ test_display_under(&intel_popcnt, &[0xf3, 0x4f, 0x0f, 0xb8, 0xc1], "popcnt r8, r9");
+ test_invalid_under(&no_popcnt, &[0xf3, 0x4f, 0x0f, 0xb8, 0xc1]);
}
#[test]
@@ -821,12 +873,18 @@ fn test_misc() {
test_display(&[0xf3, 0x48, 0xa5], "rep movs es:[rdi], ds:[rsi]");
test_display(&[0xf3, 0x45, 0x0f, 0xbc, 0xd7], "tzcnt r10d, r15d");
- // this is actually vmx
- // test_invalid(&[0x66, 0x0f, 0xc7, 0x03]);
- test_display(&[0x66, 0x4f, 0x0f, 0xc7, 0x33], "vmclear [r11]");
- test_display(&[0x66, 0x0f, 0xc7, 0x33], "vmclear [rbx]");
- test_display(&[0xf3, 0x4f, 0x0f, 0xc7, 0x33], "vmxon [r11]");
- test_display(&[0xf3, 0x0f, 0xc7, 0x33], "vmxon [rbx]");
+ test_display(&[0xf3, 0x0f, 0xae, 0xc4], "rdfsbase esp");
+ test_display(&[0xf3, 0x4f, 0x0f, 0xae, 0xc4], "rdfsbase r12");
+ test_display(&[0xf3, 0x0f, 0xae, 0xcc], "rdgsbase esp");
+ test_display(&[0xf3, 0x4f, 0x0f, 0xae, 0xcc], "rdgsbase r12");
+ test_display(&[0xf3, 0x0f, 0xae, 0xd4], "wrfsbase esp");
+ test_display(&[0xf3, 0x4f, 0x0f, 0xae, 0xd4], "wrfsbase r12");
+ test_display(&[0xf3, 0x0f, 0xae, 0xdc], "wrgsbase esp");
+ test_display(&[0xf3, 0x4f, 0x0f, 0xae, 0xdc], "wrgsbase r12");
+ test_display(&[0x66, 0x0f, 0xae, 0x3f], "clflushopt [rdi]"); // or clflush without 66
+ test_invalid(&[0x66, 0x0f, 0xae, 0xff]);
+ test_display(&[0x66, 0x0f, 0xae, 0x37], "clwb [rdi]");
+ test_invalid(&[0x66, 0x0f, 0xae, 0xf7]);
}
#[test]
@@ -1139,8 +1197,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");
}
@@ -1165,3 +1223,31 @@ fn test_sha() {
test_display(&[0x0f, 0x38, 0xcc, 0x12], "sha256msg1 xmm2, [rdx]");
test_display(&[0x0f, 0x38, 0xcd, 0x12], "sha256msg2 xmm2, [rdx]");
}
+
+#[test]
+fn test_vmx() {
+ test_display(&[0x0f, 0xc7, 0x3f], "vmptrst [rdi]");
+ test_display(&[0x0f, 0xc7, 0x37], "vmptrld [rdi]");
+ test_display(&[0xf3, 0x0f, 0xc7, 0xf7], "rdrand edi");
+ test_display(&[0xf3, 0x0f, 0xc7, 0x37], "vmxon [rdi]");
+ test_display(&[0x66, 0x0f, 0xc7, 0xf7], "rdrand di");
+ test_display(&[0x66, 0x0f, 0xc7, 0x37], "vmclear [rdi]");
+
+ // this is actually vmx
+ // test_invalid(&[0x66, 0x0f, 0xc7, 0x03]);
+ test_display(&[0x66, 0x4f, 0x0f, 0xc7, 0x33], "vmclear [r11]");
+ test_display(&[0x66, 0x0f, 0xc7, 0x33], "vmclear [rbx]");
+ test_display(&[0xf3, 0x4f, 0x0f, 0xc7, 0x33], "vmxon [r11]");
+ test_display(&[0xf3, 0x0f, 0xc7, 0x33], "vmxon [rbx]");
+}
+
+#[test]
+fn test_rdpid() {
+ test_display(&[0xf3, 0x0f, 0xc7, 0xfd], "rdpid ebp");
+}
+
+#[test]
+fn test_cmpxchg8b() {
+ test_display(&[0x0f, 0xc7, 0x0f], "cmpxchg8b [rdi]");
+ test_display(&[0x4f, 0x0f, 0xc7, 0x0f], "cmpxchg16b [r15]");
+}
diff --git a/test/long_mode/operand.rs b/test/long_mode/operand.rs
index 1250b8a..f0300d6 100644
--- a/test/long_mode/operand.rs
+++ b/test/long_mode/operand.rs
@@ -1,5 +1,4 @@
-use yaxpeax_arch::{Decoder, LengthedInstruction};
-use yaxpeax_x86::long_mode::{DecodeError, InstDecoder, Opcode, Operand, RegSpec};
+use yaxpeax_x86::long_mode::{Operand, RegSpec};
#[test]
fn register_widths() {
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() {