// 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 archId; 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 ""; } } 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[] = { { ArchInfo::kIdX86, false, false }, { ArchInfo::kIdX64, false, false }, { ArchInfo::kIdX64, false, true }, { ArchInfo::kIdX64, true , false }, { ArchInfo::kIdX64, 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), info.useRex1 ? "true" : "false", info.useRex2 ? "true" : "false"); CodeHolder code; code.init(CodeInfo(info.archId)); 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.archId() == ArchInfo::kIdHost) { JitRuntime runtime; VoidFunc p; Error err = runtime.add(&p, &code); if (err == kErrorOk) p(); } } return 0; }