asmjit 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,247 @@
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_FORMATTER_H_INCLUDED
7
+ #define ASMJIT_CORE_FORMATTER_H_INCLUDED
8
+
9
+ #include "../core/globals.h"
10
+ #include "../core/inst.h"
11
+ #include "../core/string.h"
12
+ #include "../core/support.h"
13
+
14
+ ASMJIT_BEGIN_NAMESPACE
15
+
16
+ //! \addtogroup asmjit_logging
17
+ //! \{
18
+
19
+ class BaseBuilder;
20
+ class BaseEmitter;
21
+ class BaseNode;
22
+ struct Operand_;
23
+
24
+ //! Format flags used by \ref Logger and \ref FormatOptions.
25
+ enum class FormatFlags : uint32_t {
26
+ //! No formatting flags.
27
+ kNone = 0u,
28
+
29
+ //! Show also binary form of each logged instruction (Assembler).
30
+ kMachineCode = 0x00000001u,
31
+ //! Show a text explanation of some immediate values.
32
+ kExplainImms = 0x00000002u,
33
+ //! Use hexadecimal notation of immediate values.
34
+ kHexImms = 0x00000004u,
35
+ //! Use hexadecimal notation of addresses and offsets in addresses.
36
+ kHexOffsets = 0x00000008u,
37
+ //! Show casts between virtual register types (Compiler output).
38
+ kRegCasts = 0x00000010u,
39
+ //! Show positions associated with nodes (Compiler output).
40
+ kPositions = 0x00000020u
41
+ };
42
+ ASMJIT_DEFINE_ENUM_FLAGS(FormatFlags)
43
+
44
+ //! Format indentation group, used by \ref FormatOptions.
45
+ enum class FormatIndentationGroup : uint32_t {
46
+ //! Indentation used for instructions and directives.
47
+ kCode = 0u,
48
+ //! Indentation used for labels and function nodes.
49
+ kLabel = 1u,
50
+ //! Indentation used for comments (not inline comments).
51
+ kComment = 2u,
52
+
53
+ //! \cond INTERNAL
54
+ //! Reserved for future use.
55
+ kReserved = 3u,
56
+ //! \endcond
57
+
58
+ //! Maximum value of `FormatIndentationGroup`.
59
+ kMaxValue = kReserved
60
+ };
61
+
62
+ //! Format padding group, used by \ref FormatOptions.
63
+ enum class FormatPaddingGroup : uint32_t {
64
+ //! Describes padding of a regular line, which can represent instruction, data, or assembler directives.
65
+ kRegularLine = 0,
66
+ //! Describes padding of machine code dump that is visible next to the instruction, if enabled.
67
+ kMachineCode = 1,
68
+
69
+ //! Maximum value of `FormatPaddingGroup`.
70
+ kMaxValue = kMachineCode
71
+ };
72
+
73
+ //! Formatting options used by \ref Logger and \ref Formatter.
74
+ class FormatOptions {
75
+ public:
76
+ //! \name Members
77
+ //! \{
78
+
79
+ //! Format flags.
80
+ FormatFlags _flags = FormatFlags::kNone;
81
+ //! Indentations for each indentation group.
82
+ Support::Array<uint8_t, uint32_t(FormatIndentationGroup::kMaxValue) + 1> _indentation {};
83
+ //! Paddings for each padding group.
84
+ Support::Array<uint16_t, uint32_t(FormatPaddingGroup::kMaxValue) + 1> _padding {};
85
+
86
+ //! \}
87
+
88
+ //! \name Reset
89
+ //! \{
90
+
91
+ //! Resets FormatOptions to its default initialized state.
92
+ inline void reset() noexcept {
93
+ _flags = FormatFlags::kNone;
94
+ _indentation.fill(uint8_t(0));
95
+ _padding.fill(uint16_t(0));
96
+ }
97
+
98
+ //! \}
99
+
100
+ //! \name Accessors
101
+ //! \{
102
+
103
+ //! Returns format flags.
104
+ inline FormatFlags flags() const noexcept { return _flags; }
105
+ //! Tests whether the given `flag` is set in format flags.
106
+ inline bool hasFlag(FormatFlags flag) const noexcept { return Support::test(_flags, flag); }
107
+
108
+ //! Resets all format flags to `flags`.
109
+ inline void setFlags(FormatFlags flags) noexcept { _flags = flags; }
110
+ //! Adds `flags` to format flags.
111
+ inline void addFlags(FormatFlags flags) noexcept { _flags |= flags; }
112
+ //! Removes `flags` from format flags.
113
+ inline void clearFlags(FormatFlags flags) noexcept { _flags &= ~flags; }
114
+
115
+ //! Returns indentation for the given indentation `group`.
116
+ inline uint8_t indentation(FormatIndentationGroup group) const noexcept { return _indentation[group]; }
117
+ //! Sets indentation for the given indentation `group`.
118
+ inline void setIndentation(FormatIndentationGroup group, uint32_t n) noexcept { _indentation[group] = uint8_t(n); }
119
+ //! Resets indentation for the given indentation `group` to zero.
120
+ inline void resetIndentation(FormatIndentationGroup group) noexcept { _indentation[group] = uint8_t(0); }
121
+
122
+ //! Returns pading for the given padding `group`.
123
+ inline size_t padding(FormatPaddingGroup group) const noexcept { return _padding[group]; }
124
+ //! Sets pading for the given padding `group`.
125
+ inline void setPadding(FormatPaddingGroup group, size_t n) noexcept { _padding[group] = uint16_t(n); }
126
+ //! Resets pading for the given padding `group` to zero, which means that a default padding will be used
127
+ //! based on the target architecture properties.
128
+ inline void resetPadding(FormatPaddingGroup group) noexcept { _padding[group] = uint16_t(0); }
129
+
130
+ //! \}
131
+ };
132
+
133
+ //! Provides formatting functionality to format operands, instructions, and nodes.
134
+ namespace Formatter {
135
+
136
+ #ifndef ASMJIT_NO_LOGGING
137
+
138
+ //! Appends a formatted `typeId` to the output string `sb`.
139
+ ASMJIT_API Error formatTypeId(
140
+ String& sb,
141
+ TypeId typeId) noexcept;
142
+
143
+ //! Appends a formatted `featureId` to the output string `sb`.
144
+ //!
145
+ //! See \ref CpuFeatures.
146
+ ASMJIT_API Error formatFeature(
147
+ String& sb,
148
+ Arch arch,
149
+ uint32_t featureId) noexcept;
150
+
151
+ //! Appends a formatted register to the output string `sb`.
152
+ //!
153
+ //! \note Emitter is optional, but it's required to format virtual registers, which won't be formatted properly
154
+ //! if the `emitter` is not provided.
155
+ ASMJIT_API Error formatRegister(
156
+ String& sb,
157
+ FormatFlags formatFlags,
158
+ const BaseEmitter* emitter,
159
+ Arch arch,
160
+ RegType regType,
161
+ uint32_t regId) noexcept;
162
+
163
+ //! Appends a formatted label to the output string `sb`.
164
+ //!
165
+ //! \note Emitter is optional, but it's required to format named labels properly, otherwise the formatted as
166
+ //! it is an anonymous label.
167
+ ASMJIT_API Error formatLabel(
168
+ String& sb,
169
+ FormatFlags formatFlags,
170
+ const BaseEmitter* emitter,
171
+ uint32_t labelId) noexcept;
172
+
173
+ //! Appends a formatted operand to the output string `sb`.
174
+ //!
175
+ //! \note Emitter is optional, but it's required to format named labels and virtual registers. See
176
+ //! \ref formatRegister() and \ref formatLabel() for more details.
177
+ ASMJIT_API Error formatOperand(
178
+ String& sb,
179
+ FormatFlags formatFlags,
180
+ const BaseEmitter* emitter,
181
+ Arch arch,
182
+ const Operand_& op) noexcept;
183
+
184
+ //! Appends a formatted data-type to the output string `sb`.
185
+ ASMJIT_API Error formatDataType(
186
+ String& sb,
187
+ FormatFlags formatFlags,
188
+ Arch arch,
189
+ TypeId typeId) noexcept;
190
+
191
+ //! Appends a formatted data to the output string `sb`.
192
+ ASMJIT_API Error formatData(
193
+ String& sb,
194
+ FormatFlags formatFlags,
195
+ Arch arch,
196
+ TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;
197
+
198
+ //! Appends a formatted instruction to the output string `sb`.
199
+ //!
200
+ //! \note Emitter is optional, but it's required to format named labels and virtual registers. See
201
+ //! \ref formatRegister() and \ref formatLabel() for more details.
202
+ ASMJIT_API Error formatInstruction(
203
+ String& sb,
204
+ FormatFlags formatFlags,
205
+ const BaseEmitter* emitter,
206
+ Arch arch,
207
+ const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
208
+
209
+ #ifndef ASMJIT_NO_BUILDER
210
+ //! Appends a formatted node to the output string `sb`.
211
+ //!
212
+ //! The `node` must belong to the provided `builder`.
213
+ ASMJIT_API Error formatNode(
214
+ String& sb,
215
+ const FormatOptions& formatOptions,
216
+ const BaseBuilder* builder,
217
+ const BaseNode* node) noexcept;
218
+
219
+ //! Appends formatted nodes to the output string `sb`.
220
+ //!
221
+ //! All nodes that are part of the given `builder` will be appended.
222
+ ASMJIT_API Error formatNodeList(
223
+ String& sb,
224
+ const FormatOptions& formatOptions,
225
+ const BaseBuilder* builder) noexcept;
226
+
227
+ //! Appends formatted nodes to the output string `sb`.
228
+ //!
229
+ //! This function works the same as \ref formatNode(), but appends more nodes to the output string,
230
+ //! separating each node with a newline '\n' character.
231
+ ASMJIT_API Error formatNodeList(
232
+ String& sb,
233
+ const FormatOptions& formatOptions,
234
+ const BaseBuilder* builder,
235
+ const BaseNode* begin,
236
+ const BaseNode* end) noexcept;
237
+ #endif
238
+
239
+ #endif
240
+
241
+ } // {Formatter}
242
+
243
+ //! \}
244
+
245
+ ASMJIT_END_NAMESPACE
246
+
247
+ #endif // ASMJIT_CORE_FORMATTER_H_INCLUDED
@@ -0,0 +1,34 @@
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_FORMATTER_P_H_INCLUDED
7
+ #define ASMJIT_CORE_FORMATTER_P_H_INCLUDED
8
+
9
+ #include "../core/formatter.h"
10
+
11
+ ASMJIT_BEGIN_NAMESPACE
12
+
13
+ //! \cond INTERNAL
14
+ //! \addtogroup asmjit_logging
15
+ //! \{
16
+
17
+ namespace Formatter {
18
+
19
+ static ASMJIT_FORCE_INLINE size_t paddingFromOptions(const FormatOptions& formatOptions, FormatPaddingGroup group) noexcept {
20
+ static constexpr uint16_t _defaultPaddingTable[uint32_t(FormatPaddingGroup::kMaxValue) + 1] = { 44, 26 };
21
+ static_assert(uint32_t(FormatPaddingGroup::kMaxValue) + 1 == 2, "If a new group is defined it must be added here");
22
+
23
+ size_t padding = formatOptions.padding(group);
24
+ return padding ? padding : size_t(_defaultPaddingTable[uint32_t(group)]);
25
+ }
26
+
27
+ } // {Formatter}
28
+
29
+ //! \}
30
+ //! \endcond
31
+
32
+ ASMJIT_END_NAMESPACE
33
+
34
+ #endif // ASMJIT_CORE_FORMATTER_H_P_INCLUDED
@@ -0,0 +1,286 @@
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
+ #include "../core/api-build_p.h"
7
+ #include "../core/archtraits.h"
8
+ #include "../core/func.h"
9
+ #include "../core/operand.h"
10
+ #include "../core/type.h"
11
+ #include "../core/funcargscontext_p.h"
12
+
13
+ #if !defined(ASMJIT_NO_X86)
14
+ #include "../x86/x86func_p.h"
15
+ #endif
16
+
17
+ #if !defined(ASMJIT_NO_AARCH64)
18
+ #include "../arm/a64func_p.h"
19
+ #endif
20
+
21
+ ASMJIT_BEGIN_NAMESPACE
22
+
23
+ // CallConv - Init & Reset
24
+ // =======================
25
+
26
+ ASMJIT_FAVOR_SIZE Error CallConv::init(CallConvId ccId, const Environment& environment) noexcept {
27
+ reset();
28
+
29
+ #if !defined(ASMJIT_NO_X86)
30
+ if (environment.isFamilyX86())
31
+ return x86::FuncInternal::initCallConv(*this, ccId, environment);
32
+ #endif
33
+
34
+ #if !defined(ASMJIT_NO_AARCH64)
35
+ if (environment.isFamilyAArch64())
36
+ return a64::FuncInternal::initCallConv(*this, ccId, environment);
37
+ #endif
38
+
39
+ return DebugUtils::errored(kErrorInvalidArgument);
40
+ }
41
+
42
+ // FuncDetail - Init / Reset
43
+ // =========================
44
+
45
+ ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& signature, const Environment& environment) noexcept {
46
+ CallConvId ccId = signature.callConvId();
47
+ uint32_t argCount = signature.argCount();
48
+
49
+ if (ASMJIT_UNLIKELY(argCount > Globals::kMaxFuncArgs))
50
+ return DebugUtils::errored(kErrorInvalidArgument);
51
+
52
+ CallConv& cc = _callConv;
53
+ ASMJIT_PROPAGATE(cc.init(ccId, environment));
54
+
55
+ uint32_t registerSize = Environment::registerSizeFromArch(cc.arch());
56
+ uint32_t deabstractDelta = TypeUtils::deabstractDeltaOfSize(registerSize);
57
+
58
+ const TypeId* signatureArgs = signature.args();
59
+ for (uint32_t argIndex = 0; argIndex < argCount; argIndex++) {
60
+ FuncValuePack& argPack = _args[argIndex];
61
+ argPack[0].initTypeId(TypeUtils::deabstract(signatureArgs[argIndex], deabstractDelta));
62
+ }
63
+
64
+ _argCount = uint8_t(argCount);
65
+ _vaIndex = uint8_t(signature.vaIndex());
66
+
67
+ TypeId ret = signature.ret();
68
+ if (ret != TypeId::kVoid)
69
+ _rets[0].initTypeId(TypeUtils::deabstract(ret, deabstractDelta));
70
+
71
+ #if !defined(ASMJIT_NO_X86)
72
+ if (environment.isFamilyX86())
73
+ return x86::FuncInternal::initFuncDetail(*this, signature, registerSize);
74
+ #endif
75
+
76
+ #if !defined(ASMJIT_NO_AARCH64)
77
+ if (environment.isFamilyAArch64())
78
+ return a64::FuncInternal::initFuncDetail(*this, signature, registerSize);
79
+ #endif
80
+
81
+ // We should never bubble here as if `cc.init()` succeeded then there has to be an implementation for the current
82
+ // architecture. However, stay safe.
83
+ return DebugUtils::errored(kErrorInvalidArgument);
84
+ }
85
+
86
+ // FuncFrame - Init
87
+ // ================
88
+
89
+ ASMJIT_FAVOR_SIZE Error FuncFrame::init(const FuncDetail& func) noexcept {
90
+ Arch arch = func.callConv().arch();
91
+ if (!Environment::isValidArch(arch))
92
+ return DebugUtils::errored(kErrorInvalidArch);
93
+
94
+ const ArchTraits& archTraits = ArchTraits::byArch(arch);
95
+
96
+ // Initializing FuncFrame means making a copy of some properties of `func`. Properties like `_localStackSize` will
97
+ // be set by the user before the frame is finalized.
98
+ reset();
99
+
100
+ _arch = arch;
101
+ _spRegId = uint8_t(archTraits.spRegId());
102
+ _saRegId = uint8_t(BaseReg::kIdBad);
103
+
104
+ uint32_t naturalStackAlignment = func.callConv().naturalStackAlignment();
105
+ uint32_t minDynamicAlignment = Support::max<uint32_t>(naturalStackAlignment, 16);
106
+
107
+ if (minDynamicAlignment == naturalStackAlignment)
108
+ minDynamicAlignment <<= 1;
109
+
110
+ _naturalStackAlignment = uint8_t(naturalStackAlignment);
111
+ _minDynamicAlignment = uint8_t(minDynamicAlignment);
112
+ _redZoneSize = uint8_t(func.redZoneSize());
113
+ _spillZoneSize = uint8_t(func.spillZoneSize());
114
+ _finalStackAlignment = uint8_t(_naturalStackAlignment);
115
+
116
+ if (func.hasFlag(CallConvFlags::kCalleePopsStack)) {
117
+ _calleeStackCleanup = uint16_t(func.argStackSize());
118
+ }
119
+
120
+ // Initial masks of dirty and preserved registers.
121
+ for (RegGroup group : RegGroupVirtValues{}) {
122
+ _dirtyRegs[group] = func.usedRegs(group);
123
+ _preservedRegs[group] = func.preservedRegs(group);
124
+ }
125
+
126
+ // Exclude stack pointer - this register is never included in saved GP regs.
127
+ _preservedRegs[RegGroup::kGp] &= ~Support::bitMask(archTraits.spRegId());
128
+
129
+ // The size and alignment of save/restore area of registers for each virtual register group
130
+ _saveRestoreRegSize = func.callConv()._saveRestoreRegSize;
131
+ _saveRestoreAlignment = func.callConv()._saveRestoreAlignment;
132
+
133
+ return kErrorOk;
134
+ }
135
+
136
+ // FuncFrame - Finalize
137
+ // ====================
138
+
139
+ ASMJIT_FAVOR_SIZE Error FuncFrame::finalize() noexcept {
140
+ if (!Environment::isValidArch(arch()))
141
+ return DebugUtils::errored(kErrorInvalidArch);
142
+
143
+ const ArchTraits& archTraits = ArchTraits::byArch(arch());
144
+
145
+ uint32_t registerSize = _saveRestoreRegSize[RegGroup::kGp];
146
+ uint32_t vectorSize = _saveRestoreRegSize[RegGroup::kVec];
147
+ uint32_t returnAddressSize = archTraits.hasLinkReg() ? 0u : registerSize;
148
+
149
+ // The final stack alignment must be updated accordingly to call and local stack alignments.
150
+ uint32_t stackAlignment = _finalStackAlignment;
151
+ ASMJIT_ASSERT(stackAlignment == Support::max(_naturalStackAlignment,
152
+ _callStackAlignment,
153
+ _localStackAlignment));
154
+
155
+ bool hasFP = hasPreservedFP();
156
+ bool hasDA = hasDynamicAlignment();
157
+
158
+ uint32_t kSp = archTraits.spRegId();
159
+ uint32_t kFp = archTraits.fpRegId();
160
+ uint32_t kLr = archTraits.linkRegId();
161
+
162
+ // Make frame pointer dirty if the function uses it.
163
+ if (hasFP) {
164
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(kFp);
165
+
166
+ // Currently required by ARM, if this works differently across architectures we would have to generalize most
167
+ // likely in CallConv.
168
+ if (kLr != BaseReg::kIdBad)
169
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(kLr);
170
+ }
171
+
172
+ // These two are identical if the function doesn't align its stack dynamically.
173
+ uint32_t saRegId = _saRegId;
174
+ if (saRegId == BaseReg::kIdBad)
175
+ saRegId = kSp;
176
+
177
+ // Fix stack arguments base-register from SP to FP in case it was not picked before and the function performs
178
+ // dynamic stack alignment.
179
+ if (hasDA && saRegId == kSp)
180
+ saRegId = kFp;
181
+
182
+ // Mark as dirty any register but SP if used as SA pointer.
183
+ if (saRegId != kSp)
184
+ _dirtyRegs[RegGroup::kGp] |= Support::bitMask(saRegId);
185
+
186
+ _spRegId = uint8_t(kSp);
187
+ _saRegId = uint8_t(saRegId);
188
+
189
+ // Setup stack size used to save preserved registers.
190
+ uint32_t saveRestoreSizes[2] {};
191
+ for (RegGroup group : RegGroupVirtValues{})
192
+ saveRestoreSizes[size_t(!archTraits.hasInstPushPop(group))]
193
+ += Support::alignUp(Support::popcnt(savedRegs(group)) * saveRestoreRegSize(group), saveRestoreAlignment(group));
194
+
195
+ _pushPopSaveSize = uint16_t(saveRestoreSizes[0]);
196
+ _extraRegSaveSize = uint16_t(saveRestoreSizes[1]);
197
+
198
+ uint32_t v = 0; // The beginning of the stack frame relative to SP after prolog.
199
+ v += callStackSize(); // Count 'callStackSize' <- This is used to call functions.
200
+ v = Support::alignUp(v, stackAlignment); // Align to function's stack alignment.
201
+
202
+ _localStackOffset = v; // Store 'localStackOffset' <- Function's local stack starts here.
203
+ v += localStackSize(); // Count 'localStackSize' <- Function's local stack ends here.
204
+
205
+ // If the function's stack must be aligned, calculate the alignment necessary to store vector registers, and set
206
+ // `FuncAttributes::kAlignedVecSR` to inform PEI that it can use instructions that perform aligned stores/loads.
207
+ if (stackAlignment >= vectorSize && _extraRegSaveSize) {
208
+ addAttributes(FuncAttributes::kAlignedVecSR);
209
+ v = Support::alignUp(v, vectorSize); // Align 'extraRegSaveOffset'.
210
+ }
211
+
212
+ _extraRegSaveOffset = v; // Store 'extraRegSaveOffset' <- Non-GP save/restore starts here.
213
+ v += _extraRegSaveSize; // Count 'extraRegSaveSize' <- Non-GP save/restore ends here.
214
+
215
+ // Calculate if dynamic alignment (DA) slot (stored as offset relative to SP) is required and its offset.
216
+ if (hasDA && !hasFP) {
217
+ _daOffset = v; // Store 'daOffset' <- DA pointer would be stored here.
218
+ v += registerSize; // Count 'daOffset'.
219
+ }
220
+ else {
221
+ _daOffset = FuncFrame::kTagInvalidOffset;
222
+ }
223
+
224
+ // Link Register
225
+ // -------------
226
+ //
227
+ // The stack is aligned after the function call as the return address is stored in a link register. Some
228
+ // architectures may require to always have aligned stack after PUSH/POP operation, which is represented
229
+ // by ArchTraits::stackAlignmentConstraint().
230
+ //
231
+ // No Link Register (X86/X64)
232
+ // --------------------------
233
+ //
234
+ // The return address should be stored after GP save/restore regs. It has the same size as `registerSize`
235
+ // (basically the native register/pointer size). We don't adjust it now as `v` now contains the exact size
236
+ // that the function requires to adjust (call frame + stack frame, vec stack size). The stack (if we consider
237
+ // this size) is misaligned now, as it's always aligned before the function call - when `call()` is executed
238
+ // it pushes the current EIP|RIP onto the stack, and misaligns it by 12 or 8 bytes (depending on the
239
+ // architecture). So count number of bytes needed to align it up to the function's CallFrame (the beginning).
240
+ if (v || hasFuncCalls() || !returnAddressSize)
241
+ v += Support::alignUpDiff(v + pushPopSaveSize() + returnAddressSize, stackAlignment);
242
+
243
+ _pushPopSaveOffset = v; // Store 'pushPopSaveOffset' <- Function's push/pop save/restore starts here.
244
+ _stackAdjustment = v; // Store 'stackAdjustment' <- SA used by 'add SP, SA' and 'sub SP, SA'.
245
+ v += _pushPopSaveSize; // Count 'pushPopSaveSize' <- Function's push/pop save/restore ends here.
246
+ _finalStackSize = v; // Store 'finalStackSize' <- Final stack used by the function.
247
+
248
+ if (!archTraits.hasLinkReg())
249
+ v += registerSize; // Count 'ReturnAddress' <- As CALL pushes onto stack.
250
+
251
+ // If the function performs dynamic stack alignment then the stack-adjustment must be aligned.
252
+ if (hasDA)
253
+ _stackAdjustment = Support::alignUp(_stackAdjustment, stackAlignment);
254
+
255
+ // Calculate where the function arguments start relative to SP.
256
+ _saOffsetFromSP = hasDA ? FuncFrame::kTagInvalidOffset : v;
257
+
258
+ // Calculate where the function arguments start relative to FP or user-provided register.
259
+ _saOffsetFromSA = hasFP ? returnAddressSize + registerSize // Return address + frame pointer.
260
+ : returnAddressSize + _pushPopSaveSize; // Return address + all push/pop regs.
261
+
262
+ return kErrorOk;
263
+ }
264
+
265
+ // FuncArgsAssignment - UpdateFuncFrame
266
+ // ====================================
267
+
268
+ ASMJIT_FAVOR_SIZE Error FuncArgsAssignment::updateFuncFrame(FuncFrame& frame) const noexcept {
269
+ Arch arch = frame.arch();
270
+ const FuncDetail* func = funcDetail();
271
+
272
+ if (!func)
273
+ return DebugUtils::errored(kErrorInvalidState);
274
+
275
+ RAConstraints constraints;
276
+ ASMJIT_PROPAGATE(constraints.init(arch));
277
+
278
+ FuncArgsContext ctx;
279
+ ASMJIT_PROPAGATE(ctx.initWorkData(frame, *this, &constraints));
280
+ ASMJIT_PROPAGATE(ctx.markDstRegsDirty(frame));
281
+ ASMJIT_PROPAGATE(ctx.markScratchRegs(frame));
282
+ ASMJIT_PROPAGATE(ctx.markStackArgsReg(frame));
283
+ return kErrorOk;
284
+ }
285
+
286
+ ASMJIT_END_NAMESPACE