asmjit_test_assembler.h (2906B)
1 // This file is part of AsmJit project <https://asmjit.com> 2 // 3 // See <asmjit/core.h> or LICENSE.md for license and copyright information 4 // SPDX-License-Identifier: Zlib 5 6 #ifndef ASMJIT_TEST_ASSEMBLER_H_INCLUDED 7 #define ASMJIT_TEST_ASSEMBLER_H_INCLUDED 8 9 #include <asmjit/core.h> 10 #include <stdio.h> 11 12 struct TestSettings { 13 bool verbose; 14 bool validate; 15 }; 16 17 template<typename AssemblerType> 18 class AssemblerTester { 19 public: 20 asmjit::Environment env {}; 21 asmjit::CodeHolder code {}; 22 AssemblerType assembler {}; 23 asmjit::Label L0 {}; 24 const TestSettings& settings; 25 26 size_t passed {}; 27 size_t count {}; 28 29 AssemblerTester(asmjit::Arch arch, const TestSettings& settings) noexcept 30 : env(arch), 31 settings(settings) { 32 prepare(); 33 } 34 35 void print_header(const char* arch_name) noexcept { 36 printf("%s assembler tests:\n", arch_name); 37 } 38 39 void print_summary() noexcept { 40 printf(" Passed: %zu / %zu tests\n\n", passed, count); 41 } 42 43 bool did_pass() const noexcept { return passed == count; } 44 45 void prepare() noexcept { 46 code.reset(); 47 code.init(env, 0); 48 code.attach(&assembler); 49 L0 = assembler.new_label(); 50 51 if (settings.validate) 52 assembler.add_diagnostic_options(asmjit::DiagnosticOptions::kValidateAssembler); 53 } 54 55 ASMJIT_NOINLINE bool test_valid_instruction(const char* s, const char* expected_opcode, asmjit::Error err = asmjit::Error::kOk) noexcept { 56 count++; 57 58 if (err != asmjit::Error::kOk) { 59 printf(" !! %s\n" 60 " <%s>\n", s, asmjit::DebugUtils::error_as_string(err)); 61 prepare(); 62 return false; 63 } 64 65 asmjit::String encoded_opcode; 66 asmjit::Section* text = code.text_section(); 67 68 encoded_opcode.append_hex(text->data(), text->buffer_size()); 69 if (encoded_opcode != expected_opcode) { 70 printf(" !! [%s] <- %s\n" 71 " [%s] (Expected)\n", encoded_opcode.data(), s, expected_opcode); 72 prepare(); 73 return false; 74 } 75 76 if (settings.verbose) 77 printf(" OK [%s] <- %s\n", encoded_opcode.data(), s); 78 79 passed++; 80 prepare(); 81 return true; 82 } 83 84 ASMJIT_NOINLINE bool test_invalid_instruction(const char* s, asmjit::Error expected_error, asmjit::Error err) noexcept { 85 count++; 86 87 if (err == asmjit::Error::kOk) { 88 printf(" !! %s passed, but should have failed with <%s> error\n", s, asmjit::DebugUtils::error_as_string(expected_error)); 89 prepare(); 90 return false; 91 } 92 93 if (err != asmjit::Error::kOk) { 94 printf(" !! %s failed with <%s>, but should have failed with <%s>\n", s, asmjit::DebugUtils::error_as_string(err), asmjit::DebugUtils::error_as_string(expected_error)); 95 prepare(); 96 return false; 97 } 98 99 if (settings.verbose) 100 printf(" OK [%s] <- %s\n", asmjit::DebugUtils::error_as_string(err), s); 101 102 passed++; 103 prepare(); 104 return true; 105 } 106 }; 107 108 #endif // ASMJIT_TEST_ASSEMBLER_H_INCLUDED