Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorkobalicek <kobalicek.petr@gmail.com>2021-01-26 03:00:10 +0300
committerkobalicek <kobalicek.petr@gmail.com>2021-01-26 03:00:29 +0300
commit58b6c025f2b89b1beac9c5a5f84c4c6ae5a521b1 (patch)
treea295e5ec4d27345c5e894d24e138520b3f16f9bc /test
parent1422faa011dbbb976ae9b5efa84eed5ab5e8f8da (diff)
[ABI] Added more AVX_VNNI instructions, added MOVABS for explicit Imm64 encodings, added more assembler tests
Diffstat (limited to 'test')
-rw-r--r--test/asmjit_test_assembler.cpp83
-rw-r--r--test/asmjit_test_assembler.h96
-rw-r--r--test/asmjit_test_assembler_x86.cpp604
-rw-r--r--test/asmjit_test_compiler.cpp52
-rw-r--r--test/asmjit_test_emitters.cpp (renamed from test/asmjit_test_x86_asm.cpp)16
-rw-r--r--test/asmjit_test_instinfo.cpp (renamed from test/asmjit_test_x86_instinfo.cpp)47
-rw-r--r--test/asmjit_test_x86_sections.cpp6
7 files changed, 870 insertions, 34 deletions
diff --git a/test/asmjit_test_assembler.cpp b/test/asmjit_test_assembler.cpp
new file mode 100644
index 0000000..559235e
--- /dev/null
+++ b/test/asmjit_test_assembler.cpp
@@ -0,0 +1,83 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include <asmjit/core.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asmjit_test_assembler.h"
+#include "cmdline.h"
+
+using namespace asmjit;
+
+#if defined(ASMJIT_BUILD_X86)
+bool testX86Assembler(const TestSettings& settings) noexcept;
+bool testX64Assembler(const TestSettings& settings) noexcept;
+#endif
+
+int main(int argc, char* argv[]) {
+ CmdLine cmdLine(argc, argv);
+
+ TestSettings settings {};
+ settings.quiet = cmdLine.hasArg("--quiet");
+
+ printf("AsmJit Assembler Test-Suite v%u.%u.%u:\n\n",
+ unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
+ unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
+ unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF));
+
+ printf("Usage:\n");
+ printf(" --help Show usage only\n");
+ printf(" --arch=<ARCH> Select architecture to run ('all' by default)\n");
+ printf(" --quiet Show only assembling errors [%s]\n", settings.quiet ? "x" : " ");
+ printf("\n");
+
+ if (cmdLine.hasArg("--help"))
+ return 0;
+
+ const char* arch = cmdLine.valueOf("--arch", "all");
+ bool x86Failed = false;
+ bool x64Failed = false;
+
+#if defined(ASMJIT_BUILD_X86)
+ if ((strcmp(arch, "all") == 0 || strcmp(arch, "x86") == 0))
+ x86Failed = !testX86Assembler(settings);
+
+ if ((strcmp(arch, "all") == 0 || strcmp(arch, "x64") == 0))
+ x64Failed = !testX64Assembler(settings);
+#endif
+
+ bool failed = x86Failed || x64Failed;
+
+ if (failed) {
+ if (x86Failed) printf("** X86 test suite failed **\n");
+ if (x64Failed) printf("** X64 test suite failed **\n");
+ printf("** FAILURE **\n");
+ }
+ else {
+ printf("** SUCCESS **\n");
+ }
+
+ return failed ? 1 : 0;
+}
diff --git a/test/asmjit_test_assembler.h b/test/asmjit_test_assembler.h
new file mode 100644
index 0000000..6f7a549
--- /dev/null
+++ b/test/asmjit_test_assembler.h
@@ -0,0 +1,96 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#ifndef ASMJIT_TEST_ASSEMBLER_H_INCLUDED
+#define ASMJIT_TEST_ASSEMBLER_H_INCLUDED
+
+#include <asmjit/core.h>
+#include <stdio.h>
+
+struct TestSettings {
+ bool quiet;
+};
+
+template<typename AssemblerType>
+class AssemblerTester {
+public:
+ asmjit::Environment env {};
+ asmjit::CodeHolder code {};
+ AssemblerType assembler {};
+ const TestSettings& settings;
+
+ size_t passed {};
+ size_t count {};
+
+ AssemblerTester(uint32_t arch, const TestSettings& settings) noexcept
+ : env(arch),
+ settings(settings) {}
+
+ void printHeader(const char* archName) noexcept {
+ printf("%s assembler tests:\n", archName);
+ }
+
+ void printSummary() noexcept {
+ printf(" Passed: %zu / %zu tests\n\n", passed, count);
+ }
+
+ bool didPass() const noexcept { return passed == count; }
+
+ void beforeInstruction() noexcept {
+ code.init(env, 0);
+ code.attach(&assembler);
+ }
+
+ bool testInstruction(const char* expectedOpcode, const char* s, uint32_t err) noexcept {
+ count++;
+
+ if (err) {
+ printf(" !! %s\n"
+ " <%s>\n", s, asmjit::DebugUtils::errorAsString(err));
+ return false;
+ }
+
+ asmjit::String encodedOpcode;
+ asmjit::Section* text = code.textSection();
+
+ encodedOpcode.appendHex(text->data(), text->bufferSize());
+ if (encodedOpcode != expectedOpcode) {
+ printf(" !! [%s] <- %s\n"
+ " [%s] (Expected)\n", encodedOpcode.data(), s, expectedOpcode);
+ return false;
+ }
+
+ if (!settings.quiet)
+ printf(" OK [%s] <- %s\n", encodedOpcode.data(), s);
+
+ passed++;
+ return true;
+ }
+
+ void afterInstruction() noexcept {
+ code.reset();
+ }
+};
+
+#endif // ASMJIT_TEST_ASSEMBLER_H_INCLUDED
+
diff --git a/test/asmjit_test_assembler_x86.cpp b/test/asmjit_test_assembler_x86.cpp
new file mode 100644
index 0000000..323a2da
--- /dev/null
+++ b/test/asmjit_test_assembler_x86.cpp
@@ -0,0 +1,604 @@
+// AsmJit - Machine code generation for C++
+//
+// * Official AsmJit Home Page: https://asmjit.com
+// * Official Github Repository: https://github.com/asmjit/asmjit
+//
+// Copyright (c) 2008-2020 The AsmJit Authors
+//
+// This software is provided 'as-is', without any express or implied
+// warranty. In no event will the authors be held liable for any damages
+// arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it
+// freely, subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented; you must not
+// claim that you wrote the original software. If you use this software
+// in a product, an acknowledgment in the product documentation would be
+// appreciated but is not required.
+// 2. Altered source versions must be plainly marked as such, and must not be
+// misrepresented as being the original software.
+// 3. This notice may not be removed or altered from any source distribution.
+
+#include <asmjit/core.h>
+#if defined(ASMJIT_BUILD_X86)
+
+#include <asmjit/x86.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "asmjit_test_assembler.h"
+#include "cmdline.h"
+
+using namespace asmjit;
+
+#define TEST_INSTRUCTION(OPCODE, ...) \
+ do { \
+ tester.beforeInstruction(); \
+ tester.testInstruction(OPCODE, #__VA_ARGS__, tester.assembler.__VA_ARGS__); \
+ tester.afterInstruction(); \
+ } while (0)
+
+bool testX86Assembler(const TestSettings& settings) noexcept {
+ using namespace x86;
+
+ AssemblerTester<Assembler> tester(Environment::kArchX86, settings);
+ tester.printHeader("X86");
+
+ // Base Instructions.
+ TEST_INSTRUCTION("8AE0" , mov(ah, al));
+ TEST_INSTRUCTION("8AF0" , mov(dh, al));
+ TEST_INSTRUCTION("8BC3" , mov(eax, ebx));
+ TEST_INSTRUCTION("89D8" , mod_mr().mov(eax, ebx));
+ TEST_INSTRUCTION("B800000000" , mov(eax, 0));
+ TEST_INSTRUCTION("BB00000000" , mov(ebx, 0));
+ TEST_INSTRUCTION("B8FFFFFFFF" , mov(eax, 0xFFFFFFFF));
+ TEST_INSTRUCTION("8CE0" , mov(eax, fs));
+ TEST_INSTRUCTION("8EE0" , mov(fs, eax));
+ TEST_INSTRUCTION("8B10" , mov(edx, ptr(eax)));
+ TEST_INSTRUCTION("8B10" , mov(edx, ptr(eax, 0)));
+ TEST_INSTRUCTION("8B9080000000" , mov(edx, ptr(eax, 128)));
+ TEST_INSTRUCTION("8B1408" , mov(edx, ptr(eax, ecx)));
+ TEST_INSTRUCTION("8B940880000000" , mov(edx, ptr(eax, ecx, 0, 128)));
+ TEST_INSTRUCTION("8B1408" , mov(edx, ptr(eax, ecx)));
+ TEST_INSTRUCTION("8B544820" , mov(edx, ptr(eax, ecx, 1, 32)));
+ TEST_INSTRUCTION("8B548840" , mov(edx, ptr(eax, ecx, 2, 64)));
+ TEST_INSTRUCTION("8B94C800010000" , mov(edx, ptr(eax, ecx, 3, 128 + 128)));
+ TEST_INSTRUCTION("8B1408" , mov(edx, ptr(eax, ecx)));
+ TEST_INSTRUCTION("8B940880000000" , mov(edx, ptr(eax, ecx, 0, 128)));
+ TEST_INSTRUCTION("8B1408" , mov(edx, ptr(eax, ecx)));
+ TEST_INSTRUCTION("8B544820" , mov(edx, ptr(eax, ecx, 1, 32)));
+ TEST_INSTRUCTION("8B54C802" , mov(edx, ptr(eax, ecx, 3, 2)));
+ TEST_INSTRUCTION("0F20C0" , mov(eax, cr0));
+ TEST_INSTRUCTION("F00F20C0" , mov(eax, cr8));
+ TEST_INSTRUCTION("A344332211" , mov(ptr(0x11223344), eax));
+ TEST_INSTRUCTION("890544332211" , mod_mr().mov(ptr(0x11223344), eax));
+ TEST_INSTRUCTION("891D44332211" , mov(ptr(0x11223344), ebx));
+ TEST_INSTRUCTION("0FBE07" , movsx(eax, byte_ptr(edi)));
+ TEST_INSTRUCTION("0FBF07" , movsx(eax, word_ptr(edi)));
+ TEST_INSTRUCTION("0FB607" , movzx(eax, byte_ptr(edi)));
+ TEST_INSTRUCTION("0FB6C6" , movzx(eax, dh));
+ TEST_INSTRUCTION("0FB707" , movzx(eax, word_ptr(edi)));
+ TEST_INSTRUCTION("03D9" , add(ebx, ecx));
+ TEST_INSTRUCTION("83C001" , add(eax, 1));
+ TEST_INSTRUCTION("0504030201" , add(eax, 0x01020304));
+ TEST_INSTRUCTION("66050201" , add(ax, 0x0102));
+ TEST_INSTRUCTION("6603849004030201" , add(ax, ptr(eax, edx, 2, 0x01020304)));
+ TEST_INSTRUCTION("F00118" , lock().add(ptr(eax), ebx));
+ TEST_INSTRUCTION("F00FC138" , lock().xadd(ptr(eax), edi));
+ TEST_INSTRUCTION("660FBA2001" , bt(word_ptr(eax), 1));
+ TEST_INSTRUCTION("0FBA2001" , bt(dword_ptr(eax), 1));
+ TEST_INSTRUCTION("FE00" , inc(byte_ptr(eax)));
+ TEST_INSTRUCTION("66FF00" , inc(word_ptr(eax)));
+ TEST_INSTRUCTION("FF00" , inc(dword_ptr(eax)));
+ TEST_INSTRUCTION("F6D8" , neg(al));
+ TEST_INSTRUCTION("F6DC" , neg(ah));
+ TEST_INSTRUCTION("F7D8" , neg(eax));
+ TEST_INSTRUCTION("F7D0" , not_(eax));
+ TEST_INSTRUCTION("0F95C3" , setnz(bl));
+ TEST_INSTRUCTION("0F94C7" , setz(bh));
+ TEST_INSTRUCTION("F600FF" , test(byte_ptr(eax), 0xFF));
+ TEST_INSTRUCTION("66F700FF00" , test(word_ptr(eax), 0xFF));
+ TEST_INSTRUCTION("F700FF000000" , test(dword_ptr(eax), 0xFF));
+ TEST_INSTRUCTION("A836" , test(al, 0x36));
+ TEST_INSTRUCTION("F6C436" , test(ah, 0x36));
+ TEST_INSTRUCTION("50" , push(eax));
+ TEST_INSTRUCTION("51" , push(ecx));
+ TEST_INSTRUCTION("52" , push(edx));
+ TEST_INSTRUCTION("53" , push(ebx));
+ TEST_INSTRUCTION("54" , push(esp));
+ TEST_INSTRUCTION("55" , push(ebp));
+ TEST_INSTRUCTION("56" , push(esi));
+ TEST_INSTRUCTION("57" , push(edi));
+ TEST_INSTRUCTION("0E" , push(cs));
+ TEST_INSTRUCTION("16" , push(ss));
+ TEST_INSTRUCTION("1E" , push(ds));
+ TEST_INSTRUCTION("06" , push(es));
+ TEST_INSTRUCTION("0FA0" , push(fs));
+ TEST_INSTRUCTION("0FA8" , push(gs));
+ TEST_INSTRUCTION("C8010002" , enter(1, 2));
+ TEST_INSTRUCTION("C9" , leave());
+ TEST_INSTRUCTION("FF10" , call(ptr(eax)));
+ TEST_INSTRUCTION("FF10" , call(dword_ptr(eax)));
+ TEST_INSTRUCTION("66C501" , lds(ax, ptr(ecx)));
+ TEST_INSTRUCTION("C501" , lds(eax, ptr(ecx)));
+ TEST_INSTRUCTION("66C401" , les(ax, ptr(ecx)));
+ TEST_INSTRUCTION("C401" , les(eax, ptr(ecx)));
+ TEST_INSTRUCTION("660FB401" , lfs(ax, ptr(ecx)));
+ TEST_INSTRUCTION("0FB401" , lfs(eax, ptr(ecx)));
+ TEST_INSTRUCTION("660FB501" , lgs(ax, ptr(ecx)));
+ TEST_INSTRUCTION("0FB501" , lgs(eax, ptr(ecx)));
+ TEST_INSTRUCTION("660FB201" , lss(ax, ptr(ecx)));
+ TEST_INSTRUCTION("0FB201" , lss(eax, ptr(ecx)));
+
+ // NOP.
+ TEST_INSTRUCTION("90" , nop());
+ TEST_INSTRUCTION("660F1F0400" , nop(word_ptr(eax, eax)));
+ TEST_INSTRUCTION("660F1F0400" , nop(word_ptr(eax, eax), ax));
+ TEST_INSTRUCTION("660F1F1C00" , nop(word_ptr(eax, eax), bx));
+ TEST_INSTRUCTION("0F1F0400" , nop(dword_ptr(eax, eax)));
+ TEST_INSTRUCTION("0F1F0400" , nop(dword_ptr(eax, eax), eax));
+ TEST_INSTRUCTION("0F1F1C00" , nop(dword_ptr(eax, eax), ebx));
+
+ // LEA.
+ TEST_INSTRUCTION("67668D00" , lea(ax, ptr(bx, si)));
+ TEST_INSTRUCTION("67668D01" , lea(ax, ptr(bx, di)));
+ TEST_INSTRUCTION("67668D02" , lea(ax, ptr(bp, si)));
+ TEST_INSTRUCTION("67668D03" , lea(ax, ptr(bp, di)));
+ TEST_INSTRUCTION("67668D04" , lea(ax, ptr(si)));
+ TEST_INSTRUCTION("67668D05" , lea(ax, ptr(di)));
+ TEST_INSTRUCTION("67668D4600" , lea(ax, ptr(bp)));
+ TEST_INSTRUCTION("67668D07" , lea(ax, ptr(bx)));
+ TEST_INSTRUCTION("67668D4010" , lea(ax, ptr(bx, si, 0, 0x10)));
+ TEST_INSTRUCTION("67668D4120" , lea(ax, ptr(bx, di, 0, 0x20)));
+ TEST_INSTRUCTION("67668D4240" , lea(ax, ptr(bp, si, 0, 0x40)));
+ TEST_INSTRUCTION("67668D4360" , lea(ax, ptr(bp, di, 0, 0x60)));
+ TEST_INSTRUCTION("67668D848000" , lea(ax, ptr(si, 0x80)));
+ TEST_INSTRUCTION("67668D85A000" , lea(ax, ptr(di, 0xA0)));
+ TEST_INSTRUCTION("67668D86C000" , lea(ax, ptr(bp, 0xC0)));
+ TEST_INSTRUCTION("67668D87FF01" , lea(ax, ptr(bx, 0x01FF)));
+ TEST_INSTRUCTION("678D00" , lea(eax, ptr(bx, si)));
+ TEST_INSTRUCTION("678D01" , lea(eax, ptr(bx, di)));
+ TEST_INSTRUCTION("8D0433" , lea(eax, ptr(ebx, esi)));
+ TEST_INSTRUCTION("8D043B" , lea(eax, ptr(ebx, edi)));
+ TEST_INSTRUCTION("8D0500000000" , lea(eax, ptr(0)));
+
+ // XACQUIRE|XRELEASE|RTM.
+ TEST_INSTRUCTION("C6F811" , xabort(0x11));
+ TEST_INSTRUCTION("F2F00108" , xacquire().lock().add(dword_ptr(eax), ecx));
+ TEST_INSTRUCTION("F3F00108" , xrelease().lock().add(dword_ptr(eax), ecx));
+
+ // BND.
+ TEST_INSTRUCTION("660F1ACA" , bndmov(bnd1, bnd2));
+ TEST_INSTRUCTION("F20F1ACF" , bndcu(bnd1, edi));
+ TEST_INSTRUCTION("0F1A0408" , bndldx(bnd0, ptr(eax, ecx)));
+ TEST_INSTRUCTION("0F1B0C08" , bndstx(ptr(eax, ecx), bnd1));
+
+ // BMI+.
+ TEST_INSTRUCTION("66F30FB8C2" , popcnt(ax, dx));
+ TEST_INSTRUCTION("F30FB8C2" , popcnt(eax, edx));
+ TEST_INSTRUCTION("66F30FBDC2" , lzcnt(ax, dx));
+ TEST_INSTRUCTION("F30FBDC2" , lzcnt(eax, edx));
+ TEST_INSTRUCTION("66F30FBCC2" , tzcnt(ax, dx));
+ TEST_INSTRUCTION("F30FBCC2" , tzcnt(eax, edx));
+
+ // CRC32.
+ TEST_INSTRUCTION("F20F38F0C7" , crc32(eax, bh));
+ TEST_INSTRUCTION("66F20F38F1C3" , crc32(eax, bx));
+ TEST_INSTRUCTION("F20F38F1C1" , crc32(eax, ecx));
+ TEST_INSTRUCTION("F20F38F006" , crc32(eax, byte_ptr(esi)));
+ TEST_INSTRUCTION("66F20F38F106" , crc32(eax, word_ptr(esi)));
+ TEST_INSTRUCTION("F20F38F106" , crc32(eax, dword_ptr(esi)));
+
+ // FPU.
+ TEST_INSTRUCTION("9B" , fwait());
+ TEST_INSTRUCTION("D800" , fadd(dword_ptr(eax)));
+ TEST_INSTRUCTION("DC00" , fadd(qword_ptr(eax)));
+
+ // MMX & SSE.
+ TEST_INSTRUCTION("0F6FC1" , movq(mm0, mm1));
+ TEST_INSTRUCTION("0F6E00" , movd(mm0, ptr(eax)));
+ TEST_INSTRUCTION("0F6F0418" , movq(mm0, ptr(eax, ebx)));
+ TEST_INSTRUCTION("0F7E38" , movd(ptr(eax), mm7));
+ TEST_INSTRUCTION("0F7F0418" , movq(ptr(eax, ebx), mm0));
+ TEST_INSTRUCTION("F30F7EC1" , movq(xmm0, xmm1));
+ TEST_INSTRUCTION("660F6E0418" , movd(xmm0, ptr(eax, ebx)));
+ TEST_INSTRUCTION("F30F7E0418" , movq(xmm0, ptr(eax, ebx)));
+ TEST_INSTRUCTION("660F7E0C18" , movd(ptr(eax, ebx), xmm1));
+ TEST_INSTRUCTION("660FD60C18" , movq(ptr(eax, ebx), xmm1));
+ TEST_INSTRUCTION("0F280498" , movaps(xmm0, ptr(eax, ebx, 2)));
+ TEST_INSTRUCTION("660F280498" , movapd(xmm0, ptr(eax, ebx, 2)));
+ TEST_INSTRUCTION("660F6F0498" , movdqa(xmm0, ptr(eax, ebx, 2)));
+ TEST_INSTRUCTION("0F290C98" , movaps(ptr(eax, ebx, 2), xmm1));
+ TEST_INSTRUCTION("660F290C98" , movapd(ptr(eax, ebx, 2), xmm1));
+ TEST_INSTRUCTION("660F7F0C98" , movdqa(ptr(eax, ebx, 2), xmm1));
+ TEST_INSTRUCTION("F30F2DC1" , cvtss2si(eax, xmm1));
+ TEST_INSTRUCTION("F20F2DC1" , cvtsd2si(eax, xmm1));
+ TEST_INSTRUCTION("F30F2AC2" , cvtsi2ss(xmm0, edx));
+ TEST_INSTRUCTION("F20F2AC2" , cvtsi2sd(xmm0, edx));
+ TEST_INSTRUCTION("660F3A41C100" , dppd(xmm0, xmm1, 0));
+ TEST_INSTRUCTION("0FDBC1" , pand(mm0, mm1));
+ TEST_INSTRUCTION("660FDBC1" , pand(xmm0, xmm1));
+ TEST_INSTRUCTION("660FFDC1" , paddw(xmm0, xmm1));
+
+ // AVX & AVX512.
+ TEST_INSTRUCTION("C5F96E5A10" , vmovd(xmm3, dword_ptr(edx, 0x10)));
+ TEST_INSTRUCTION("C5FA7E5A10" , vmovq(xmm3, qword_ptr(edx, 0x10)));
+ TEST_INSTRUCTION("C5F97E5A10" , vmovd(dword_ptr(edx, 0x10), xmm3));
+ TEST_INSTRUCTION("C5F9D65A10" , vmovq(qword_ptr(edx, 0x10), xmm3));
+ TEST_INSTRUCTION("C5F96EEB" , vmovd(xmm5, ebx));
+ TEST_INSTRUCTION("C5F97EEB" , vmovd(ebx, xmm5));
+ TEST_INSTRUCTION("C5FA7EC1" , vmovq(xmm0, xmm1));
+ TEST_INSTRUCTION("62F17D086EC0" , evex().vmovd(xmm0, eax));
+ TEST_INSTRUCTION("62F17D087EC0" , evex().vmovd(eax, xmm0));
+ TEST_INSTRUCTION("C5F5FDC7" , vpaddw(ymm0, ymm1, ymm7));
+ TEST_INSTRUCTION("C4E37141C200" , vdppd(xmm0, xmm1, xmm2, 0));
+ TEST_INSTRUCTION("62F1F5D95800" , k(k1).z().vaddpd(zmm0, zmm1, ptr(eax)._1to8()));
+ TEST_INSTRUCTION("C5F058C2" , vaddps(xmm0, xmm1, xmm2));
+ TEST_INSTRUCTION("62F1748858C2" , z().vaddps(xmm0, xmm1, xmm2));
+ TEST_INSTRUCTION("62F1748958C2" , k(k1).z().vaddps(xmm0, xmm1, xmm2));
+ TEST_INSTRUCTION("62F16C4FC25498040F" , k(k7).vcmpps(k2, zmm2, zmmword_ptr(eax, ebx, 2, 256), 15));
+ TEST_INSTRUCTION("62F16C5FC25498400F" , k(k7).vcmpps(k2, zmm2, dword_ptr(eax, ebx, 2, 256)._1to16(), 15));
+ TEST_INSTRUCTION("C5FA2DC1" , vcvtss2si(eax, xmm1));
+ TEST_INSTRUCTION("C5FB2DC1" , vcvtsd2si(eax, xmm1));
+ TEST_INSTRUCTION("C5F22AC2" , vcvtsi2ss(xmm0, xmm1, edx));
+ TEST_INSTRUCTION("C5F32AC2" , vcvtsi2sd(xmm0, xmm1, edx));
+ TEST_INSTRUCTION("C5FBE63B" , vcvtpd2dq(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5FFE63B" , vcvtpd2dq(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5F95A3B" , vcvtpd2ps(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5FD5A3B" , vcvtpd2ps(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5F95AC1" , vcvtpd2ps(xmm0, xmm1));
+ TEST_INSTRUCTION("C5F95A03" , vcvtpd2ps(xmm0, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5FD5AC1" , vcvtpd2ps(xmm0, ymm1));
+ TEST_INSTRUCTION("C5FD5A03" , vcvtpd2ps(xmm0, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FD485AC1" , vcvtpd2ps(ymm0, zmm1));
+ TEST_INSTRUCTION("62F1FD485A03" , vcvtpd2ps(ymm0, zmmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC08793B" , vcvtpd2udq(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC28793B" , vcvtpd2udq(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC085B3B" , vcvtqq2ps(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC285B3B" , vcvtqq2ps(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5F9E63B" , vcvttpd2dq(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("C5FDE63B" , vcvttpd2dq(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC08783B" , vcvttpd2udq(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FC28783B" , vcvttpd2udq(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FF087A3B" , vcvtuqq2ps(xmm7, xmmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F1FF287A3B" , vcvtuqq2ps(xmm7, ymmword_ptr(ebx)));
+ TEST_INSTRUCTION("62F3FD08663F01" , vfpclasspd(k7, xmmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("62F3FD28663F01" , vfpclasspd(k7, ymmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("62F3FD48663F01" , vfpclasspd(k7, zmmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("62F37D08663F01" , vfpclassps(k7, xmmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("62F37D28663F01" , vfpclassps(k7, ymmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("62F37D48663F01" , vfpclassps(k7, zmmword_ptr(edi), 0x01));
+ TEST_INSTRUCTION("C4E2F990040500000000" , vpgatherdq(xmm0, ptr(0, xmm0), xmm0));
+ TEST_INSTRUCTION("C4E2FD91040500000000" , vpgatherqq(ymm0, ptr(0, ymm0), ymm0));
+ TEST_INSTRUCTION("C4E2E9920C00" , vgatherdpd(xmm1, ptr(eax, xmm0), xmm2));
+ TEST_INSTRUCTION("62F36D083ECB00" , vpcmpub(k1, xmm2, xmm3, 0x0));
+ TEST_INSTRUCTION("62F26D48CF4C1101" , vgf2p8mulb(zmm1, zmm2, zmmword_ptr(ecx, edx, 0, 64)));
+ TEST_INSTRUCTION("62F3ED48CE4C11010F" , vgf2p8affineqb(zmm1, zmm2, zmmword_ptr(ecx, edx, 0, 64), 15));
+ TEST_INSTRUCTION("62F3ED48CF4C11010F" , vgf2p8affineinvqb(zmm1, zmm2, zmmword_ptr(ecx, edx, 0, 64), 15));
+ TEST_INSTRUCTION("62F2674868246D00F8FFFF" , vp2intersectd(k4, k5, zmm3, zmmword_ptr(0xFFFFF800, ebp, 1)));
+
+ // AVX512_VNNI vs AVX_VNNI.
+ TEST_INSTRUCTION("62F2552850F4" , vpdpbusd(ymm6, ymm5, ymm4));
+ TEST_INSTRUCTION("C4E25550F4" , vex().vpdpbusd(ymm6, ymm5, ymm4));
+
+ tester.printSummary();
+ return tester.didPass();
+}
+
+bool testX64Assembler(const TestSettings& settings) noexcept {
+ using namespace x86;
+
+ AssemblerTester<Assembler> tester(Environment::kArchX64, settings);
+ tester.printHeader("X64");
+
+ // Base Instructions.
+ TEST_INSTRUCTION("B800000000" , mov(eax, 0));
+ TEST_INSTRUCTION("BB00000000" , mov(ebx, 0));
+ TEST_INSTRUCTION("48C7C300000000" , mov(rbx, 0));
+ TEST_INSTRUCTION("48BB8877665544332211" , mov(rbx, 0x001122334455667788));
+ TEST_INSTRUCTION("48BB0000000000000000" , long_().mov(rbx, 0));
+ TEST_INSTRUCTION("8AE0" , mov(ah, al));
+ TEST_INSTRUCTION("8AF0" , mov(dh, al));
+ TEST_INSTRUCTION("B8E8030000" , mov(eax, 1000));
+ TEST_INSTRUCTION("0F20C0" , mov(rax, cr0));
+ TEST_INSTRUCTION("440F20C0" , mov(rax, cr8));
+ TEST_INSTRUCTION("488B0500000000" , mov(rax, ptr(rip)));
+ TEST_INSTRUCTION("4A8B0460" , mov(rax, ptr(rax, r12, 1)));
+ TEST_INSTRUCTION("4A8B0468" , mov(rax, ptr(rax, r13, 1)));
+ TEST_INSTRUCTION("4A8B846000010000" , mov(rax, ptr(rax, r12, 1, 256)));
+ TEST_INSTRUCTION("89042544332211" , mov(ptr_abs(0x11223344), eax));
+ TEST_INSTRUCTION("891C2544332211" , mov(ptr_abs(0x11223344), ebx));
+ TEST_INSTRUCTION("A38877665544332211" , mov(ptr_abs(0x1122334455667788), eax));
+ TEST_INSTRUCTION("A34433221100000000" , movabs(ptr(0x0000000011223344), eax));
+ TEST_INSTRUCTION("A38877665544332211" , movabs(ptr(0x1122334455667788), eax));
+ TEST_INSTRUCTION("48A1EFCDAB8967452301" , movabs(rax, ptr(0x123456789ABCDEF)));
+ TEST_INSTRUCTION("0FBE07" , movsx(eax, byte_ptr(rdi)));
+ TEST_INSTRUCTION("480FBE07" , movsx(rax, byte_ptr(rdi)));
+ TEST_INSTRUCTION("0FBF07" , movsx(eax, word_ptr(rdi)));
+ TEST_INSTRUCTION("480FBF07" , movsx(rax, word_ptr(rdi)));
+ TEST_INSTRUCTION("486307" , movsxd(rax, ptr(rdi)));
+ TEST_INSTRUCTION("486307" , movsxd(rax, dword_ptr(rdi)));
+ TEST_INSTRUCTION("6663C3" , movsxd(ax, bx));
+ TEST_INSTRUCTION("63C3" , movsxd(eax, ebx));
+ TEST_INSTRUCTION("4863C3" , movsxd(rax, ebx));
+ TEST_INSTRUCTION("0FB6C6" , movzx(eax, dh));
+ TEST_INSTRUCTION("0FB607" , movzx(eax, byte_ptr(rdi)));
+ TEST_INSTRUCTION("480FB607" , movzx(rax, byte_ptr(rdi)));
+ TEST_INSTRUCTION("440FB6FA" , movzx(r15d, dl));
+ TEST_INSTRUCTION("440FB6FD" , movzx(r15d, bpl));
+ TEST_INSTRUCTION("0FB707" , movzx(eax, word_ptr(rdi)));
+ TEST_INSTRUCTION("480FB707" , movzx(rax, word_ptr(rdi)));
+ TEST_INSTRUCTION("03D9" , add(ebx, ecx));
+ TEST_INSTRUCTION("83C001" , add(eax, 1));
+ TEST_INSTRUCTION("0504030201" , add(eax, 0x01020304));
+ TEST_INSTRUCTION("66050201" , add(ax, 0x0102));
+ TEST_INSTRUCTION("6603849004030201" , add(ax, ptr(rax, rdx, 2, 0x01020304)));
+ TEST_INSTRUCTION("F00118" , lock().add(ptr(rax), ebx));
+ TEST_INSTRUCTION("F0480FC138" , lock().xadd(ptr(rax), rdi));
+ TEST_INSTRUCTION("660FC8" , bswap(ax));
+ TEST_INSTRUCTION("0FC8" , bswap(eax));
+ TEST_INSTRUCTION("480FC8" , bswap(rax));
+ TEST_INSTRUCTION("660FBA2001" , bt(word_ptr(rax), 1));
+ TEST_INSTRUCTION("0FBA2001" , bt(dword_ptr(rax), 1));
+ TEST_INSTRUCTION("480FBA2001" , bt(qword_ptr(rax), 1));
+ TEST_INSTRUCTION("FE00" , inc(byte_ptr(rax)));
+ TEST_INSTRUCTION("66FF00" , inc(word_ptr(rax)));
+ TEST_INSTRUCTION("FF00" , inc(dword_ptr(rax)));
+ TEST_INSTRUCTION("48FF00" , inc(qword_ptr(rax)));
+ TEST_INSTRUCTION("411351FD" , adc(edx, dword_ptr(r9, -3)));
+ TEST_INSTRUCTION("F6D8" , neg(al));
+ TEST_INSTRUCTION("F6DC" , neg(ah));
+ TEST_INSTRUCTION("40F6DE" , neg(sil));
+ TEST_INSTRUCTION("F7D8" , neg(eax));
+ TEST_INSTRUCTION("F7D0" , not_(eax));
+ TEST_INSTRUCTION("0F95C3" , setnz(bl));
+ TEST_INSTRUCTION("0F94C7" , setz(bh));
+ TEST_INSTRUCTION("400F94C0" , rex().setz(al));
+ TEST_INSTRUCTION("410F94C7" , setz(r15b));
+ TEST_INSTRUCTION("F600FF" , test(byte_ptr(rax), 0xFF));
+ TEST_INSTRUCTION("66F700FF00" , test(word_ptr(rax), 0xFF));
+ TEST_INSTRUCTION("F700FF000000" , test(dword_ptr(rax), 0xFF));
+ TEST_INSTRUCTION("48F700FF000000" , test(qword_ptr(rax), 0xFF));
+ TEST_INSTRUCTION("A836" , test(al, 0x36));
+ TEST_INSTRUCTION("F6C436" , test(ah, 0x36));
+ TEST_INSTRUCTION("50" , push(rax));
+ TEST_INSTRUCTION("51" , push(rcx));
+ TEST_INSTRUCTION("52" , push(rdx));
+ TEST_INSTRUCTION("53" , push(rbx));
+ TEST_INSTRUCTION("54" , push(rsp));
+ TEST_INSTRUCTION("55" , push(rbp));
+ TEST_INSTRUCTION("56" , push(rsi));
+ TEST_INSTRUCTION("57" , push(rdi));
+ TEST_INSTRUCTION("4150" , push(r8));
+ TEST_INSTRUCTION("4151" , push(r9));
+ TEST_INSTRUCTION("4152" , push(r10));
+ TEST_INSTRUCTION("4153" , push(r11));
+ TEST_INSTRUCTION("4154" , push(r12));
+ TEST_INSTRUCTION("4155" , push(r13));
+ TEST_INSTRUCTION("4156" , push(r14));
+ TEST_INSTRUCTION("4157" , push(r15));
+ TEST_INSTRUCTION("0FA0" , push(fs));
+ TEST_INSTRUCTION("0FA8" , push(gs));
+ TEST_INSTRUCTION("400FA0" , rex().push(fs));
+ TEST_INSTRUCTION("400FA8" , rex().push(gs));
+ TEST_INSTRUCTION("C8010002" , enter(1, 2));
+ TEST_INSTRUCTION("40C8010002" , rex().enter(1, 2));
+ TEST_INSTRUCTION("C9" , leave());
+ TEST_INSTRUCTION("FF10" , call(ptr(rax)));
+ TEST_INSTRUCTION("FF10" , call(qword_ptr(rax)));
+ TEST_INSTRUCTION("660FB401" , lfs(ax, ptr(rcx)));
+ TEST_INSTRUCTION("0FB401" , lfs(eax, ptr(rcx)));
+ TEST_INSTRUCTION("480FB401" , lfs(rax, ptr(rcx)));
+ TEST_INSTRUCTION("660FB501" , lgs(ax, ptr(rcx)));
+ TEST_INSTRUCTION("0FB501" , lgs(eax, ptr(rcx)));
+ TEST_INSTRUCTION("480FB501" , lgs(rax, ptr(rcx)));
+ TEST_INSTRUCTION("660FB201" , lss(ax, ptr(rcx)));
+ TEST_INSTRUCTION("0FB201" , lss(eax, ptr(rcx)));
+ TEST_INSTRUCTION("480FB201" , lss(rax, ptr(rcx)));
+ TEST_INSTRUCTION("40863424" , xchg(ptr(rsp), sil));
+ TEST_INSTRUCTION("40863C24" , xchg(ptr(rsp), dil));
+
+ // NOP.
+ TEST_INSTRUCTION("90" , nop());
+ TEST_INSTRUCTION("660F1F0400" , nop(word_ptr(rax, rax)));
+ TEST_INSTRUCTION("660F1F0400" , nop(word_ptr(rax, rax), ax));
+ TEST_INSTRUCTION("660F1F1C00" , nop(word_ptr(rax, rax), bx));
+ TEST_INSTRUCTION("0F1F0400" , nop(dword_ptr(rax, rax)));
+ TEST_INSTRUCTION("0F1F0400" , nop(dword_ptr(rax, rax), eax));
+ TEST_INSTRUCTION("0F1F1C00" , nop(dword_ptr(rax, rax), ebx));
+ TEST_INSTRUCTION("480F1F0400" , nop(qword_ptr(rax, rax)));
+ TEST_INSTRUCTION("480F1F0400" , nop(qword_ptr(rax, rax), rax));
+ TEST_INSTRUCTION("480F1F1C00" , nop(qword_ptr(rax, rax), rbx));
+
+ // LEA.
+ TEST_INSTRUCTION("8D042500000000" , lea(eax, ptr(0)));
+ TEST_INSTRUCTION("488D042500000000" , lea(rax, ptr(0)));
+ TEST_INSTRUCTION("488D0433" , lea(rax, ptr(rbx, rsi)));
+ TEST_INSTRUCTION("488D043B" , lea(rax, ptr(rbx, rdi)));
+ TEST_INSTRUCTION("488D840000400000" , lea(rax, ptr(rax, rax, 0, 0x4000)));
+
+ // CRC32.
+ TEST_INSTRUCTION("F20F38F0C7" , crc32(eax, bh));
+ TEST_INSTRUCTION("66F20F38F1C3" , crc32(eax, bx));
+ TEST_INSTRUCTION("F20F38F1C1" , crc32(eax, ecx));
+ TEST_INSTRUCTION("F20F38F006" , crc32(eax, byte_ptr(rsi)));
+ TEST_INSTRUCTION("66F20F38F106" , crc32(eax, word_ptr(rsi)));
+ TEST_INSTRUCTION("F20F38F106" , crc32(eax, dword_ptr(rsi)));
+ TEST_INSTRUCTION("F2480F38F0C3" , crc32(rax, bl));
+ TEST_INSTRUCTION("F2480F38F1C1" , crc32(rax, rcx));
+ TEST_INSTRUCTION("F2480F38F006" , crc32(rax, byte_ptr(rsi)));
+ TEST_INSTRUCTION("F2480F38F106" , crc32(rax, qword_ptr(rsi)));
+
+ // XACQUIRE|XRELEASE|RTM.
+ TEST_INSTRUCTION("C6F811" , xabort(0x11));
+ TEST_INSTRUCTION("F2F0480108" , xacquire().lock().add(qword_ptr(rax), rcx));
+ TEST_INSTRUCTION("F3F0480108" , xrelease().lock().add(qword_ptr(rax), rcx));
+
+ // BND.
+ TEST_INSTRUCTION("660F1ACA" , bndmov(bnd1, bnd2));
+ TEST_INSTRUCTION("F20F1ACF" , bndcu(bnd1, rdi));
+ TEST_INSTRUCTION("0F1A0408" , bndldx(bnd0, ptr(rax, rcx)));
+ TEST_INSTRUCTION("0F1B0C08" , bndstx(ptr(rax, rcx), bnd1));
+
+ // BMI+.
+ TEST_INSTRUCTION("66F30FB8C2" , popcnt(ax, dx));
+ TEST_INSTRUCTION("66F3450FB8C1" , popcnt(r8w, r9w));
+ TEST_INSTRUCTION("F30FB8C2" , popcnt(eax, edx));
+ TEST_INSTRUCTION("F3480FB8C2" , popcnt(rax, rdx));
+ TEST_INSTRUCTION("66F30FBDC2" , lzcnt(ax, dx));
+ TEST_INSTRUCTION("66F3450FBDC7" , lzcnt(r8w, r15w));
+ TEST_INSTRUCTION("F30FBDC2" , lzcnt(eax, edx));
+ TEST_INSTRUCTION("F3490FBDC2" , lzcnt(rax, r10));
+ TEST_INSTRUCTION("66F30FBCC2" , tzcnt(ax, dx));
+ TEST_INSTRUCTION("66F3450FBCC7" , tzcnt(r8w, r15w));
+ TEST_INSTRUCTION("F30FBCC2" , tzcnt(eax, edx));
+ TEST_INSTRUCTION("F34D0FBCFA" , tzcnt(r15, r10));
+
+ // FPU.
+ TEST_INSTRUCTION("9B" , fwait());
+ TEST_INSTRUCTION("D800" , fadd(dword_ptr(rax)));
+ TEST_INSTRUCTION("DC00" , fadd(qword_ptr(rax)));
+
+ // MMX & SSE.
+ TEST_INSTRUCTION("0F6FC1" , movq(mm0, mm1));
+ TEST_INSTRUCTION("0F6E00" , movd(mm0, ptr(rax)));
+ TEST_INSTRUCTION("0F6F0418" , movq(mm0, ptr(rax, rbx)));
+ TEST_INSTRUCTION("0F7E38" , movd(ptr(rax), mm7));
+ TEST_INSTRUCTION("0F7F0418" , movq(ptr(rax, rbx), mm0));
+ TEST_INSTRUCTION("F30F7EC1" , movq(xmm0, xmm1));
+ TEST_INSTRUCTION("660F6E0418" , movd(xmm0, ptr(rax, rbx)));
+ TEST_INSTRUCTION("F30F7E0418" , movq(xmm0, ptr(rax, rbx)));
+ TEST_INSTRUCTION("660F7E0C18" , movd(ptr(rax, rbx), xmm1));
+ TEST_INSTRUCTION("660FD60C18" , movq(ptr(rax, rbx), xmm1));
+ TEST_INSTRUCTION("0F280498" , movaps(xmm0, ptr(rax, rbx, 2)));
+ TEST_INSTRUCTION("660F280498" , movapd(xmm0, ptr(rax, rbx, 2)));
+ TEST_INSTRUCTION("660F6F0498" , movdqa(xmm0, ptr(rax, rbx, 2)));
+ TEST_INSTRUCTION("0F290C98" , movaps(ptr(rax, rbx, 2), xmm1));
+ TEST_INSTRUCTION("660F290C98" , movapd(ptr(rax, rbx, 2), xmm1));
+ TEST_INSTRUCTION("660F7F0C98" , movdqa(ptr(rax, rbx, 2), xmm1));
+ TEST_INSTRUCTION("F30F2DC1" , cvtss2si(eax, xmm1));
+ TEST_INSTRUCTION("F3480F2DC1" , cvtss2si(rax, xmm1));
+ TEST_INSTRUCTION("F20F2DC1" , cvtsd2si(eax, xmm1));
+ TEST_INSTRUCTION("F2480F2DC1" , cvtsd2si(rax, xmm1));
+ TEST_INSTRUCTION("F30F2AC2" , cvtsi2ss(xmm0, edx));
+ TEST_INSTRUCTION("F3480F2AC2" , cvtsi2ss(xmm0, rdx));
+ TEST_INSTRUCTION("F20F2AC2" , cvtsi2sd(xmm0, edx));
+ TEST_INSTRUCTION("F2480F2AC2" , cvtsi2sd(xmm0, rdx));
+ TEST_INSTRUCTION("66450F3A41D300" , dppd(xmm10, xmm11, 0));
+ TEST_INSTRUCTION("0FDBC1" , pand(mm0, mm1));
+ TEST_INSTRUCTION("660FDBC1" , pand(xmm0, xmm1));
+ TEST_INSTRUCTION("660FFDC1" , paddw(xmm0, xmm1));
+
+ // AVX & AVX512.
+ TEST_INSTRUCTION("C5F96E5A10" , vmovd(xmm3, dword_ptr(rdx, 0x10)));
+ TEST_INSTRUCTION("C5FA7E5A10" , vmovq(xmm3, qword_ptr(rdx, 0x10)));
+ TEST_INSTRUCTION("C5F97E5A10" , vmovd(dword_ptr(rdx, 0x10), xmm3));
+ TEST_INSTRUCTION("C5F9D65A10" , vmovq(qword_ptr(rdx, 0x10), xmm3));
+ TEST_INSTRUCTION("C5F96EEB" , vmovd(xmm5, ebx));
+ TEST_INSTRUCTION("C4E1F96EEB" , vmovq(xmm5, rbx));
+ TEST_INSTRUCTION("62617D086EFB" , vmovd(xmm31, ebx));
+ TEST_INSTRUCTION("6261FD086EFB" , vmovq(xmm31, rbx));
+ TEST_INSTRUCTION("C5F97EEB" , vmovd(ebx, xmm5));
+ TEST_INSTRUCTION("C4E1F97EEB" , vmovq(rbx, xmm5));
+ TEST_INSTRUCTION("62617D087EFB" , vmovd(ebx, xmm31));
+ TEST_INSTRUCTION("6261FD087EFB" , vmovq(rbx, xmm31));
+ TEST_INSTRUCTION("C5FA7EC1" , vmovq(xmm0, xmm1));
+ TEST_INSTRUCTION("62F17D086EC0" , evex().vmovd(xmm0, eax));
+ TEST_INSTRUCTION("62F1FD086EC0" , evex().vmovq(xmm0, rax));
+ TEST_INSTRUCTION("62F17D087EC0" , evex().vmovd(eax, xmm0));
+ TEST_INSTRUCTION("62F1FD087EC0" , evex().vmovq(rax, xmm0));
+ TEST_INSTRUCTION("C44135FDC7" , vpaddw(ymm8, ymm9, ymm15));
+ TEST_INSTRUCTION("C4432141D400" , vdppd(xmm10, xmm11, xmm12, 0));
+ TEST_INSTRUCTION("6271B5D95808" , k(k1).z().vaddpd(zmm9, zmm9, ptr(rax)._1to8()));
+ TEST_INSTRUCTION("C5F058C2" , vaddps(xmm0, xmm1, xmm2));
+ TEST_INSTRUCTION("62F1748858C2" , z().vaddps(xmm0, xmm1, xmm2));
+ TEST_INSTRUCTION("C5FA2DC1" , vcvtss2si(eax, xmm1));
+ TEST_INSTRUCTION("C4E1FA2DC1" , vcvtss2si(rax, xmm1));
+ TEST_INSTRUCTION("C5FB2DC1" , vcvtsd2si(eax, xmm1));
+ TEST_INSTRUCTION("C4E1FB2DC1" , vcvtsd2si(rax, xmm1));
+ TEST_INSTRUCTION("C5F22AC2" , vcvtsi2ss(xmm0, xmm1, edx));
+ TEST_INSTRUCTION("C4E1F22AC2" , vcvtsi2ss(xmm0, xmm1, rdx));
+ TEST_INSTRUCTION("C5F32AC2" , vcvtsi2sd(xmm0, xmm1, edx));
+ TEST_INSTRUCTION("C4E1F32AC2" , vcvtsi2sd(xmm0, xmm1, rdx));
+ TEST_INSTRUCTION("C57BE63B" , vcvtpd2dq(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("C57FE63B" , vcvtpd2dq(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("C5795A3B" , vcvtpd2ps(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("C57D5A3B" , vcvtpd2ps(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC08793B" , vcvtpd2udq(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC28793B" , vcvtpd2udq(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC085B3B" , vcvtqq2ps(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC285B3B" , vcvtqq2ps(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("C5F95AC1" , vcvtpd2ps(xmm0, xmm1));
+ TEST_INSTRUCTION("C5F95A03" , vcvtpd2ps(xmm0, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("C5FD5AC1" , vcvtpd2ps(xmm0, ymm1));
+ TEST_INSTRUCTION("C5FD5A03" , vcvtpd2ps(xmm0, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("62F1FD485AC1" , vcvtpd2ps(ymm0, zmm1));
+ TEST_INSTRUCTION("62F1FD485A03" , vcvtpd2ps(ymm0, zmmword_ptr(rbx)));
+ TEST_INSTRUCTION("C579E63B" , vcvttpd2dq(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("C57DE63B" , vcvttpd2dq(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC08783B" , vcvttpd2udq(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FC28783B" , vcvttpd2udq(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FF087A3B" , vcvtuqq2ps(xmm15, xmmword_ptr(rbx)));
+ TEST_INSTRUCTION("6271FF287A3B" , vcvtuqq2ps(xmm15, ymmword_ptr(rbx)));
+ TEST_INSTRUCTION("62F3FD08663F01" , vfpclasspd(k7, xmmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("62F3FD28663701" , vfpclasspd(k6, ymmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("62F3FD48662F01" , vfpclasspd(k5, zmmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("62F37D08662701" , vfpclassps(k4, xmmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("62F37D28661F01" , vfpclassps(k3, ymmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("62F37D48661701" , vfpclassps(k2, zmmword_ptr(rdi), 0x01));
+ TEST_INSTRUCTION("6201951058F4" , rn_sae().vaddpd(zmm30, zmm29, zmm28));
+ TEST_INSTRUCTION("6201953058F4" , rd_sae().vaddpd(zmm30, zmm29, zmm28));
+ TEST_INSTRUCTION("6201955058F4" , ru_sae().vaddpd(zmm30, zmm29, zmm28));
+ TEST_INSTRUCTION("6201957058F4" , rz_sae().vaddpd(zmm30, zmm29, zmm28));
+ TEST_INSTRUCTION("62F16C4FC25498040F" , k(k7).vcmpps(k2, zmm2, zmmword_ptr(rax, rbx, 2, 256), 15));
+ TEST_INSTRUCTION("62F16C1FC25498400F" , k(k7).vcmpps(k2, xmm2, dword_ptr(rax, rbx, 2, 256)._1to4(), 15));
+ TEST_INSTRUCTION("62F16C3FC25498400F" , k(k7).vcmpps(k2, ymm2, dword_ptr(rax, rbx, 2, 256)._1to8(), 15));
+ TEST_INSTRUCTION("62F16C5FC25498400F" , k(k7).vcmpps(k2, zmm2, dword_ptr(rax, rbx, 2, 256)._1to16(), 15));
+ TEST_INSTRUCTION("62F1FD58C2C100" , sae().vcmppd(k0, zmm0, zmm1, 0x00));
+ TEST_INSTRUCTION("6201FD182EF5" , sae().vucomisd(xmm30, xmm29));
+ TEST_INSTRUCTION("62017C182EF5" , sae().vucomiss(xmm30, xmm29));
+ TEST_INSTRUCTION("C4E2FD91040500000000" , vpgatherqq(ymm0, ptr(0, ymm0), ymm0));
+ TEST_INSTRUCTION("C4E2E9920C00" , vgatherdpd(xmm1, ptr(rax, xmm0), xmm2));
+ TEST_INSTRUCTION("C4E26990440D00" , vpgatherdd(xmm0, ptr(rbp, xmm1), xmm2));
+ TEST_INSTRUCTION("C4C26990040C" , vpgatherdd(xmm0, ptr(r12, xmm1), xmm2));
+ TEST_INSTRUCTION("C4C26990440D00" , vpgatherdd(xmm0, ptr(r13, xmm1), xmm2));
+ TEST_INSTRUCTION("62F36D083ECB00" , vpcmpub(k1, xmm2, xmm3, 0x0));
+ TEST_INSTRUCTION("C5E9FE4C1140" , vpaddd(xmm1, xmm2, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("C5EDFE4C1140" , vpaddd(ymm1, ymm2, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62F16D48FE4C1101" , vpaddd(zmm1, zmm2, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62E23D0850441104" , vpdpbusd(xmm16, xmm8, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62E23D2850441102" , vpdpbusd(ymm16, ymm8, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62E23D4850441101" , vpdpbusd(zmm16, zmm8, ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62F26D48CF4C1101" , vgf2p8mulb(zmm1, zmm2, zmmword_ptr(rcx, rdx, 0, 64)));
+ TEST_INSTRUCTION("62F3ED48CE4C11010F" , vgf2p8affineqb(zmm1, zmm2, zmmword_ptr(rcx, rdx, 0, 64), 15));
+ TEST_INSTRUCTION("62F3ED48CF4C11010F" , vgf2p8affineinvqb(zmm1, zmm2, zmmword_ptr(rcx, rdx, 0, 64), 15));
+ TEST_INSTRUCTION("62F27D087AC6" , vpbroadcastb(xmm0, esi));
+ TEST_INSTRUCTION("62F27D287AC6" , vpbroadcastb(ymm0, esi));
+ TEST_INSTRUCTION("62F27D487AC6" , vpbroadcastb(zmm0, esi));
+ TEST_INSTRUCTION("62F2CD088DF8" , vpermw(xmm7, xmm6, xmm0));
+ TEST_INSTRUCTION("C4E3FD01FE01" , vpermpd(ymm7, ymm6, 1));
+ TEST_INSTRUCTION("62F3FD4801FE01" , vpermpd(zmm7, zmm6, 1));
+ TEST_INSTRUCTION("62F2CD2816F8" , vpermpd(ymm7, ymm6, ymm0));
+ TEST_INSTRUCTION("62F2CD4816F8" , vpermpd(zmm7, zmm6, zmm0));
+ TEST_INSTRUCTION("C4E24D16F9" , vpermps(ymm7, ymm6, ymm1));
+ TEST_INSTRUCTION("62F24D4816F9" , vpermps(zmm7, zmm6, zmm1));
+ TEST_INSTRUCTION("6292472068F0" , vp2intersectd(k6, k7, ymm23, ymm24));
+ TEST_INSTRUCTION("62B2472068B4F500000010" , vp2intersectd(k6, k7, ymm23, ptr(rbp, r14, 3, 268435456)));
+ TEST_INSTRUCTION("62F24730683500000000" , vp2intersectd(k6, k7, ymm23, dword_ptr(rip)._1to8()));
+ TEST_INSTRUCTION("62F2472068742DE0" , vp2intersectd(k6, k7, ymm23, ymmword_ptr(rbp, rbp, 0, -1024)));
+ TEST_INSTRUCTION("62F2472068717F" , vp2intersectd(k6, k7, ymm23, ymmword_ptr(rcx, 4064)));
+
+ // AVX512_VNNI vs AVX_VNNI.
+ TEST_INSTRUCTION("62F2552850F4" , vpdpbusd(ymm6, ymm5, ymm4));
+ TEST_INSTRUCTION("C4E25550F4" , vex().vpdpbusd(ymm6, ymm5, ymm4));
+
+ tester.printSummary();
+ return tester.didPass();
+}
+
+#undef TEST_INSTRUCTION
+
+#endif
diff --git a/test/asmjit_test_compiler.cpp b/test/asmjit_test_compiler.cpp
index 45adb70..c13ba18 100644
--- a/test/asmjit_test_compiler.cpp
+++ b/test/asmjit_test_compiler.cpp
@@ -29,6 +29,7 @@
#include <memory>
#include <vector>
+#include <chrono>
#include "cmdline.h"
#include "asmjit_test_compiler.h"
@@ -53,6 +54,27 @@ void compiler_add_a64_tests(TestApp& app);
using namespace asmjit;
+class PerformanceTimer {
+public:
+ typedef std::chrono::high_resolution_clock::time_point TimePoint;
+
+ TimePoint _startTime {};
+ TimePoint _endTime {};
+
+ inline void start() {
+ _startTime = std::chrono::high_resolution_clock::now();
+ }
+
+ inline void stop() {
+ _endTime = std::chrono::high_resolution_clock::now();
+ }
+
+ inline double duration() const {
+ std::chrono::duration<double> elapsed = _endTime - _startTime;
+ return elapsed.count() * 1000;
+ }
+};
+
// ============================================================================
// [TestApp]
// ============================================================================
@@ -79,7 +101,7 @@ int TestApp::handleArgs(int argc, const char* const* argv) {
}
void TestApp::showInfo() {
- printf("AsmJit Compiler Test-Suite v%u.%u.%u [Arch=%s]:\n",
+ printf("AsmJit Compiler Test-Suite v%u.%u.%u (Arch=%s):\n",
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
@@ -109,11 +131,16 @@ int TestApp::run() {
stringLogger.addFlags(kFormatFlags);
#endif
+ double compileTime = 0;
+ double finalizeTime = 0;
+
for (std::unique_ptr<TestCase>& test : _tests) {
JitRuntime runtime;
CodeHolder code;
SimpleErrorHandler errorHandler;
+ PerformanceTimer perfTimer;
+
code.init(runtime.environment());
code.setErrorHandler(&errorHandler);
@@ -141,13 +168,20 @@ int TestApp::run() {
arm::Compiler cc(&code);
#endif
+ perfTimer.start();
test->compile(cc);
+ perfTimer.stop();
+ compileTime += perfTimer.duration();
void* func = nullptr;
Error err = errorHandler._err;
- if (!err)
+ if (!err) {
+ perfTimer.start();
err = cc.finalize();
+ perfTimer.stop();
+ finalizeTime += perfTimer.duration();
+ }
#ifndef ASMJIT_NO_LOGGING
if (_dumpAsm) {
@@ -213,13 +247,17 @@ int TestApp::run() {
}
}
+ printf("\n");
+ printf("Summary:\n");
+ printf(" OutputSize: %zu bytes\n", _outputSize);
+ printf(" CompileTime: %.2f ms\n", compileTime);
+ printf(" FinalizeTime: %.2f ms\n", finalizeTime);
+ printf("\n");
+
if (_nFailed == 0)
- printf("\nSuccess:\n All %u tests passed\n", unsigned(_tests.size()));
+ printf("** SUCCESS: All %u tests passed **\n", unsigned(_tests.size()));
else
- printf("\nFailure:\n %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size()));
-
- printf(" OutputSize=%zu\n", _outputSize);
- printf("\n");
+ printf("** FAILURE: %u of %u tests failed **\n", _nFailed, unsigned(_tests.size()));
return _nFailed == 0 ? 0 : 1;
#endif
diff --git a/test/asmjit_test_x86_asm.cpp b/test/asmjit_test_emitters.cpp
index 5000c1e..6f94851 100644
--- a/test/asmjit_test_x86_asm.cpp
+++ b/test/asmjit_test_emitters.cpp
@@ -132,7 +132,7 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
err = cb.finalize();
if (err) {
- printf("x86::Builder::finalize() failed: %s\n", DebugUtils::errorAsString(err));
+ printf("** FAILURE: x86::Builder::finalize() failed (%s) **\n", DebugUtils::errorAsString(err));
return 1;
}
break;
@@ -147,7 +147,7 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
err = cc.finalize();
if (err) {
- printf("x86::Compiler::finalize() failed: %s\n", DebugUtils::errorAsString(err));
+ printf("** FAILURE: x86::Compiler::finalize() failed (%s) **\n", DebugUtils::errorAsString(err));
return 1;
}
break;
@@ -160,7 +160,7 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
err = rt.add(&fn, &code);
if (err) {
- printf("JitRuntime::add() failed: %s\n", DebugUtils::errorAsString(err));
+ printf("** FAILURE: JitRuntime::add() failed (%s) **\n", DebugUtils::errorAsString(err));
return 1;
}
@@ -178,7 +178,11 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
}
int main() {
- printf("AsmJit X86 Emitter Test\n\n");
+ printf("AsmJit Emitters Test-Suite v%u.%u.%u\n",
+ unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
+ unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
+ unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF));
+ printf("\n");
JitRuntime rt;
unsigned nFailed = 0;
@@ -194,9 +198,9 @@ int main() {
#endif
if (!nFailed)
- printf("Success:\n All tests passed\n");
+ printf("** SUCCESS **\n");
else
- printf("Failure:\n %u %s failed\n", nFailed, nFailed == 1 ? "test" : "tests");
+ printf("** FAILURE - %u %s failed ** \n", nFailed, nFailed == 1 ? "test" : "tests");
return nFailed ? 1 : 0;
}
diff --git a/test/asmjit_test_x86_instinfo.cpp b/test/asmjit_test_instinfo.cpp
index 68d870d..dc53fd7 100644
--- a/test/asmjit_test_x86_instinfo.cpp
+++ b/test/asmjit_test_instinfo.cpp
@@ -44,8 +44,6 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
InstRWInfo rw;
InstAPI::queryRWInfo(arch, inst, operands, opCount, &rw);
- sb.append("Instruction:\n");
- sb.append(" ");
#ifndef ASMJIT_NO_LOGGING
Formatter::formatInstruction(sb, 0, nullptr, arch, inst, operands, opCount);
#else
@@ -53,11 +51,11 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
#endif
sb.append("\n");
- sb.append("Operands:\n");
+ sb.append(" Operands:\n");
for (uint32_t i = 0; i < rw.opCount(); i++) {
const OpRWInfo& op = rw.operand(i);
- sb.appendFormat(" [%u] Op=%c Read=%016llX Write=%016llX Extend=%016llX",
+ sb.appendFormat(" [%u] Op=%c Read=%016llX Write=%016llX Extend=%016llX",
i,
accessLetter(op.isRead(), op.isWrite()),
op.readByteMask(),
@@ -80,7 +78,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
}
if (rw.readFlags() | rw.writeFlags()) {
- sb.append("Flags: \n");
+ sb.append(" Flags: \n");
struct FlagMap {
uint32_t flag;
@@ -103,7 +101,7 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
{ x86::Status::kC3, "C3" }
};
- sb.append(" ");
+ sb.append(" ");
for (uint32_t f = 0; f < 13; f++) {
char c = accessLetter((rw.readFlags() & flagMap[f].flag) != 0,
(rw.writeFlags() & flagMap[f].flag) != 0);
@@ -122,8 +120,8 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
#ifndef ASMJIT_NO_LOGGING
if (!features.empty()) {
- sb.append("Features:\n");
- sb.append(" ");
+ sb.append(" Features:\n");
+ sb.append(" ");
bool first = true;
BaseFeatures::Iterator it(features.iterator());
@@ -142,8 +140,9 @@ static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* opera
}
template<typename... Args>
-static void printInfoSimple(uint32_t arch, uint32_t instId, Args&&... args) {
+static void printInfoSimple(uint32_t arch, uint32_t instId, uint32_t options, Args&&... args) {
BaseInst inst(instId);
+ inst.addOptions(options);
Operand_ opArray[] = { std::forward<Args>(args)... };
printInfo(arch, inst, opArray, sizeof...(args));
}
@@ -162,35 +161,43 @@ static void testX86Arch() {
uint32_t arch = Environment::kArchX64;
printInfoSimple(arch,
- x86::Inst::kIdAdd,
+ x86::Inst::kIdAdd, 0,
x86::eax, x86::ebx);
printInfoSimple(arch,
- x86::Inst::kIdLods,
+ x86::Inst::kIdLods, 0,
x86::eax , dword_ptr(x86::rsi));
printInfoSimple(arch,
- x86::Inst::kIdPshufd,
+ x86::Inst::kIdPshufd, 0,
x86::xmm0, x86::xmm1, imm(0));
printInfoSimple(arch,
- x86::Inst::kIdPextrw,
+ x86::Inst::kIdPextrw, 0,
x86::eax, x86::xmm1, imm(0));
printInfoSimple(arch,
- x86::Inst::kIdPextrw,
+ x86::Inst::kIdPextrw, 0,
x86::ptr(x86::rax), x86::xmm1, imm(0));
printInfoSimple(arch,
- x86::Inst::kIdVaddpd,
+ x86::Inst::kIdVpdpbusd, 0,
+ x86::xmm0, x86::xmm1, x86::xmm2);
+
+ printInfoSimple(arch,
+ x86::Inst::kIdVpdpbusd, x86::Inst::kOptionVex,
+ x86::xmm0, x86::xmm1, x86::xmm2);
+
+ printInfoSimple(arch,
+ x86::Inst::kIdVaddpd, 0,
x86::ymm0, x86::ymm1, x86::ymm2);
printInfoSimple(arch,
- x86::Inst::kIdVaddpd,
+ x86::Inst::kIdVaddpd, 0,
x86::ymm0, x86::ymm30, x86::ymm31);
printInfoSimple(arch,
- x86::Inst::kIdVaddpd,
+ x86::Inst::kIdVaddpd, 0,
x86::zmm0, x86::zmm1, x86::zmm2);
printInfoExtra(arch,
@@ -206,7 +213,11 @@ static void testX86Arch() {
}
int main() {
- printf("AsmJit Instruction Information Test\n\n");
+ printf("AsmJit Instruction Info Test-Suite v%u.%u.%u\n",
+ unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
+ unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
+ unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF));
+ printf("\n");
testX86Arch();
diff --git a/test/asmjit_test_x86_sections.cpp b/test/asmjit_test_x86_sections.cpp
index 599fa57..85d2dda 100644
--- a/test/asmjit_test_x86_sections.cpp
+++ b/test/asmjit_test_x86_sections.cpp
@@ -51,7 +51,7 @@ using namespace asmjit;
static const uint8_t dataArray[] = { 2, 9, 4, 7, 1, 3, 8, 5, 6, 0 };
static void fail(const char* message, Error err) {
- printf("%s: %s\n", message, DebugUtils::errorAsString(err));
+ printf("** FAILURE: %s (%s) **\n", message, DebugUtils::errorAsString(err));
exit(1);
}
@@ -169,11 +169,11 @@ int main() {
fn(3) != dataArray[3] ||
fn(6) != dataArray[6] ||
fn(9) != dataArray[9] ) {
- printf("Failure:\n The generated function returned incorrect result(s)\n");
+ printf("** FAILURE: The generated function returned incorrect result(s) **\n");
return 1;
}
- printf("Success:\n The generated function returned expected results\n");
+ printf("** SUCCESS **\n");
return 0;
}