// 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. // ---------------------------------------------------------------------------- // 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 #include #include #include "./asmjit_test_opcode.h" using namespace asmjit; struct OpcodeDumpInfo { uint32_t arch; bool useRex1; bool useRex2; }; 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"; } } struct TestErrorHandler : public ErrorHandler { virtual void handleError(Error err, const char* message, BaseEmitter* origin) { (void)origin; printf("ERROR 0x%08X: %s\n", err, message); } }; typedef void (*VoidFunc)(void); int main() { TestErrorHandler eh; OpcodeDumpInfo infoList[] = { { 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", archToString(info.arch), info.useRex1 ? "true" : "false", info.useRex2 ? "true" : "false"); CodeHolder code; code.init(Environment(info.arch)); code.setErrorHandler(&eh); #ifndef ASMJIT_NO_LOGGING FileLogger logger(stdout); logger.addFlags(FormatOptions::kFlagMachineCode); code.setLogger(&logger); #endif x86::Assembler a(&code); asmtest::generateOpcodes(a.as(), info.useRex1, info.useRex2); // If this is the host architecture the code generated can be executed // for debugging purposes (the first instruction is ret anyway). if (code.arch() == Environment::kArchHost) { JitRuntime runtime; VoidFunc p; Error err = runtime.add(&p, &code); if (err == kErrorOk) p(); } } return 0; }