diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 321c8ab5d..5bc3f887a 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4703,18 +4703,18 @@ void OpDispatchBuilder::MOVBEOp(OpcodeArgs) { const auto SrcSize = OpSizeFromSrc(Op); Ref Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.Align = OpSize::i8Bit}); - Src = _Rev(std::max(OpSize::i32Bit, SrcSize), Src); - if (SrcSize == OpSize::i16Bit) { + if (DestIsMem(Op) || SrcSize != OpSize::i16Bit) { + Src = _Rev(SrcSize, Src); + StoreResult(GPRClass, Op, Op->Dest, Src, OpSize::iInvalid); + } else { + Src = _Rev(std::max(OpSize::i32Bit, SrcSize), Src); // 16-bit does an insert. // Rev of 16-bit value as 32-bit replaces the result in the upper 16-bits of the result. // bfxil the 16-bit result in to the GPR. Ref Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GPRSize, Op->Flags); auto Result = _Bfxil(GPRSize, 16, 16, Dest, Src); StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, GPRSize, OpSize::iInvalid); - } else { - // 32-bit does regular zext - StoreResult(GPRClass, Op, Op->Dest, Src, OpSize::iInvalid); } } diff --git a/unittests/ASM/Disabled_Tests_Simulator b/unittests/ASM/Disabled_Tests_Simulator index 1b300a28b..ed185d0ba 100644 --- a/unittests/ASM/Disabled_Tests_Simulator +++ b/unittests/ASM/Disabled_Tests_Simulator @@ -107,3 +107,6 @@ Test_TwoByte/0F_31.asm # Simulator doesn't support executing a syscall Test_Secondary/09_F3_07.asm + +# Vixl sim at 256-bit vector width access too much memory with some AVX instructions +Test_modrm_oob/VEX.asm diff --git a/unittests/ASM/Disabled_Tests_host b/unittests/ASM/Disabled_Tests_host index 2db012db9..3373888fb 100644 --- a/unittests/ASM/Disabled_Tests_host +++ b/unittests/ASM/Disabled_Tests_host @@ -10,3 +10,6 @@ Test_Secondary/07_XX_00.asm # We don't emulate all of the MXCSR bits Test_VEX/vldmxcsr.asm + +# 3DNow! +Test_modrm_oob/DDD.asm diff --git a/unittests/ASM/Includes/modrm_oob_macros.mac b/unittests/ASM/Includes/modrm_oob_macros.mac new file mode 100644 index 000000000..f0fbc063b --- /dev/null +++ b/unittests/ASM/Includes/modrm_oob_macros.mac @@ -0,0 +1,114 @@ +%macro w2 2 +; Ensures that the load doesn't read past the end. +%1 [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 [r14] +%endmacro + +%macro r2 2 +; Ensures that the load doesn't read past the end. +%1 [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 [r14] +%endmacro + +%macro w3 3 +; Ensures that the load doesn't read past the end. +%1 [r15 - %2], %3 + +; Ensures the load doesn't read before the start. +%1 [r14], %3 +%endmacro + +%macro w3_size 3 +; Ensures that the load doesn't read past the end. +%1 %3 [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 %3 [r14] +%endmacro + +%macro r3 3 +; Ensures that the load doesn't read past the end. +%1 %3, [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 %3, [r14] +%endmacro + +%macro rw3 3 +r3 %1, %2, %3 +w3 %1, %2, %3 +%endmacro + +%macro w4 4 +; Ensures that the load doesn't read past the end. +%1 [r15 - %2], %3, %4 + +; Ensures the load doesn't read before the start. +%1 [r14], %3, %4 +%endmacro + +%macro w4_size 4 +; Ensures that the load doesn't read past the end. +%1 %3 [r15 - %2], %4 + +; Ensures the load doesn't read before the start. +%1 %3 [r14], %4 +%endmacro + +%macro r4 4 +; Ensures that the load doesn't read past the end. +%1 %3, [r15 - %2], %4 + +; Ensures the load doesn't read before the start. +%1 %3, [r14], %4 +%endmacro + +%macro r4_size 4 +; Ensures that the load doesn't read past the end. +%1 %4, %3 [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 %4, %3 [r14] +%endmacro + +%macro rw4 4 +r4 %1, %2, %3, %4 +w4 %1, %2, %3, %3 +%endmacro + +%macro r4_fma 4 +; Ensures that the load doesn't read past the end. +%1 %3, %4, [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 %3, %4, [r14] +%endmacro + +%macro r5_fma_sized 5 +; Ensures that the load doesn't read past the end. +%1 %4, %5, %3 [r15 - %2] + +; Ensures the load doesn't read before the start. +%1 %4, %5, %3 [r14] +%endmacro + +%macro w5_size 5 +; Ensures that the load doesn't read past the end. +%1 %3 [r15 - %2], %4, %5 + +; Ensures the load doesn't read before the start. +%1 %3 [r14], %4, %5 +%endmacro + +%macro r5_size 5 +; Ensures that the load doesn't read past the end. +%1 %4, %3 [r15 - %2], %5 + +; Ensures the load doesn't read before the start. +%1 %4, %3 [r14], %5 +%endmacro + diff --git a/unittests/ASM/modrm_oob/DDD.asm b/unittests/ASM/modrm_oob/DDD.asm new file mode 100644 index 000000000..7efb1144f --- /dev/null +++ b/unittests/ASM/modrm_oob/DDD.asm @@ -0,0 +1,50 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; DDD +r3 pi2fw, 8, mm0 +r3 pi2fd, 8, mm0 +r3 pf2iw, 8, mm0 +r3 pf2id, 8, mm0 +r3 pfrcpv, 8, mm0 +r3 pfrsqrtv, 8, mm0 +r3 pfnacc, 8, mm0 +r3 pfpnacc, 8, mm0 +r3 pfcmpge, 8, mm0 +r3 pfmin, 8, mm0 +r3 pfrcp, 8, mm0 +r3 pfrsqrt, 8, mm0 +r3 pfsub, 8, mm0 +r3 pfadd, 8, mm0 +r3 pfcmpgt, 8, mm0 +r3 pfmax, 8, mm0 +r3 pfrcpit1, 8, mm0 +r3 pfrsqit1, 8, mm0 +r3 pfsubr, 8, mm0 +r3 pfacc, 8, mm0 +r3 pfcmpeq, 8, mm0 +r3 pfmul, 8, mm0 +r3 pfrcpit2, 8, mm0 +; Nasm doesn't understand this instruction. +; r3 pmulhrw, 8, mm0 +r3 pswapd, 8, mm0 +r3 pavgusb, 8, mm0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/H0F38.asm b/unittests/ASM/modrm_oob/H0F38.asm new file mode 100644 index 000000000..a4523416b --- /dev/null +++ b/unittests/ASM/modrm_oob/H0F38.asm @@ -0,0 +1,125 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; H0F38 +r3 pshufb, 8, mm0 +r3 pshufb, 16, xmm0 + +r3 phaddw, 8, mm0 +r3 phaddw, 16, xmm0 + +r3 phaddd, 8, mm0 +r3 phaddd, 16, xmm0 + +r3 phaddsw, 8, mm0 +r3 phaddsw, 16, xmm0 + +r3 pmaddubsw, 8, mm0 +r3 pmaddubsw, 16, xmm0 + +r3 phsubw, 8, mm0 +r3 phsubw, 16, xmm0 + +r3 phsubd, 8, mm0 +r3 phsubd, 16, xmm0 + +r3 phsubsw, 8, mm0 +r3 phsubsw, 16, xmm0 + +r3 psignb, 8, mm0 +r3 psignb, 16, xmm0 + +r3 psignw, 8, mm0 +r3 psignw, 16, xmm0 + +r3 psignd, 8, mm0 +r3 psignd, 16, xmm0 + +r3 pmulhrsw, 8, mm0 +r3 pmulhrsw, 16, xmm0 + +r3 pblendvb, 16, xmm0 +r3 blendvps, 16, xmm0 +r3 blendvpd, 16, xmm0 +r3 ptest, 16, xmm0 + +r3 pabsb, 8, mm0 +r3 pabsb, 16, xmm0 + +r3 pabsw, 8, mm0 +r3 pabsw, 16, xmm0 + +r3 pabsd, 8, mm0 +r3 pabsd, 16, xmm0 + +r3 pmovsxbw, 16, xmm0 +r3 pmovsxbd, 16, xmm0 +r3 pmovsxbq, 16, xmm0 +r3 pmovsxwd, 16, xmm0 +r3 pmovsxwq, 16, xmm0 +r3 pmovsxdq, 16, xmm0 +r3 pmuldq, 16, xmm0 +r3 pcmpeqq, 16, xmm0 +r3 movntdqa, 16, xmm0 +r3 packusdw, 16, xmm0 +r3 pmovzxbw, 16, xmm0 +r3 pmovzxbd, 16, xmm0 +r3 pmovzxbq, 16, xmm0 +r3 pmovzxwd, 16, xmm0 +r3 pmovzxwq, 16, xmm0 +r3 pmovzxdq, 16, xmm0 +r3 pcmpgtq, 16, xmm0 +r3 pminsb, 16, xmm0 +r3 pminsd, 16, xmm0 +r3 pminuw, 16, xmm0 +r3 pminud, 16, xmm0 +r3 pmaxsb, 16, xmm0 +r3 pmaxsd, 16, xmm0 +r3 pmaxuw, 16, xmm0 +r3 pmaxud, 16, xmm0 +r3 pmulld, 16, xmm0 +r3 sha1nexte, 16, xmm0 +r3 sha1msg1, 16, xmm0 +r3 sha1msg2, 16, xmm0 +r3 sha256rnds2, 16, xmm0 +r3 sha256msg1, 16, xmm0 +r3 sha256msg2, 16, xmm0 +r3 aesimc, 16, xmm0 +r3 aesenc, 16, xmm0 +r3 aesenclast, 16, xmm0 +r3 aesdec, 16, xmm0 +r3 aesdeclast, 16, xmm0 + +rw3 movbe, 2, ax +rw3 movbe, 4, eax +rw3 movbe, 8, rax + +r4_size crc32, 1, byte, eax +r4_size crc32, 2, word, eax +r4_size crc32, 4, dword, eax +r4_size crc32, 8, qword, rax + +r3 adcx, 4, eax +r3 adcx, 8, rax + +r3 adox, 4, eax +r3 adox, 8, rax + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/H0F3A.asm b/unittests/ASM/modrm_oob/H0F3A.asm new file mode 100644 index 000000000..4a42c64a4 --- /dev/null +++ b/unittests/ASM/modrm_oob/H0F3A.asm @@ -0,0 +1,55 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; H0F3A +w4 pextrq, 8, xmm0, 0 +r4 pinsrq, 8, xmm0, 0 +w4 pextrd, 4, xmm0, 0 +r4 pinsrd, 4, xmm0, 0 + +r4 palignr, 8, mm0, 0 +r4 palignr, 16, xmm0, 0 +r4 roundps, 16, xmm0, 0 +r4 roundpd, 16, xmm0, 0 +r4 roundpd, 16, xmm0, 0 +r4 roundss, 4, xmm0, 0 +r4 roundsd, 8, xmm0, 0 +r4 blendps, 16, xmm0, 0 +r4 blendpd, 16, xmm0, 0 +r4 pblendw, 16, xmm0, 0 +r4 palignr, 8, mm0, 0 +r4 palignr, 16, xmm0, 0 +w4 pextrb, 1, xmm0, 0 +w4 pextrw, 2, xmm0, 0 +w4 extractps, 4, xmm0, 0 +r4 pinsrb, 1, xmm0, 0 +r4 insertps, 4, xmm0, 0 +r4 dpps, 16, xmm0, 0 +r4 dppd, 16, xmm0, 0 +r4 mpsadbw, 16, xmm0, 0 +r4 pclmulqdq, 16, xmm0, 0 +r4 pcmpestrm, 16, xmm0, 0 +r4 pcmpestri, 16, xmm0, 0 +r4 pcmpistrm, 16, xmm0, 0 +r4 pcmpistri, 16, xmm0, 0 +r4 sha1rnds4, 16, xmm0, 0 +r4 aeskeygenassist, 16, xmm0, 0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/Primary.asm b/unittests/ASM/modrm_oob/Primary.asm new file mode 100644 index 000000000..3e4e68ec3 --- /dev/null +++ b/unittests/ASM/modrm_oob/Primary.asm @@ -0,0 +1,112 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Primary table +rw3 add, 8, rax +rw3 add, 4, eax +rw3 add, 2, ax +rw3 add, 1, al + +w3 lock add, 8, rax +w3 lock add, 4, eax +w3 lock add, 2, ax +w3 lock add, 1, al + +rw3 or, 8, rax +rw3 or, 4, eax +rw3 or, 2, ax +rw3 or, 1, al + +w3 lock or, 8, rax +w3 lock or, 4, eax +w3 lock or, 2, ax +w3 lock or, 1, al + +rw3 adc, 8, rax +rw3 adc, 4, eax +rw3 adc, 2, ax +rw3 adc, 1, al + +w3 lock adc, 8, rax +w3 lock adc, 4, eax +w3 lock adc, 2, ax +w3 lock adc, 1, al + +rw3 sbb, 8, rax +rw3 sbb, 4, eax +rw3 sbb, 2, ax +rw3 sbb, 1, al + +w3 lock sbb, 8, rax +w3 lock sbb, 4, eax +w3 lock sbb, 2, ax +w3 lock sbb, 1, al + +rw3 and, 8, rax +rw3 and, 4, eax +rw3 and, 2, ax +rw3 and, 1, al + +w3 lock and, 8, rax +w3 lock and, 4, eax +w3 lock and, 2, ax +w3 lock and, 1, al + +rw3 xor, 8, rax +rw3 xor, 4, eax +rw3 xor, 2, ax +rw3 xor, 1, al + +w3 lock xor, 8, rax +w3 lock xor, 4, eax +w3 lock xor, 2, ax +w3 lock xor, 1, al + +rw3 cmp, 8, rax +rw3 cmp, 4, eax +rw3 cmp, 2, ax +rw3 cmp, 1, al + +r4 imul, 8, rax, 4 +r4 imul, 4, eax, 4 +r4 imul, 2, ax, 4 + +r4 imul, 8, rax, 0x1004 +r4 imul, 4, eax, 0x1004 +r4 imul, 2, ax, 0x1004 + +rw3 test, 8, rax +rw3 test, 4, eax +rw3 test, 2, ax +rw3 test, 1, al + +rw3 xchg, 8, rax +rw3 xchg, 4, eax +rw3 xchg, 2, ax +rw3 xchg, 1, al + +rw3 mov, 8, rax +rw3 mov, 4, eax +rw3 mov, 2, ax +rw3 mov, 1, al + +r3 movsxd, 4, rax + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/PrimaryGroup.asm b/unittests/ASM/modrm_oob/PrimaryGroup.asm new file mode 100644 index 000000000..25bd537ac --- /dev/null +++ b/unittests/ASM/modrm_oob/PrimaryGroup.asm @@ -0,0 +1,203 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Primary Group + +w4_size add, 1, byte, 1 +w4_size add, 2, word, 1 +w4_size add, 4, dword, 1 +w4_size add, 8, qword, 1 + +w4_size lock add, 1, byte, 1 +w4_size lock add, 2, word, 1 +w4_size lock add, 4, dword, 1 +w4_size lock add, 8, qword, 1 + +w4_size or, 1, byte, 1 +w4_size or, 2, word, 1 +w4_size or, 4, dword, 1 +w4_size or, 8, qword, 1 + +w4_size lock or, 1, byte, 1 +w4_size lock or, 2, word, 1 +w4_size lock or, 4, dword, 1 +w4_size lock or, 8, qword, 1 + +w4_size adc, 1, byte, 1 +w4_size adc, 2, word, 1 +w4_size adc, 4, dword, 1 +w4_size adc, 8, qword, 1 + +w4_size lock adc, 1, byte, 1 +w4_size lock adc, 2, word, 1 +w4_size lock adc, 4, dword, 1 +w4_size lock adc, 8, qword, 1 + +w4_size sbb, 1, byte, 1 +w4_size sbb, 2, word, 1 +w4_size sbb, 4, dword, 1 +w4_size sbb, 8, qword, 1 + +w4_size lock sbb, 1, byte, 1 +w4_size lock sbb, 2, word, 1 +w4_size lock sbb, 4, dword, 1 +w4_size lock sbb, 8, qword, 1 + +w4_size and, 1, byte, 1 +w4_size and, 2, word, 1 +w4_size and, 4, dword, 1 +w4_size and, 8, qword, 1 + +w4_size lock and, 1, byte, 1 +w4_size lock and, 2, word, 1 +w4_size lock and, 4, dword, 1 +w4_size lock and, 8, qword, 1 + +w4_size sub, 1, byte, 1 +w4_size sub, 2, word, 1 +w4_size sub, 4, dword, 1 +w4_size sub, 8, qword, 1 + +w4_size lock sub, 1, byte, 1 +w4_size lock sub, 2, word, 1 +w4_size lock sub, 4, dword, 1 +w4_size lock sub, 8, qword, 1 + +w4_size xor, 1, byte, 1 +w4_size xor, 2, word, 1 +w4_size xor, 4, dword, 1 +w4_size xor, 8, qword, 1 + +w4_size lock xor, 1, byte, 1 +w4_size lock xor, 2, word, 1 +w4_size lock xor, 4, dword, 1 +w4_size lock xor, 8, qword, 1 + +w4_size cmp, 1, byte, 1 +w4_size cmp, 2, word, 1 +w4_size cmp, 4, dword, 1 +w4_size cmp, 8, qword, 1 + +w4_size rol, 1, byte, 1 +w4_size rol, 2, word, 1 +w4_size rol, 4, dword, 1 +w4_size rol, 8, qword, 1 + +w4_size ror, 1, byte, 1 +w4_size ror, 2, word, 1 +w4_size ror, 4, dword, 1 +w4_size ror, 8, qword, 1 + +w4_size rcl, 1, byte, 1 +w4_size rcl, 2, word, 1 +w4_size rcl, 4, dword, 1 +w4_size rcl, 8, qword, 1 + +w4_size rcr, 1, byte, 1 +w4_size rcr, 2, word, 1 +w4_size rcr, 4, dword, 1 +w4_size rcr, 8, qword, 1 + +w4_size shl, 1, byte, 1 +w4_size shl, 2, word, 1 +w4_size shl, 4, dword, 1 +w4_size shl, 8, qword, 1 + +w4_size shr, 1, byte, 1 +w4_size shr, 2, word, 1 +w4_size shr, 4, dword, 1 +w4_size shr, 8, qword, 1 + +w4_size sar, 1, byte, 1 +w4_size sar, 2, word, 1 +w4_size sar, 4, dword, 1 +w4_size sar, 8, qword, 1 + +w4_size test, 1, byte, 1 +w4_size test, 2, word, 1 +w4_size test, 4, dword, 1 +w4_size test, 8, qword, 1 + +w3_size not, 1, byte +w3_size not, 2, word +w3_size not, 4, dword +w3_size not, 8, qword + +w3_size lock not, 1, byte +w3_size lock not, 2, word +w3_size lock not, 4, dword +w3_size lock not, 8, qword + +w3_size neg, 1, byte +w3_size neg, 2, word +w3_size neg, 4, dword +w3_size neg, 8, qword + +w3_size lock neg, 1, byte +w3_size lock neg, 2, word +w3_size lock neg, 4, dword +w3_size lock neg, 8, qword + +w3_size mul, 1, byte +w3_size mul, 2, word +w3_size mul, 4, dword +w3_size mul, 8, qword + +w3_size imul, 1, byte +w3_size imul, 2, word +w3_size imul, 4, dword +w3_size imul, 8, qword + +w3_size div, 1, byte +w3_size div, 2, word +w3_size div, 4, dword +w3_size div, 8, qword + +w3_size idiv, 1, byte +w3_size idiv, 2, word +w3_size idiv, 4, dword +w3_size idiv, 8, qword + +w3_size inc, 1, byte +w3_size inc, 2, word +w3_size inc, 4, dword +w3_size inc, 8, qword + +w3_size lock inc, 1, byte +w3_size lock inc, 2, word +w3_size lock inc, 4, dword +w3_size lock inc, 8, qword + +w3_size dec, 1, byte +w3_size dec, 2, word +w3_size dec, 4, dword +w3_size dec, 8, qword + +w3_size lock dec, 1, byte +w3_size lock dec, 2, word +w3_size lock dec, 4, dword +w3_size lock dec, 8, qword + +w4_size mov, 1, byte, 1 +w4_size mov, 2, word, 1 +w4_size mov, 4, dword, 1 +w4_size mov, 8, qword, 1 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/Secondary.asm b/unittests/ASM/modrm_oob/Secondary.asm new file mode 100644 index 000000000..f411c3d2e --- /dev/null +++ b/unittests/ASM/modrm_oob/Secondary.asm @@ -0,0 +1,292 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary table +rw3 movups, 16, xmm0 +rw3 movlps, 8, xmm0 +r3 unpcklps, 16, xmm0 +r3 unpckhps, 16, xmm0 +rw3 movhps, 8, xmm0 +rw3 movaps, 16, xmm0 +r3 cvtpi2ps, 8, xmm0 +w3 movntps, 16, xmm0 +r3 cvttps2pi, 8, mm0 +r3 cvtps2pi, 8, mm0 +r3 ucomiss, 4, xmm0 +r3 comiss, 4, xmm0 + +r3 cmovo, 8, rax +r3 cmovo, 4, eax +r3 cmovo, 2, ax + +r3 cmovno, 8, rax +r3 cmovno, 4, eax +r3 cmovno, 2, ax + +r3 cmovb, 8, rax +r3 cmovb, 4, eax +r3 cmovb, 2, ax + +r3 cmovnb, 8, rax +r3 cmovnb, 4, eax +r3 cmovnb, 2, ax + +r3 cmovz, 8, rax +r3 cmovz, 4, eax +r3 cmovz, 2, ax + +r3 cmovnz, 8, rax +r3 cmovnz, 4, eax +r3 cmovnz, 2, ax + +r3 cmovbe, 8, rax +r3 cmovbe, 4, eax +r3 cmovbe, 2, ax + +r3 cmovnbe, 8, rax +r3 cmovnbe, 4, eax +r3 cmovnbe, 2, ax + +r3 cmovs, 8, rax +r3 cmovs, 4, eax +r3 cmovs, 2, ax + +r3 cmovns, 8, rax +r3 cmovns, 4, eax +r3 cmovns, 2, ax + +r3 cmovp, 8, rax +r3 cmovp, 4, eax +r3 cmovp, 2, ax + +r3 cmovnp, 8, rax +r3 cmovnp, 4, eax +r3 cmovnp, 2, ax + +r3 cmovl, 8, rax +r3 cmovl, 4, eax +r3 cmovl, 2, ax + +r3 cmovnl, 8, rax +r3 cmovnl, 4, eax +r3 cmovnl, 2, ax + +r3 cmovle, 8, rax +r3 cmovle, 4, eax +r3 cmovle, 2, ax + +r3 cmovnle, 8, rax +r3 cmovnle, 4, eax +r3 cmovnle, 2, ax + +r3 sqrtps, 16, xmm0 +r3 rsqrtps, 16, xmm0 +r3 rcpps, 16, xmm0 +r3 andps, 16, xmm0 +r3 andnps, 16, xmm0 +r3 orps, 16, xmm0 +r3 xorps, 16, xmm0 +r3 addps, 16, xmm0 +r3 mulps, 16, xmm0 +r3 cvtps2pd, 8, xmm0 +r3 cvtdq2ps, 16, xmm0 +r3 subps, 16, xmm0 +r3 minps, 16, xmm0 +r3 divps, 16, xmm0 +r3 maxps, 16, xmm0 +r3 punpcklbw, 16, xmm0 +r3 punpcklwd, 16, xmm0 +r3 punpckldq, 16, xmm0 +r3 packsswb, 16, xmm0 +r3 pcmpgtb, 16, xmm0 +r3 pcmpgtw, 16, xmm0 +r3 pcmpgtd, 16, xmm0 +r3 packuswb, 16, xmm0 +r3 punpckhbw, 16, xmm0 +r3 punpckhwd, 16, xmm0 +r3 punpckhdq, 16, xmm0 +r3 packssdw, 16, xmm0 + +rw3 movd, 4, mm0 +rw3 movq, 8, mm0 +r4 pshufw, 8, mm0, 0 +r3 pcmpeqb, 8, mm0 +r3 pcmpeqw, 8, mm0 +r3 pcmpeqd, 8, mm0 + +rw3 movd, 4, xmm0 +rw3 movq, 8, xmm0 + +w2 seto, 1 +w2 setno, 1 +w2 setb, 1 +w2 setnb, 1 +w2 setz, 1 +w2 setnz, 1 +w2 setbe, 1 +w2 setnbe, 1 +w2 sets, 1 +w2 setns, 1 +w2 setp, 1 +w2 setnp, 1 +w2 setl, 1 +w2 setnl, 1 +w2 setle, 1 +w2 setnle, 1 + +mov rax, 0 +w3 bt, 2, ax +w3 bt, 4, eax +w3 bt, 8, rax + +w4 shld, 2, ax, 1 +w4 shld, 4, eax, 1 +w4 shld, 8, rax, 1 + +mov cl, 1 +w4 shld, 2, ax, cl +w4 shld, 4, eax, cl +w4 shld, 8, rax, cl + +mov rax, 0 +w3 bts, 2, ax +w3 bts, 4, eax +w3 bts, 8, rax + +w4 shrd, 2, ax, 1 +w4 shrd, 4, eax, 1 +w4 shrd, 8, rax, 1 + +mov cl, 1 +w4 shrd, 2, ax, cl +w4 shrd, 4, eax, cl +w4 shld, 8, rax, cl + +r3 imul, 8, rax +r3 imul, 4, eax +r3 imul, 2, ax + +w3 cmpxchg, 8, rax +w3 cmpxchg, 4, eax +w3 cmpxchg, 2, ax +w3 cmpxchg, 1, al + +mov rax, 0 +w3 btr, 2, ax +w3 btr, 4, eax +w3 btr, 8, rax + +; MOVZX is a bit special +movzx rax, byte [r15 - 1] +movzx rax, byte [r14] +movzx rax, word [r15 - 2] +movzx rax, word [r14] + +mov rax, 0 +w3 btc, 2, ax +w3 btc, 4, eax +w3 btc, 8, rax + +r3 bsf, 2, ax +r3 bsf, 4, eax +r3 bsf, 8, rax + +r3 bsr, 2, ax +r3 bsr, 4, eax +r3 bsr, 8, rax + +; MOVSX is a bit special +movsx rax, byte [r15 - 1] +movsx rax, byte [r14] +movsx rax, word [r15 - 2] +movsx rax, word [r14] + +w3 xadd, 1, al +w3 xadd, 2, ax +w3 xadd, 4, eax +w3 xadd, 8, rax + +w3 lock xadd, 1, al +w3 lock xadd, 2, ax +w3 lock xadd, 4, eax +w3 lock xadd, 8, rax + + +r4 cmpps, 16, xmm0, 0 +r4 cmpps, 16, xmm0, 1 +r4 cmpps, 16, xmm0, 2 +r4 cmpps, 16, xmm0, 3 +r4 cmpps, 16, xmm0, 4 +r4 cmpps, 16, xmm0, 5 +r4 cmpps, 16, xmm0, 6 +r4 cmpps, 16, xmm0, 7 + +w3 movnti, 4, eax +w3 movnti, 8, rax + +r4 pinsrw, 2, xmm0, 0 +r4 shufps, 16, xmm0, 0 + +r3 psrlw, 8, mm0 +r3 psrld, 8, mm0 +r3 psrlq, 8, mm0 +r3 paddq, 8, mm0 +r3 pmullw, 8, mm0 +r3 psubusb, 8, mm0 +r3 psubusw, 8, mm0 +r3 pminub, 8, mm0 +r3 pand, 8, mm0 +r3 paddusb, 8, mm0 +r3 paddusw, 8, mm0 +r3 pmaxub, 8, mm0 +r3 pandn, 8, mm0 +r3 pavgb, 8, mm0 +r3 psraw, 8, mm0 +r3 psrad, 8, mm0 +r3 pavgw, 8, mm0 +r3 pmulhuw, 8, mm0 +r3 pmulhw, 8, mm0 + +w3 movntq, 8, mm0 + + +r3 psubsb, 8, mm0 +r3 psubsw, 8, mm0 +r3 pminsw, 8, mm0 +r3 por, 8, mm0 +r3 paddsb, 8, mm0 +r3 paddsw, 8, mm0 +r3 pmaxsw, 8, mm0 +r3 pxor, 8, mm0 +r3 psllw, 8, mm0 +r3 pslld, 8, mm0 +r3 psllq, 8, mm0 +r3 pmuludq, 8, mm0 +r3 pmaddwd, 8, mm0 +r3 psadbw, 8, mm0 +r3 psubb, 8, mm0 +r3 psubw, 8, mm0 +r3 psubd, 8, mm0 +r3 psubq, 8, mm0 +r3 paddb, 8, mm0 +r3 paddw, 8, mm0 +r3 paddd, 8, mm0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/SecondaryGroup.asm b/unittests/ASM/modrm_oob/SecondaryGroup.asm new file mode 100644 index 000000000..187bb9b55 --- /dev/null +++ b/unittests/ASM/modrm_oob/SecondaryGroup.asm @@ -0,0 +1,57 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary Group +; w2 sldt, 2 +; w2 str, 2 +; w2 verr, 2 +; w2 verw, 2 +; SGDT +; SIDT +w2 smsw, 2 + +w4_size bt, 2, word, 0 +w4_size bt, 4, dword, 0 +w4_size bt, 8, qword, 0 + +w4_size bts, 2, word, 0 +w4_size bts, 4, dword, 0 +w4_size bts, 8, qword, 0 + +w4_size btr, 2, word, 0 +w4_size btr, 4, dword, 0 +w4_size btr, 8, qword, 0 + +w4_size btc, 2, word, 0 +w4_size btc, 4, dword, 0 +w4_size btc, 8, qword, 0 + +w2 cmpxchg8b, 8 +w2 cmpxchg16b, 16 + +w2 fxsave, 512 +r2 fxrstor, 512 + +w2 stmxcsr, 4 +r2 ldmxcsr, 4 + +; XSAVE/XRSTOR size is variable and can't be tested here. + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/SecondaryModRM.asm b/unittests/ASM/modrm_oob/SecondaryModRM.asm new file mode 100644 index 000000000..fa471c64e --- /dev/null +++ b/unittests/ASM/modrm_oob/SecondaryModRM.asm @@ -0,0 +1,30 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary ModRM + +; clzero is a bit special +lea rax, [r15 - 64] +clzero rax + +lea rax, [r14] +clzero rax + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/SecondaryOpSize.asm b/unittests/ASM/modrm_oob/SecondaryOpSize.asm new file mode 100644 index 000000000..62c75bbd0 --- /dev/null +++ b/unittests/ASM/modrm_oob/SecondaryOpSize.asm @@ -0,0 +1,130 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary Opsize +rw3 movupd, 16, xmm0 +rw3 movlpd, 8, xmm0 +r3 unpcklpd, 16, xmm0 +r3 unpckhpd, 16, xmm0 +rw3 movhpd, 8, xmm0 +rw3 movapd, 16, xmm0 +r3 cvtpi2pd, 8, xmm0 +w3 movntpd, 16, xmm0 +r3 cvttpd2pi, 16, mm0 +r3 cvtpd2pi, 16, mm0 +r3 ucomisd, 8, xmm0 +r3 comisd, 8, xmm0 + +r3 sqrtpd, 16, xmm0 +r3 andpd, 16, xmm0 +r3 andnpd, 16, xmm0 +r3 orpd, 16, xmm0 +r3 xorpd, 16, xmm0 +r3 addpd, 16, xmm0 +r3 mulpd, 16, xmm0 +r3 cvtpd2ps, 16, xmm0 +r3 cvtps2dq, 16, xmm0 +r3 subpd, 16, xmm0 +r3 minpd, 16, xmm0 +r3 divpd, 16, xmm0 +r3 maxpd, 16, xmm0 + +r3 punpcklbw, 16, xmm0 +r3 punpcklwd, 16, xmm0 +r3 punpckldq, 16, xmm0 +r3 packsswb, 16, xmm0 +r3 pcmpgtb, 16, xmm0 +r3 pcmpgtw, 16, xmm0 +r3 pcmpgtd, 16, xmm0 +r3 packuswb, 16, xmm0 +r3 punpckhbw, 16, xmm0 +r3 punpckhwd, 16, xmm0 +r3 punpckhdq, 16, xmm0 +r3 packssdw, 16, xmm0 +r3 punpcklqdq, 16, xmm0 +r3 punpckhqdq, 16, xmm0 + +rw3 movdqa, 16, xmm0 + +r4 pshufd, 16, xmm0, 1 + +r3 pcmpeqb, 16, xmm0 +r3 pcmpeqw, 16, xmm0 +r3 pcmpeqd, 16, xmm0 +r3 haddpd, 16, xmm0 +r3 hsubpd, 16, xmm0 + +r4 cmppd, 16, xmm0, 0 +r4 cmppd, 16, xmm0, 1 +r4 cmppd, 16, xmm0, 2 +r4 cmppd, 16, xmm0, 3 +r4 cmppd, 16, xmm0, 4 +r4 cmppd, 16, xmm0, 5 +r4 cmppd, 16, xmm0, 6 +r4 cmppd, 16, xmm0, 7 + +r4 pinsrw, 2, xmm0, 0 +w4 pextrw, 2, xmm0, 0 + +r4 shufpd, 16, xmm0, 0 +r3 addsubpd, 16, xmm0 +r3 psrlw, 16, xmm0 +r3 psrld, 16, xmm0 +r3 psrlq, 16, xmm0 +r3 paddq, 16, xmm0 +r3 psubusb, 16, xmm0 +r3 psubusw, 16, xmm0 +r3 pminub, 16, xmm0 +r3 pand, 16, xmm0 +r3 paddusb, 16, xmm0 +r3 paddusw, 16, xmm0 +r3 pmaxub, 16, xmm0 +r3 pandn, 16, xmm0 + +r3 pavgb, 16, xmm0 +r3 psraw, 16, xmm0 +r3 psrad, 16, xmm0 +r3 pavgw, 16, xmm0 +r3 pmulhuw, 16, xmm0 +r3 pmulhw, 16, xmm0 +r3 cvttpd2dq, 16, xmm0 +w3 movntdq, 16, xmm0 +r3 psubsb, 16, xmm0 +r3 pminsw, 16, xmm0 +r3 por, 16, xmm0 +r3 paddsb, 16, xmm0 +r3 paddsw, 16, xmm0 +r3 pmaxsw, 16, xmm0 +r3 pxor, 16, xmm0 +r3 psllw, 16, xmm0 +r3 pslld, 16, xmm0 +r3 psllq, 16, xmm0 +r3 pmuludq, 16, xmm0 +r3 pmaddwd, 16, xmm0 +r3 psadbw, 16, xmm0 +r3 psubb, 16, xmm0 +r3 psubw, 16, xmm0 +r3 psubd, 16, xmm0 +r3 psubq, 16, xmm0 +r3 paddb, 16, xmm0 +r3 paddw, 16, xmm0 +r3 paddd, 16, xmm0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/SecondaryREP.asm b/unittests/ASM/modrm_oob/SecondaryREP.asm new file mode 100644 index 000000000..9f663ef1e --- /dev/null +++ b/unittests/ASM/modrm_oob/SecondaryREP.asm @@ -0,0 +1,80 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary REP +rw3 movss, 4, xmm0 +r3 movsldup, 16, xmm0 +r3 movshdup, 16, xmm0 + +; cvtsi2ss is a bit special +cvtsi2ss xmm0, dword [r15 - 4] +cvtsi2ss xmm0, dword [r14] + +cvtsi2ss xmm0, qword [r15 - 8] +cvtsi2ss xmm0, qword [r14] + +w3 movntss, 4, xmm0 + +r3 cvttss2si, 4, eax +r3 cvttss2si, 8, rax + +r3 cvtss2si, 4, eax +r3 cvtss2si, 8, rax + +r3 sqrtss, 4, xmm0 +r3 rsqrtss, 4, xmm0 +r3 rcpss, 4, xmm0 +r3 addss, 4, xmm0 +r3 mulss, 4, xmm0 +r3 cvtss2sd, 4, xmm0 +r3 cvttps2dq, 16, xmm0 +r3 subss, 4, xmm0 +r3 minss, 4, xmm0 +r3 divss, 4, xmm0 +r3 maxss, 4, xmm0 + +rw3 movdqu, 16, xmm0 +r4 pshufhw, 16, xmm0, 0 +rw3 movq, 8, xmm0 + +r3 popcnt, 2, ax +r3 popcnt, 4, eax +r3 popcnt, 8, rax + +r3 tzcnt, 2, ax +r3 tzcnt, 4, eax +r3 tzcnt, 8, rax + +r3 lzcnt, 2, ax +r3 lzcnt, 4, eax +r3 lzcnt, 8, rax + +r4 cmpss, 4, xmm0, 0 +r4 cmpss, 4, xmm0, 1 +r4 cmpss, 4, xmm0, 2 +r4 cmpss, 4, xmm0, 3 +r4 cmpss, 4, xmm0, 4 +r4 cmpss, 4, xmm0, 5 +r4 cmpss, 4, xmm0, 6 +r4 cmpss, 4, xmm0, 7 + +r3 cvtdq2pd, 8, xmm0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/SecondaryREPNE.asm b/unittests/ASM/modrm_oob/SecondaryREPNE.asm new file mode 100644 index 000000000..acf9bad3a --- /dev/null +++ b/unittests/ASM/modrm_oob/SecondaryREPNE.asm @@ -0,0 +1,63 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; Secondary REPNE +rw3 movsd, 8, xmm0 +r3 movddup, 8, xmm0 + +; cvtsi2sd is a bit special +cvtsi2sd xmm0, dword [r15 - 4] +cvtsi2sd xmm0, dword [r14] + +cvtsi2sd xmm0, qword [r15 - 8] +cvtsi2sd xmm0, qword [r14] + +w3 movntsd, 8, xmm0 + +r3 cvttsd2si, 8, rax +r3 cvtsd2si, 8, rax + +r3 sqrtsd, 8, xmm0 +r3 addsd, 8, xmm0 +r3 mulsd, 8, xmm0 +r3 cvtsd2ss, 8, xmm0 +r3 subsd, 8, xmm0 +r3 minsd, 8, xmm0 +r3 divsd, 8, xmm0 +r3 maxsd, 8, xmm0 + +r4 pshuflw, 16, xmm0, 0 +r3 haddps, 16, xmm0 +r3 hsubps, 16, xmm0 + +r4 cmpsd, 8, xmm0, 0 +r4 cmpsd, 8, xmm0, 1 +r4 cmpsd, 8, xmm0, 2 +r4 cmpsd, 8, xmm0, 3 +r4 cmpsd, 8, xmm0, 4 +r4 cmpsd, 8, xmm0, 5 +r4 cmpsd, 8, xmm0, 6 +r4 cmpsd, 8, xmm0, 7 + +r3 addsubps, 16, xmm0 +r3 cvtpd2dq, 16, xmm0 +r3 lddqu, 16, xmm0 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/VEX.asm b/unittests/ASM/modrm_oob/VEX.asm new file mode 100644 index 000000000..ab1216c1a --- /dev/null +++ b/unittests/ASM/modrm_oob/VEX.asm @@ -0,0 +1,578 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; VEX map 1 +%macro r_avx 1 +r3 %1, 16, xmm0 +r3 %1, 32, ymm0 +%endmacro + +%macro r_avx_2_reg 1 +r4 %1, 16, xmm0, xmm1 +r4 %1, 32, ymm0, ymm1 +%endmacro + +%macro r_avx_fma 1 +r4_fma %1, 16, xmm0, xmm1 +r4_fma %1, 32, ymm0, ymm2 +%endmacro + +%macro r2_avx 2 +r4 %1, 16, xmm0, %2 +r4 %1, 32, ymm0, %2 +%endmacro + +%macro w_avx 1 +w3 %1, 16, xmm0 +w3 %1, 32, ymm0 +%endmacro + +%macro rw_avx 1 +r_avx %1 +w_avx %1 +%endmacro + +; VEX +rw_avx vmovups +rw_avx vmovupd +rw3 vmovss, 4, xmm0 +rw3 vmovsd, 8, xmm0 + +rw3 vmovlps, 8, xmm0 +rw3 vmovlpd, 8, xmm0 + +r_avx vmovsldup +r_avx vmovddup + +r_avx vunpcklps +r_avx vunpcklpd +r_avx vunpckhps +r_avx vunpckhpd + +rw3 vmovhps, 8, xmm0 +rw3 vmovhpd, 8, xmm0 + +r_avx vmovshdup +r_avx vsqrtps +r_avx vsqrtpd + +r3 vsqrtss, 4, xmm0 +r3 vsqrtsd, 8, xmm0 + +r_avx vrsqrtps +r3 vrsqrtss, 4, xmm0 + +r_avx vrcpps +r3 vrcpss, 4, xmm0 + +r_avx vandps +r_avx vandpd +r_avx vandnps +r_avx vandnpd +r_avx vorps +r_avx vorpd +r_avx vxorps +r_avx vxorpd +r_avx vpunpcklbw +r_avx vpunpcklwd +r_avx vpunpckldq + +r_avx vpacksswb +r_avx vpcmpgtb +r_avx vpcmpgtw +r_avx vpcmpgtd +r_avx vpackuswb + +r2_avx vpshufd, 0 +r2_avx vpshufhw, 0 +r2_avx vpshuflw, 0 + +r_avx vpcmpeqb +r_avx vpcmpeqw +r_avx vpcmpeqd + +r2_avx vcmpps, 0 +r2_avx vcmpps, 1 +r2_avx vcmpps, 2 +r2_avx vcmpps, 3 +r2_avx vcmpps, 4 +r2_avx vcmpps, 5 +r2_avx vcmpps, 6 +r2_avx vcmpps, 7 + +r2_avx vcmppd, 0 +r2_avx vcmppd, 1 +r2_avx vcmppd, 2 +r2_avx vcmppd, 3 +r2_avx vcmppd, 4 +r2_avx vcmppd, 5 +r2_avx vcmppd, 6 +r2_avx vcmppd, 7 + +r4 vcmpss, 4, xmm0, 0 +r4 vcmpss, 4, xmm0, 1 +r4 vcmpss, 4, xmm0, 2 +r4 vcmpss, 4, xmm0, 3 +r4 vcmpss, 4, xmm0, 4 +r4 vcmpss, 4, xmm0, 5 +r4 vcmpss, 4, xmm0, 6 +r4 vcmpss, 4, xmm0, 7 + +r4 vcmpsd, 8, xmm0, 0 +r4 vcmpsd, 8, xmm0, 1 +r4 vcmpsd, 8, xmm0, 2 +r4 vcmpsd, 8, xmm0, 3 +r4 vcmpsd, 8, xmm0, 4 +r4 vcmpsd, 8, xmm0, 5 +r4 vcmpsd, 8, xmm0, 6 +r4 vcmpsd, 8, xmm0, 7 + +r4 vpinsrw, 2, xmm0, 0 +w4 vpextrw, 2, xmm0, 0 + +r2_avx vshufps, 0 +r2_avx vshufpd, 0 + +rw_avx vmovaps +rw_avx vmovapd + +r4_size vcvtsi2ss, 4, dword, xmm0 +r4_size vcvtsi2ss, 8, qword, xmm0 + +r4_size vcvtsi2sd, 4, dword, xmm0 +r4_size vcvtsi2sd, 8, qword, xmm0 + +w_avx vmovntps +w_avx vmovntpd + +r4_size vcvttss2si, 4, dword, eax +r4_size vcvttss2si, 4, dword, rax + +r4_size vcvttsd2si, 8, qword, eax +r4_size vcvttsd2si, 8, qword, rax + +r4_size vcvtss2si, 4, dword, eax +r4_size vcvtss2si, 4, dword, rax + +r4_size vcvtsd2si, 8, qword, eax +r4_size vcvtsd2si, 8, qword, rax + +r4_size vucomiss, 4, dword, xmm0 +r4_size vucomisd, 8, qword, xmm0 + +r4_size vcomiss, 4, dword, xmm0 +r4_size vcomisd, 8, qword, xmm0 + +r_avx vaddps +r_avx vaddpd +r4_size vaddss, 4, dword, xmm0 +r4_size vaddsd, 8, qword, xmm0 + +r_avx vmulps +r_avx vmulpd +r4_size vmulss, 4, dword, xmm0 +r4_size vmulsd, 8, qword, xmm0 + +r4_size vcvtps2pd, 8, qword, xmm0 +r4_size vcvtps2pd, 16, oword, ymm0 + +r4_size vcvtpd2ps, 16, oword, xmm0 +r4_size vcvtpd2ps, 32, yword, xmm0 + +r4_size vcvtss2sd, 4, dword, xmm0 +r4_size vcvtsd2ss, 8, qword, xmm0 + +r_avx vcvtdq2ps +r_avx vcvtps2dq +r_avx vcvttps2dq + +r_avx vsubps +r_avx vsubpd +r4_size vsubss, 4, dword, xmm0 +r4_size vsubsd, 8, qword, xmm0 + +r_avx vminps +r_avx vminpd +r4_size vminss, 4, dword, xmm0 +r4_size vminsd, 8, qword, xmm0 + +r_avx vdivps +r_avx vdivpd +r4_size vdivss, 4, dword, xmm0 +r4_size vdivsd, 8, qword, xmm0 + +r_avx vmaxps +r_avx vmaxpd +r4_size vmaxss, 4, dword, xmm0 +r4_size vmaxsd, 8, qword, xmm0 + +r_avx vpunpckhbw +r_avx vpunpckhwd +r_avx vpunpckhdq +r_avx vpackssdw +r_avx vpunpcklqdq +r_avx vpunpckhqdq + +rw3 vmovq, 8, xmm0 +rw3 vmovd, 4, xmm0 + +r_avx vmovdqa +r_avx vmovdqu +r_avx vhaddpd +r_avx vhaddps +r_avx vhsubpd +r_avx vhsubps +r_avx vaddsubpd +r_avx vaddsubps + +r_avx vpsrlw +r_avx vpsrld +r_avx vpsrlq +r_avx vpaddq +r_avx vpmullw +r_avx vpsubusb +r_avx vpsubusw +r_avx vpand +r_avx vpaddusb +r_avx vpmaxub +r_avx vpandn +r_avx vpavgb +r_avx vpsraw +r_avx vpsrad +r_avx vpavgw +r_avx vpmulhuw +r_avx vpmulhw +r4_size vcvttpd2dq, 16, oword, xmm0 +r4_size vcvttpd2dq, 32, yword, xmm0 +r_avx vcvtdq2pd +r4_size vcvtpd2dq, 16, oword, xmm0 +r4_size vcvtpd2dq, 32, yword, xmm0 +w_avx vmovntdq +r_avx vpsubsb +r_avx vpsubsw +r_avx vpminsw +r_avx vpor +r_avx vpaddsb +r_avx vpaddsw +r_avx vpmaxsw +r_avx vpxor +r_avx vlddqu +r_avx vpsllw +r_avx vpslld +r_avx vpsllq +r_avx vpmuludq +r_avx vpmaddwd +r_avx vpsadbw +r_avx vpsubb +r_avx vpsubw +r_avx vpsubd +r_avx vpsubq +r_avx vpaddb +r_avx vpaddw +r_avx vpaddd +r_avx vpaddq + +; VEX Map 2 +r_avx vpshufb +r_avx vphaddw +r_avx vphaddd +r_avx vphaddsw +r_avx vpmaddubsw +r_avx vphsubw +r_avx vphsubd +r_avx vphsubsw +r_avx vpsignb +r_avx vpsignw +r_avx vpsignd +r_avx vpsignd +r_avx vpmulhrsw +r_avx vpermilps +r_avx vpermilpd +r_avx vtestps +r_avx vtestpd + +r4_size vcvtph2ps, 8, qword, xmm0 +r4_size vcvtph2ps, 16, oword, ymm0 + +r3 vpermps, 32, ymm0 +r_avx vptest +r4_size vbroadcastss, 4, dword, xmm0 +r4_size vbroadcastss, 4, dword, ymm0 + +r4_size vbroadcastsd, 8, qword, ymm0 +r3 vbroadcastf128, 16, ymm0 + +r_avx vpabsb +r_avx vpabsw +r_avx vpabsd + +r4_size vpmovsxbw, 8, qword, xmm0 +r4_size vpmovsxbw, 16, oword, ymm0 + +r4_size vpmovsxbd, 4, dword, xmm0 +r4_size vpmovsxbd, 8, qword, ymm0 + +r4_size vpmovsxbq, 2, word, xmm0 +r4_size vpmovsxbq, 4, dword, ymm0 + +r4_size vpmovsxwd, 8, qword, xmm0 +r4_size vpmovsxwd, 16, oword, ymm0 + +r4_size vpmovsxwq, 4, dword, xmm0 +r4_size vpmovsxwq, 8, qword, ymm0 + +r4_size vpmovsxdq, 8, qword, xmm0 +r4_size vpmovsxdq, 16, oword, ymm0 + +r_avx vpmuldq +r_avx vpcmpeqq +r_avx vmovntdqa +r_avx vpackusdw + +; VMASKMOVPS/PD is complex and can't be tested here. + +r4_size vpmovzxbw, 8, qword, xmm0 +r4_size vpmovzxbw, 16, oword, ymm0 + +r4_size vpmovzxbd, 4, dword, xmm0 +r4_size vpmovzxbd, 8, qword, ymm0 + +r4_size vpmovzxbq, 2, word, xmm0 +r4_size vpmovzxbq, 4, dword, ymm0 + +r4_size vpmovzxwd, 8, qword, xmm0 +r4_size vpmovzxwd, 16, oword, ymm0 + +r4_size vpmovzxwq, 4, dword, xmm0 +r4_size vpmovzxwq, 8, qword, ymm0 + +r4_size vpmovzxdq, 8, qword, xmm0 +r4_size vpmovzxdq, 16, oword, ymm0 + +r3 vpermd, 32, ymm0 +r_avx vpcmpgtq +r_avx vpminsb +r_avx vpminsd +r_avx vpminuw +r_avx vpminud +r_avx vpmaxsb +r_avx vpmaxsd +r_avx vpmaxuw +r_avx vpmaxud +r_avx vpmulld +r3 vphminposuw, 16, xmm0 +r_avx vpsrlvd +r_avx vpsrlvq +r_avx vpsravd +r_avx vpsllvd +r_avx vpsllvq + +r4_size vpbroadcastd, 4, dword, xmm0 +r4_size vpbroadcastd, 4, dword, ymm0 + +r4_size vpbroadcastq, 8, qword, xmm0 +r4_size vpbroadcastq, 8, qword, ymm0 + +r4_size vbroadcasti128, 16, oword, ymm0 + +; VPMASKMOVD/Q is complex and can't be tested here. +; V{P,}GATHER* is complex and can't be tested here. +r_avx_fma vfmaddsub132pd +r_avx_fma vfmsubadd132pd +r_avx_fma vfmaddsub132ps +r_avx_fma vfmsubadd132ps + +r_avx_fma vfmadd132pd +r_avx_fma vfmadd132ps +r_avx_fma vfmsub132pd +r_avx_fma vfmsub132ps +r_avx_fma vfnmadd132pd +r_avx_fma vfnmadd132ps +r_avx_fma vfnmsub132pd +r_avx_fma vfnmsub132ps +r_avx_fma vfmadd213pd +r_avx_fma vfmadd213ps +r_avx_fma vfmsub213pd +r_avx_fma vfmsub213ps +r_avx_fma vfnmadd213pd +r_avx_fma vfnmadd213ps +r_avx_fma vfnmsub213pd +r_avx_fma vfnmsub213ps +r_avx_fma vfmadd231pd +r_avx_fma vfmadd231ps +r_avx_fma vfmsub231pd +r_avx_fma vfmsub231ps +r_avx_fma vfnmadd231pd +r_avx_fma vfnmadd231ps +r_avx_fma vfnmsub231pd +r_avx_fma vfnmsub231ps +r_avx_fma vfmaddsub213pd +r_avx_fma vfmaddsub213ps +r_avx_fma vfmsubadd213pd +r_avx_fma vfmsubadd213ps +r_avx_fma vfmaddsub231pd +r_avx_fma vfmaddsub231ps +r_avx_fma vfmsubadd231pd +r_avx_fma vfmsubadd231ps + +r5_fma_sized vfmadd132sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmadd132ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfmsub132sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmsub132ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmadd132sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmadd132ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmsub132sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmsub132ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfmadd213sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmadd213ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfmsub213sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmsub213ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmadd213sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmadd213ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmsub213sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmsub213ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfmadd231sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmadd231ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfmsub231sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfmsub231ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmadd231sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmadd231ss, 4, dword, xmm0, xmm1 + +r5_fma_sized vfnmsub231sd, 8, qword, xmm0, xmm1 +r5_fma_sized vfnmsub231ss, 4, dword, xmm0, xmm1 + +r3 vaesimc, 16, xmm0 +r3 vaesenc, 16, xmm0 +r3 vaesenclast, 16, xmm0 +r3 vaesdec, 16, xmm0 +r3 vaesdeclast, 16, xmm0 + +r5_fma_sized andn, 4, dword, eax, ebx +r5_fma_sized andn, 8, qword, rax, rbx + +; bzhi is a bit special. +bzhi eax, dword [r15 - 4], ebx +bzhi eax, dword [r14], ebx + +bzhi rax, qword [r15 - 8], rbx +bzhi rax, qword [r14], rbx + +r5_fma_sized pext, 4, dword, eax, ebx +r5_fma_sized pext, 8, qword, rax, rbx + +r5_fma_sized pdep, 4, dword, eax, ebx +r5_fma_sized pdep, 8, qword, rax, rbx + +r5_fma_sized mulx, 4, dword, eax, ebx +r5_fma_sized mulx, 8, qword, rax, rbx + +; bextr is a bit special. +bextr eax, dword [r15 - 4], ebx +bextr eax, dword [r14], ebx + +bextr rax, qword [r15 - 8], rbx +bextr rax, qword [r14], rbx + +; shlx is a bit special. +shlx eax, dword [r15 - 4], ebx +shlx eax, dword [r14], ebx + +shlx rax, qword [r15 - 8], rbx +shlx rax, qword [r14], rbx + +; sarx is a bit special. +sarx eax, dword [r15 - 4], ebx +sarx eax, dword [r14], ebx + +sarx rax, qword [r15 - 8], rbx +sarx rax, qword [r14], rbx + +; shrx is a bit special. +shrx eax, dword [r15 - 4], ebx +shrx eax, dword [r14], ebx + +shrx rax, qword [r15 - 8], rbx +shrx rax, qword [r14], rbx + +; VEX Map 3 +r4 vpermq, 32, ymm0, 0 +r4 vpermpd, 32, ymm0, 0 + +r2_avx vpblendd, 0 +r2_avx vpermilps, 0 +r2_avx vpermilpd, 0 +r4 vperm2f128, 32, ymm0, 0 +r2_avx vroundps, 0 +r2_avx vroundpd, 0 + +r4 vroundss, 4, xmm0, 0 +r4 vroundsd, 8, xmm0, 0 +r2_avx vblendps, 0 +r2_avx vblendpd, 0 +r2_avx vpblendw, 0 +r2_avx vpalignr, 0 + +w5_size vpextrb, 1, byte, xmm0, 0 +w5_size vpextrw, 2, word, xmm0, 0 +w5_size vpextrd, 4, dword, xmm0, 0 +w5_size vextractps, 4, dword, xmm0, 0 +w5_size vpextrq, 8, qword, xmm0, 0 +r4 vinsertf128, 16, ymm0, 0 +w5_size vextractf128, 16, oword, ymm0, 0 +w5_size vcvtps2ph, 8, qword, xmm0, 0 +w5_size vcvtps2ph, 16, oword, ymm0, 0 + +r5_size vpinsrb, 1, byte, xmm0, 0 +r5_size vinsertps, 4, dword, xmm0, 0 +r5_size vpinsrd, 4, dword, xmm0, 0 +r5_size vpinsrq, 8, qword, xmm0, 0 +r4 vinserti128, 16, ymm0, 0 +w5_size vextracti128, 16, oword, ymm0, 0 + +r2_avx vdpps, 0 +r4 vdppd, 16, xmm0, 0 +r2_avx vmpsadbw, 0 +r2_avx vpclmulqdq, 0 +r4 vperm2i128, 32, ymm0, 0 + +r_avx_2_reg vblendvps +r_avx_2_reg vblendvpd +r_avx_2_reg vpblendvb + +r4 vpcmpestrm, 16, xmm0, 0 +r4 vpcmpestri, 16, xmm0, 0 +r4 vpcmpistrm, 16, xmm0, 0 +r4 vpcmpistri, 16, xmm0, 0 +r4 vaeskeygenassist, 16, xmm0, 0 + +r4 rorx, 4, eax, 1 +r4 rorx, 8, rax, 1 + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/VEXGroup.asm b/unittests/ASM/modrm_oob/VEXGroup.asm new file mode 100644 index 000000000..f5aaf399d --- /dev/null +++ b/unittests/ASM/modrm_oob/VEXGroup.asm @@ -0,0 +1,33 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; VEX group 15 +w2 vstmxcsr, 4 +w2 vldmxcsr, 4 + +; VEX group 17 +r3 blsr, 4, eax +r3 blsr, 8, rax +r3 blsmsk, 4, eax +r3 blsmsk, 8, rax +r3 blsi, 4, eax +r3 blsi, 8, rax + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/X87.asm b/unittests/ASM/modrm_oob/X87.asm new file mode 100644 index 000000000..046a87a76 --- /dev/null +++ b/unittests/ASM/modrm_oob/X87.asm @@ -0,0 +1,139 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; X87 + +; These macros using the w* versions are actually reads. +%macro x87_f48_op 1 +fldz +w3_size %1, 4, dword +w3_size %1, 8, qword +ffreep +%endmacro + +%macro x87_i24_op 1 +fldz +w3_size %1, 2, word +w3_size %1, 4, dword +ffreep +%endmacro + +x87_f48_op fadd +x87_f48_op fmul +x87_f48_op fcom + +; fcomp is special +fldz +w3_size fcomp, 4, dword +fldz +w3_size fcomp, 8, qword + +x87_f48_op fsub +x87_f48_op fsubr +x87_f48_op fdiv +x87_f48_op fdivr + +; fld is special +w3_size fld, 4, dword +ffreep +w3_size fld, 8, qword +ffreep +w3_size fld, 10, tword +ffreep + +; fst is special +fldz +w3_size fst, 4, dword +w3_size fst, 8, qword + +; fstp is special +fldz +w3_size fstp, 4, dword +fldz +w3_size fstp, 8, qword +fldz +w3_size fstp, 10, tword + +w2 fnstenv, 28 +w2 fldenv, 28 + +w2 o16 fnstenv, 14 +w2 o16 fldenv, 14 + +w2 fnstcw, 2 +w2 fldcw, 2 + +x87_i24_op fiadd +x87_i24_op fimul +x87_i24_op ficom + +; ficomp is special +fldz +w3_size ficomp, 2, word +fldz +w3_size ficomp, 4, dword + +x87_i24_op fisub +x87_i24_op fisubr + +x87_i24_op fidiv +x87_i24_op fidivr + +; fild is special +w3_size fild, 2, word +ffreep +w3_size fild, 4, dword +ffreep +w3_size fild, 8, qword +ffreep + +; fist is special +fldz +w3_size fist, 2, word +w3_size fist, 4, dword + +; fistp is special +fldz +w3_size fistp, 2, word +fldz +w3_size fistp, 4, dword +fldz +w3_size fistp, 8, qword + +; fisttp is special +fldz +w3_size fisttp, 2, word +fldz +w3_size fisttp, 4, dword +fldz +w3_size fisttp, 8, qword + +w2 fnsave, 108 +w2 frstor, 108 + +w2 fnstsw, 2 + +w2 o16 fnsave, 94 +w2 o16 frstor, 94 + +w3_size fbld, 10, tword +w3_size fbstp, 10, tword + +; Done +mov rax, 1 +hlt diff --git a/unittests/ASM/modrm_oob/X87_Reduced.asm b/unittests/ASM/modrm_oob/X87_Reduced.asm new file mode 100644 index 000000000..bf684193d --- /dev/null +++ b/unittests/ASM/modrm_oob/X87_Reduced.asm @@ -0,0 +1,140 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "1" + }, + "MemoryRegions": { + "0x100000000": "4096", + "0x100002000": "4096" + }, + "Env": { "FEX_X87REDUCEDPRECISION" : "1" } +} +%endif + +mov r15, 0x100001000 +mov r14, 0x100002000 +mov rax, 0 + +%include "modrm_oob_macros.mac" + +; X87 + +; These macros using the w* versions are actually reads. +%macro x87_f48_op 1 +fldz +w3_size %1, 4, dword +w3_size %1, 8, qword +ffreep +%endmacro + +%macro x87_i24_op 1 +fldz +w3_size %1, 2, word +w3_size %1, 4, dword +ffreep +%endmacro + +x87_f48_op fadd +x87_f48_op fmul +x87_f48_op fcom + +; fcomp is special +fldz +w3_size fcomp, 4, dword +fldz +w3_size fcomp, 8, qword + +x87_f48_op fsub +x87_f48_op fsubr +x87_f48_op fdiv +x87_f48_op fdivr + +; fld is special +w3_size fld, 4, dword +ffreep +w3_size fld, 8, qword +ffreep +w3_size fld, 10, tword +ffreep + +; fst is special +fldz +w3_size fst, 4, dword +w3_size fst, 8, qword + +; fstp is special +fldz +w3_size fstp, 4, dword +fldz +w3_size fstp, 8, qword +fldz +w3_size fstp, 10, tword + +w2 fnstenv, 28 +w2 fldenv, 28 + +w2 o16 fnstenv, 14 +w2 o16 fldenv, 14 + +w2 fnstcw, 2 +w2 fldcw, 2 + +x87_i24_op fiadd +x87_i24_op fimul +x87_i24_op ficom + +; ficomp is special +fldz +w3_size ficomp, 2, word +fldz +w3_size ficomp, 4, dword + +x87_i24_op fisub +x87_i24_op fisubr + +x87_i24_op fidiv +x87_i24_op fidivr + +; fild is special +w3_size fild, 2, word +ffreep +w3_size fild, 4, dword +ffreep +w3_size fild, 8, qword +ffreep + +; fist is special +fldz +w3_size fist, 2, word +w3_size fist, 4, dword + +; fistp is special +fldz +w3_size fistp, 2, word +fldz +w3_size fistp, 4, dword +fldz +w3_size fistp, 8, qword + +; fisttp is special +fldz +w3_size fisttp, 2, word +fldz +w3_size fisttp, 4, dword +fldz +w3_size fisttp, 8, qword + +w2 fnsave, 108 +w2 frstor, 108 + +w2 fnstsw, 2 + +w2 o16 fnsave, 94 +w2 o16 frstor, 94 + +w3_size fbld, 10, tword +w3_size fbstp, 10, tword + +; Done +mov rax, 1 +hlt