asmjit_test_opcode.cpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // [AsmJit]
  2. // Machine Code Generation for C++.
  3. //
  4. // [License]
  5. // Zlib - See LICENSE.md file in the package.
  6. // This file is used to test opcodes generated by AsmJit. Output can be
  7. // disassembled in your IDE or by your favorite disassembler. Instructions
  8. // are grouped by category and then sorted alphabetically.
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include "./asmjit.h"
  12. #include "./asmjit_test_opcode.h"
  13. using namespace asmjit;
  14. struct OpcodeDumpInfo {
  15. uint32_t archId;
  16. bool useRex1;
  17. bool useRex2;
  18. };
  19. static const char* archIdToString(uint32_t archId) {
  20. switch (archId) {
  21. case ArchInfo::kIdNone: return "None";
  22. case ArchInfo::kIdX86 : return "X86";
  23. case ArchInfo::kIdX64 : return "X64";
  24. case ArchInfo::kIdA32 : return "A32";
  25. case ArchInfo::kIdA64 : return "A64";
  26. default:
  27. return "<unknown>";
  28. }
  29. }
  30. struct TestErrorHandler : public ErrorHandler {
  31. virtual void handleError(Error err, const char* message, BaseEmitter* origin) {
  32. (void)origin;
  33. printf("ERROR 0x%08X: %s\n", err, message);
  34. }
  35. };
  36. typedef void (*VoidFunc)(void);
  37. int main(int argc, char* argv[]) {
  38. ASMJIT_UNUSED(argc);
  39. ASMJIT_UNUSED(argv);
  40. TestErrorHandler eh;
  41. OpcodeDumpInfo infoList[] = {
  42. { ArchInfo::kIdX86, false, false },
  43. { ArchInfo::kIdX64, false, false },
  44. { ArchInfo::kIdX64, false, true },
  45. { ArchInfo::kIdX64, true , false },
  46. { ArchInfo::kIdX64, true , true }
  47. };
  48. for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(infoList); i++) {
  49. const OpcodeDumpInfo& info = infoList[i];
  50. printf("Opcodes [ARCH=%s REX1=%s REX2=%s]\n",
  51. archIdToString(info.archId),
  52. info.useRex1 ? "true" : "false",
  53. info.useRex2 ? "true" : "false");
  54. CodeHolder code;
  55. code.init(CodeInfo(info.archId));
  56. code.setErrorHandler(&eh);
  57. #ifndef ASMJIT_NO_LOGGING
  58. FileLogger logger(stdout);
  59. logger.addFlags(FormatOptions::kFlagMachineCode);
  60. code.setLogger(&logger);
  61. #endif
  62. x86::Assembler a(&code);
  63. asmtest::generateOpcodes(a.as<x86::Emitter>(), info.useRex1, info.useRex2);
  64. // If this is the host architecture the code generated can be executed
  65. // for debugging purposes (the first instruction is ret anyway).
  66. if (code.archId() == ArchInfo::kIdHost) {
  67. JitRuntime runtime;
  68. VoidFunc p;
  69. Error err = runtime.add(&p, &code);
  70. if (err == kErrorOk) p();
  71. }
  72. }
  73. return 0;
  74. }