asmjit 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/asmjit.gemspec +1 -1
  4. data/ext/asmjit/asmjit/.editorconfig +10 -0
  5. data/ext/asmjit/asmjit/.github/FUNDING.yml +1 -0
  6. data/ext/asmjit/asmjit/.github/workflows/build-config.json +47 -0
  7. data/ext/asmjit/asmjit/.github/workflows/build.yml +156 -0
  8. data/ext/asmjit/asmjit/.gitignore +6 -0
  9. data/ext/asmjit/asmjit/CMakeLists.txt +611 -0
  10. data/ext/asmjit/asmjit/LICENSE.md +17 -0
  11. data/ext/asmjit/asmjit/README.md +69 -0
  12. data/ext/asmjit/asmjit/src/asmjit/a64.h +62 -0
  13. data/ext/asmjit/asmjit/src/asmjit/arm/a64archtraits_p.h +81 -0
  14. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.cpp +5115 -0
  15. data/ext/asmjit/asmjit/src/asmjit/arm/a64assembler.h +72 -0
  16. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.cpp +51 -0
  17. data/ext/asmjit/asmjit/src/asmjit/arm/a64builder.h +57 -0
  18. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.cpp +60 -0
  19. data/ext/asmjit/asmjit/src/asmjit/arm/a64compiler.h +247 -0
  20. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper.cpp +464 -0
  21. data/ext/asmjit/asmjit/src/asmjit/arm/a64emithelper_p.h +50 -0
  22. data/ext/asmjit/asmjit/src/asmjit/arm/a64emitter.h +1228 -0
  23. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter.cpp +298 -0
  24. data/ext/asmjit/asmjit/src/asmjit/arm/a64formatter_p.h +59 -0
  25. data/ext/asmjit/asmjit/src/asmjit/arm/a64func.cpp +189 -0
  26. data/ext/asmjit/asmjit/src/asmjit/arm/a64func_p.h +33 -0
  27. data/ext/asmjit/asmjit/src/asmjit/arm/a64globals.h +1894 -0
  28. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi.cpp +278 -0
  29. data/ext/asmjit/asmjit/src/asmjit/arm/a64instapi_p.h +41 -0
  30. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.cpp +1957 -0
  31. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb.h +74 -0
  32. data/ext/asmjit/asmjit/src/asmjit/arm/a64instdb_p.h +876 -0
  33. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.cpp +85 -0
  34. data/ext/asmjit/asmjit/src/asmjit/arm/a64operand.h +312 -0
  35. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass.cpp +852 -0
  36. data/ext/asmjit/asmjit/src/asmjit/arm/a64rapass_p.h +105 -0
  37. data/ext/asmjit/asmjit/src/asmjit/arm/a64utils.h +179 -0
  38. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter.cpp +143 -0
  39. data/ext/asmjit/asmjit/src/asmjit/arm/armformatter_p.h +44 -0
  40. data/ext/asmjit/asmjit/src/asmjit/arm/armglobals.h +21 -0
  41. data/ext/asmjit/asmjit/src/asmjit/arm/armoperand.h +621 -0
  42. data/ext/asmjit/asmjit/src/asmjit/arm.h +62 -0
  43. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-begin.h +17 -0
  44. data/ext/asmjit/asmjit/src/asmjit/asmjit-scope-end.h +9 -0
  45. data/ext/asmjit/asmjit/src/asmjit/asmjit.h +33 -0
  46. data/ext/asmjit/asmjit/src/asmjit/core/api-build_p.h +55 -0
  47. data/ext/asmjit/asmjit/src/asmjit/core/api-config.h +613 -0
  48. data/ext/asmjit/asmjit/src/asmjit/core/archcommons.h +229 -0
  49. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.cpp +160 -0
  50. data/ext/asmjit/asmjit/src/asmjit/core/archtraits.h +290 -0
  51. data/ext/asmjit/asmjit/src/asmjit/core/assembler.cpp +406 -0
  52. data/ext/asmjit/asmjit/src/asmjit/core/assembler.h +129 -0
  53. data/ext/asmjit/asmjit/src/asmjit/core/builder.cpp +889 -0
  54. data/ext/asmjit/asmjit/src/asmjit/core/builder.h +1391 -0
  55. data/ext/asmjit/asmjit/src/asmjit/core/codebuffer.h +113 -0
  56. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.cpp +1149 -0
  57. data/ext/asmjit/asmjit/src/asmjit/core/codeholder.h +1035 -0
  58. data/ext/asmjit/asmjit/src/asmjit/core/codewriter.cpp +175 -0
  59. data/ext/asmjit/asmjit/src/asmjit/core/codewriter_p.h +179 -0
  60. data/ext/asmjit/asmjit/src/asmjit/core/compiler.cpp +582 -0
  61. data/ext/asmjit/asmjit/src/asmjit/core/compiler.h +737 -0
  62. data/ext/asmjit/asmjit/src/asmjit/core/compilerdefs.h +173 -0
  63. data/ext/asmjit/asmjit/src/asmjit/core/constpool.cpp +363 -0
  64. data/ext/asmjit/asmjit/src/asmjit/core/constpool.h +250 -0
  65. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.cpp +1162 -0
  66. data/ext/asmjit/asmjit/src/asmjit/core/cpuinfo.h +813 -0
  67. data/ext/asmjit/asmjit/src/asmjit/core/emithelper.cpp +323 -0
  68. data/ext/asmjit/asmjit/src/asmjit/core/emithelper_p.h +58 -0
  69. data/ext/asmjit/asmjit/src/asmjit/core/emitter.cpp +333 -0
  70. data/ext/asmjit/asmjit/src/asmjit/core/emitter.h +741 -0
  71. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils.cpp +129 -0
  72. data/ext/asmjit/asmjit/src/asmjit/core/emitterutils_p.h +89 -0
  73. data/ext/asmjit/asmjit/src/asmjit/core/environment.cpp +46 -0
  74. data/ext/asmjit/asmjit/src/asmjit/core/environment.h +508 -0
  75. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.cpp +14 -0
  76. data/ext/asmjit/asmjit/src/asmjit/core/errorhandler.h +228 -0
  77. data/ext/asmjit/asmjit/src/asmjit/core/formatter.cpp +584 -0
  78. data/ext/asmjit/asmjit/src/asmjit/core/formatter.h +247 -0
  79. data/ext/asmjit/asmjit/src/asmjit/core/formatter_p.h +34 -0
  80. data/ext/asmjit/asmjit/src/asmjit/core/func.cpp +286 -0
  81. data/ext/asmjit/asmjit/src/asmjit/core/func.h +1445 -0
  82. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext.cpp +293 -0
  83. data/ext/asmjit/asmjit/src/asmjit/core/funcargscontext_p.h +199 -0
  84. data/ext/asmjit/asmjit/src/asmjit/core/globals.cpp +133 -0
  85. data/ext/asmjit/asmjit/src/asmjit/core/globals.h +393 -0
  86. data/ext/asmjit/asmjit/src/asmjit/core/inst.cpp +113 -0
  87. data/ext/asmjit/asmjit/src/asmjit/core/inst.h +772 -0
  88. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.cpp +1242 -0
  89. data/ext/asmjit/asmjit/src/asmjit/core/jitallocator.h +261 -0
  90. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.cpp +80 -0
  91. data/ext/asmjit/asmjit/src/asmjit/core/jitruntime.h +89 -0
  92. data/ext/asmjit/asmjit/src/asmjit/core/logger.cpp +69 -0
  93. data/ext/asmjit/asmjit/src/asmjit/core/logger.h +198 -0
  94. data/ext/asmjit/asmjit/src/asmjit/core/misc_p.h +33 -0
  95. data/ext/asmjit/asmjit/src/asmjit/core/operand.cpp +132 -0
  96. data/ext/asmjit/asmjit/src/asmjit/core/operand.h +1611 -0
  97. data/ext/asmjit/asmjit/src/asmjit/core/osutils.cpp +84 -0
  98. data/ext/asmjit/asmjit/src/asmjit/core/osutils.h +61 -0
  99. data/ext/asmjit/asmjit/src/asmjit/core/osutils_p.h +68 -0
  100. data/ext/asmjit/asmjit/src/asmjit/core/raassignment_p.h +418 -0
  101. data/ext/asmjit/asmjit/src/asmjit/core/rabuilders_p.h +612 -0
  102. data/ext/asmjit/asmjit/src/asmjit/core/radefs_p.h +1204 -0
  103. data/ext/asmjit/asmjit/src/asmjit/core/ralocal.cpp +1166 -0
  104. data/ext/asmjit/asmjit/src/asmjit/core/ralocal_p.h +254 -0
  105. data/ext/asmjit/asmjit/src/asmjit/core/rapass.cpp +1969 -0
  106. data/ext/asmjit/asmjit/src/asmjit/core/rapass_p.h +1183 -0
  107. data/ext/asmjit/asmjit/src/asmjit/core/rastack.cpp +184 -0
  108. data/ext/asmjit/asmjit/src/asmjit/core/rastack_p.h +171 -0
  109. data/ext/asmjit/asmjit/src/asmjit/core/string.cpp +559 -0
  110. data/ext/asmjit/asmjit/src/asmjit/core/string.h +372 -0
  111. data/ext/asmjit/asmjit/src/asmjit/core/support.cpp +494 -0
  112. data/ext/asmjit/asmjit/src/asmjit/core/support.h +1773 -0
  113. data/ext/asmjit/asmjit/src/asmjit/core/target.cpp +14 -0
  114. data/ext/asmjit/asmjit/src/asmjit/core/target.h +53 -0
  115. data/ext/asmjit/asmjit/src/asmjit/core/type.cpp +74 -0
  116. data/ext/asmjit/asmjit/src/asmjit/core/type.h +419 -0
  117. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.cpp +722 -0
  118. data/ext/asmjit/asmjit/src/asmjit/core/virtmem.h +242 -0
  119. data/ext/asmjit/asmjit/src/asmjit/core/zone.cpp +353 -0
  120. data/ext/asmjit/asmjit/src/asmjit/core/zone.h +615 -0
  121. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.cpp +309 -0
  122. data/ext/asmjit/asmjit/src/asmjit/core/zonehash.h +186 -0
  123. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.cpp +163 -0
  124. data/ext/asmjit/asmjit/src/asmjit/core/zonelist.h +209 -0
  125. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.cpp +176 -0
  126. data/ext/asmjit/asmjit/src/asmjit/core/zonestack.h +239 -0
  127. data/ext/asmjit/asmjit/src/asmjit/core/zonestring.h +120 -0
  128. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.cpp +99 -0
  129. data/ext/asmjit/asmjit/src/asmjit/core/zonetree.h +380 -0
  130. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.cpp +356 -0
  131. data/ext/asmjit/asmjit/src/asmjit/core/zonevector.h +690 -0
  132. data/ext/asmjit/asmjit/src/asmjit/core.h +1861 -0
  133. data/ext/asmjit/asmjit/src/asmjit/x86/x86archtraits_p.h +148 -0
  134. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.cpp +5110 -0
  135. data/ext/asmjit/asmjit/src/asmjit/x86/x86assembler.h +685 -0
  136. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.cpp +52 -0
  137. data/ext/asmjit/asmjit/src/asmjit/x86/x86builder.h +351 -0
  138. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.cpp +61 -0
  139. data/ext/asmjit/asmjit/src/asmjit/x86/x86compiler.h +721 -0
  140. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper.cpp +619 -0
  141. data/ext/asmjit/asmjit/src/asmjit/x86/x86emithelper_p.h +60 -0
  142. data/ext/asmjit/asmjit/src/asmjit/x86/x86emitter.h +4315 -0
  143. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter.cpp +944 -0
  144. data/ext/asmjit/asmjit/src/asmjit/x86/x86formatter_p.h +58 -0
  145. data/ext/asmjit/asmjit/src/asmjit/x86/x86func.cpp +503 -0
  146. data/ext/asmjit/asmjit/src/asmjit/x86/x86func_p.h +33 -0
  147. data/ext/asmjit/asmjit/src/asmjit/x86/x86globals.h +2169 -0
  148. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi.cpp +1732 -0
  149. data/ext/asmjit/asmjit/src/asmjit/x86/x86instapi_p.h +41 -0
  150. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.cpp +4427 -0
  151. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb.h +563 -0
  152. data/ext/asmjit/asmjit/src/asmjit/x86/x86instdb_p.h +311 -0
  153. data/ext/asmjit/asmjit/src/asmjit/x86/x86opcode_p.h +436 -0
  154. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.cpp +231 -0
  155. data/ext/asmjit/asmjit/src/asmjit/x86/x86operand.h +1085 -0
  156. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass.cpp +1509 -0
  157. data/ext/asmjit/asmjit/src/asmjit/x86/x86rapass_p.h +94 -0
  158. data/ext/asmjit/asmjit/src/asmjit/x86.h +93 -0
  159. data/ext/asmjit/asmjit/src/asmjit.natvis +245 -0
  160. data/ext/asmjit/asmjit/test/asmjit_test_assembler.cpp +84 -0
  161. data/ext/asmjit/asmjit/test/asmjit_test_assembler.h +85 -0
  162. data/ext/asmjit/asmjit/test/asmjit_test_assembler_a64.cpp +4006 -0
  163. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x64.cpp +17833 -0
  164. data/ext/asmjit/asmjit/test/asmjit_test_assembler_x86.cpp +8300 -0
  165. data/ext/asmjit/asmjit/test/asmjit_test_compiler.cpp +253 -0
  166. data/ext/asmjit/asmjit/test/asmjit_test_compiler.h +73 -0
  167. data/ext/asmjit/asmjit/test/asmjit_test_compiler_a64.cpp +690 -0
  168. data/ext/asmjit/asmjit/test/asmjit_test_compiler_x86.cpp +4317 -0
  169. data/ext/asmjit/asmjit/test/asmjit_test_emitters.cpp +197 -0
  170. data/ext/asmjit/asmjit/test/asmjit_test_instinfo.cpp +181 -0
  171. data/ext/asmjit/asmjit/test/asmjit_test_misc.h +257 -0
  172. data/ext/asmjit/asmjit/test/asmjit_test_perf.cpp +62 -0
  173. data/ext/asmjit/asmjit/test/asmjit_test_perf.h +61 -0
  174. data/ext/asmjit/asmjit/test/asmjit_test_perf_a64.cpp +699 -0
  175. data/ext/asmjit/asmjit/test/asmjit_test_perf_x86.cpp +5032 -0
  176. data/ext/asmjit/asmjit/test/asmjit_test_unit.cpp +172 -0
  177. data/ext/asmjit/asmjit/test/asmjit_test_x86_sections.cpp +172 -0
  178. data/ext/asmjit/asmjit/test/asmjitutils.h +38 -0
  179. data/ext/asmjit/asmjit/test/broken.cpp +312 -0
  180. data/ext/asmjit/asmjit/test/broken.h +148 -0
  181. data/ext/asmjit/asmjit/test/cmdline.h +61 -0
  182. data/ext/asmjit/asmjit/test/performancetimer.h +41 -0
  183. data/ext/asmjit/asmjit/tools/configure-makefiles.sh +13 -0
  184. data/ext/asmjit/asmjit/tools/configure-ninja.sh +13 -0
  185. data/ext/asmjit/asmjit/tools/configure-sanitizers.sh +13 -0
  186. data/ext/asmjit/asmjit/tools/configure-vs2019-x64.bat +2 -0
  187. data/ext/asmjit/asmjit/tools/configure-vs2019-x86.bat +2 -0
  188. data/ext/asmjit/asmjit/tools/configure-vs2022-x64.bat +2 -0
  189. data/ext/asmjit/asmjit/tools/configure-vs2022-x86.bat +2 -0
  190. data/ext/asmjit/asmjit/tools/configure-xcode.sh +8 -0
  191. data/ext/asmjit/asmjit/tools/enumgen.js +417 -0
  192. data/ext/asmjit/asmjit/tools/enumgen.sh +3 -0
  193. data/ext/asmjit/asmjit/tools/tablegen-arm.js +365 -0
  194. data/ext/asmjit/asmjit/tools/tablegen-arm.sh +3 -0
  195. data/ext/asmjit/asmjit/tools/tablegen-x86.js +2638 -0
  196. data/ext/asmjit/asmjit/tools/tablegen-x86.sh +3 -0
  197. data/ext/asmjit/asmjit/tools/tablegen.js +947 -0
  198. data/ext/asmjit/asmjit/tools/tablegen.sh +4 -0
  199. data/ext/asmjit/asmjit.cc +18 -0
  200. data/lib/asmjit/version.rb +1 -1
  201. metadata +197 -2
@@ -0,0 +1,1861 @@
1
+ // This file is part of AsmJit project <https://asmjit.com>
2
+ //
3
+ // See asmjit.h or LICENSE.md for license and copyright information
4
+ // SPDX-License-Identifier: Zlib
5
+
6
+ #ifndef ASMJIT_CORE_H_INCLUDED
7
+ #define ASMJIT_CORE_H_INCLUDED
8
+
9
+ //! Root namespace used by AsmJit.
10
+ namespace asmjit {
11
+
12
+ //! \mainpage API Reference
13
+ //!
14
+ //! AsmJit C++ API reference documentation generated by Doxygen.
15
+ //!
16
+ //! AsmJit library uses one global namespace called \ref asmjit, which provides the whole functionality. Core
17
+ //! functionality is within \ref asmjit namespace and architecture specific functionality is always in its own
18
+ //! namespace. For example \ref asmjit::x86 provides both 32-bit and 64-bit X86 code generation.
19
+ //!
20
+ //! \section main_groups Documentation Groups
21
+ //!
22
+ //! AsmJit documentation is structured into groups. Groups can be followed in order to learn AsmJit, but knowledge
23
+ //! from multiple groups is required to use AsmJit properly:
24
+ //!
25
+ //! $$DOCS_GROUP_OVERVIEW$$
26
+ //!
27
+ //! \note It's important to understand that in order to learn AsmJit all groups are important. Some groups can be
28
+ //! omitted if a particular tool is out of interest - for example \ref asmjit_assembler users don't need to know
29
+ //! about \ref asmjit_builder, but it's not the opposite. \ref asmjit_builder users should know about \ref
30
+ //! asmjit_assembler as it also uses operands, labels, and other concepts. Similarly \ref asmjit_compiler users
31
+ //! should know how both \ref asmjit_assembler and \ref asmjit_builder tools work.
32
+ //!
33
+ //! \section where_to_start Where To Start
34
+ //!
35
+ //! AsmJit \ref asmjit_core provides the following two classes that are essential from the code generation perspective:
36
+ //!
37
+ //! - \ref CodeHolder provides functionality to temporarily hold the generated code. It stores all the necessary
38
+ //! information about the code - code buffers, sections, labels, symbols, and information about relocations.
39
+ //!
40
+ //! - \ref BaseEmitter provides interface used by emitter implementations. The interface provides basic building
41
+ //! blocks that are then implemented by \ref BaseAssembler, \ref BaseBuilder, and \ref BaseCompiler.
42
+ //!
43
+ //! Code emitters:
44
+ //!
45
+ //! - \ref asmjit_assembler - provides direct machine code generation.
46
+ //!
47
+ //! - \ref asmjit_builder - provides intermediate code generation that can be processed before it's serialized to
48
+ //! \ref BaseAssembler.
49
+ //!
50
+ //! - \ref asmjit_compiler - provides high-level code generation with built-in register allocation.
51
+ //!
52
+ //! - \ref FuncNode - provides insight into how function looks from the Compiler perspective and how it's stored in
53
+ //! a node-list.
54
+ //!
55
+ //! \section main_recommendations Recommendations
56
+ //!
57
+ //! The following steps are recommended for all AsmJit users:
58
+ //!
59
+ //! - Make sure that you use \ref Logger, see \ref asmjit_logging.
60
+ //!
61
+ //! - Make sure that you use \ref ErrorHandler, see \ref asmjit_error_handling.
62
+ //!
63
+ //! - Instruction validation in your debug builds can reveal problems too. AsmJit provides validation at instruction
64
+ //! level that can be enabled via \ref BaseEmitter::addDiagnosticOptions(). See \ref DiagnosticOptions for more
65
+ //! details.
66
+ //!
67
+ //! - If you are a Compiler user, use diagnostic options and read carefully if anything suspicious pops out.
68
+ //! Diagnostic options can be enabled via \ref BaseEmitter::addDiagnosticOptions(). If unsure which ones to use,
69
+ //! enable annotations and all debug options: `DiagnosticOptions::kRAAnnotate | DiagnosticOptions::kRADebugAll`.
70
+ //!
71
+ //! - Make sure you put a breakpoint into \ref DebugUtils::errored() function if you have a problem with AsmJit
72
+ //! returning errors during instruction encoding or register allocation. Having an active breakpoint there can
73
+ //! help to reveal the origin of the error, to inspect variables and other conditions that caused it.
74
+ //!
75
+ //! The reason for using \ref Logger and \ref ErrorHandler is that they provide a very useful information about what's
76
+ //! happening inside emitters. In many cases the information provided by these two is crucial to quickly identify and
77
+ //! fix issues that happen during development (for example wrong instruction, address, or register used). In addition,
78
+ //! output from \ref Logger is always necessary when filling bug reports. In other words, using logging and proper error
79
+ //! handling can save a lot of time during the development and can also save users from submitting issues.
80
+ //!
81
+ //! \section main_other Other Pages
82
+ //!
83
+ //! - <a href="annotated.html">Class List</a> - List of classes sorted alphabetically
84
+ //! - <a href="namespaceasmjit.html">AsmJit Namespace</a> - List of symbols provided by `asmjit` namespace
85
+
86
+
87
+ //! \defgroup asmjit_build Build Instructions
88
+ //! \brief Build instructions, supported environments, and feature selection.
89
+ //!
90
+ //! ### Overview
91
+ //!
92
+ //! AsmJit is designed to be easy embeddable in any project. However, it depends on some compile-time definitions that
93
+ //! can be used to enable or disable features to decrease the resulting binary size. A typical way of building AsmJit
94
+ //! is to use [cmake](https://www.cmake.org), but it's also possible to just include AsmJit source code in your project
95
+ //! and to just build it. The easiest way to include AsmJit in your project is to just include **src** directory in
96
+ //! your project and to define \ref ASMJIT_STATIC. AsmJit can be just updated from time to time without any changes to
97
+ //! this integration process. Do not embed AsmJit's `test` files in such case as these are used exclusively for testing.
98
+ //!
99
+ //! ### Supported C++ Compilers
100
+ //!
101
+ //! - Requirements:
102
+ //!
103
+ //! - AsmJit won't build without C++11 enabled. If you use older GCC or Clang you would have to enable at least
104
+ //! C++11 standard through compiler flags.
105
+ //!
106
+ //! - Tested:
107
+ //!
108
+ //! - **Clang** - Tested by GitHub Actions - Clang 3.9+ (with C++11 enabled) is officially supported (older Clang
109
+ //! versions having C++11 support are probably fine, but are not regularly tested).
110
+ //!
111
+ //! - **GNU** - Tested by GitHub Actions - GCC 4.8+ (with C++11 enabled) is officially supported.
112
+ //!
113
+ //! - **MINGW** - Should work, but it's not tested in our CI environment.
114
+ //!
115
+ //! - **MSVC** - Tested by GitHub Actions - VS2017+ is officially supported, VS2015 is reported to work.
116
+ //!
117
+ //! - Untested:
118
+ //!
119
+ //! - **Intel** - No maintainers and no CI environment to regularly test this compiler.
120
+ //!
121
+ //! - **Other** C++ compilers would require basic support in
122
+ //! [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h).
123
+ //!
124
+ //! ### Supported Operating Systems and Platforms
125
+ //!
126
+ //! - Tested:
127
+ //!
128
+ //! - **Linux** - Tested by GitHub Actions (any distribution is generally supported).
129
+ //!
130
+ //! - **Mac OS** - Tested by GitHub Actions (any version is supported).
131
+ //!
132
+ //! - **Windows** - Tested by GitHub Actions - (Windows 7+ is officially supported).
133
+ //!
134
+ //! - **Emscripten** - Works if compiled with \ref ASMJIT_NO_JIT. AsmJit cannot generate WASM code, but can be
135
+ //! used to generate X86/X64 code within a browser, for example.
136
+ //!
137
+ //! - Untested:
138
+ //!
139
+ //! - **BSDs** - No maintainers, no CI environment to regularly test BSDs, but they should work out of box.
140
+ //!
141
+ //! - **Haiku** - Not regularly tested, but reported to work.
142
+ //!
143
+ //! - **Other** operating systems would require some testing and support in the following files:
144
+ //! - [core/api-config.h](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/api-config.h)
145
+ //! - [core/osutils.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/osutils.cpp)
146
+ //! - [core/virtmem.cpp](https://github.com/asmjit/asmjit/tree/master/src/asmjit/core/virtmem.cpp)
147
+ //!
148
+ //! ### Supported Backends / Architectures
149
+ //!
150
+ //! - **X86** and **X86_64** - Both 32-bit and 64-bit backends tested on CI.
151
+ //! - **AArch64** - AArch64 backend is currently only partially tested (there is no native AArch64 runner to test
152
+ //! AsmJit Builder/Compiler)
153
+ //!
154
+ //! ### Static Builds and Embedding
155
+ //!
156
+ //! These definitions can be used to enable static library build. Embed is used when AsmJit's source code is embedded
157
+ //! directly in another project, implies static build as well.
158
+ //!
159
+ //! - \ref ASMJIT_EMBED - Asmjit is embedded, implies \ref ASMJIT_STATIC.
160
+ //! - \ref ASMJIT_STATIC - Enable static-library build.
161
+ //!
162
+ //! \note Projects that use AsmJit statically must define \ref ASMJIT_STATIC in all compilation units that use AsmJit,
163
+ //! otherwise AsmJit would use dynamic library imports in \ref ASMJIT_API decorator. The recommendation is to define
164
+ //! this macro across the whole project that uses AsmJit this way.
165
+ //!
166
+ //! ### Build Configuration
167
+ //!
168
+ //! These definitions control whether asserts are active or not. By default AsmJit would autodetect build configuration
169
+ //! from existing pre-processor definitions, but this behavior can be overridden, for example to enable debug asserts
170
+ //! in release configuration.
171
+ //!
172
+ //! - \ref ASMJIT_BUILD_DEBUG - Overrides build configuration to debug, asserts will be enabled in this case.
173
+ //! - \ref ASMJIT_BUILD_RELEASE - Overrides build configuration to release, asserts will be disabled in this case.
174
+ //!
175
+ //! \note There is usually no need to override the build configuration. AsmJit detects the build configuration by
176
+ //! checking whether `NDEBUG` is defined and automatically defines \ref ASMJIT_BUILD_RELEASE if configuration overrides
177
+ //! were not used. We only recommend using build configuration overrides in special situations, like using AsmJit in
178
+ //! release configuration with asserts enabled for whatever reason.
179
+ //!
180
+ //! ### AsmJit Backends
181
+ //!
182
+ //! AsmJit currently supports only X86/X64 backend, but the plan is to add more backends in the future. By default
183
+ //! AsmJit builds only the host backend, which is autodetected at compile-time, but this can be overridden.
184
+ //!
185
+ //! - \ref ASMJIT_NO_X86 - Disable X86/X64 backends.
186
+ //! - \ref ASMJIT_NO_FOREIGN - Disables the support for foreign architectures.
187
+ //!
188
+ //! ### Features Selection
189
+ //!
190
+ //! AsmJit builds by defaults all supported features, which includes all emitters, logging, instruction validation and
191
+ //! introspection, and JIT memory allocation. Features can be disabled at compile time by using `ASMJIT_NO_...`
192
+ //! definitions.
193
+ //!
194
+ //! - \ref ASMJIT_NO_DEPRECATED - Disables deprecated API at compile time so it won't be available and the
195
+ //! compilation will fail if there is attempt to use such API. This includes deprecated classes, namespaces,
196
+ //! enumerations, and functions.
197
+ //!
198
+ //! - \ref ASMJIT_NO_BUILDER - Disables \ref asmjit_builder functionality completely. This implies \ref
199
+ //! ASMJIT_NO_COMPILER as \ref asmjit_compiler cannot be used without \ref asmjit_builder.
200
+ //!
201
+ //! - \ref ASMJIT_NO_COMPILER - Disables \ref asmjit_compiler functionality completely.
202
+ //!
203
+ //! - \ref ASMJIT_NO_JIT - Disables JIT memory management and \ref JitRuntime.
204
+ //!
205
+ //! - \ref ASMJIT_NO_LOGGING - Disables \ref Logger and \ref Formatter.
206
+ //!
207
+ //! - \ref ASMJIT_NO_TEXT - Disables everything that contains string representation of AsmJit constants, should
208
+ //! be used together with \ref ASMJIT_NO_LOGGING as logging doesn't make sense without the ability to query
209
+ //! instruction names, register names, etc...
210
+ //!
211
+ //! - \ref ASMJIT_NO_VALIDATION - Disables validation API.
212
+ //!
213
+ //! - \ref ASMJIT_NO_INTROSPECTION - Disables instruction introspection API, must be used together with \ref
214
+ //! ASMJIT_NO_COMPILER as \ref asmjit_compiler requires introspection for its liveness analysis and register
215
+ //! allocation.
216
+ //!
217
+ //! \note It's not recommended to disable features if you plan to build AsmJit as a shared library that will be
218
+ //! used by multiple projects that you don't control how AsmJit was built (for example AsmJit in a Linux distribution).
219
+ //! The possibility to disable certain features exists mainly for customized AsmJit builds.
220
+
221
+
222
+ //! \defgroup asmjit_breaking_changes Breaking Changes
223
+ //! \brief Documentation of breaking changes
224
+ //!
225
+ //! ### Overview
226
+ //!
227
+ //! AsmJit is a live project that is being actively developed. Deprecating the existing API in favor of a new
228
+ //! one is preferred, but it's not always possible if the changes are significant. AsmJit authors prefer to do
229
+ //! accumulated breaking changes at once instead of breaking the API often. This page documents deprecated and
230
+ //! removed APIs and should serve as a how-to guide for people that want to port existing code to work with the
231
+ //! newest AsmJit.
232
+ //!
233
+ //! ### Tips
234
+ //!
235
+ //! Useful tips before you start:
236
+ //!
237
+ //! - Visit our [Public Gitter Channel](https://gitter.im/asmjit/asmjit) if you need a quick help.
238
+ //!
239
+ //! - Build AsmJit with `ASMJIT_NO_DEPRECATED` macro defined to make sure that you are not using deprecated
240
+ //! functionality at all. Deprecated functions are decorated with `ASMJIT_DEPRECATED()` macro, but sometimes
241
+ //! it's not possible to decorate everything like classes, which are used by deprecated functions as well,
242
+ //! because some compilers would warn about that. If your project compiles fine with `ASMJIT_NO_DEPRECATED`
243
+ //! it's not using anything, which was deprecated.
244
+ //!
245
+ //! ### Changes committed at 2021-12-13
246
+ //!
247
+ //! Core changes:
248
+ //!
249
+ //! - Removed old deprecated API.
250
+ //!
251
+ //! - Many enumerations were changed to enum class, and many public APIs were changed to use such enums instead
252
+ //! of uint32_t. This change makes some APIs backward incompatible - there are no deprecations this time.
253
+ //!
254
+ //! - Extracted operand signature manipulation to `OperandSignature`.
255
+ //! - Setting function arguments through `Compiler::setArg()` was deprecated, use FuncNode::setArg() instead.
256
+ //! - Moved `{arch}::Features::k` to `CpuFeatures::{arch}::k`.
257
+ //! - Moved `BaseEmitter::kEncodingOption` to `EncodingOptions::k`.
258
+ //! - Moved `BaseEmitter::kFlag` to `EmitterFlags::k`.
259
+ //! - Moved `BaseEmitter::kType` to `EmitterType::k`.
260
+ //! - Moved `BaseEmitter::kValidationOption` to `DiagnosticOptions::kValidate`.
261
+ //! - Moved `BaseFeatures` to `CpuFeatures`.
262
+ //! - Moved `BaseInst::kControl` to `InstControlFlow::k`.
263
+ //! - Moved `BaseInst::kOption` and `x86::Inst::kOption` to `InstOptions::k`.
264
+ //! - Moved `BaseNode::kNode` to `NodeType::k`.
265
+ //! - Moved `BaseReg::kGroup` and `x86::Reg::kGroup` to `RegGroup::k`.
266
+ //! - Moved `BaseReg::kType` and `x86::Reg::kType` to `RegType::k`.
267
+ //! - Moved `CallConv::kFlag` to `CallConvFlags::k`.
268
+ //! - Moved `CallConv::kId` to `CallConvId::k`.
269
+ //! - Moved `CallConv::kStrategy` to `CallConvStrategy::k`.
270
+ //! - Moved `CodeBuffer::kFlag` to `CodeBufferFlags`.
271
+ //! - Moved `ConstPool::kScope` to `ConstPoolScope::k`.
272
+ //! - Moved `Environment::kArch` to `Arch::k`.
273
+ //! - Moved `Environment::kSubArch` to `SubArch::k`.
274
+ //! - Moved `Environment::kFormat` to `OjectFormat::k`.
275
+ //! - Moved `Environment::kPlatform` to `Platform::k`.
276
+ //! - Moved `Environment::kAbi` to `PlatformABI::k`.
277
+ //! - Moved `Environment::kVendor` to `Vendor::k`.
278
+ //! - Moved `FormatOptions::kFlag` to `FormatFlags::k` and `DiagnosticOptions::k` (Compiler diagnostics flags).
279
+ //! - Moved `FormatOptions::kIndentation` to `FormatIndentationGroup::k`.
280
+ //! - Moved `FuncFrame::kAttr` to `FuncAttributes::k`.
281
+ //! - Moved `Globals::kReset` to `ResetPolicy::k`.
282
+ //! - Moved `InstDB::kAvx512Flag` to `InstDB::Avx512Flags::k`.
283
+ //! - Moved `InstDB::kFlag` to `InstDB::InstFlags::k`.
284
+ //! - Moved `InstDB::kMemFlag` to `InstDB::OpFlags::kMem`.
285
+ //! - Moved `InstDB::kMode` to `InstDB::Mode::k`.
286
+ //! - Moved `InstDB::kOpFlag` to `InstDB::OpFlags::k{OpType}...`.
287
+ //! - Moved `JitAllocator::kOption` to `JitAllocatorOptions::k`.
288
+ //! - Moved `Label::kType` to `LabelType::k`.
289
+ //! - Moved `Operand::kOpType` to `OperandType::k`.
290
+ //! - Moved `OpRWInfo::kFlag` to `OpRWFlags::k`.
291
+ //! - Moved `Type::kId` to `TypeId::k`.
292
+ //! - Moved `VirtMem::k` to `VirtMem::MemoryFlags::k`.
293
+ //!
294
+ //! ### Changes committed at 2020-05-30
295
+ //!
296
+ //! AsmJit has been cleaned up significantly, many todo items have been fixed and many functions and classes have
297
+ //! been redesigned, some in an incompatible way.
298
+ //!
299
+ //! Core changes:
300
+ //!
301
+ //! - `Imm` operand has now only `Imm::value()` and `Imm::valueAs()` functions that return its value content,
302
+ //! and `Imm::setValue()` function that sets the content. Functions like `setI8()`, `setU8()` were deprecated.
303
+ //!
304
+ //! Old functions were deprecated, but code using them should still compile.
305
+ //!
306
+ //! - `ArchInfo` has been replaced with `Environment`. Environment provides more details about the architecture,
307
+ //! but drops some properties that were used by arch info - `gpSize(`) and `gpCount()`. `gpSize()` can be replaced
308
+ //! with `registerSize()` getter, which returns a native register size of the architecture the environment uses.
309
+ //! However, `gpCount()` was removed - at the moment `ArchTraits` can be used to access such properties.
310
+ //!
311
+ //! Some other functions were renamed, like `ArchInfo::isX86Family()` is now `Environment::isFamilyX86()`, etc.
312
+ //! The reason for changing the order was support for more propertries and all the accessors now start with the
313
+ //! type of the property, like `Environment::isPlatformWindows()`.
314
+ //!
315
+ //! This function causes many other classes to provide `environment()` getter instead of `archInfo()` getter.
316
+ //! In addition, AsmJit now uses `arch()` to get an architecture instead of `archId()`. `ArchInfo::kIdXXX` was
317
+ //! renamed to `Environment::kArchXXX`.
318
+ //!
319
+ //! Some functions were deprecated, some removed...
320
+ //!
321
+ //! - `CodeInfo` has been removed in favor of `Environment`. If you used `CodeInfo` to set architecture and base
322
+ //! address, this is now possible with `Environment` and setting base address explicitly by `CodeHolder::init()`
323
+ //! - the first argument is `Environment`, and the second argument is base address, which defaults to
324
+ //! `Globals::kNoBaseAddress`.
325
+ //!
326
+ //! CodeInfo class was deprecated, but the code using it should still compile with warnings.
327
+ //!
328
+ //! - `CallConv` has been updated to offer a more unified way of representing calling conventions - many calling
329
+ //! conventions were abstracted to follow standard naming like `CallConvId::kCDecl` or `CallConvId::kStdCall`.
330
+ //!
331
+ //! This change means that other APIs like `FuncDetail::init()` now require both, calling convention and target
332
+ //! `Environment`.
333
+ //!
334
+ //! - `Logging` namespace has been renamed to `Formatter`, which now provides general functionality for formatting
335
+ //! in AsmJit.
336
+ //!
337
+ //! Logging namespace should still work, but its use is deprecated. Unfortunately this will be without deprecation
338
+ //! warnings, so make sure you don't use it.
339
+ //!
340
+ //! - `Data64`, `Data128`, and `Data256` structs were deprecated and should no longer be used. There is no replacement,
341
+ //! AsmJit users should simply create their own structures if they need them or use the new repeated embed API in
342
+ //! emitters, see `BaseEmitter::embedDataArray()`.
343
+ //!
344
+ //! Emitter changes:
345
+ //!
346
+ //! - `BaseEmitter::emit()` function signature has been changed to accept 3 operands by reference and the rest 3
347
+ //! operands as a continuous array. This change is purely cosmetic and shouldn't affect users as emit() has many
348
+ //! overloads that dispatch to the right function.
349
+ //!
350
+ //! - `x86::Emitter` (Assembler, Builder, Compiler) deprecates embed utilities like `dint8()`, `duint8()`, `duint16()`,
351
+ //! `dxmm()`, etc... in favor of a new and more powerful `BaseEmitter::embedDataArray()`. This function also allows
352
+ //! emitting repeated values and/or patterns, which is used by helpers `BaseEmitter::embedUInt8()`, and others...
353
+ //!
354
+ //! - Validation is now available through `BaseEmitter::DiagnosticOptions`, which can be enabled/disabled through
355
+ //! `BaseEmitter::addDiagnosticOptions()` and `BaseEmitter::clearDiagnosticOptions()`, respectively. Validation
356
+ //! options now separate between encoding and Builder/Compiler so it's possible to choose the granularity required.
357
+ //!
358
+ //! Builder changes:
359
+ //!
360
+ //! - Internal functions for creating nodes were redesigned. They now accept a pointer to the node created as
361
+ //! a first parameter. These changes should not affect AsmJit users as these functions were used internally.
362
+ //!
363
+ //! Compiler changes:
364
+ //!
365
+ //! - `FuncCallNode` has been renamed to `InvokeNode`. Additionally, function calls should now use
366
+ //! `x86::Compiler::invoke()` instead of `call()`. The reason behind this is to remove the confusion between a
367
+ //! `call` instruction and AsmJit's `call()` intrinsic, which is now `invoke()`.
368
+ //!
369
+ //! - Creating new nodes also changed. Now the preferred way of invoking a function is to call
370
+ //! `x86::Compiler::invoke()` where the first argument is `InvokeNode**`. The function now returns an error and
371
+ //! would call `ErrorHandler` in case of a failure. Error handling was unspecified in the past - the function was
372
+ //! marked noexcept, but called error handler, which could throw.
373
+ //!
374
+ //! The reason behind this change is to make the API consistent with other changes and to also make it possible
375
+ //! to inspect the possible error. In the previous API it returned a new node or `nullptr` in case of error,
376
+ //! which the user couldn't inspect unless there was an attached `ErrorHandler`.
377
+ //!
378
+ //! Samples:
379
+ //!
380
+ //! ```
381
+ //! #include <asmjit/x86.h>
382
+ //!
383
+ //! using namespace asmjit;
384
+ //!
385
+ //! // The basic setup of JitRuntime and CodeHolder changed, use environment()
386
+ //! // instead of codeInfo().
387
+ //! void basicSetup() {
388
+ //! JitRuntime rt;
389
+ //! CodeHolder code(rt.environment());
390
+ //! }
391
+ //!
392
+ //! // Calling a function (Compiler) changed - use invoke() instead of call().
393
+ //! void functionInvocation(x86::Compiler& cc) {
394
+ //! InvokeNode* invokeNode;
395
+ //! cc.invoke(&invokeNode, targetOperand, FuncSignatureT<...>(...));
396
+ //! }
397
+ //! ```
398
+
399
+
400
+ //! \defgroup asmjit_core Core
401
+ //! \brief Globals, code storage, and emitter interface.
402
+ //!
403
+ //! ### Overview
404
+ //!
405
+ //! AsmJit library uses \ref CodeHolder to hold code during code generation and emitters inheriting from \ref
406
+ //! BaseEmitter to emit code. CodeHolder uses containers to manage its data:
407
+ //!
408
+ //! - \ref Section - stores information about a code or data section.
409
+ //! - \ref CodeBuffer - stores actual code or data, part of \ref Section.
410
+ //! - \ref LabelEntry - stores information about a label - its name, offset, section where it belongs to, and
411
+ //! other bits.
412
+ //! - \ref LabelLink - stores information about yet unbound label, which was already used by the assembler.
413
+ //! - \ref RelocEntry - stores information about a relocation.
414
+ //! - \ref AddressTableEntry - stores information about an address, which was used in a jump or call. Such
415
+ //! address may need relocation.
416
+ //!
417
+ //! To generate code you would need to instantiate at least the following classes:
418
+ //!
419
+ //! - \ref CodeHolder - to hold code during code generation.
420
+ //! - \ref BaseEmitter - to emit code into \ref CodeHolder.
421
+ //! - \ref Target (optional) - most likely \ref JitRuntime to keep the generated code in executable memory. \ref
422
+ //! Target can be customized by inheriting from it.
423
+ //!
424
+ //! There are also other core classes that are important:
425
+ //!
426
+ //! - \ref Environment - describes where the code will run. Environment brings the concept of target triples or
427
+ //! tuples into AsmJit, which means that users can specify target architecture, platform, and ABI.
428
+ //! - \ref TypeId - encapsulates lightweight type functionality that can be used to describe primitive and vector
429
+ //! types. Types are used by higher level utilities, for example by \ref asmjit_function and \ref asmjit_compiler.
430
+ //! - \ref CpuInfo - encapsulates CPU information - stores both CPU information and CPU features described by \ref
431
+ //! CpuFeatures.
432
+ //!
433
+ //! AsmJit also provides global constants:
434
+ //!
435
+ //! - \ref Globals - namespace that provides global constants.
436
+ //! - \ref ByteOrder - byte-order constants and functionality.
437
+ //!
438
+ //! \note CodeHolder examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
439
+ //!
440
+ //! ### CodeHolder & Emitters
441
+ //!
442
+ //! The example below shows how the mentioned classes interact to generate X86 code:
443
+ //!
444
+ //! ```
445
+ //! #include <asmjit/x86.h>
446
+ //! #include <stdio.h>
447
+ //!
448
+ //! using namespace asmjit;
449
+ //!
450
+ //! // Signature of the generated function.
451
+ //! typedef int (*Func)(void);
452
+ //!
453
+ //! int main() {
454
+ //! JitRuntime rt; // Runtime specialized for JIT code execution.
455
+ //!
456
+ //! CodeHolder code; // Holds code and relocation information.
457
+ //! code.init(rt.environment()); // Initialize code to match the JIT environment.
458
+ //!
459
+ //! x86::Assembler a(&code); // Create and attach x86::Assembler to code.
460
+ //! a.mov(x86::eax, 1); // Move one to eax register.
461
+ //! a.ret(); // Return from function.
462
+ //! // ===== x86::Assembler is no longer needed from here and can be destroyed =====
463
+ //!
464
+ //! Func fn; // Holds address to the generated function.
465
+ //! Error err = rt.add(&fn, &code); // Add the generated code to the runtime.
466
+ //! if (err) return 1; // Handle a possible error returned by AsmJit.
467
+ //! // ===== CodeHolder is no longer needed from here and can be destroyed =====
468
+ //!
469
+ //! int result = fn(); // Execute the generated code.
470
+ //! printf("%d\n", result); // Print the resulting "1".
471
+ //!
472
+ //! // All classes use RAII, all resources will be released before `main()` returns,
473
+ //! // the generated function can be, however, released explicitly if you intend to
474
+ //! // reuse or keep the runtime alive, which you should in a production-ready code.
475
+ //! rt.release(fn);
476
+ //!
477
+ //! return 0;
478
+ //! }
479
+ //! ```
480
+ //!
481
+ //! The example above used \ref x86::Assembler as an emitter. AsmJit provides the following emitters that offer various
482
+ //! levels of abstraction:
483
+ //!
484
+ //! - \ref asmjit_assembler - Low-level emitter that emits directly to \ref CodeBuffer.
485
+ //! - \ref asmjit_builder - Low-level emitter that emits to a \ref BaseNode list.
486
+ //! - \ref asmjit_compiler - High-level emitter that provides register allocation.
487
+ //!
488
+ //! ### Targets and JitRuntime
489
+ //!
490
+ //! AsmJit's \ref Target is an interface that provides basic target abstraction. At the moment AsmJit provides only
491
+ //! one implementation called \ref JitRuntime, which as the name suggests provides JIT code target and execution
492
+ //! runtime. \ref JitRuntime provides all the necessary stuff to implement a simple JIT compiler with basic memory
493
+ //! management. It only provides \ref JitRuntime::add() and \ref JitRuntime::release() functions that are used to
494
+ //! either add code to the runtime or release it. \ref JitRuntime doesn't do any decisions on when the code should be
495
+ //! released, the decision is up to the developer.
496
+ //!
497
+ //! See more at \ref asmjit_virtual_memory group.
498
+ //!
499
+ //! ### More About Environment
500
+ //!
501
+ //! In the previous example the \ref Environment is retrieved from \ref JitRuntime. It's logical as \ref JitRuntime
502
+ //! always returns an \ref Environment that is compatible with the host. For example if your application runs on X86_64
503
+ //! CPU the \ref Environment returned will use \ref Arch::kX64 architecture in contrast to \ref Arch::kX86, which will
504
+ //! be used in 32-bit mode on an X86 target.
505
+ //!
506
+ //! AsmJit allows to setup the \ref Environment manually and to select a different architecture and ABI when necessary.
507
+ //! So let's do something else this time, let's always generate a 32-bit code and print its binary representation. To
508
+ //! do that, we can create our own \ref Environment and initialize it to \ref Arch::kX86.
509
+ //!
510
+ //! ```
511
+ //! #include <asmjit/x86.h>
512
+ //! #include <stdio.h>
513
+ //!
514
+ //! using namespace asmjit;
515
+ //!
516
+ //! int main(int argc, char* argv[]) {
517
+ //! using namespace asmjit::x86;
518
+ //!
519
+ //! // Create a custom environment initialized to 32-bit X86 architecture.
520
+ //! Environment env;
521
+ //! env.setArch(Arch::kX86);
522
+ //!
523
+ //! CodeHolder code; // Create a CodeHolder.
524
+ //! code.init(env); // Initialize CodeHolder with custom environment.
525
+ //!
526
+ //! // Generate a 32-bit function that sums 4 floats and looks like:
527
+ //! // void func(float* dst, const float* a, const float* b)
528
+ //! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
529
+ //!
530
+ //! a.mov(eax, dword_ptr(esp, 4)); // Load the destination pointer.
531
+ //! a.mov(ecx, dword_ptr(esp, 8)); // Load the first source pointer.
532
+ //! a.mov(edx, dword_ptr(esp, 12)); // Load the second source pointer.
533
+ //!
534
+ //! a.movups(xmm0, ptr(ecx)); // Load 4 floats from [ecx] to XMM0.
535
+ //! a.movups(xmm1, ptr(edx)); // Load 4 floats from [edx] to XMM1.
536
+ //! a.addps(xmm0, xmm1); // Add 4 floats in XMM1 to XMM0.
537
+ //! a.movups(ptr(eax), xmm0); // Store the result to [eax].
538
+ //! a.ret(); // Return from function.
539
+ //!
540
+ //! // We have no Runtime this time, it's on us what we do with the code.
541
+ //! // CodeHolder stores code in Section, which provides some basic properties
542
+ //! // and CodeBuffer structure. We are interested in section's CodeBuffer.
543
+ //! //
544
+ //! // NOTE: The first section is always '.text', it can be retrieved by
545
+ //! // code.sectionById(0) or simply by code.textSection().
546
+ //! CodeBuffer& buffer = code.textSection()->buffer();
547
+ //!
548
+ //! // Print the machine-code generated or do something else with it...
549
+ //! // 8B4424048B4C24048B5424040F28010F58010F2900C3
550
+ //! for (size_t i = 0; i < buffer.length; i++)
551
+ //! printf("%02X", buffer.data[i]);
552
+ //!
553
+ //! return 0;
554
+ //! }
555
+ //! ```
556
+ //!
557
+ //! ### Explicit Code Relocation
558
+ //!
559
+ //! In addition to \ref Environment, \ref CodeHolder can be configured to specify a base-address (or a virtual base
560
+ //! address in a linker terminology), which could be static (useful when you know the location where the target's
561
+ //! machine code will be) or dynamic. AsmJit assumes dynamic base-address by default and relocates the code held by
562
+ //! \ref CodeHolder to a user provided address on-demand. To be able to relocate to a user provided address it needs
563
+ //! to store some information about relocations, which is represented by \ref RelocEntry. Relocation entries are only
564
+ //! required if you call external functions from the generated code that cannot be encoded by using a 32-bit
565
+ //! displacement (64-bit displacements are not provided by aby supported architecture).
566
+ //!
567
+ //! There is also a concept called \ref LabelLink - label link is a lightweight data structure that doesn't have any
568
+ //! identifier and is stored in \ref LabelEntry as a single-linked list. Label link represents either unbound yet used
569
+ //! label and cross-sections links (only relevant to code that uses multiple sections). Since crossing sections is
570
+ //! something that cannot be resolved immediately these links persist until offsets of these sections are assigned and
571
+ //! until \ref CodeHolder::resolveUnresolvedLinks() is called. It's an error if you end up with code that has
572
+ //! unresolved label links after flattening. You can verify it by calling \ref CodeHolder::hasUnresolvedLinks(), which
573
+ //! inspects the value returned by \ref CodeHolder::unresolvedLinkCount().
574
+ //!
575
+ //! AsmJit can flatten code that uses multiple sections by assigning each section an incrementing offset that respects
576
+ //! its alignment. Use \ref CodeHolder::flatten() to do that. After the sections are flattened their offsets and
577
+ //! virtual sizes are adjusted to respect each section's buffer size and alignment. The \ref
578
+ //! CodeHolder::resolveUnresolvedLinks() function must be called before relocating the code held by \ref CodeHolder.
579
+ //! You can also flatten your code manually by iterating over all sections and calculating their offsets (relative to
580
+ //! base) by your own algorithm. In that case \ref CodeHolder::flatten() should not be called, however,
581
+ //! \ref CodeHolder::resolveUnresolvedLinks() should be.
582
+ //!
583
+ //! The example below shows how to use a built-in virtual memory allocator \ref JitAllocator instead of using \ref
584
+ //! JitRuntime (just in case you want to use your own memory management) and how to relocate the generated code
585
+ //! into your own memory block - you can use your own virtual memory allocator if you prefer that, but that's OS
586
+ //! specific and not covered by the documentation.
587
+ //!
588
+ //! The following code is similar to the previous one, but implements a function working in both 32-bit and 64-bit
589
+ //! environments:
590
+ //!
591
+ //! ```
592
+ //! #include <asmjit/x86.h>
593
+ //! #include <stdio.h>
594
+ //!
595
+ //! using namespace asmjit;
596
+ //!
597
+ //! typedef void (*SumIntsFunc)(int* dst, const int* a, const int* b);
598
+ //!
599
+ //! int main() {
600
+ //! // Create a custom environment that matches the current host environment.
601
+ //! Environment env = Environment::host();
602
+ //!
603
+ //! CodeHolder code; // Create a CodeHolder.
604
+ //! code.init(env); // Initialize CodeHolder with environment.
605
+ //!
606
+ //! x86::Assembler a(&code); // Create and attach x86::Assembler to `code`.
607
+ //!
608
+ //! // Signature: 'void func(int* dst, const int* a, const int* b)'.
609
+ //! x86::Gp dst;
610
+ //! x86::Gp src_a;
611
+ //! x86::Gp src_b;
612
+ //!
613
+ //! // Handle the difference between 32-bit and 64-bit calling conventions
614
+ //! // (arguments passed through stack vs. arguments passed by registers).
615
+ //! if (env.is32Bit()) {
616
+ //! dst = x86::eax;
617
+ //! src_a = x86::ecx;
618
+ //! src_b = x86::edx;
619
+ //! a.mov(dst , x86::dword_ptr(x86::esp, 4));
620
+ //! a.mov(src_a, x86::dword_ptr(x86::esp, 8));
621
+ //! a.mov(src_b, x86::dword_ptr(x86::esp, 12));
622
+ //! }
623
+ //! else {
624
+ //! if (env.isPlatformWindows()) {
625
+ //! dst = x86::rcx; // First argument (destination pointer).
626
+ //! src_a = x86::rdx; // Second argument (source 'a' pointer).
627
+ //! src_b = x86::r8; // Third argument (source 'b' pointer).
628
+ //! }
629
+ //! else {
630
+ //! dst = x86::rdi; // First argument (destination pointer).
631
+ //! src_a = x86::rsi; // Second argument (source 'a' pointer).
632
+ //! src_b = x86::rdx; // Third argument (source 'b' pointer).
633
+ //! }
634
+ //! }
635
+ //!
636
+ //! a.movdqu(x86::xmm0, x86::ptr(src_a)); // Load 4 ints from [src_a] to XMM0.
637
+ //! a.movdqu(x86::xmm1, x86::ptr(src_b)); // Load 4 ints from [src_b] to XMM1.
638
+ //! a.paddd(x86::xmm0, x86::xmm1); // Add 4 ints in XMM1 to XMM0.
639
+ //! a.movdqu(x86::ptr(dst), x86::xmm0); // Store the result to [dst].
640
+ //! a.ret(); // Return from function.
641
+ //!
642
+ //! // Even when we didn't use multiple sections AsmJit could insert one section
643
+ //! // called '.addrtab' (address table section), which would be filled by data
644
+ //! // required by relocations (absolute jumps and calls). You can omit this code
645
+ //! // if you are 100% sure your code doesn't contain multiple sections and
646
+ //! // such relocations. You can use `CodeHolder::hasAddressTable()` to verify
647
+ //! // whether the address table section does exist.
648
+ //! code.flatten();
649
+ //! code.resolveUnresolvedLinks();
650
+ //!
651
+ //! // After the code was generated it can be relocated manually to any memory
652
+ //! // location, however, we need to know it's size before we perform memory
653
+ //! // allocation. `CodeHolder::codeSize()` returns the worst estimated code
654
+ //! // size in case that relocations are not possible without trampolines (in
655
+ //! // that case some extra code at the end of the current code buffer is
656
+ //! // generated during relocation).
657
+ //! size_t estimatedSize = code.codeSize();
658
+ //!
659
+ //! // Instead of rolling up our own memory allocator we can use the one AsmJit
660
+ //! // provides. It's decoupled so you don't need to use `JitRuntime` for that.
661
+ //! JitAllocator allocator;
662
+ //!
663
+ //! // Allocate an executable virtual memory and handle a possible failure.
664
+ //! void* p = allocator.alloc(estimatedSize);
665
+ //! if (!p)
666
+ //! return 0;
667
+ //!
668
+ //! // Now relocate the code to the address provided by the memory allocator.
669
+ //! // Please note that this DOESN'T COPY anything to `p`. This function will
670
+ //! // store the address in CodeHolder and use relocation entries to patch the
671
+ //! // existing code in all sections to respect the base address provided.
672
+ //! code.relocateToBase((uint64_t)p);
673
+ //!
674
+ //! // This is purely optional. There are cases in which the relocation can omit
675
+ //! // unneeded data, which would shrink the size of address table. If that
676
+ //! // happened the codeSize returned after relocateToBase() would be smaller
677
+ //! // than the originally `estimatedSize`.
678
+ //! size_t codeSize = code.codeSize();
679
+ //!
680
+ //! // This will copy code from all sections to `p`. Iterating over all sections
681
+ //! // and calling `memcpy()` would work as well, however, this function supports
682
+ //! // additional options that can be used to also zero pad sections' virtual
683
+ //! // size, etc.
684
+ //! //
685
+ //! // With some additional features, copyFlattenData() does roughly this:
686
+ //! // for (Section* section : code.sections())
687
+ //! // memcpy((uint8_t*)p + section->offset(),
688
+ //! // section->data(),
689
+ //! // section->bufferSize());
690
+ //! code.copyFlattenedData(p, codeSize, CopySectionFlags::kPadSectionBuffer);
691
+ //!
692
+ //! // Execute the generated function.
693
+ //! int inA[4] = { 4, 3, 2, 1 };
694
+ //! int inB[4] = { 1, 5, 2, 8 };
695
+ //! int out[4];
696
+ //!
697
+ //! // This code uses AsmJit's ptr_as_func<> to cast between void* and SumIntsFunc.
698
+ //! ptr_as_func<SumIntsFunc>(p)(out, inA, inB);
699
+ //!
700
+ //! // Prints {5 8 4 9}
701
+ //! printf("{%d %d %d %d}\n", out[0], out[1], out[2], out[3]);
702
+ //!
703
+ //! // Release 'p' is it's no longer needed. It will be destroyed with 'vm'
704
+ //! // instance anyway, but it's a good practice to release it explicitly
705
+ //! // when you know that the function will not be needed anymore.
706
+ //! allocator.release(p);
707
+ //!
708
+ //! return 0;
709
+ //! }
710
+ //! ```
711
+ //!
712
+ //! If you know the base-address in advance (before the code generation) it can be passed as a second argument to
713
+ //! \ref CodeHolder::init(). In that case the Assembler will know the absolute position of each instruction and
714
+ //! would be able to use it during instruction encoding to prevent relocations where possible. The following example
715
+ //! shows how to configure the base address:
716
+ //!
717
+ //! ```
718
+ //! #include <asmjit/x86.h>
719
+ //! #include <stdio.h>
720
+ //!
721
+ //! using namespace asmjit;
722
+ //!
723
+ //! void initializeCodeHolder(CodeHolder& code) {
724
+ //! Environment env = Environment::host();
725
+ //! uint64_t baseAddress = uint64_t(0x1234);
726
+ //!
727
+ //! // initialize CodeHolder with environment and custom base address.
728
+ //! code.init(env, baseAddress);
729
+ //! }
730
+ //! ```
731
+ //!
732
+ //! ### Label Offsets and Links
733
+ //!
734
+ //! When a label that is not yet bound is used by the Assembler, it creates a \ref LabelLink, which is then added to
735
+ //! a \ref LabelEntry. These links are also created if a label is used in a different section than in which it was
736
+ //! bound. Let's examine some functions that can be used to check whether there are any unresolved links.
737
+ //!
738
+ //! ```
739
+ //! #include <asmjit/core.h>
740
+ //! #include <stdio.h>
741
+ //!
742
+ //! using namespace asmjit;
743
+ //!
744
+ //! void labelLinksExample(CodeHolder& code, const Label& label) {
745
+ //! // Tests whether the `label` is bound.
746
+ //! bool isBound = code.isLabelBound(label);
747
+ //! printf("Label %u is %s\n", label.id(), isBound ? "bound" : "not bound");
748
+ //!
749
+ //! // Returns true if the code contains either referenced, but unbound
750
+ //! // labels, or cross-section label links that are not resolved yet.
751
+ //! bool hasUnresolved = code.hasUnresolvedLinks(); // Boolean answer.
752
+ //! size_t nUnresolved = code.unresolvedLinkCount(); // Count of unresolved links.
753
+ //!
754
+ //! printf("Number of unresolved links: %zu\n", nUnresolved);
755
+ //! }
756
+ //! ```
757
+ //!
758
+ //! There is no function that would return the number of unbound labels as this is completely unimportant from
759
+ //! CodeHolder's perspective. If a label is not used then it doesn't matter whether it's bound or not, only actually
760
+ //! used labels matter. After a Label is bound it's possible to query its offset offset relative to the start of the
761
+ //! section where it was bound:
762
+ //!
763
+ //! ```
764
+ //! #include <asmjit/core.h>
765
+ //! #include <stdio.h>
766
+ //!
767
+ //! using namespace asmjit;
768
+ //!
769
+ //! void labelOffsetExample(CodeHolder& code, const Label& label) {
770
+ //! // Label offset is known after it's bound. The offset provided is relative
771
+ //! // to the start of the section, see below for alternative. If the given
772
+ //! // label is not bound the offset returned will be zero. It's recommended
773
+ //! // to always check whether the label is bound before using its offset.
774
+ //! uint64_t sectionOffset = code.labelOffset(label);
775
+ //! printf("Label offset relative to section: %llu\n", (unsigned long long)sectionOffset);
776
+ //!
777
+ //! // If you use multiple sections and want the offset relative to the base.
778
+ //! // NOTE: This function expects that the section has already an offset and
779
+ //! // the label-link was resolved (if this is not true you will still get an
780
+ //! // offset relative to the start of the section).
781
+ //! uint64_t baseOffset = code.labelOffsetFromBase(label);
782
+ //! printf("Label offset relative to base: %llu\n", (unsigned long long)baseOffset);
783
+ //! }
784
+ //! ```
785
+ //!
786
+ //! ### Sections
787
+ //!
788
+ //! AsmJit allows to create multiple sections within the same \ref CodeHolder. A test-case
789
+ //! [asmjit_test_x86_sections.cpp](https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_x86_sections.cpp)
790
+ //! can be used as a reference point although the following example should also provide a useful insight:
791
+ //!
792
+ //! ```
793
+ //! #include <asmjit/x86.h>
794
+ //! #include <stdio.h>
795
+ //!
796
+ //! using namespace asmjit;
797
+ //!
798
+ //! void sectionsExample(CodeHolder& code) {
799
+ //! // Text section is always provided as the first section.
800
+ //! Section* text = code.textSection(); // or code.sectionById(0);
801
+ //!
802
+ //! // To create another section use CodeHolder::newSection().
803
+ //! Section* data;
804
+ //! Error err = code.newSection(&data,
805
+ //! ".data", // Section name
806
+ //! SIZE_MAX, // Name length if the name is not null terminated (or SIZE_MAX).
807
+ //! SectionFlags::kNone, // Section flags, see SectionFlags.
808
+ //! 8, // Section alignment, must be power of 2.
809
+ //! 0); // Section order value (optional, default 0).
810
+ //!
811
+ //! // When you switch sections in Assembler, Builder, or Compiler the cursor
812
+ //! // will always move to the end of that section. When you create an Assembler
813
+ //! // the cursor would be placed at the end of the first (.text) section, which
814
+ //! // is initially empty.
815
+ //! x86::Assembler a(&code);
816
+ //! Label L_Data = a.newLabel();
817
+ //!
818
+ //! a.mov(x86::eax, x86::ebx); // Emits in .text section.
819
+ //!
820
+ //! a.section(data); // Switches to the end of .data section.
821
+ //! a.bind(L_Data); // Binds label in this .data section
822
+ //! a.db(0x01); // Emits byte in .data section.
823
+ //!
824
+ //! a.section(text); // Switches to the end of .text section.
825
+ //! a.add(x86::ebx, x86::eax); // Emits in .text section.
826
+ //!
827
+ //! // References a label in .text section, which was bound in .data section.
828
+ //! // This would create a LabelLink even when the L_Data is already bound,
829
+ //! // because the reference crosses sections. See below...
830
+ //! a.lea(x86::rsi, x86::ptr(L_Data));
831
+ //! }
832
+ //! ```
833
+ //!
834
+ //! The last line in the example above shows that a LabelLink would be created even for bound labels that cross
835
+ //! sections. In this case a referenced label was bound in another section, which means that the link couldn't be
836
+ //! resolved at that moment. If your code uses sections, but you wish AsmJit to flatten these sections (you don't
837
+ //! plan to flatten them manually) then there is an API for that.
838
+ //!
839
+ //! ```
840
+ //! #include <asmjit/x86.h>
841
+ //! #include <stdio.h>
842
+ //!
843
+ //! using namespace asmjit;
844
+ //!
845
+ //! // ... (continuing the previous example) ...
846
+ //! void sectionsExampleContinued(CodeHolder& code) {
847
+ //! // Suppose we have some code that contains multiple sections and
848
+ //! // we would like to flatten it by using AsmJit's built-in API:
849
+ //! Error err = code.flatten();
850
+ //! if (err) {
851
+ //! // There are many reasons it can fail, so always handle a possible error.
852
+ //! printf("Failed to flatten the code: %s\n", DebugUtils::errorAsString(err));
853
+ //! exit(1);
854
+ //! }
855
+ //!
856
+ //! // After flattening all sections would contain assigned offsets
857
+ //! // relative to base. Offsets are 64-bit unsigned integers so we
858
+ //! // cast them to `size_t` for simplicity. On 32-bit targets it's
859
+ //! // guaranteed that the offset cannot be greater than `2^32 - 1`.
860
+ //! printf("Data section offset %zu", size_t(data->offset()));
861
+ //!
862
+ //! // The flattening doesn't resolve unresolved label links, this
863
+ //! // has to be done manually as flattening can be done separately.
864
+ //! err = code.resolveUnresolvedLinks();
865
+ //! if (err) {
866
+ //! // This is the kind of error that should always be handled...
867
+ //! printf("Failed to resolve label links: %s\n", DebugUtils::errorAsString(err));
868
+ //! exit(1);
869
+ //! }
870
+ //!
871
+ //! if (code.hasUnresolvedLinks()) {
872
+ //! // This would mean either unbound label or some other issue.
873
+ //! printf("The code has %zu unbound labels\n", code.unresovedLinkCount());
874
+ //! exit(1);
875
+ //! }
876
+ //! }
877
+ //! ```
878
+
879
+
880
+ //! \defgroup asmjit_assembler Assembler
881
+ //! \brief Assembler interface and operands.
882
+ //!
883
+ //! ### Overview
884
+ //!
885
+ //! AsmJit's Assembler is used to emit machine code directly into a \ref CodeBuffer. In general, code generation
886
+ //! with assembler requires the knowledge of the following:
887
+ //!
888
+ //! - \ref BaseAssembler and architecture-specific assemblers:
889
+ //! - \ref x86::Assembler - Assembler specific to X86 architecture
890
+ //! - \ref Operand and its variations:
891
+ //! - \ref BaseReg - Base class for a register operand, inherited by:
892
+ //! - \ref x86::Reg - Register operand specific to X86 architecture.
893
+ //! - \ref BaseMem - Base class for a memory operand, inherited by:
894
+ //! - \ref x86::Mem - Memory operand specific to X86 architecture.
895
+ //! - \ref Imm - Immediate (value) operand.
896
+ //! - \ref Label - Label operand.
897
+ //!
898
+ //! \note Assembler examples use \ref x86::Assembler as abstract interfaces cannot be used to generate code.
899
+ //!
900
+ //! ### Operand Basics
901
+ //!
902
+ //! Let's start with operands. \ref Operand is a data structure that defines a data layout of any operand. It can be
903
+ //! inherited, but any class inheriting it cannot add any members to it, only the existing layout can be reused.
904
+ //! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them
905
+ //! at run-time. Operands are small (always 16 bytes per \ref Operand) and can be copied and passed by value. Please
906
+ //! never allocate individual operands dynamically by using a `new` keyword - it would work, but then you would have
907
+ //! to be responsible for deleting such operands. In AsmJit operands are always part of some other data structures
908
+ //! like \ref InstNode, which is part of \ref asmjit_builder tool.
909
+ //!
910
+ //! Operands contain only identifiers, but not pointers to any code-generation data. For example \ref Label operand
911
+ //! only provides label identifier, but not a pointer to \ref LabelEntry structure. In AsmJit such IDs are used to
912
+ //! link stuff together without having to deal with pointers.
913
+ //!
914
+ //! AsmJit's operands all inherit from a base class called \ref Operand. Operands have the following properties that
915
+ //! are commonly accessible by getters and setters:
916
+ //!
917
+ //! - \ref Operand - Base operand, which only provides accessors that are common to all operand types.
918
+ //! - \ref BaseReg - Describes either physical or virtual register. Physical registers have id that matches the
919
+ //! target's machine id directly whereas virtual registers must be allocated into physical registers by a register
920
+ //! allocator pass. Register operand provides:
921
+ //! - Register Type (\ref RegType) - Unique id that describes each possible register provided by the target
922
+ //! architecture - for example X86 backend provides general purpose registers (GPB-LO, GPB-HI, GPW, GPD, and GPQ)
923
+ //! and all types of other registers like K, MM, BND, XMM, YMM, ZMM, and TMM.
924
+ //! - Register Group (\ref RegGroup) - Groups multiple register types under a single group - for example all
925
+ //! general-purpose registers (of all sizes) on X86 are part of \ref RegGroup::kGp and all SIMD registers
926
+ //! (XMM, YMM, ZMM) are part of \ref RegGroup::kVec.
927
+ //! - Register Size - Contains the size of the register in bytes. If the size depends on the mode (32-bit vs
928
+ //! 64-bit) then generally the higher size is used (for example RIP register has size 8 by default).
929
+ //! - Register Id - Contains physical or virtual id of the register.
930
+ //! - \ref BaseMem - Used to reference a memory location. Memory operand provides:
931
+ //! - Base Register - A base register type and id (physical or virtual).
932
+ //! - Index Register - An index register type and id (physical or virtual).
933
+ //! - Offset - Displacement or absolute address to be referenced (32-bit if base register is used and 64-bit if
934
+ //! base register is not used).
935
+ //! - Flags that can describe various architecture dependent information (like scale and segment-override on X86).
936
+ //! - \ref Imm - Immediate values are usually part of instructions (encoded within the instruction itself) or data.
937
+ //! - \ref Label - used to reference a location in code or data. Labels must be created by the \ref BaseEmitter or
938
+ //! by \ref CodeHolder. Each label has its unique id per \ref CodeHolder instance.
939
+ //!
940
+ //! ### Operand Manipulation
941
+ //!
942
+ //! AsmJit allows to construct operands dynamically, to store them, and to query a complete information about them at
943
+ //! run-time. Operands are small (always 16 bytes per `Operand`) and should be always copied (by value) if you intend
944
+ //! to store them (don't create operands by using `new` keyword, it's not recommended). Operands are safe to be passed
945
+ //! to `memcpy()` and `memset()`, which becomes handy when working with arrays of operands. If you set all members of
946
+ //! an \ref Operand to zero the operand would become NONE operand, which is the same as a default constructed Operand.
947
+ //!
948
+ //! The example below illustrates how operands can be used and modified even without using any other code generation
949
+ //! classes. The example uses X86 architecture-specific operands.
950
+ //!
951
+ //! ```
952
+ //! #include <asmjit/x86.h>
953
+ //!
954
+ //! using namespace asmjit;
955
+ //!
956
+ //! // Registers can be copied, it's a common practice.
957
+ //! x86::Gp dstRegByValue() { return x86::ecx; }
958
+ //!
959
+ //! void usingOperandsExample(x86::Assembler& a) {
960
+ //! // Gets `ecx` register returned by a function.
961
+ //! x86::Gp dst = dstRegByValue();
962
+ //! // Gets `rax` register directly from the provided `x86` namespace.
963
+ //! x86::Gp src = x86::rax;
964
+ //! // Constructs `r10` dynamically.
965
+ //! x86::Gp idx = x86::gpq(10);
966
+ //! // Constructs [src + idx] memory address - referencing [rax + r10].
967
+ //! x86::Mem m = x86::ptr(src, idx);
968
+ //!
969
+ //! // Examine `m`: Returns `RegType::kX86_Gpq`.
970
+ //! m.indexType();
971
+ //! // Examine `m`: Returns 10 (`r10`).
972
+ //! m.indexId();
973
+ //!
974
+ //! // Reconstruct `idx` stored in mem:
975
+ //! x86::Gp idx_2 = x86::Gp::fromTypeAndId(m.indexType(), m.indexId());
976
+ //!
977
+ //! // True, `idx` and idx_2` are identical.
978
+ //! idx == idx_2;
979
+ //!
980
+ //! // Possible - op will still be the same as `m`.
981
+ //! Operand op = m;
982
+ //! // True (can be casted to BaseMem or architecture-specific Mem).
983
+ //! op.isMem();
984
+ //!
985
+ //! // True, `op` is just a copy of `m`.
986
+ //! m == op;
987
+ //!
988
+ //! // Static cast is fine and valid here.
989
+ //! static_cast<BaseMem&>(op).addOffset(1);
990
+ //! // However, using `as<T>()` to cast to a derived type is preferred.
991
+ //! op.as<BaseMem>().addOffset(1);
992
+ //! // False, `op` now points to [rax + r10 + 2], which is not [rax + r10].
993
+ //! m == op;
994
+ //!
995
+ //! // Emitting 'mov' - type safe way.
996
+ //! a.mov(dst, m);
997
+ //! // Not possible, `mov` doesn't provide mov(x86::Gp, Operand) overload.
998
+ //! a.mov(dst, op);
999
+ //!
1000
+ //! // Type-unsafe, but possible.
1001
+ //! a.emit(x86::Inst::kIdMov, dst, m);
1002
+ //! // Also possible, `emit()` is typeless and can be used with raw Operand.
1003
+ //! a.emit(x86::Inst::kIdMov, dst, op);
1004
+ //! }
1005
+ //! ```
1006
+ //!
1007
+ //! Some operands have to be created explicitly by emitters. For example labels must be created by \ref
1008
+ //! BaseEmitter::newLabel(), which creates a label entry and returns a \ref Label operand with the id that refers
1009
+ //! to it. Such label then can be used by emitters.
1010
+ //!
1011
+ //! ### Memory Operands
1012
+ //!
1013
+ //! Some architectures like X86 provide a complex memory addressing model that allows to encode addresses having a
1014
+ //! BASE register, INDEX register with a possible scale (left shift), and displacement (called offset in AsmJit).
1015
+ //! Memory address on X86 can also specify memory segment (segment-override in X86 terminology) and some instructions
1016
+ //! (gather / scatter) require INDEX to be a \ref x86::Vec register instead of a general-purpose register.
1017
+ //!
1018
+ //! AsmJit allows to encode and work with all forms of addresses mentioned and implemented by X86. In addition, it
1019
+ //! also allows to construct absolute 64-bit memory address operands, which is only allowed in one form of 'mov'
1020
+ //! instruction.
1021
+ //!
1022
+ //! ```
1023
+ //! #include <asmjit/x86.h>
1024
+ //!
1025
+ //! using namespace asmjit;
1026
+ //!
1027
+ //! void testX86Mem() {
1028
+ //! // Makes it easier to access x86 stuff...
1029
+ //! using namespace asmjit::x86;
1030
+ //!
1031
+ //! // BASE + OFFSET.
1032
+ //! Mem a = ptr(rax); // a = [rax]
1033
+ //! Mem b = ptr(rax, 15); // b = [rax + 15]
1034
+ //!
1035
+ //! // BASE + INDEX << SHIFT - Shift is in BITS as used by X86!
1036
+ //! Mem c = ptr(rax, rbx); // c = [rax + rbx]
1037
+ //! Mem d = ptr(rax, rbx, 2); // d = [rax + rbx << 2]
1038
+ //! Mem e = ptr(rax, rbx, 2, 15); // e = [rax + rbx << 2 + 15]
1039
+ //!
1040
+ //! // BASE + VM (Vector Index) (encoded as MOD+VSIB).
1041
+ //! Mem f = ptr(rax, xmm1); // f = [rax + xmm1]
1042
+ //! Mem g = ptr(rax, xmm1, 2); // g = [rax + xmm1 << 2]
1043
+ //! Mem h = ptr(rax, xmm1, 2, 15); // h = [rax + xmm1 << 2 + 15]
1044
+ //!
1045
+ //! // Absolute address:
1046
+ //! uint64_t addr = (uint64_t)0x1234;
1047
+ //! Mem i = ptr(addr); // i = [0x1234]
1048
+ //! Mem j = ptr(addr, rbx); // j = [0x1234 + rbx]
1049
+ //! Mem k = ptr(addr, rbx, 2); // k = [0x1234 + rbx << 2]
1050
+ //!
1051
+ //! // LABEL - Will be encoded as RIP (64-bit) or absolute address (32-bit).
1052
+ //! Label L = ...;
1053
+ //! Mem m = ptr(L); // m = [L]
1054
+ //! Mem n = ptr(L, rbx); // n = [L + rbx]
1055
+ //! Mem o = ptr(L, rbx, 2); // o = [L + rbx << 2]
1056
+ //! Mem p = ptr(L, rbx, 2, 15); // p = [L + rbx << 2 + 15]
1057
+ //!
1058
+ //! // RIP - 64-bit only (RIP can't use INDEX).
1059
+ //! Mem q = ptr(rip, 24); // q = [rip + 24]
1060
+ //! }
1061
+ //! ```
1062
+ //!
1063
+ //! Memory operands can optionally contain memory size. This is required by instructions where the memory size cannot
1064
+ //! be deduced from other operands, like `inc` and `dec` on X86:
1065
+ //!
1066
+ //! ```
1067
+ //! #include <asmjit/x86.h>
1068
+ //!
1069
+ //! using namespace asmjit;
1070
+ //!
1071
+ //! void testX86Mem() {
1072
+ //! // The same as: dword ptr [rax + rbx].
1073
+ //! x86::Mem a = x86::dword_ptr(rax, rbx);
1074
+ //!
1075
+ //! // The same as: qword ptr [rdx + rsi << 0 + 1].
1076
+ //! x86::Mem b = x86::qword_ptr(rdx, rsi, 0, 1);
1077
+ //! }
1078
+ //! ```
1079
+ //!
1080
+ //! Memory operands provide API that can be used to access its properties:
1081
+ //!
1082
+ //! ```
1083
+ //! #include <asmjit/x86.h>
1084
+ //!
1085
+ //! using namespace asmjit;
1086
+ //!
1087
+ //! void testX86Mem() {
1088
+ //! // The same as: dword ptr [rax + 12].
1089
+ //! x86::Mem mem = x86::dword_ptr(rax, 12);
1090
+ //!
1091
+ //! mem.hasBase(); // true.
1092
+ //! mem.hasIndex(); // false.
1093
+ //! mem.size(); // 4.
1094
+ //! mem.offset(); // 12.
1095
+ //!
1096
+ //! mem.setSize(0); // Sets the size to 0 (makes it sizeless).
1097
+ //! mem.addOffset(-1); // Adds -1 to the offset and makes it 11.
1098
+ //! mem.setOffset(0); // Sets the offset to 0.
1099
+ //! mem.setBase(rcx); // Changes BASE to RCX.
1100
+ //! mem.setIndex(rax); // Changes INDEX to RAX.
1101
+ //! mem.hasIndex(); // true.
1102
+ //! }
1103
+ //! // ...
1104
+ //! ```
1105
+ //!
1106
+ //! Making changes to memory operand is very comfortable when emitting loads
1107
+ //! and stores:
1108
+ //!
1109
+ //! ```
1110
+ //! #include <asmjit/x86.h>
1111
+ //!
1112
+ //! using namespace asmjit;
1113
+ //!
1114
+ //! void testX86Mem(CodeHolder& code) {
1115
+ //! x86::Assembler a(code); // Your initialized x86::Assembler.
1116
+ //! x86::Mem mSrc = x86::ptr(eax); // Construct [eax] memory operand.
1117
+ //!
1118
+ //! // One way of emitting bunch of loads is to use `mem.adjusted()`, which
1119
+ //! // returns a new memory operand and keeps the source operand unchanged.
1120
+ //! a.movaps(x86::xmm0, mSrc); // No adjustment needed to load [eax].
1121
+ //! a.movaps(x86::xmm1, mSrc.adjusted(16)); // Loads from [eax + 16].
1122
+ //! a.movaps(x86::xmm2, mSrc.adjusted(32)); // Loads from [eax + 32].
1123
+ //! a.movaps(x86::xmm3, mSrc.adjusted(48)); // Loads from [eax + 48].
1124
+ //!
1125
+ //! // ... do something with xmm0-3 ...
1126
+ //!
1127
+ //! // Another way of adjusting memory is to change the operand in-place.
1128
+ //! // If you want to keep the original operand you can simply clone it.
1129
+ //! x86::Mem mDst = mSrc.clone(); // Clone mSrc.
1130
+ //!
1131
+ //! a.movaps(mDst, x86::xmm0); // Stores xmm0 to [eax].
1132
+ //! mDst.addOffset(16); // Adds 16 to `mDst`.
1133
+ //!
1134
+ //! a.movaps(mDst, x86::xmm1); // Stores to [eax + 16] .
1135
+ //! mDst.addOffset(16); // Adds 16 to `mDst`.
1136
+ //!
1137
+ //! a.movaps(mDst, x86::xmm2); // Stores to [eax + 32].
1138
+ //! mDst.addOffset(16); // Adds 16 to `mDst`.
1139
+ //!
1140
+ //! a.movaps(mDst, x86::xmm3); // Stores to [eax + 48].
1141
+ //! }
1142
+ //! ```
1143
+ //!
1144
+ //! ### Assembler Examples
1145
+ //!
1146
+ //! - \ref x86::Assembler provides many X86/X64 examples.
1147
+
1148
+
1149
+ //! \defgroup asmjit_builder Builder
1150
+ //! \brief Builder interface, nodes, and passes.
1151
+ //!
1152
+ //! ### Overview
1153
+ //!
1154
+ //! Both \ref BaseBuilder and \ref BaseCompiler interfaces describe emitters that emit into a representation that
1155
+ //! allows further processing. The code stored in such representation is completely safe to be patched, simplified,
1156
+ //! reordered, obfuscated, removed, injected, analyzed, or processed some other way. Each instruction, label,
1157
+ //! directive, or other building block is stored as \ref BaseNode (or derived class like \ref InstNode or \ref
1158
+ //! LabelNode) and contains all the information necessary to pass that node later to the assembler.
1159
+ //!
1160
+ //! \ref BaseBuilder is an emitter that inherits from \ref BaseEmitter interface. It was designed to provide a maximum
1161
+ //! compatibility with the existing \ref BaseAssembler emitter so users can move from assembler to builder when needed,
1162
+ //! for example to implement post-processing, which is not possible with Assembler.
1163
+ //!
1164
+ //! ### Builder Nodes
1165
+ //!
1166
+ //! \ref BaseBuilder doesn't generate machine code directly, it uses an intermediate representation based on nodes,
1167
+ //! however, it allows to serialize to \ref BaseAssembler when the code is ready to be encoded.
1168
+ //!
1169
+ //! There are multiple node types used by both \ref BaseBuilder and \ref BaseCompiler :
1170
+ //!
1171
+ //! - Basic nodes:
1172
+ //! - \ref BaseNode - Base class for all nodes.
1173
+ //! - \ref InstNode - Represents an instruction node.
1174
+ //! - \ref AlignNode - Represents an alignment directive (.align).
1175
+ //! - \ref LabelNode - Represents a location where to bound a \ref Label.
1176
+ //!
1177
+ //! - Data nodes:
1178
+ //! - \ref EmbedDataNode - Represents data.
1179
+ //! - \ref EmbedLabelNode - Represents \ref Label address embedded as data.
1180
+ //! - \ref EmbedLabelDeltaNode - Represents a difference of two labels embedded in data.
1181
+ //! - \ref ConstPoolNode - Represents a constant pool data embedded as data.
1182
+ //!
1183
+ //! - Informative nodes:
1184
+ //! - \ref CommentNode - Represents a comment string, doesn't affect code generation.
1185
+ //! - \ref SentinelNode - A marker that can be used to remember certain position in code or data, doesn't affect
1186
+ //! code generation. Used by \ref FuncNode to mark the end of a function.
1187
+ //!
1188
+ //! - Other nodes are provided by \ref asmjit_compiler infrastructure.
1189
+ //!
1190
+ //! ### Builder Examples
1191
+ //!
1192
+ //! - \ref x86::Builder provides many X86/X64 examples.
1193
+
1194
+
1195
+ //! \defgroup asmjit_compiler Compiler
1196
+ //! \brief Compiler interface.
1197
+ //!
1198
+ //! ### Overview
1199
+ //!
1200
+ //! \ref BaseCompiler is a high-level interface, which provides register allocation and support for defining and
1201
+ //! invoking functions, built on top of \ref BaseBuilder interface At the moment it's the easiest way of generating
1202
+ //! code in AsmJit as most architecture and OS specifics is properly abstracted and handled by AsmJit automatically.
1203
+ //! However, abstractions also mean restrictions, which means that \ref BaseCompiler has more limitations than \ref
1204
+ //! BaseAssembler or \ref BaseBuilder.
1205
+ //!
1206
+ //! Since \ref BaseCompiler provides register allocation it also establishes the concept of functions - a function
1207
+ //! in Compiler sense is a unit in which virtual registers are allocated into physical registers by the register
1208
+ //! allocator. In addition, it enables to use such virtual registers in function invocations.
1209
+ //!
1210
+ //! \ref BaseCompiler automatically handles function calling conventions. It's still architecture dependent, but
1211
+ //! makes the code generation much easies. Functions are essential; the first-step to generate some code is to define
1212
+ //! a signature of the function to be generated (before generating the function body itself). Function arguments and
1213
+ //! return value(s) are handled by assigning virtual registers to them. Similarly, function calls are handled the same
1214
+ //! way.
1215
+ //!
1216
+ //! ### Compiler Nodes
1217
+ //!
1218
+ //! \ref BaseCompiler adds some nodes that are required for function generation and invocation:
1219
+ //!
1220
+ //! - \ref FuncNode - Represents a function definition.
1221
+ //! - \ref FuncRetNode - Represents a function return.
1222
+ //! - \ref InvokeNode - Represents a function invocation.
1223
+ //!
1224
+ //! \ref BaseCompiler also makes the use of passes (\ref Pass) and automatically adds an architecture-dependent
1225
+ //! register allocator pass to the list of passes when attached to \ref CodeHolder.
1226
+ //!
1227
+ //! ### Compiler Examples
1228
+ //!
1229
+ //! - \ref x86::Compiler provides many X86/X64 examples.
1230
+ //!
1231
+ //! ### Compiler Tips
1232
+ //!
1233
+ //! Users of AsmJit have done mistakes in the past, this section should provide some useful tips for beginners:
1234
+ //!
1235
+ //! - Virtual registers in compiler are bound to a single function. At the moment the implementation doesn't
1236
+ //! care whether a single virtual register is used in multiple functions, but it sees it as two independent
1237
+ //! virtual registers in that case. This means that virtual registers cannot be used to implement global
1238
+ //! variables. Global variables are basically memory addresses which functions can read from and write to,
1239
+ //! and they have to be implemented in the same way.
1240
+ //!
1241
+ //! - Compiler provides a useful debugging functionality, which can be turned on through \ref FormatFlags. Use
1242
+ //! \ref Logger::addFlags() to turn on additional logging features when using Compiler.
1243
+
1244
+
1245
+ //! \defgroup asmjit_function Function
1246
+ //! \brief Function definitions.
1247
+ //!
1248
+ //! ### Overview
1249
+ //!
1250
+ //! AsmJit provides functionality that can be used to define function signatures and to calculate automatically
1251
+ //! optimal function frame that can be used directly by a prolog and epilog insertion. This feature was exclusive
1252
+ //! to AsmJit's Compiler for a very long time, but was abstracted out and is now available for all users regardless
1253
+ //! of the emitter they use. The following use cases are possible:
1254
+ //!
1255
+ //! - Calculate function frame before the function is generated - this is the only way available to \ref
1256
+ //! BaseAssembler users and it will be described in this section.
1257
+ //!
1258
+ //! - Calculate function frame after the function is generated - this way is generally used by \ref BaseBuilder
1259
+ //! and \ref BaseCompiler emitters and this way is generally described in \ref asmjit_compiler section.
1260
+ //!
1261
+ //! The following concepts are used to describe and create functions in AsmJit:
1262
+ //!
1263
+ //! - \ref TypeId - Type-id is an 8-bit value that describes a platform independent type as we know from C/C++.
1264
+ //! It provides abstractions for most common types like `int8_t`, `uint32_t`, `uintptr_t`, `float`, `double`,
1265
+ //! and all possible vector types to match ISAs up to AVX512. \ref TypeId was introduced originally for \ref
1266
+ //! asmjit_compiler, but it's now used by \ref FuncSignature as well.
1267
+ //!
1268
+ //! - \ref CallConv - Describes a calling convention - this class contains instructions to assign registers and
1269
+ //! stack addresses to function arguments and return value(s), but doesn't specify any function signature itself.
1270
+ //! Calling conventions are architecture and OS dependent.
1271
+ //!
1272
+ //! - \ref FuncSignature - Describes a function signature, for example `int func(int, int)`. FuncSignature contains
1273
+ //! a function calling convention id, return value type, and function arguments. The signature itself is platform
1274
+ //! independent and uses \ref TypeId to describe types of function arguments and function return value(s).
1275
+ //!
1276
+ //! - \ref FuncDetail - Architecture and ABI dependent information that describes \ref CallConv and expanded \ref
1277
+ //! FuncSignature. Each function argument and return value is represented as \ref FuncValue that contains the
1278
+ //! original \ref TypeId enriched with additional information that specifies whether the value is passed or
1279
+ //! returned by register (and which register) or by stack. Each value also contains some other metadata that
1280
+ //! provide additional information required to handle it properly (for example whether a vector is passed
1281
+ //! indirectly by a pointer as required by WIN64 calling convention).
1282
+ //!
1283
+ //! - \ref FuncFrame - Contains information about the function frame that can be used by prolog/epilog inserter
1284
+ //! (PEI). Holds call stack size size and alignment, local stack size and alignment, and various attributes that
1285
+ //! describe how prolog and epilog should be constructed. `FuncFrame` doesn't know anything about function's
1286
+ //! arguments or return values, it hold only information necessary to create a valid and ABI conforming function
1287
+ //! prologs and epilogs.
1288
+ //!
1289
+ //! - \ref FuncArgsAssignment - A helper class that can be used to reassign function arguments into user specified
1290
+ //! registers. It's architecture and ABI dependent mapping from function arguments described by \ref CallConv
1291
+ //! and \ref FuncDetail into registers specified by the user.
1292
+ //!
1293
+ //! It's a lot of concepts where each represents one step in a function frame calculation. It can be used to create
1294
+ //! function prologs, epilogs, and also to calculate information necessary to perform function calls.
1295
+
1296
+
1297
+ //! \defgroup asmjit_logging Logging
1298
+ //! \brief Logging and formatting.
1299
+ //!
1300
+ //! ### Overview
1301
+ //!
1302
+ //! The initial phase of a project that generates machine code is not always smooth. Failure cases are common not just
1303
+ //! at the beginning phase, but also during the development or refactoring. AsmJit provides logging functionality to
1304
+ //! address this issue. AsmJit does already a good job with function overloading to prevent from emitting unencodable
1305
+ //! instructions, but it can't prevent from emitting machine code that is correct at instruction level, but doesn't
1306
+ //! work when it's executed asa whole. Logging has always been an important part of AsmJit's infrastructure and looking
1307
+ //! at logs can sometimes reveal code generation issues quickly.
1308
+ //!
1309
+ //! AsmJit provides API for logging and formatting:
1310
+ //!
1311
+ //! - \ref Logger - A logger that you can pass to \ref CodeHolder and all emitters that inherit from \ref BaseEmitter.
1312
+ //!
1313
+ //! - \ref FormatOptions - Formatting options that can change how instructions and operands are formatted.
1314
+ //!
1315
+ //! - \ref Formatter - A namespace that provides functions that can format input data like \ref Operand, \ref BaseReg,
1316
+ //! \ref Label, and \ref BaseNode into \ref String.
1317
+ //!
1318
+ //! AsmJit's \ref Logger serves the following purposes:
1319
+ //!
1320
+ //! - Provides a basic foundation for logging.
1321
+ //!
1322
+ //! - Abstract class leaving the implementation on users. The following built-in implementations are provided for
1323
+ //! simplicity:
1324
+ //!
1325
+ //! - \ref FileLogger implements logging into a standard `FILE` stream.
1326
+ //! - \ref StringLogger serializes all logs into a \ref String instance.
1327
+ //!
1328
+ //! AsmJit's \ref FormatOptions provides the following to customize the formatting of instructions and operands through:
1329
+ //!
1330
+ //! - \ref FormatFlags
1331
+ //! - \ref FormatIndentationGroup
1332
+ //!
1333
+ //! ### Logging
1334
+ //!
1335
+ //! A \ref Logger is typically attached to a \ref CodeHolder, which propagates it to all attached emitters
1336
+ //! automatically. The example below illustrates how to use \ref FileLogger that outputs to standard output:
1337
+ //!
1338
+ //! ```
1339
+ //! #include <asmjit/core.h>
1340
+ //! #include <stdio.h>
1341
+ //!
1342
+ //! using namespace asmjit;
1343
+ //!
1344
+ //! int main() {
1345
+ //! JitRuntime rt; // Runtime specialized for JIT code execution.
1346
+ //! FileLogger logger(stdout); // Logger should always survive CodeHolder.
1347
+ //!
1348
+ //! CodeHolder code; // Holds code and relocation information.
1349
+ //! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
1350
+ //! code.setLogger(&logger); // Attach the `logger` to `code` holder.
1351
+ //!
1352
+ //! // ... code as usual, everything emitted will be logged to `stdout` ...
1353
+ //! return 0;
1354
+ //! }
1355
+ //! ```
1356
+ //!
1357
+ //! If output to FILE stream is not desired it's possible to use \ref StringLogger, which concatenates everything
1358
+ //! into a multi-line string:
1359
+ //!
1360
+ //! ```
1361
+ //! #include <asmjit/core.h>
1362
+ //! #include <stdio.h>
1363
+ //! #include <utility>
1364
+ //!
1365
+ //! using namespace asmjit;
1366
+ //!
1367
+ //! int main() {
1368
+ //! JitRuntime rt; // Runtime specialized for JIT code execution.
1369
+ //! StringLogger logger; // Logger should always survive CodeHolder.
1370
+ //!
1371
+ //! CodeHolder code; // Holds code and relocation information.
1372
+ //! code.init(rt.environment()); // Initialize to the same arch as JIT runtime.
1373
+ //! code.setLogger(&logger); // Attach the `logger` to `code` holder.
1374
+ //!
1375
+ //! // ... code as usual, logging will be concatenated to logger string ...
1376
+ //!
1377
+ //! // You can either use the string from StringLogger directly or you can
1378
+ //! // move it. Logger::data() returns its content as null terminated char[].
1379
+ //! printf("Logger content: %s\n", logger.data());
1380
+ //!
1381
+ //! // It can be moved into your own string like this:
1382
+ //! String content = std::move(logger.content());
1383
+ //! printf("The same content: %s\n", content.data());
1384
+ //!
1385
+ //! return 0;
1386
+ //! }
1387
+ //! ```
1388
+ //!
1389
+ //! ### Formatting
1390
+ //!
1391
+ //! AsmJit uses \ref Formatter to format inputs that are then passed to \ref Logger. Formatting is public and can be
1392
+ //! used by AsmJit users as well. The most important thing to know regarding formatting is that \ref Formatter always
1393
+ //! appends to the output string, so it can be used to build complex strings without having to concatenate
1394
+ //! intermediate strings.
1395
+ //!
1396
+ //! The first example illustrates how to format operands:
1397
+ //!
1398
+ //! ```
1399
+ //! #include <asmjit/core.h>
1400
+ //! #include <stdio.h>
1401
+ //!
1402
+ //! using namespace asmjit;
1403
+ //!
1404
+ //! void logOperand(Arch arch, const Operand_& op) {
1405
+ //! // The emitter is optional (named labels and virtual registers need it).
1406
+ //! BaseEmitter* emitter = nullptr;
1407
+ //!
1408
+ //! // No flags by default.
1409
+ //! FormatFlags formatFlags = FormatFlags::kNone;
1410
+ //!
1411
+ //! StringTmp<128> sb;
1412
+ //! Formatter::formatOperand(sb, formatFlags, emitter, arch, op);
1413
+ //! printf("%s\n", sb.data());
1414
+ //! }
1415
+ //!
1416
+ //! void formattingExample() {
1417
+ //! using namespace x86;
1418
+ //!
1419
+ //! // Architecture is not part of operand, it must be passed explicitly.
1420
+ //! // Format flags. We pass it explicitly also to 'logOperand' to make
1421
+ //! // compatible with what AsmJit normally does.
1422
+ //! Arch arch = Arch::kX64;
1423
+ //!
1424
+ //! log(arch, rax); // Prints 'rax'.
1425
+ //! log(arch, ptr(rax, rbx, 2)); // Prints '[rax + rbx * 4]`.
1426
+ //! log(arch, dword_ptr(rax, rbx, 2)); // Prints 'dword [rax + rbx * 4]`.
1427
+ //! log(arch, imm(42)); // Prints '42'.
1428
+ //! }
1429
+ //! ```
1430
+ //!
1431
+ //! Next example illustrates how to format whole instructions:
1432
+ //!
1433
+ //! ```
1434
+ //! #include <asmjit/core.h>
1435
+ //! #include <stdio.h>
1436
+ //! #include <utility>
1437
+ //!
1438
+ //! using namespace asmjit;
1439
+ //!
1440
+ //! template<typename... Args>
1441
+ //! void logInstruction(Arch arch, const BaseInst& inst, Args&&... args) {
1442
+ //! // The emitter is optional (named labels and virtual registers need it).
1443
+ //! BaseEmitter* emitter = nullptr;
1444
+ //!
1445
+ //! // No flags by default.
1446
+ //! FormatFlags formatFlags = FormatFlags::kNone;
1447
+ //!
1448
+ //! // The formatter expects operands in an array.
1449
+ //! Operand_ operands { std::forward<Args>(args)... };
1450
+ //!
1451
+ //! StringTmp<128> sb;
1452
+ //! Formatter::formatInstruction(
1453
+ //! sb, formatFlags, emitter, arch, inst, operands, sizeof...(args));
1454
+ //! printf("%s\n", sb.data());
1455
+ //! }
1456
+ //!
1457
+ //! void formattingExample() {
1458
+ //! using namespace x86;
1459
+ //!
1460
+ //! // Architecture is not part of operand, it must be passed explicitly.
1461
+ //! // Format flags. We pass it explicitly also to 'logOperand' to make
1462
+ //! // compatible with what AsmJit normally does.
1463
+ //! Arch arch = Arch::kX64;
1464
+ //!
1465
+ //! // Prints 'mov rax, rcx'.
1466
+ //! logInstruction(arch, BaseInst(Inst::kIdMov), rax, rcx);
1467
+ //!
1468
+ //! // Prints 'vaddpd zmm0, zmm1, [rax] {1to8}'.
1469
+ //! logInstruction(arch,
1470
+ //! BaseInst(Inst::kIdVaddpd),
1471
+ //! zmm0, zmm1, ptr(rax)._1toN());
1472
+ //!
1473
+ //! // BaseInst abstracts instruction id, instruction options, and extraReg.
1474
+ //! // Prints 'lock add [rax], rcx'.
1475
+ //! logInstruction(arch,
1476
+ //! BaseInst(Inst::kIdAdd, InstOptions::kX86_Lock),
1477
+ //! x86::ptr(rax), rcx);
1478
+ //!
1479
+ //! // Similarly an extra register (like AVX-512 selector) can be used.
1480
+ //! // Prints 'vaddpd zmm0 {k2} {z}, zmm1, [rax]'.
1481
+ //! logInstruction(arch,
1482
+ //! BaseInst(Inst::kIdAdd, InstOptions::kX86_ZMask, k2),
1483
+ //! zmm0, zmm1, ptr(rax));
1484
+ //! }
1485
+ //! ```
1486
+ //!
1487
+ //! And finally, the example below illustrates how to use a built-in function to format the content of
1488
+ //! \ref BaseBuilder, which consists of nodes:
1489
+ //!
1490
+ //! ```
1491
+ //! #include <asmjit/core.h>
1492
+ //! #include <stdio.h>
1493
+ //!
1494
+ //! using namespace asmjit;
1495
+ //!
1496
+ //! void formattingExample(BaseBuilder* builder) {
1497
+ //! FormatFlags formatFlags = FormatFlags::kNone;
1498
+ //!
1499
+ //! // This also shows how temporary strings can be used.
1500
+ //! StringTmp<512> sb;
1501
+ //!
1502
+ //! // FormatNodeList requires the String for output, formatting flags, which
1503
+ //! // were zero (no extra flags), and the builder instance, which we have
1504
+ //! // provided. An overloaded version also exists, which accepts begin and
1505
+ //! // and end nodes, which can be used to only format a range of nodes.
1506
+ //! Formatter::formatNodeList(sb, formatFlags, builder);
1507
+ //!
1508
+ //! // You can do whatever else with the string, it's always null terminated,
1509
+ //! // so it can be passed to C functions like printf().
1510
+ //! printf("%s\n", sb.data());
1511
+ //! }
1512
+ //! ```
1513
+
1514
+
1515
+ //! \defgroup asmjit_error_handling Error Handling
1516
+ //! \brief Error handling.
1517
+ //!
1518
+ //! ### Overview
1519
+ //!
1520
+ //! AsmJit uses error codes to represent and return errors. Every function that can fail returns an \ref Error code.
1521
+ //! Exceptions are never thrown by AsmJit itself even in extreme conditions like out-of-memory, but it's possible to
1522
+ //! override \ref ErrorHandler::handleError() to throw, in that case no error will be returned and exception will be
1523
+ //! thrown instead. All functions where this can happen are not marked `noexcept`.
1524
+ //!
1525
+ //! Errors should never be ignored, however, checking errors after each AsmJit API call would simply overcomplicate
1526
+ //! the whole code generation experience. \ref ErrorHandler exists to make the use of AsmJit API simpler as it allows
1527
+ //! to customize how errors can be handled:
1528
+ //!
1529
+ //! - Record the error and continue (the way how the error is user-implemented).
1530
+ //! - Throw an exception. AsmJit doesn't use exceptions and is completely exception-safe, but it's perfectly legal
1531
+ //! to throw an exception from the error handler.
1532
+ //! - Use plain old C's `setjmp()` and `longjmp()`. Asmjit always puts Assembler, Builder and Compiler to a
1533
+ //! consistent state before calling \ref ErrorHandler::handleError(), so `longjmp()` can be used without issues
1534
+ //! to cancel the code-generation if an error occurred. This method can be used if exception handling in your
1535
+ //! project is turned off and you still want some comfort. In most cases it should be safe as AsmJit uses \ref
1536
+ //! Zone memory and the ownership of memory it allocates always ends with the instance that allocated it. If
1537
+ //! using this approach please never jump outside the life-time of \ref CodeHolder and \ref BaseEmitter.
1538
+ //!
1539
+ //! ### Using ErrorHandler
1540
+ //!
1541
+ //! An example of attaching \ref ErrorHandler to \ref CodeHolder.
1542
+ //!
1543
+ //! ```
1544
+ //! #include <asmjit/x86.h>
1545
+ //! #include <stdio.h>
1546
+ //!
1547
+ //! using namespace asmjit;
1548
+ //!
1549
+ //! // A simple error handler implementation, extend according to your needs.
1550
+ //! class MyErrorHandler : public ErrorHandler {
1551
+ //! public:
1552
+ //! void handleError(Error err, const char* message, BaseEmitter* origin) override {
1553
+ //! printf("AsmJit error: %s\n", message);
1554
+ //! }
1555
+ //! };
1556
+ //!
1557
+ //! int main() {
1558
+ //! JitRuntime rt;
1559
+ //!
1560
+ //! MyErrorHandler myErrorHandler;
1561
+ //! CodeHolder code;
1562
+ //!
1563
+ //! code.init(rt.environment());
1564
+ //! code.setErrorHandler(&myErrorHandler);
1565
+ //!
1566
+ //! x86::Assembler a(&code);
1567
+ //! // ... code generation ...
1568
+ //!
1569
+ //! return 0;
1570
+ //! }
1571
+ //! ```
1572
+ //!
1573
+ //! Useful classes in error handling group:
1574
+ //!
1575
+ //! - See \ref DebugUtils that provides utilities useful for debugging.
1576
+ //! - See \ref Error that lists error codes that AsmJit uses.
1577
+ //! - See \ref ErrorHandler for more details about error handling.
1578
+
1579
+
1580
+ //! \defgroup asmjit_instruction_db Instruction DB
1581
+ //! \brief Instruction database (introspection, read/write, validation, ...).
1582
+ //!
1583
+ //! ### Overview
1584
+ //!
1585
+ //! AsmJit provides a public instruction database that can be used to query information about a complete instruction.
1586
+ //! The instruction database requires the knowledge of the following:
1587
+ //!
1588
+ //! - \ref BaseInst - Base instruction that contains instruction id, options, and a possible extra-register that
1589
+ //! represents either REP prefix counter or AVX-512 selector (mask).
1590
+ //!
1591
+ //! - \ref Operand - Represents operands of an instruction.
1592
+ //!
1593
+ //! Each instruction can be then queried for the following information:
1594
+ //!
1595
+ //! - \ref InstRWInfo - Read/write information of instruction and its oprands (includes \ref OpRWInfo).
1596
+ //!
1597
+ //! - \ref CpuFeatures - CPU features required to execute the instruction.
1598
+ //!
1599
+ //! In addition to query functionality AsmJit is also able to validate whether an instruction and its operands are
1600
+ //! valid. This is useful for making sure that what user tries to emit is correct and it can be also used by other
1601
+ //! projects that parse user input, like AsmTK project.
1602
+ //!
1603
+ //! ### Query API
1604
+ //!
1605
+ //! The instruction query API is provided by \ref InstAPI namespace. The following queries are possible:
1606
+ //!
1607
+ //! - \ref InstAPI::queryRWInfo() - queries read/write information of the given instruction and its operands.
1608
+ //! Includes also CPU flags read/written.
1609
+ //!
1610
+ //! - \ref InstAPI::queryFeatures() - queries CPU features that are required to execute the given instruction. A full
1611
+ //! instruction with operands must be given as some architectures like X86 may require different features for the
1612
+ //! same instruction based on its operands.
1613
+ //!
1614
+ //! - <a href="https://github.com/asmjit/asmjit/blob/master/test/asmjit_test_instinfo.cpp">asmjit_test_instinfo.cpp</a>
1615
+ //! can be also used as a reference about accessing instruction information.
1616
+ //!
1617
+ //! ### Validation API
1618
+ //!
1619
+ //! The instruction validation API is provided by \ref InstAPI namespace in the similar fashion like the Query API,
1620
+ //! however, validation can also be turned on at \ref BaseEmitter level. The following is possible:
1621
+ //!
1622
+ //! - \ref InstAPI::validate() - low-level instruction validation function that is used internally by emitters
1623
+ //! if strict validation is enabled.
1624
+ //!
1625
+ //! - \ref BaseEmitter::addDiagnosticOptions() - can be used to enable validation at emitter level, see \ref
1626
+ //! DiagnosticOptions.
1627
+
1628
+
1629
+ //! \defgroup asmjit_virtual_memory Virtual Memory
1630
+ //! \brief Virtual memory management.
1631
+ //!
1632
+ //! ### Overview
1633
+ //!
1634
+ //! AsmJit's virtual memory management is divided into two main categories:
1635
+ //!
1636
+ //! - Low level API that provides cross-platform abstractions for virtual memory allocation. Implemented in
1637
+ //! \ref VirtMem namespace.
1638
+ //!
1639
+ //! - High level API that makes it very easy to store generated code for execution. See \ref JitRuntime, which is
1640
+ //! used by many examples for its simplicity and easy integration with \ref CodeHolder. There is also \ref
1641
+ //! JitAllocator, which lays somewhere between RAW memory allocation and \ref JitRuntime.
1642
+
1643
+
1644
+ //! \defgroup asmjit_zone Zone Memory
1645
+ //! \brief Zone memory allocator and containers.
1646
+ //!
1647
+ //! ### Overview
1648
+ //!
1649
+ //! AsmJit uses zone memory allocation (also known as Arena allocation) to allocate most of the data it uses. It's a
1650
+ //! fast allocator that allows AsmJit to allocate a lot of small data structures fast and without `malloc()` overhead.
1651
+ //! Since code generators and all related classes are usually short-lived this approach decreases memory usage and
1652
+ //! fragmentation as arena-based allocators always allocate larger blocks of memory, which are then split into smaller
1653
+ //! chunks.
1654
+ //!
1655
+ //! Another advantage of zone memory allocation is that since the whole library uses this strategy it's very easy to
1656
+ //! deallocate everything that a particular instance is holding by simply releasing the memory the allocator holds.
1657
+ //! This improves destruction time of such objects as there is no destruction at all. Long-lived objects just reset
1658
+ //! its data in destructor or in their reset() member function for a future reuse. For this purpose all containers in
1659
+ //! AsmJit are also zone allocated.
1660
+ //!
1661
+ //! ### Zone Allocation
1662
+ //!
1663
+ //! - \ref Zone - Incremental zone memory allocator with minimum features. It can only allocate memory without the
1664
+ //! possibility to return it back to the allocator.
1665
+ //!
1666
+ //! - \ref ZoneTmp - A temporary \ref Zone with some initial static storage. If the allocation requests fit the
1667
+ //! static storage allocated then there will be no dynamic memory allocation during the lifetime of \ref ZoneTmp,
1668
+ //! otherwise it would act as \ref Zone with one preallocated block on the stack.
1669
+ //!
1670
+ //! - \ref ZoneAllocator - A wrapper of \ref Zone that provides the capability of returning memory to the allocator.
1671
+ //! Such memory is stored in a pool for later reuse.
1672
+ //!
1673
+ //! ### Zone Allocated Containers
1674
+ //!
1675
+ //! - \ref ZoneString - Zone allocated string.
1676
+ //! - \ref ZoneHash - Zone allocated hash table.
1677
+ //! - \ref ZoneTree - Zone allocated red-black tree.
1678
+ //! - \ref ZoneList - Zone allocated double-linked list.
1679
+ //! - \ref ZoneStack - Zone allocated stack.
1680
+ //! - \ref ZoneVector - Zone allocated vector.
1681
+ //! - \ref ZoneBitVector - Zone allocated vector of bits.
1682
+ //!
1683
+ //! ### Using Zone Allocated Containers
1684
+ //!
1685
+ //! The most common data structure exposed by AsmJit is \ref ZoneVector. It's very similar to `std::vector`, but the
1686
+ //! implementation doesn't use exceptions and uses the mentioned \ref ZoneAllocator for performance reasons. You don't
1687
+ //! have to worry about allocations as you should not need to add items to AsmJit's data structures directly as there
1688
+ //! should be API for all required operations.
1689
+ //!
1690
+ //! The following APIs in \ref CodeHolder returns \ref ZoneVector reference:
1691
+ //!
1692
+ //! ```
1693
+ //! using namespace asmjit;
1694
+ //!
1695
+ //! void example(CodeHolder& code) {
1696
+ //! // Contains all emitters attached to CodeHolder.
1697
+ //! const ZoneVector<BaseEmitter*>& emitters = code.emitters();
1698
+ //!
1699
+ //! // Contains all section entries managed by CodeHolder.
1700
+ //! const ZoneVector<Section*>& sections = code.sections();
1701
+ //!
1702
+ //! // Contains all label entries managed by CodeHolder.
1703
+ //! const ZoneVector<LabelEntry*>& labelEntries = code.labelEntries();
1704
+ //!
1705
+ //! // Contains all relocation entries managed by CodeHolder.
1706
+ //! const ZoneVector<RelocEntry*>& relocEntries = code.relocEntries();
1707
+ //! }
1708
+ //! ```
1709
+ //!
1710
+ //! \ref ZoneVector has overloaded array access operator to make it possible to access its elements through operator[].
1711
+ //! Some standard functions like \ref ZoneVector::empty(), \ref ZoneVector::size(), and \ref ZoneVector::data() are
1712
+ //! provided as well. Vectors are also iterable through a range-based for loop:
1713
+ //!
1714
+ //! ```
1715
+ //! using namespace asmjit;
1716
+ //!
1717
+ //! void example(CodeHolder& code) {
1718
+ //! for (LabelEntry* le : code.labelEntries()) {
1719
+ //! printf("Label #%u {Bound=%s Offset=%llu}",
1720
+ //! le->id(),
1721
+ //! le->isBound() ? "true" : "false",
1722
+ //! (unsigned long long)le->offset());
1723
+ //! }
1724
+ //! }
1725
+ //! ```
1726
+ //!
1727
+ //! ### Design Considerations
1728
+ //!
1729
+ //! Zone-allocated containers do not store the allocator within the container. This decision was made to reduce the
1730
+ //! footprint of such containers as AsmJit tooling, especially Compiler's register allocation, may use many instances
1731
+ //! of such containers to perform code analysis and register allocation.
1732
+ //!
1733
+ //! For example to append an item into a \ref ZoneVector it's required to pass the allocator as the first argument,
1734
+ //! so it can be used in case that the vector needs a reallocation. Such function also returns an error, which must
1735
+ //! be propagated to the caller.
1736
+ //!
1737
+ //! ```
1738
+ //! using namespace asmjit
1739
+ //!
1740
+ //! Error example(ZoneAllocator* allocator) {
1741
+ //! ZoneVector<int> vector;
1742
+ //!
1743
+ //! // Unfortunately, allocator must be provided to all functions that mutate
1744
+ //! // the vector. However, AsmJit users should never need to do this as all
1745
+ //! // manipulation should be done through public API, which takes care of
1746
+ //! // that.
1747
+ //! for (int i = 0; i < 100; i++) {
1748
+ //! ASMJIT_PROPAGATE(vector.append(allocator, i));
1749
+ //! }
1750
+ //!
1751
+ //! // By default vector's destructor doesn't release anything as it knows
1752
+ //! // that its content is zone allocated. However, \ref ZoneVector::release
1753
+ //! // can be used to explicitly release the vector data to the allocator if
1754
+ //! // necessary
1755
+ //! vector.release(allocator);
1756
+ //! }
1757
+ //! ```
1758
+ //!
1759
+ //! Containers like \ref ZoneVector also provide a functionality to reserve a certain number of items before any items
1760
+ //! are added to it. This approach is used internally in most places as it allows to prepare space for data that will
1761
+ //! be added to some container before the data itself was created.
1762
+ //!
1763
+ //! ```
1764
+ //! using namespace asmjit
1765
+ //!
1766
+ //! Error example(ZoneAllocator* allocator) {
1767
+ //! ZoneVector<int> vector;
1768
+ //!
1769
+ //! ASMJIT_PROPAGATE(vector.willGrow(100));
1770
+ //! for (int i = 0; i < 100; i++) {
1771
+ //! // Cannot fail.
1772
+ //! vector.appendUnsafe(allocator, i);
1773
+ //! }
1774
+ //!
1775
+ //! vector.release(allocator);
1776
+ //! }
1777
+ //! ```
1778
+
1779
+
1780
+ //! \defgroup asmjit_utilities Utilities
1781
+ //! \brief Utility classes and functions.
1782
+ //!
1783
+ //! ### Overview
1784
+ //!
1785
+ //! AsmJit uses and provides utility classes and functions, that can be used with AsmJit. The functionality can be
1786
+ //! divided into the following topics:
1787
+ //!
1788
+ //! ### String Functionality
1789
+ //!
1790
+ //! - \ref String - AsmJit's string container, which is used internally and which doesn't use exceptions and has
1791
+ //! a stable layout, which is not dependent on C++ standard library.
1792
+ //!
1793
+ //! - \ref StringTmp - String that can have base storage allocated on stack. The amount of storage on stack can
1794
+ //! be specified as a template parameter.
1795
+ //!
1796
+ //! - \ref FixedString - Fixed string container limited up to N characters.
1797
+ //!
1798
+ //! ### Code Generation Utilities
1799
+ //!
1800
+ //! - \ref ConstPool - Constant pool used by \ref BaseCompiler, but also available to users that may find use of it.
1801
+ //!
1802
+ //! ### Support Functionality Used by AsmJit
1803
+ //!
1804
+ //! - \ref Support namespace provides many other utility functions and classes that are used by AsmJit, and made
1805
+ //! public.
1806
+
1807
+
1808
+ //! \defgroup asmjit_x86 X86 Backend
1809
+ //! \brief X86/X64 backend.
1810
+
1811
+
1812
+ //! \defgroup asmjit_arm ARM Commons
1813
+ //! \brief ARM commons shared between AArch32 and AArch64.
1814
+
1815
+
1816
+ //! \defgroup asmjit_a64 AArch64 Backend
1817
+ //! \brief AArch64 backend.
1818
+
1819
+
1820
+ //! \cond INTERNAL
1821
+ //! \defgroup asmjit_ra RA
1822
+ //! \brief Register allocator internals.
1823
+ //! \endcond
1824
+
1825
+ } // {asmjit}
1826
+
1827
+ #include "asmjit-scope-begin.h"
1828
+ #include "core/archtraits.h"
1829
+ #include "core/assembler.h"
1830
+ #include "core/builder.h"
1831
+ #include "core/codeholder.h"
1832
+ #include "core/compiler.h"
1833
+ #include "core/constpool.h"
1834
+ #include "core/cpuinfo.h"
1835
+ #include "core/emitter.h"
1836
+ #include "core/environment.h"
1837
+ #include "core/errorhandler.h"
1838
+ #include "core/formatter.h"
1839
+ #include "core/func.h"
1840
+ #include "core/globals.h"
1841
+ #include "core/inst.h"
1842
+ #include "core/jitallocator.h"
1843
+ #include "core/jitruntime.h"
1844
+ #include "core/logger.h"
1845
+ #include "core/operand.h"
1846
+ #include "core/osutils.h"
1847
+ #include "core/string.h"
1848
+ #include "core/support.h"
1849
+ #include "core/target.h"
1850
+ #include "core/type.h"
1851
+ #include "core/virtmem.h"
1852
+ #include "core/zone.h"
1853
+ #include "core/zonehash.h"
1854
+ #include "core/zonelist.h"
1855
+ #include "core/zonetree.h"
1856
+ #include "core/zonestack.h"
1857
+ #include "core/zonestring.h"
1858
+ #include "core/zonevector.h"
1859
+ #include "asmjit-scope-end.h"
1860
+
1861
+ #endif // ASMJIT_CORE_H_INCLUDED