summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asmjit/test
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2020-06-12 11:55:10 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2020-06-12 11:55:10 +0700
commit19214dd8e6528e056166a37b441568a9a264b086 (patch)
tree7403411d6d536153d1df6d8923f7594ace8b9a4f /3rdparty/asmjit/test
parent7b6dbd7a1442d6a77f3b410966fdc41769e417b5 (diff)
asmjist: sync with upstream (nw)
Diffstat (limited to '3rdparty/asmjit/test')
-rw-r--r--3rdparty/asmjit/test/asmjit_bench_x86.cpp36
-rw-r--r--3rdparty/asmjit/test/asmjit_test_misc.h6
-rw-r--r--3rdparty/asmjit/test/asmjit_test_opcode.cpp40
-rw-r--r--3rdparty/asmjit/test/asmjit_test_opcode.h1
-rw-r--r--3rdparty/asmjit/test/asmjit_test_unit.cpp166
-rw-r--r--3rdparty/asmjit/test/asmjit_test_x86_asm.cpp13
-rw-r--r--3rdparty/asmjit/test/asmjit_test_x86_cc.cpp590
-rw-r--r--3rdparty/asmjit/test/asmjit_test_x86_instinfo.cpp128
-rw-r--r--3rdparty/asmjit/test/asmjit_test_x86_sections.cpp17
9 files changed, 589 insertions, 408 deletions
diff --git a/3rdparty/asmjit/test/asmjit_bench_x86.cpp b/3rdparty/asmjit/test/asmjit_bench_x86.cpp
index 95f792d0c03..40d90088c01 100644
--- a/3rdparty/asmjit/test/asmjit_bench_x86.cpp
+++ b/3rdparty/asmjit/test/asmjit_bench_x86.cpp
@@ -37,7 +37,7 @@ using namespace asmjit;
// [Configuration]
// ============================================================================
-static constexpr uint32_t kNumRepeats = 25;
+static constexpr uint32_t kNumRepeats = 20;
static constexpr uint32_t kNumIterations = 1000;
// ============================================================================
@@ -80,12 +80,12 @@ namespace BenchUtils {
}
template<typename EmitterT, typename FuncT>
- static void bench(CodeHolder& code, uint32_t archId, const char* testName, const FuncT& func) noexcept {
+ static void bench(CodeHolder& code, uint32_t arch, const char* testName, const FuncT& func) noexcept {
EmitterT emitter;
const char* archName =
- archId == ArchInfo::kIdX86 ? "X86" :
- archId == ArchInfo::kIdX64 ? "X64" : "???";
+ arch == Environment::kArchX86 ? "X86" :
+ arch == Environment::kArchX64 ? "X64" : "???";
const char* emitterName =
emitter.isAssembler() ? "Assembler" :
@@ -95,14 +95,13 @@ namespace BenchUtils {
Performance perf;
uint64_t codeSize = 0;
- CodeInfo codeInfo(archId);
- codeInfo.setCdeclCallConv(archId == ArchInfo::kIdX86 ? CallConv::kIdX86CDecl : CallConv::kIdX86SysV64);
+ Environment env(arch);
for (uint32_t r = 0; r < kNumRepeats; r++) {
perf.start();
codeSize = 0;
for (uint32_t i = 0; i < kNumIterations; i++) {
- code.init(codeInfo);
+ code.init(env);
code.attach(&emitter);
func(emitter);
@@ -113,7 +112,7 @@ namespace BenchUtils {
perf.end();
}
- printf("[%s] %-9s %-8s | Time:%6u [ms] | ", archName, emitterName, testName, perf.best);
+ printf("[%s] %-9s %-10s | Time:%6u [ms] | ", archName, emitterName, testName, perf.best);
if (codeSize)
printf("Speed: %7.3f [MB/s]", mbps(perf.best, codeSize));
else
@@ -127,30 +126,35 @@ namespace BenchUtils {
// ============================================================================
#ifdef ASMJIT_BUILD_X86
-static void benchX86(uint32_t archId) noexcept {
+static void benchX86(uint32_t arch) noexcept {
CodeHolder code;
- BenchUtils::bench<x86::Assembler>(code, archId, "[raw]", [](x86::Assembler& a) {
+ BenchUtils::bench<x86::Assembler>(code, arch, "[fast]", [](x86::Assembler& a) {
+ asmtest::generateOpcodes(a.as<x86::Emitter>());
+ });
+
+ BenchUtils::bench<x86::Assembler>(code, arch, "[validate]", [](x86::Assembler& a) {
+ a.addValidationOptions(BaseEmitter::kValidationOptionAssembler);
asmtest::generateOpcodes(a.as<x86::Emitter>());
});
#ifndef ASMJIT_NO_BUILDER
- BenchUtils::bench<x86::Builder>(code, archId, "[raw]", [](x86::Builder& cb) {
+ BenchUtils::bench<x86::Builder>(code, arch, "[no-asm]", [](x86::Builder& cb) {
asmtest::generateOpcodes(cb.as<x86::Emitter>());
});
- BenchUtils::bench<x86::Builder>(code, archId, "[final]", [](x86::Builder& cb) {
+ BenchUtils::bench<x86::Builder>(code, arch, "[asm]", [](x86::Builder& cb) {
asmtest::generateOpcodes(cb.as<x86::Emitter>());
cb.finalize();
});
#endif
#ifndef ASMJIT_NO_COMPILER
- BenchUtils::bench<x86::Compiler>(code, archId, "[raw]", [](x86::Compiler& cc) {
+ BenchUtils::bench<x86::Compiler>(code, arch, "[no-asm]", [](x86::Compiler& cc) {
asmtest::generateAlphaBlend(cc);
});
- BenchUtils::bench<x86::Compiler>(code, archId, "[final]", [](x86::Compiler& cc) {
+ BenchUtils::bench<x86::Compiler>(code, arch, "[asm]", [](x86::Compiler& cc) {
asmtest::generateAlphaBlend(cc);
cc.finalize();
});
@@ -160,8 +164,8 @@ static void benchX86(uint32_t archId) noexcept {
int main() {
#ifdef ASMJIT_BUILD_X86
- benchX86(ArchInfo::kIdX86);
- benchX86(ArchInfo::kIdX64);
+ benchX86(Environment::kArchX86);
+ benchX86(Environment::kArchX64);
#endif
return 0;
diff --git a/3rdparty/asmjit/test/asmjit_test_misc.h b/3rdparty/asmjit/test/asmjit_test_misc.h
index be1757ab1c9..03273272d1b 100644
--- a/3rdparty/asmjit/test/asmjit_test_misc.h
+++ b/3rdparty/asmjit/test/asmjit_test_misc.h
@@ -52,7 +52,7 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
Label L_LargeEnd = cc.newLabel();
Label L_DataPool = cc.newLabel();
- cc.addFunc(FuncSignatureT<void, void*, const void*, size_t>(cc.codeInfo().cdeclCallConv()));
+ cc.addFunc(FuncSignatureT<void, void*, const void*, size_t>(CallConv::kIdHost));
cc.setArg(0, dst);
cc.setArg(1, src);
@@ -177,8 +177,8 @@ static void generateAlphaBlend(asmjit::x86::Compiler& cc) {
// Data.
cc.align(kAlignData, 16);
cc.bind(L_DataPool);
- cc.dxmm(Data128::fromI16(0x0080));
- cc.dxmm(Data128::fromI16(0x0101));
+ cc.embedUInt16(uint16_t(0x0080u), 8);
+ cc.embedUInt16(uint16_t(0x0101u), 8);
}
} // {asmtest}
diff --git a/3rdparty/asmjit/test/asmjit_test_opcode.cpp b/3rdparty/asmjit/test/asmjit_test_opcode.cpp
index 908435beb00..d61a6e4bc29 100644
--- a/3rdparty/asmjit/test/asmjit_test_opcode.cpp
+++ b/3rdparty/asmjit/test/asmjit_test_opcode.cpp
@@ -21,9 +21,11 @@
// misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.
+// ----------------------------------------------------------------------------
// This file is used to test opcodes generated by AsmJit. Output can be
// disassembled in your IDE or by your favorite disassembler. Instructions
// are grouped by category and then sorted alphabetically.
+// ----------------------------------------------------------------------------
#include <asmjit/x86.h>
#include <stdio.h>
@@ -34,21 +36,21 @@
using namespace asmjit;
struct OpcodeDumpInfo {
- uint32_t archId;
+ uint32_t arch;
bool useRex1;
bool useRex2;
};
-static const char* archIdToString(uint32_t archId) {
- switch (archId) {
- case ArchInfo::kIdNone: return "None";
- case ArchInfo::kIdX86 : return "X86";
- case ArchInfo::kIdX64 : return "X64";
- case ArchInfo::kIdA32 : return "A32";
- case ArchInfo::kIdA64 : return "A64";
-
- default:
- return "<unknown>";
+static const char* archToString(uint32_t arch) noexcept {
+ switch (arch & ~Environment::kArchBigEndianMask) {
+ case Environment::kArchX86 : return "X86";
+ case Environment::kArchX64 : return "X64";
+ case Environment::kArchARM : return "ARM";
+ case Environment::kArchThumb : return "Thumb";
+ case Environment::kArchAArch64 : return "AArch64";
+ case Environment::kArchMIPS_LE : return "MIPS";
+ case Environment::kArchMIPS64_LE: return "MIPS64";
+ default: return "Unknown";
}
}
@@ -65,23 +67,23 @@ int main() {
TestErrorHandler eh;
OpcodeDumpInfo infoList[] = {
- { ArchInfo::kIdX86, false, false },
- { ArchInfo::kIdX64, false, false },
- { ArchInfo::kIdX64, false, true },
- { ArchInfo::kIdX64, true , false },
- { ArchInfo::kIdX64, true , true }
+ { Environment::kArchX86, false, false },
+ { Environment::kArchX64, false, false },
+ { Environment::kArchX64, false, true },
+ { Environment::kArchX64, true , false },
+ { Environment::kArchX64, true , true }
};
for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(infoList); i++) {
const OpcodeDumpInfo& info = infoList[i];
printf("Opcodes [ARCH=%s REX1=%s REX2=%s]\n",
- archIdToString(info.archId),
+ archToString(info.arch),
info.useRex1 ? "true" : "false",
info.useRex2 ? "true" : "false");
CodeHolder code;
- code.init(CodeInfo(info.archId));
+ code.init(Environment(info.arch));
code.setErrorHandler(&eh);
#ifndef ASMJIT_NO_LOGGING
@@ -95,7 +97,7 @@ int main() {
// If this is the host architecture the code generated can be executed
// for debugging purposes (the first instruction is ret anyway).
- if (code.archId() == ArchInfo::kIdHost) {
+ if (code.arch() == Environment::kArchHost) {
JitRuntime runtime;
VoidFunc p;
diff --git a/3rdparty/asmjit/test/asmjit_test_opcode.h b/3rdparty/asmjit/test/asmjit_test_opcode.h
index e89db426ffd..6f052f526b8 100644
--- a/3rdparty/asmjit/test/asmjit_test_opcode.h
+++ b/3rdparty/asmjit/test/asmjit_test_opcode.h
@@ -91,7 +91,6 @@ static void generateOpcodes(asmjit::x86::Emitter* e, bool useRex1 = false, bool
Zmm zmmA = useRex1 ? zmm8 : zmm0;
Zmm zmmB = useRex2 ? zmm9 : zmm1;
Zmm zmmC = useRex2 ? zmm10 : zmm2;
- Zmm zmmD = useRex2 ? zmm11 : zmm3;
Mem vx_ptr = ptr(gzB, xmmB);
Mem vy_ptr = ptr(gzB, ymmB);
diff --git a/3rdparty/asmjit/test/asmjit_test_unit.cpp b/3rdparty/asmjit/test/asmjit_test_unit.cpp
index f88018a7ac1..3aac7401e17 100644
--- a/3rdparty/asmjit/test/asmjit_test_unit.cpp
+++ b/3rdparty/asmjit/test/asmjit_test_unit.cpp
@@ -35,25 +35,26 @@ struct DumpCpuFeature {
const char* name;
};
-static const char* hostArch() noexcept {
- switch (ArchInfo::kIdHost) {
- case ArchInfo::kIdX86: return "X86";
- case ArchInfo::kIdX64: return "X64";
- case ArchInfo::kIdA32: return "ARM32";
- case ArchInfo::kIdA64: return "ARM64";
+static const char* archToString(uint32_t arch) noexcept {
+ switch (arch & ~Environment::kArchBigEndianMask) {
+ case Environment::kArchX86 : return "X86";
+ case Environment::kArchX64 : return "X64";
+ case Environment::kArchARM : return "ARM";
+ case Environment::kArchThumb : return "Thumb";
+ case Environment::kArchAArch64 : return "AArch64";
+ case Environment::kArchMIPS_LE : return "MIPS";
+ case Environment::kArchMIPS64_LE: return "MIPS64";
default: return "Unknown";
}
}
-static void dumpFeatures(const CpuInfo& cpu, const DumpCpuFeature* data, size_t count) noexcept {
- for (size_t i = 0; i < count; i++)
- if (cpu.hasFeature(data[i].feature))
- INFO(" %s", data[i].name);
-}
-
static void dumpCpu(void) noexcept {
const CpuInfo& cpu = CpuInfo::host();
+ // --------------------------------------------------------------------------
+ // [CPU Information]
+ // --------------------------------------------------------------------------
+
INFO("Host CPU:");
INFO(" Vendor : %s", cpu.vendor());
INFO(" Brand : %s", cpu.brand());
@@ -68,137 +69,20 @@ static void dumpCpu(void) noexcept {
INFO("");
// --------------------------------------------------------------------------
- // [X86]
+ // [CPU Features]
// --------------------------------------------------------------------------
-#if ASMJIT_ARCH_X86
- static const DumpCpuFeature x86FeaturesList[] = {
- { x86::Features::kNX , "NX" },
- { x86::Features::kMT , "MT" },
- { x86::Features::k3DNOW , "3DNOW" },
- { x86::Features::k3DNOW2 , "3DNOW2" },
- { x86::Features::kADX , "ADX" },
- { x86::Features::kAESNI , "AESNI" },
- { x86::Features::kALTMOVCR8 , "ALTMOVCR8" },
- { x86::Features::kAVX , "AVX" },
- { x86::Features::kAVX2 , "AVX2" },
- { x86::Features::kAVX512_4FMAPS , "AVX512_4FMAPS" },
- { x86::Features::kAVX512_4VNNIW , "AVX512_4VNNIW" },
- { x86::Features::kAVX512_BITALG , "AVX512_BITALG" },
- { x86::Features::kAVX512_BW , "AVX512_BW" },
- { x86::Features::kAVX512_CDI , "AVX512_CDI" },
- { x86::Features::kAVX512_DQ , "AVX512_DQ" },
- { x86::Features::kAVX512_ERI , "AVX512_ERI" },
- { x86::Features::kAVX512_F , "AVX512_F" },
- { x86::Features::kAVX512_IFMA , "AVX512_IFMA" },
- { x86::Features::kAVX512_PFI , "AVX512_PFI" },
- { x86::Features::kAVX512_VBMI , "AVX512_VBMI" },
- { x86::Features::kAVX512_VBMI2 , "AVX512_VBMI2" },
- { x86::Features::kAVX512_VL , "AVX512_VL" },
- { x86::Features::kAVX512_VNNI , "AVX512_VNNI" },
- { x86::Features::kAVX512_VPOPCNTDQ, "AVX512_VPOPCNTDQ" },
- { x86::Features::kBMI , "BMI" },
- { x86::Features::kBMI2 , "BMI2" },
- { x86::Features::kCLFLUSH , "CLFLUSH" },
- { x86::Features::kCLFLUSHOPT , "CLFLUSHOPT" },
- { x86::Features::kCLWB , "CLWB" },
- { x86::Features::kCLZERO , "CLZERO" },
- { x86::Features::kCMOV , "CMOV" },
- { x86::Features::kCMPXCHG16B , "CMPXCHG16B" },
- { x86::Features::kCMPXCHG8B , "CMPXCHG8B" },
- { x86::Features::kERMS , "ERMS" },
- { x86::Features::kF16C , "F16C" },
- { x86::Features::kFMA , "FMA" },
- { x86::Features::kFMA4 , "FMA4" },
- { x86::Features::kFPU , "FPU" },
- { x86::Features::kFSGSBASE , "FSGSBASE" },
- { x86::Features::kFXSR , "FXSR" },
- { x86::Features::kFXSROPT , "FXSROPT" },
- { x86::Features::kGEODE , "GEODE" },
- { x86::Features::kGFNI , "GFNI" },
- { x86::Features::kHLE , "HLE" },
- { x86::Features::kI486 , "I486" },
- { x86::Features::kLAHFSAHF , "LAHFSAHF" },
- { x86::Features::kLWP , "LWP" },
- { x86::Features::kLZCNT , "LZCNT" },
- { x86::Features::kMMX , "MMX" },
- { x86::Features::kMMX2 , "MMX2" },
- { x86::Features::kMONITOR , "MONITOR" },
- { x86::Features::kMONITORX , "MONITORX" },
- { x86::Features::kMOVBE , "MOVBE" },
- { x86::Features::kMPX , "MPX" },
- { x86::Features::kMSR , "MSR" },
- { x86::Features::kMSSE , "MSSE" },
- { x86::Features::kOSXSAVE , "OSXSAVE" },
- { x86::Features::kPCLMULQDQ , "PCLMULQDQ" },
- { x86::Features::kPCOMMIT , "PCOMMIT" },
- { x86::Features::kPOPCNT , "POPCNT" },
- { x86::Features::kPREFETCHW , "PREFETCHW" },
- { x86::Features::kPREFETCHWT1 , "PREFETCHWT1" },
- { x86::Features::kRDRAND , "RDRAND" },
- { x86::Features::kRDSEED , "RDSEED" },
- { x86::Features::kRDTSC , "RDTSC" },
- { x86::Features::kRDTSCP , "RDTSCP" },
- { x86::Features::kRTM , "RTM" },
- { x86::Features::kSHA , "SHA" },
- { x86::Features::kSKINIT , "SKINIT" },
- { x86::Features::kSMAP , "SMAP" },
- { x86::Features::kSMEP , "SMEP" },
- { x86::Features::kSMX , "SMX" },
- { x86::Features::kSSE , "SSE" },
- { x86::Features::kSSE2 , "SSE2" },
- { x86::Features::kSSE3 , "SSE3" },
- { x86::Features::kSSE4_1 , "SSE4.1" },
- { x86::Features::kSSE4_2 , "SSE4.2" },
- { x86::Features::kSSE4A , "SSE4A" },
- { x86::Features::kSSSE3 , "SSSE3" },
- { x86::Features::kSVM , "SVM" },
- { x86::Features::kTBM , "TBM" },
- { x86::Features::kTSX , "TSX" },
- { x86::Features::kVAES , "VAES" },
- { x86::Features::kVMX , "VMX" },
- { x86::Features::kVPCLMULQDQ , "VPCLMULQDQ" },
- { x86::Features::kXOP , "XOP" },
- { x86::Features::kXSAVE , "XSAVE" },
- { x86::Features::kXSAVEC , "XSAVEC" },
- { x86::Features::kXSAVEOPT , "XSAVEOPT" },
- { x86::Features::kXSAVES , "XSAVES" }
+#ifndef ASMJIT_NO_LOGGING
+ INFO("CPU Features:");
+ BaseFeatures::Iterator it(cpu.features().iterator());
+ while (it.hasNext()) {
+ uint32_t featureId = uint32_t(it.next());
+ StringTmp<64> featureString;
+ Formatter::formatFeature(featureString, cpu.arch(), featureId);
+ INFO(" %s\n", featureString.data());
};
-
- INFO("X86 Features:");
- dumpFeatures(cpu, x86FeaturesList, ASMJIT_ARRAY_SIZE(x86FeaturesList));
INFO("");
-#endif
-
- // --------------------------------------------------------------------------
- // [ARM]
- // --------------------------------------------------------------------------
-
-#if ASMJIT_ARCH_ARM
- static const DumpCpuFeature armFeaturesList[] = {
- { arm::Features::kARMv6 , "ARMv6" },
- { arm::Features::kARMv7 , "ARMv7" },
- { arm::Features::kARMv8 , "ARMv8" },
- { arm::Features::kTHUMB , "THUMB" },
- { arm::Features::kTHUMBv2 , "THUMBv2" },
- { arm::Features::kVFP2 , "VFPv2" },
- { arm::Features::kVFP3 , "VFPv3" },
- { arm::Features::kVFP4 , "VFPv4" },
- { arm::Features::kVFP_D32 , "VFP D32" },
- { arm::Features::kNEON , "NEON" },
- { arm::Features::kDSP , "DSP" },
- { arm::Features::kIDIV , "IDIV" },
- { arm::Features::kAES , "AES" },
- { arm::Features::kCRC32 , "CRC32" },
- { arm::Features::kSHA1 , "SHA1" },
- { arm::Features::kSHA256 , "SHA256" },
- { arm::Features::kATOMIC64 , "ATOMIC64" }
- };
-
- INFO("ARM Features:");
- dumpFeatures(cpu, armFeaturesList, ASMJIT_ARRAY_SIZE(armFeaturesList));
- INFO("");
-#endif
+#endif // !ASMJIT_NO_LOGGING
}
// ============================================================================
@@ -281,7 +165,7 @@ static void dumpSizeOf(void) noexcept {
DUMP_TYPE(BaseCompiler);
DUMP_TYPE(FuncNode);
DUMP_TYPE(FuncRetNode);
- DUMP_TYPE(FuncCallNode);
+ DUMP_TYPE(InvokeNode);
INFO("");
#endif
@@ -324,7 +208,7 @@ int main(int argc, const char* argv[]) {
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
- hostArch(),
+ archToString(Environment::kArchHost),
buildType
);
diff --git a/3rdparty/asmjit/test/asmjit_test_x86_asm.cpp b/3rdparty/asmjit/test/asmjit_test_x86_asm.cpp
index a01185d80f9..ba85100dae0 100644
--- a/3rdparty/asmjit/test/asmjit_test_x86_asm.cpp
+++ b/3rdparty/asmjit/test/asmjit_test_x86_asm.cpp
@@ -48,7 +48,7 @@ static void makeRawFunc(x86::Emitter* emitter) noexcept {
// Create and initialize `FuncDetail` and `FuncFrame`.
FuncDetail func;
- func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost));
+ func.init(FuncSignatureT<void, int*, const int*, const int*>(CallConv::kIdHost), emitter->environment());
FuncFrame frame;
frame.init(func);
@@ -101,10 +101,11 @@ static void makeCompiledFunc(x86::Compiler* cc) noexcept {
static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
#ifndef ASMJIT_NO_LOGGING
FileLogger logger(stdout);
+ logger.setIndentation(FormatOptions::kIndentationCode, 2);
#endif
CodeHolder code;
- code.init(rt.codeInfo());
+ code.init(rt.environment());
#ifndef ASMJIT_NO_LOGGING
code.setLogger(&logger);
@@ -173,8 +174,10 @@ static uint32_t testFunc(JitRuntime& rt, uint32_t emitterType) noexcept {
}
int main() {
- unsigned nFailed = 0;
+ printf("AsmJit X86 Emitter Test\n\n");
+
JitRuntime rt;
+ unsigned nFailed = 0;
nFailed += testFunc(rt, BaseEmitter::kTypeAssembler);
@@ -187,9 +190,9 @@ int main() {
#endif
if (!nFailed)
- printf("[PASSED] All tests passed\n");
+ printf("Success:\n All tests passed\n");
else
- printf("[FAILED] %u %s failed\n", nFailed, nFailed == 1 ? "test" : "tests");
+ printf("Failure:\n %u %s failed\n", nFailed, nFailed == 1 ? "test" : "tests");
return nFailed ? 1 : 0;
}
diff --git a/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp b/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp
index a0e50e97097..9e80d871978 100644
--- a/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp
+++ b/3rdparty/asmjit/test/asmjit_test_x86_cc.cpp
@@ -27,6 +27,12 @@
#include <stdlib.h>
#include <string.h>
+#include <memory>
+#include <vector>
+
+// Required for function tests that pass / return XMM registers.
+#include <emmintrin.h>
+
#include "./asmjit_test_misc.h"
#ifdef _MSC_VER
@@ -67,7 +73,7 @@ public:
virtual void handleError(Error err, const char* message, BaseEmitter* origin) {
DebugUtils::unused(origin);
_err = err;
- _message.assignString(message);
+ _message.assign(message);
}
Error _err;
@@ -81,7 +87,7 @@ public:
//! Base test interface for testing `x86::Compiler`.
class X86Test {
public:
- X86Test(const char* name = nullptr) { _name.assignString(name); }
+ X86Test(const char* name = nullptr) { _name.assign(name); }
virtual ~X86Test() {}
inline const char* name() const { return _name.data(); }
@@ -98,9 +104,7 @@ public:
class X86TestApp {
public:
- Zone _zone;
- ZoneAllocator _allocator;
- ZoneVector<X86Test*> _tests;
+ std::vector<std::unique_ptr<X86Test>> _tests;
unsigned _nFailed;
size_t _outputSize;
@@ -109,20 +113,15 @@ public:
bool _dumpAsm;
X86TestApp() noexcept
- : _zone(8096 - Zone::kBlockOverhead),
- _allocator(&_zone),
- _nFailed(0),
+ : _nFailed(0),
_outputSize(0),
_verbose(false),
_dumpAsm(false) {}
- ~X86TestApp() noexcept {
- for (X86Test* test : _tests)
- delete test;
- }
+ ~X86TestApp() noexcept {}
- Error add(X86Test* test) noexcept{
- return _tests.append(&_allocator, test);
+ void add(X86Test* test) noexcept {
+ _tests.push_back(std::unique_ptr<X86Test>(test));
}
template<class T>
@@ -169,12 +168,12 @@ int X86TestApp::run() {
stringLogger.addFlags(kFormatFlags);
#endif
- for (X86Test* test : _tests) {
+ for (std::unique_ptr<X86Test>& test : _tests) {
JitRuntime runtime;
CodeHolder code;
SimpleErrorHandler errorHandler;
- code.init(runtime.codeInfo());
+ code.init(runtime.environment());
code.setErrorHandler(&errorHandler);
#ifndef ASMJIT_NO_LOGGING
@@ -207,7 +206,7 @@ int X86TestApp::run() {
if (!_verbose) printf("\n");
String sb;
- cc.dump(sb, kFormatFlags);
+ Formatter::formatNodeList(sb, kFormatFlags, &cc);
printf("%s", sb.data());
}
#endif
@@ -261,11 +260,12 @@ int X86TestApp::run() {
}
if (_nFailed == 0)
- printf("\n[PASSED] All %u tests passed\n", unsigned(_tests.size()));
+ printf("\nSuccess:\n All %u tests passed\n", unsigned(_tests.size()));
else
- printf("\n[FAILED] %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size()));
+ printf("\nFailure:\n %u %s of %u failed\n", _nFailed, _nFailed == 1 ? "test" : "tests", unsigned(_tests.size()));
printf(" OutputSize=%zu\n", _outputSize);
+ printf("\n");
return _nFailed == 0 ? 0 : 1;
}
@@ -703,8 +703,8 @@ public:
func();
- result.appendString("ret={}");
- expect.appendString("ret={}");
+ result.append("ret={}");
+ expect.append("ret={}");
return true;
}
@@ -750,8 +750,8 @@ public:
func();
- result.appendString("ret={}");
- expect.appendString("ret={}");
+ result.append("ret={}");
+ expect.append("ret={}");
return true;
}
@@ -1051,8 +1051,8 @@ public:
for (i = 0; i < ASMJIT_ARRAY_SIZE(resultBuf); i++) {
if (i != 0) {
- result.appendChar(',');
- expect.appendChar(',');
+ result.append(',');
+ expect.append(',');
}
result.appendFormat("%u", resultBuf[i]);
@@ -1971,6 +1971,59 @@ public:
};
// ============================================================================
+// [X86Test_AllocArgsVec]
+// ============================================================================
+
+class X86Test_AllocArgsVec : public X86Test {
+public:
+ X86Test_AllocArgsVec() : X86Test("AllocArgsVec") {}
+
+ static void add(X86TestApp& app) {
+ // Not supported on Windows.
+#ifndef _WIN32
+ app.add(new X86Test_AllocArgsVec());
+#endif
+ }
+
+ virtual void compile(x86::Compiler& cc) {
+ cc.addFunc(FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(CallConv::kIdHost));
+
+ x86::Xmm a = cc.newXmm("aXmm");
+ x86::Xmm b = cc.newXmm("bXmm");
+
+ cc.setArg(0, a);
+ cc.setArg(1, b);
+
+ cc.paddb(a, b);
+ cc.ret(a);
+
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef __m128i (*Func)(__m128i, __m128i);
+ Func func = ptr_as_func<Func>(_func);
+
+ uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ uint8_t rData[16];
+ uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
+
+ __m128i aVec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(aData));
+ __m128i bVec = _mm_loadu_si128(reinterpret_cast<const __m128i*>(bData));
+
+ __m128i rVec = func(aVec, bVec);
+ _mm_storeu_si128(reinterpret_cast<__m128i*>(rData), rVec);
+
+ result.appendHex(rData, 16);
+ expect.appendHex(eData, 16);
+
+ return result == expect;
+ }
+};
+
+// ============================================================================
// [X86Test_AllocRetFloat1]
// ============================================================================
@@ -2253,21 +2306,21 @@ public:
func(dstBuffer, srcBuffer, kCount);
- result.assignString("buf={");
- expect.assignString("buf={");
+ result.assign("buf={");
+ expect.assign("buf={");
for (i = 0; i < kCount; i++) {
if (i != 0) {
- result.appendString(", ");
- expect.appendString(", ");
+ result.append(", ");
+ expect.append(", ");
}
result.appendFormat("%u", unsigned(dstBuffer[i]));
expect.appendFormat("%u", unsigned(srcBuffer[i]));
}
- result.appendString("}");
- expect.appendString("}");
+ result.append("}");
+ expect.append("}");
return result == expect;
}
@@ -2395,21 +2448,21 @@ public:
func(dstBuffer, srcBuffer, kCount);
- result.assignString("buf={");
- expect.assignString("buf={");
+ result.assign("buf={");
+ expect.assign("buf={");
for (i = 0; i < kCount; i++) {
if (i != 0) {
- result.appendString(", ");
- expect.appendString(", ");
+ result.append(", ");
+ expect.append(", ");
}
result.appendFormat("%08X", unsigned(dstBuffer[i]));
expect.appendFormat("%08X", unsigned(expBuffer[i]));
}
- result.appendString("}");
- expect.appendString("}");
+ result.append("}");
+ expect.append("}");
return result == expect;
}
@@ -2443,11 +2496,12 @@ public:
cc.shl(v2, 1);
// Call a function.
- FuncCallNode* call = cc.call(imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, v2);
- call->setArg(1, v1);
- call->setArg(2, v0);
- call->setRet(0, v0);
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
+ invokeNode->setArg(0, v2);
+ invokeNode->setArg(1, v1);
+ invokeNode->setArg(2, v0);
+ invokeNode->setRet(0, v0);
cc.ret(v0);
cc.endFunc();
@@ -2498,29 +2552,29 @@ public:
Label L_Exit = cc.newLabel();
static const char token[kTokenSize] = "-+:|abcdefghijklmnopqrstuvwxyz|";
- FuncCallNode* call;
+ InvokeNode* invokeNode;
cc.lea(p1, s1);
cc.lea(p2, s2);
// Try to corrupt the stack if wrongly allocated.
- call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p1);
- call->setArg(1, imm(token));
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, p1);
-
- call = cc.call(imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p2);
- call->setArg(1, imm(token));
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, p2);
-
- call = cc.call(imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdHostCDecl));
- call->setArg(0, p1);
- call->setArg(1, p2);
- call->setArg(2, imm(kTokenSize));
- call->setRet(0, ret);
+ cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl));
+ invokeNode->setArg(0, p1);
+ invokeNode->setArg(1, imm(token));
+ invokeNode->setArg(2, imm(kTokenSize));
+ invokeNode->setRet(0, p1);
+
+ cc.invoke(&invokeNode, imm((void*)memcpy), FuncSignatureT<void*, void*, void*, size_t>(CallConv::kIdCDecl));
+ invokeNode->setArg(0, p2);
+ invokeNode->setArg(1, imm(token));
+ invokeNode->setArg(2, imm(kTokenSize));
+ invokeNode->setRet(0, p2);
+
+ cc.invoke(&invokeNode, imm((void*)memcmp), FuncSignatureT<int, void*, void*, size_t>(CallConv::kIdCDecl));
+ invokeNode->setArg(0, p1);
+ invokeNode->setArg(1, p2);
+ invokeNode->setArg(2, imm(kTokenSize));
+ invokeNode->setRet(0, ret);
// This should be 0 on success, however, if both `p1` and `p2` were
// allocated in the same address this check will still pass.
@@ -2573,13 +2627,14 @@ public:
cc.setArg(1, y);
cc.setArg(2, z);
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
- FuncSignatureT<int, int, int, int>(CallConv::kIdHostStdCall));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setArg(2, z);
- call->setRet(0, x);
+ FuncSignatureT<int, int, int, int>(CallConv::kIdStdCall));
+ invokeNode->setArg(0, x);
+ invokeNode->setArg(1, y);
+ invokeNode->setArg(2, z);
+ invokeNode->setRet(0, x);
cc.ret(x);
cc.endFunc();
@@ -2622,18 +2677,15 @@ public:
cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
cc.setArg(0, var);
- FuncCallNode* call;
- call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
- call->setArg(0, var);
- call->setRet(0, var);
+ InvokeNode* invokeNode;
- call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<int, int>(CallConv::kIdHostFastCall));
- call->setArg(0, var);
- call->setRet(0, var);
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall));
+ invokeNode->setArg(0, var);
+ invokeNode->setRet(0, var);
+
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<int, int>(CallConv::kIdFastCall));
+ invokeNode->setArg(0, var);
+ invokeNode->setRet(0, var);
cc.ret(var);
cc.endFunc();
@@ -2659,6 +2711,97 @@ public:
};
// ============================================================================
+// [X86Test_FuncCallSIMD]
+// ============================================================================
+
+class X86Test_FuncCallSIMD : public X86Test {
+public:
+ bool _useVectorCall;
+
+ X86Test_FuncCallSIMD(bool useVectorCall)
+ : X86Test(),
+ _useVectorCall(useVectorCall) {
+ _name.assignFormat("FuncCallSIMD {%s}", _useVectorCall ? "__vectorcall" : "__cdecl");
+ }
+
+ static void add(X86TestApp& app) {
+ app.add(new X86Test_FuncCallSIMD(false));
+#ifdef _MSC_VER
+ app.add(new X86Test_FuncCallSIMD(true));
+#endif
+ }
+
+ virtual void compile(x86::Compiler& cc) {
+ cc.addFunc(FuncSignatureT<void, void*, const void*, const void*>(CallConv::kIdHost));
+
+ x86::Gp resultPtr = cc.newIntPtr("resultPtr");
+ x86::Gp aPtr = cc.newIntPtr("aPtr");
+ x86::Gp bPtr = cc.newIntPtr("bPtr");
+ x86::Gp pFn = cc.newIntPtr("pFn");
+
+ x86::Xmm aXmm = cc.newXmm("aXmm");
+ x86::Xmm bXmm = cc.newXmm("bXmm");
+
+ cc.setArg(0, resultPtr);
+ cc.setArg(1, aPtr);
+ cc.setArg(2, bPtr);
+
+ uint32_t ccId = CallConv::kIdCDecl;
+ Imm pFnImm = imm((void*)calledFunc_cdecl);
+
+#ifdef _MSC_VER
+ if (_useVectorCall) {
+ ccId = CallConv::kIdVectorCall;
+ pFnImm = imm((void*)calledFunc_vcall);
+ }
+#endif
+
+ cc.mov(pFn, pFnImm);
+ cc.movdqu(aXmm, x86::ptr(aPtr));
+ cc.movdqu(bXmm, x86::ptr(bPtr));
+
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, pFn, FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm>(ccId));
+
+ invokeNode->setArg(0, aXmm);
+ invokeNode->setArg(1, bXmm);
+ invokeNode->setRet(0, aXmm);
+
+ cc.movdqu(x86::ptr(resultPtr), aXmm);
+
+ cc.endFunc();
+ }
+
+ virtual bool run(void* _func, String& result, String& expect) {
+ typedef void (*Func)(void*, const void*, const void*);
+ Func func = ptr_as_func<Func>(_func);
+
+ uint8_t aData[16] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+ uint8_t bData[16] = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ uint8_t rData[16];
+ uint8_t eData[16] = { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
+
+ func(rData, aData, bData);
+
+ result.appendHex(rData, 16);
+ expect.appendHex(eData, 16);
+
+ return result == expect;
+ }
+
+ static __m128i calledFunc_cdecl(__m128i a, __m128i b) {
+ return _mm_add_epi8(a, b);
+ }
+
+#ifdef _MSC_VER
+ static __m128i __vectorcall calledFunc_vcall(__m128i a, __m128i b) {
+ return _mm_add_epi8(a, b);
+ }
+#endif
+};
+
+// ============================================================================
// [X86Test_FuncCallLight]
// ============================================================================
@@ -2671,8 +2814,8 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdHostCDecl);
- FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdHostLightCall2);
+ FuncSignatureT<void, const void*, const void*, const void*, const void*, void*> funcSig(CallConv::kIdCDecl);
+ FuncSignatureT<x86::Xmm, x86::Xmm, x86::Xmm> fastSig(CallConv::kIdLightCall2);
FuncNode* func = cc.newFunc(funcSig);
FuncNode* fast = cc.newFunc(fastSig);
@@ -2705,15 +2848,17 @@ public:
x86::Xmm xXmm = cc.newXmm("xXmm");
x86::Xmm yXmm = cc.newXmm("yXmm");
- FuncCallNode* call1 = cc.call(fast->label(), fastSig);
- call1->setArg(0, aXmm);
- call1->setArg(1, bXmm);
- call1->setRet(0, xXmm);
+ InvokeNode* invokeNode;
+
+ cc.invoke(&invokeNode, fast->label(), fastSig);
+ invokeNode->setArg(0, aXmm);
+ invokeNode->setArg(1, bXmm);
+ invokeNode->setRet(0, xXmm);
- FuncCallNode* call2 = cc.call(fast->label(), fastSig);
- call2->setArg(0, cXmm);
- call2->setArg(1, dXmm);
- call2->setRet(0, yXmm);
+ cc.invoke(&invokeNode, fast->label(), fastSig);
+ invokeNode->setArg(0, cXmm);
+ invokeNode->setArg(1, dXmm);
+ invokeNode->setRet(0, yXmm);
cc.pmullw(xXmm, yXmm);
cc.movups(x86::ptr(pOut), xXmm);
@@ -2798,21 +2943,22 @@ public:
cc.mov(vi, 0x18);
cc.mov(vj, 0x1E);
- // Call function.
- FuncCallNode* call = cc.call(
+ // Function call.
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, va);
- call->setArg(1, vb);
- call->setArg(2, vc);
- call->setArg(3, vd);
- call->setArg(4, ve);
- call->setArg(5, vf);
- call->setArg(6, vg);
- call->setArg(7, vh);
- call->setArg(8, vi);
- call->setArg(9, vj);
- call->setRet(0, va);
+ invokeNode->setArg(0, va);
+ invokeNode->setArg(1, vb);
+ invokeNode->setArg(2, vc);
+ invokeNode->setArg(3, vd);
+ invokeNode->setArg(4, ve);
+ invokeNode->setArg(5, vf);
+ invokeNode->setArg(6, vg);
+ invokeNode->setArg(7, vh);
+ invokeNode->setArg(8, vi);
+ invokeNode->setArg(9, vj);
+ invokeNode->setRet(0, va);
cc.ret(va);
cc.endFunc();
@@ -2856,20 +3002,21 @@ public:
cc.mov(a, 3);
// Call function.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, a);
- call->setArg(2, a);
- call->setArg(3, a);
- call->setArg(4, a);
- call->setArg(5, a);
- call->setArg(6, a);
- call->setArg(7, a);
- call->setArg(8, a);
- call->setArg(9, a);
- call->setRet(0, a);
+ invokeNode->setArg(0, a);
+ invokeNode->setArg(1, a);
+ invokeNode->setArg(2, a);
+ invokeNode->setArg(3, a);
+ invokeNode->setArg(4, a);
+ invokeNode->setArg(5, a);
+ invokeNode->setArg(6, a);
+ invokeNode->setArg(7, a);
+ invokeNode->setArg(8, a);
+ invokeNode->setArg(9, a);
+ invokeNode->setRet(0, a);
cc.ret(a);
cc.endFunc();
@@ -2908,21 +3055,22 @@ public:
x86::Gp rv = cc.newInt32("rv");
// Call function.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)X86Test_FuncCallManyArgs::calledFunc),
FuncSignatureT<int, int, int, int, int, int, int, int, int, int, int>(CallConv::kIdHost));
- call->setArg(0, imm(0x03));
- call->setArg(1, imm(0x12));
- call->setArg(2, imm(0xA0));
- call->setArg(3, imm(0x0B));
- call->setArg(4, imm(0x2F));
- call->setArg(5, imm(0x02));
- call->setArg(6, imm(0x0C));
- call->setArg(7, imm(0x12));
- call->setArg(8, imm(0x18));
- call->setArg(9, imm(0x1E));
- call->setRet(0, rv);
+ invokeNode->setArg(0, imm(0x03));
+ invokeNode->setArg(1, imm(0x12));
+ invokeNode->setArg(2, imm(0xA0));
+ invokeNode->setArg(3, imm(0x0B));
+ invokeNode->setArg(4, imm(0x2F));
+ invokeNode->setArg(5, imm(0x02));
+ invokeNode->setArg(6, imm(0x0C));
+ invokeNode->setArg(7, imm(0x12));
+ invokeNode->setArg(8, imm(0x18));
+ invokeNode->setArg(9, imm(0x1E));
+ invokeNode->setRet(0, rv);
cc.ret(rv);
cc.endFunc();
@@ -2974,21 +3122,22 @@ public:
x86::Gp rv = cc.newInt32("rv");
// Call function.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<int, void*, void*, void*, void*, void*, void*, void*, void*, void*, void*>(CallConv::kIdHost));
- call->setArg(0, imm(0x01));
- call->setArg(1, imm(0x02));
- call->setArg(2, imm(0x03));
- call->setArg(3, imm(0x04));
- call->setArg(4, imm(0x05));
- call->setArg(5, imm(0x06));
- call->setArg(6, imm(0x07));
- call->setArg(7, imm(0x08));
- call->setArg(8, imm(0x09));
- call->setArg(9, imm(0x0A));
- call->setRet(0, rv);
+ invokeNode->setArg(0, imm(0x01));
+ invokeNode->setArg(1, imm(0x02));
+ invokeNode->setArg(2, imm(0x03));
+ invokeNode->setArg(3, imm(0x04));
+ invokeNode->setArg(4, imm(0x05));
+ invokeNode->setArg(5, imm(0x06));
+ invokeNode->setArg(6, imm(0x07));
+ invokeNode->setArg(7, imm(0x08));
+ invokeNode->setArg(8, imm(0x09));
+ invokeNode->setArg(9, imm(0x0A));
+ invokeNode->setRet(0, rv);
cc.ret(rv);
cc.endFunc();
@@ -3044,15 +3193,16 @@ public:
cc.setArg(3, arg4);
// Call function.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<int, int&, int&, int&, int&>(CallConv::kIdHost));
- call->setArg(0, arg1);
- call->setArg(1, arg2);
- call->setArg(2, arg3);
- call->setArg(3, arg4);
- call->setRet(0, rv);
+ invokeNode->setArg(0, arg1);
+ invokeNode->setArg(1, arg2);
+ invokeNode->setArg(2, arg3);
+ invokeNode->setArg(3, arg4);
+ invokeNode->setRet(0, rv);
cc.ret(rv);
cc.endFunc();
@@ -3101,12 +3251,11 @@ public:
cc.setArg(1, b);
// Call function.
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<float, float, float>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, ret);
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<float, float, float>(CallConv::kIdHost));
+ invokeNode->setArg(0, a);
+ invokeNode->setArg(1, b);
+ invokeNode->setRet(0, ret);
cc.ret(ret);
cc.endFunc();
@@ -3152,12 +3301,11 @@ public:
cc.setArg(0, a);
cc.setArg(1, b);
- FuncCallNode* call = cc.call(
- imm((void*)calledFunc),
- FuncSignatureT<double, double, double>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, ret);
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, imm((void*)calledFunc), FuncSignatureT<double, double, double>(CallConv::kIdHost));
+ invokeNode->setArg(0, a);
+ invokeNode->setArg(1, b);
+ invokeNode->setRet(0, ret);
cc.ret(ret);
cc.endFunc();
@@ -3194,7 +3342,7 @@ public:
x86::Gp y = cc.newInt32("y");
x86::Gp op = cc.newInt32("op");
- FuncCallNode* call;
+ InvokeNode* invokeNode;
x86::Gp result;
cc.addFunc(FuncSignatureT<int, int, int, int>(CallConv::kIdHost));
@@ -3217,19 +3365,19 @@ public:
cc.bind(opAdd);
result = cc.newInt32("result_1");
- call = cc.call((uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setRet(0, result);
+ cc.invoke(&invokeNode, (uint64_t)calledFuncAdd, FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ invokeNode->setArg(0, x);
+ invokeNode->setArg(1, y);
+ invokeNode->setRet(0, result);
cc.ret(result);
cc.bind(opMul);
result = cc.newInt32("result_2");
- call = cc.call((uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, x);
- call->setArg(1, y);
- call->setRet(0, result);
+ cc.invoke(&invokeNode, (uint64_t)calledFuncMul, FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ invokeNode->setArg(0, x);
+ invokeNode->setArg(1, y);
+ invokeNode->setRet(0, result);
cc.ret(result);
cc.endFunc();
@@ -3291,25 +3439,25 @@ public:
x86::Gp ret = cc.newInt32("ret");
x86::Gp ptr = cc.newIntPtr("ptr");
x86::Gp idx = cc.newInt32("idx");
- FuncCallNode* call;
+ InvokeNode* invokeNode;
cc.mov(ptr, buf);
cc.mov(idx, int(i));
- call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
- call->setArg(0, ptr);
- call->setArg(1, idx);
- call->setRet(0, ret);
+ cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall));
+ invokeNode->setArg(0, ptr);
+ invokeNode->setArg(1, idx);
+ invokeNode->setRet(0, ret);
cc.add(acc0, ret);
cc.mov(ptr, buf);
cc.mov(idx, int(i));
- call = cc.call((uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdHostFastCall));
- call->setArg(0, ptr);
- call->setArg(1, idx);
- call->setRet(0, ret);
+ cc.invoke(&invokeNode, (uint64_t)calledFunc, FuncSignatureT<int, int*, int>(CallConv::kIdFastCall));
+ invokeNode->setArg(0, ptr);
+ invokeNode->setArg(1, idx);
+ invokeNode->setRet(0, ret);
cc.sub(acc1, ret);
}
@@ -3361,9 +3509,11 @@ public:
cc.mov(tmp, val);
cc.dec(tmp);
- FuncCallNode* call = cc.call(func->label(), FuncSignatureT<int, int>(CallConv::kIdHost));
- call->setArg(0, tmp);
- call->setRet(0, tmp);
+ InvokeNode* invokeNode;
+
+ cc.invoke(&invokeNode, func->label(), FuncSignatureT<int, int>(CallConv::kIdHost));
+ invokeNode->setArg(0, tmp);
+ invokeNode->setRet(0, tmp);
cc.mul(cc.newInt32(), val, tmp);
cc.bind(skip);
@@ -3413,15 +3563,16 @@ public:
// We call `int func(size_t, ...)`
// - The `vaIndex` must be 1 (first argument after size_t).
// - The full signature of varargs (int, int, int, int) must follow.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<int, size_t, int, int, int, int>(CallConv::kIdHost, 1));
- call->setArg(0, imm(4));
- call->setArg(1, a0);
- call->setArg(2, a1);
- call->setArg(3, a2);
- call->setArg(4, a3);
- call->setRet(0, a0);
+ invokeNode->setArg(0, imm(4));
+ invokeNode->setArg(1, a0);
+ invokeNode->setArg(2, a1);
+ invokeNode->setArg(3, a2);
+ invokeNode->setArg(4, a3);
+ invokeNode->setRet(0, a0);
cc.ret(a0);
cc.endFunc();
@@ -3481,15 +3632,16 @@ public:
// We call `double func(size_t, ...)`
// - The `vaIndex` must be 1 (first argument after size_t).
// - The full signature of varargs (double, double, double, double) must follow.
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)calledFunc),
FuncSignatureT<double, size_t, double, double, double, double>(CallConv::kIdHost, 1));
- call->setArg(0, imm(4));
- call->setArg(1, a0);
- call->setArg(2, a1);
- call->setArg(3, a2);
- call->setArg(4, a3);
- call->setRet(0, a0);
+ invokeNode->setArg(0, imm(4));
+ invokeNode->setArg(1, a0);
+ invokeNode->setArg(2, a1);
+ invokeNode->setArg(3, a2);
+ invokeNode->setArg(4, a3);
+ invokeNode->setRet(0, a0);
cc.ret(a0);
cc.endFunc();
@@ -3545,11 +3697,12 @@ public:
cc.setArg(0, a);
cc.setArg(1, b);
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)dummy),
FuncSignatureT<void, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
+ invokeNode->setArg(0, a);
+ invokeNode->setArg(1, b);
cc.lea(r, x86::ptr(a, b));
cc.ret(r);
@@ -3593,11 +3746,12 @@ public:
cc.setArg(0, p);
cc.movsd(arg, x86::ptr(p));
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)op),
FuncSignatureT<double, double>(CallConv::kIdHost));
- call->setArg(0, arg);
- call->setRet(0, ret);
+ invokeNode->setArg(0, arg);
+ invokeNode->setRet(0, ret);
cc.ret(ret);
cc.endFunc();
@@ -3643,11 +3797,12 @@ public:
cc.setArg(0, p);
cc.movsd(arg, x86::ptr(p));
- FuncCallNode* call = cc.call(
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode,
imm((void*)op),
FuncSignatureT<double, double>(CallConv::kIdHost));
- call->setArg(0, arg);
- call->setRet(0, ret);
+ invokeNode->setArg(0, arg);
+ invokeNode->setRet(0, ret);
cc.xorps(arg, arg);
cc.subsd(arg, ret);
@@ -3687,18 +3842,20 @@ public:
}
virtual void compile(x86::Compiler& cc) {
- FuncSignatureBuilder funcPrototype;
- funcPrototype.setCallConv(CallConv::kIdHost);
- funcPrototype.setRet(Type::kIdF64);
- cc.addFunc(funcPrototype);
+ InvokeNode* invokeNode;
- FuncSignatureBuilder callPrototype;
- callPrototype.setCallConv(CallConv::kIdHost);
- callPrototype.setRet(Type::kIdF64);
- FuncCallNode* call = cc.call(imm((void*)calledFunc), callPrototype);
+ FuncSignatureBuilder funcSignature;
+ funcSignature.setCallConv(CallConv::kIdHost);
+ funcSignature.setRet(Type::kIdF64);
+ cc.addFunc(funcSignature);
+ FuncSignatureBuilder invokeSignature;
+ invokeSignature.setCallConv(CallConv::kIdHost);
+ invokeSignature.setRet(Type::kIdF64);
+
+ cc.invoke(&invokeNode, imm((void*)calledFunc), invokeSignature);
x86::Xmm ret = cc.newXmmSd("ret");
- call->setRet(0, ret);
+ invokeNode->setRet(0, ret);
cc.ret(ret);
cc.endFunc();
@@ -3739,7 +3896,7 @@ public:
x86::Gp pFn = cc.newIntPtr("pFn");
x86::Gp vars[16];
- uint32_t i, regCount = cc.gpCount();
+ uint32_t i, regCount = cc.arch() == Environment::kArchX86 ? 8 : 16;
ASMJIT_ASSERT(regCount <= ASMJIT_ARRAY_SIZE(vars));
cc.mov(pFn, imm((void*)calledFunc));
@@ -3752,7 +3909,9 @@ public:
cc.mov(vars[i], 1);
}
- cc.call(pFn, FuncSignatureT<void>(CallConv::kIdHost));
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, pFn, FuncSignatureT<void>(CallConv::kIdHost));
+
for (i = 1; i < regCount; i++)
if (vars[i].isValid())
cc.add(vars[0], vars[i]);
@@ -3979,10 +4138,11 @@ public:
cc.setArg(0, a);
cc.setArg(1, b);
- FuncCallNode* call = cc.call(f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost));
- call->setArg(0, a);
- call->setArg(1, b);
- call->setRet(0, a);
+ InvokeNode* invokeNode;
+ cc.invoke(&invokeNode, f2->label(), FuncSignatureT<int, int, int>(CallConv::kIdHost));
+ invokeNode->setArg(0, a);
+ invokeNode->setArg(1, b);
+ invokeNode->setRet(0, a);
cc.ret(a);
cc.endFunc();
@@ -4037,7 +4197,7 @@ public:
// arguments will be passed by registers and there won't be any stack
// misalignment when we call the `handler()`. This was failing on OSX
// when targeting 32-bit.
- cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdHostFastCall));
+ cc.addFunc(FuncSignatureT<int, int, void*>(CallConv::kIdFastCall));
x86::Gp a = cc.newInt32("a");
x86::Gp b = cc.newIntPtr("b");
@@ -4123,6 +4283,7 @@ int main(int argc, char* argv[]) {
app.addT<X86Test_AllocArgsIntPtr>();
app.addT<X86Test_AllocArgsFloat>();
app.addT<X86Test_AllocArgsDouble>();
+ app.addT<X86Test_AllocArgsVec>();
app.addT<X86Test_AllocRetFloat1>();
app.addT<X86Test_AllocRetFloat2>();
app.addT<X86Test_AllocRetDouble1>();
@@ -4137,6 +4298,7 @@ int main(int argc, char* argv[]) {
app.addT<X86Test_FuncCallBase2>();
app.addT<X86Test_FuncCallStd>();
app.addT<X86Test_FuncCallFast>();
+ app.addT<X86Test_FuncCallSIMD>();
app.addT<X86Test_FuncCallLight>();
app.addT<X86Test_FuncCallManyArgs>();
app.addT<X86Test_FuncCallDuplicateArgs>();
diff --git a/3rdparty/asmjit/test/asmjit_test_x86_instinfo.cpp b/3rdparty/asmjit/test/asmjit_test_x86_instinfo.cpp
new file mode 100644
index 00000000000..1d7d5003f8b
--- /dev/null
+++ b/3rdparty/asmjit/test/asmjit_test_x86_instinfo.cpp
@@ -0,0 +1,128 @@
+// 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/x86.h>
+#include <stdio.h>
+
+using namespace asmjit;
+
+static void printInfo(uint32_t arch, const BaseInst& inst, const Operand_* operands, size_t opCount) {
+ StringTmp<512> sb;
+
+ // Read & Write Information
+ // ------------------------
+
+ 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
+ sb.append("<Logging-Not-Available>");
+#endif
+ sb.append("\n");
+
+ sb.append("Operands:\n");
+ for (uint32_t i = 0; i < rw.opCount(); i++) {
+ const OpRWInfo& op = rw.operand(i);
+ const char* access = op.isReadOnly() ? "R" :
+ op.isWriteOnly() ? "W" :
+ op.isReadWrite() ? "X" : "_";
+
+ sb.appendFormat(" [%u] RW=%s Read=%016llX Write=%016llX Extend=%016llX",
+ i, access, op.readByteMask(), op.writeByteMask(), op.extendByteMask());
+ sb.append("\n");
+ }
+
+ // CPU Features
+ // ------------
+
+ BaseFeatures features;
+ InstAPI::queryFeatures(arch, inst, operands, opCount, &features);
+
+#ifndef ASMJIT_NO_LOGGING
+ if (!features.empty()) {
+ sb.append("Features:\n");
+ sb.append(" ");
+
+ bool first = true;
+ BaseFeatures::Iterator it(features.iterator());
+ while (it.hasNext()) {
+ uint32_t featureId = uint32_t(it.next());
+ if (!first)
+ sb.append(" & ");
+ Formatter::formatFeature(sb, arch, featureId);
+ first = false;
+ }
+ sb.append("\n");
+ }
+#endif
+
+ printf("%s\n", sb.data());
+}
+
+template<typename... Args>
+static void printInfoSimple(uint32_t arch, uint32_t instId, Args&&... args) {
+ BaseInst inst(instId);
+ Operand_ opArray[] = { std::forward<Args>(args)... };
+ printInfo(arch, inst, opArray, sizeof...(args));
+}
+
+int main() {
+ using namespace x86;
+ uint32_t arch = Environment::kArchX64;
+
+ printf("AsmJit X86 Instruction Information Test\n\n");
+
+ printInfoSimple(arch,
+ x86::Inst::kIdAdd,
+ x86::eax, x86::ebx);
+
+ printInfoSimple(arch,
+ x86::Inst::kIdPshufd,
+ x86::xmm0, x86::xmm1, imm(0));
+
+ printInfoSimple(arch,
+ x86::Inst::kIdPextrw,
+ x86::eax, x86::xmm1, imm(0));
+
+ printInfoSimple(arch,
+ x86::Inst::kIdPextrw,
+ x86::ptr(rax), x86::xmm1, imm(0));
+
+ printInfoSimple(arch,
+ x86::Inst::kIdVaddpd,
+ x86::ymm0, x86::ymm1, x86::ymm2);
+
+ printInfoSimple(arch,
+ x86::Inst::kIdVaddpd,
+ x86::ymm0, x86::ymm30, x86::ymm31);
+
+ printInfoSimple(arch,
+ x86::Inst::kIdVaddpd,
+ x86::zmm0, x86::zmm1, x86::zmm2);
+
+ return 0;
+}
diff --git a/3rdparty/asmjit/test/asmjit_test_x86_sections.cpp b/3rdparty/asmjit/test/asmjit_test_x86_sections.cpp
index a9645b31649..ddafd63b8bc 100644
--- a/3rdparty/asmjit/test/asmjit_test_x86_sections.cpp
+++ b/3rdparty/asmjit/test/asmjit_test_x86_sections.cpp
@@ -53,7 +53,9 @@ static void fail(const char* message, Error err) {
}
int main() {
- CodeInfo codeInfo(ArchInfo::kIdHost);
+ printf("AsmJit X86 Sections Test\n\n");
+
+ Environment env = hostEnvironment();
JitAllocator allocator;
#ifndef ASMJIT_NO_LOGGING
@@ -62,7 +64,7 @@ int main() {
#endif
CodeHolder code;
- code.init(codeInfo);
+ code.init(env);
#ifndef ASMJIT_NO_LOGGING
code.setLogger(&logger);
@@ -83,7 +85,7 @@ int main() {
Label data = a.newLabel();
FuncDetail func;
- func.init(FuncSignatureT<size_t, size_t>(CallConv::kIdHost));
+ func.init(FuncSignatureT<size_t, size_t>(CallConv::kIdHost), code.environment());
FuncFrame frame;
frame.init(func);
@@ -159,18 +161,15 @@ int main() {
typedef size_t (*Func)(size_t idx);
Func fn = (Func)roPtr;
- printf("\nTesting the generated function:\n");
+ printf("\n");
if (fn(0) != dataArray[0] ||
fn(3) != dataArray[3] ||
fn(6) != dataArray[6] ||
fn(9) != dataArray[9] ) {
- printf(" [FAILED] The generated function returned incorrect result(s)\n");
+ printf("Failure:\n The generated function returned incorrect result(s)\n");
return 1;
}
- else {
- printf(" [PASSED] The generated function returned expected results\n");
- }
- allocator.release((void*)fn);
+ printf("Success:\n The generated function returned expected results\n");
return 0;
}