// This file is part of AsmJit project // // See asmjit.h or LICENSE.md for license and copyright information // SPDX-License-Identifier: Zlib #include #if !defined(ASMJIT_NO_X86) #include #endif // !ASMJIT_NO_X86 #if !defined(ASMJIT_NO_AARCH64) #include #endif // !ASMJIT_NO_AARCH64 #include #include #include #include #include #include "asmjitutils.h" #if !defined(ASMJIT_NO_COMPILER) #include "cmdline.h" #include "performancetimer.h" #include "asmjit_test_compiler.h" #include "asmjit_test_random.h" #endif using namespace asmjit; static void printAppInfo() { printf("AsmJit Benchmark RegAlloc v%u.%u.%u [Arch=%s] [Mode=%s]\n\n", unsigned((ASMJIT_LIBRARY_VERSION >> 16) ), unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF), unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF), asmjitArchAsString(Arch::kHost), asmjitBuildType() ); } #if !defined(ASMJIT_NO_COMPILER) class BenchRegAllocApp { public: const char* _arch = nullptr; bool _helpOnly = false; bool _verbose = false; uint32_t _maximumComplexity = 65536; BenchRegAllocApp() noexcept : _arch("all") {} ~BenchRegAllocApp() noexcept {} template inline void addT() { T::add(*this); } int handleArgs(int argc, const char* const* argv); void showInfo(); bool shouldRunArch(Arch arch) const noexcept; void emitCode(BaseCompiler* cc, uint32_t complexity, uint32_t regCount); #if !defined(ASMJIT_NO_X86) void emitCode_x86(x86::Compiler* cc, uint32_t complexity, uint32_t regCount); #endif // !ASMJIT_NO_X86 #if !defined(ASMJIT_NO_AARCH64) void emitCode_a64(a64::Compiler* cc, uint32_t complexity, uint32_t regCount); #endif // !ASMJIT_NO_AARCH64 int run(); bool runArch(Arch arch); }; int BenchRegAllocApp::handleArgs(int argc, const char* const* argv) { CmdLine cmd(argc, argv); _arch = cmd.valueOf("--arch", "all"); _maximumComplexity = cmd.valueAsUInt("--complexity", _maximumComplexity); if (cmd.hasArg("--help")) _helpOnly = true; if (cmd.hasArg("--verbose")) _verbose = true; return 0; } void BenchRegAllocApp::showInfo() { printAppInfo(); printf("Usage:\n"); printf(" asmjit_bench_regalloc [arguments]\n"); printf("\n"); printf("Arguments:\n"); printf(" --help Show usage only\n"); printf(" --arch= Select architecture to run ('all' by default)\n"); printf(" --verbose Verbose output\n"); printf(" --complexity= Maximum complexity to test (%u)\n", _maximumComplexity); printf("\n"); printf("Architectures:\n"); #if !defined(ASMJIT_NO_X86) printf(" --arch=x86 32-bit X86 architecture (X86)\n"); printf(" --arch=x64 64-bit X86 architecture (X86_64)\n"); #endif #if !defined(ASMJIT_NO_AARCH64) printf(" --arch=aarch64 64-bit ARM architecture (AArch64)\n"); #endif printf("\n"); } bool BenchRegAllocApp::shouldRunArch(Arch arch) const noexcept { if (strcmp(_arch, "all") == 0) { return true; } if (strcmp(_arch, "x86") == 0 && arch == Arch::kX86) { return true; } if (strcmp(_arch, "x64") == 0 && arch == Arch::kX64) { return true; } if (strcmp(_arch, "aarch64") == 0 && arch == Arch::kAArch64) { return true; } return false; } void BenchRegAllocApp::emitCode(BaseCompiler* cc, uint32_t complexity, uint32_t regCount) { #if !defined(ASMJIT_NO_X86) if (cc->arch() == Arch::kX86 || cc->arch() == Arch::kX64) { emitCode_x86(cc->as(), complexity, regCount); } #endif #if !defined(ASMJIT_NO_AARCH64) if (cc->arch() == Arch::kAArch64) { emitCode_a64(cc->as(), complexity, regCount); } #endif } #if !defined(ASMJIT_NO_X86) void BenchRegAllocApp::emitCode_x86(x86::Compiler* cc, uint32_t complexity, uint32_t regCount) { constexpr size_t kLocalRegCount = 3; TestUtils::Random rnd(0x1234); size_t localOpCount = 15; std::vector