Line data Source code
1 : #ifdef __PLUMED_HAS_ASMJIT
2 : // This file is part of AsmJit project <https://asmjit.com>
3 : //
4 : // See asmjit.h or LICENSE.md for license and copyright information
5 : // SPDX-License-Identifier: Zlib
6 :
7 : #ifndef ASMJIT_CORE_FORMATTER_H_INCLUDED
8 : #define ASMJIT_CORE_FORMATTER_H_INCLUDED
9 :
10 : #include "globals.h"
11 : #include "inst.h"
12 : #include "moved_string.h"
13 : #include "support.h"
14 :
15 : ASMJIT_BEGIN_NAMESPACE
16 :
17 : //! \addtogroup asmjit_logging
18 : //! \{
19 :
20 : class BaseBuilder;
21 : class BaseEmitter;
22 : class BaseNode;
23 : struct Operand_;
24 :
25 : //! Format flags used by \ref Logger and \ref FormatOptions.
26 : enum class FormatFlags : uint32_t {
27 : //! No formatting flags.
28 : kNone = 0u,
29 :
30 : //! Show also binary form of each logged instruction (Assembler).
31 : kMachineCode = 0x00000001u,
32 : //! Show a text explanation of some immediate values.
33 : kExplainImms = 0x00000002u,
34 : //! Use hexadecimal notation of immediate values.
35 : kHexImms = 0x00000004u,
36 : //! Use hexadecimal notation of addresses and offsets in addresses.
37 : kHexOffsets = 0x00000008u,
38 : //! Show casts between virtual register types (Compiler output).
39 : kRegCasts = 0x00000010u,
40 : //! Show positions associated with nodes (Compiler output).
41 : kPositions = 0x00000020u
42 : };
43 0 : ASMJIT_DEFINE_ENUM_FLAGS(FormatFlags)
44 :
45 : //! Format indentation group, used by \ref FormatOptions.
46 : enum class FormatIndentationGroup : uint32_t {
47 : //! Indentation used for instructions and directives.
48 : kCode = 0u,
49 : //! Indentation used for labels and function nodes.
50 : kLabel = 1u,
51 : //! Indentation used for comments (not inline comments).
52 : kComment = 2u,
53 :
54 : //! \cond INTERNAL
55 : //! Reserved for future use.
56 : kReserved = 3u,
57 : //! \endcond
58 :
59 : //! Maximum value of `FormatIndentationGroup`.
60 : kMaxValue = kReserved
61 : };
62 :
63 : //! Format padding group, used by \ref FormatOptions.
64 : enum class FormatPaddingGroup : uint32_t {
65 : //! Describes padding of a regular line, which can represent instruction, data, or assembler directives.
66 : kRegularLine = 0,
67 : //! Describes padding of machine code dump that is visible next to the instruction, if enabled.
68 : kMachineCode = 1,
69 :
70 : //! Maximum value of `FormatPaddingGroup`.
71 : kMaxValue = kMachineCode
72 : };
73 :
74 : //! Formatting options used by \ref Logger and \ref Formatter.
75 0 : class FormatOptions {
76 : public:
77 : //! \name Members
78 : //! \{
79 :
80 : //! Format flags.
81 : FormatFlags _flags = FormatFlags::kNone;
82 : //! Indentations for each indentation group.
83 : Support::Array<uint8_t, uint32_t(FormatIndentationGroup::kMaxValue) + 1> _indentation {};
84 : //! Paddings for each padding group.
85 : Support::Array<uint16_t, uint32_t(FormatPaddingGroup::kMaxValue) + 1> _padding {};
86 :
87 : //! \}
88 :
89 : //! \name Reset
90 : //! \{
91 :
92 : //! Resets FormatOptions to its default initialized state.
93 54984 : inline void reset() noexcept {
94 54984 : _flags = FormatFlags::kNone;
95 : _indentation.fill(uint8_t(0));
96 : _padding.fill(uint16_t(0));
97 54984 : }
98 :
99 : //! \}
100 :
101 : //! \name Accessors
102 : //! \{
103 :
104 : //! Returns format flags.
105 0 : inline FormatFlags flags() const noexcept { return _flags; }
106 : //! Tests whether the given `flag` is set in format flags.
107 0 : inline bool hasFlag(FormatFlags flag) const noexcept { return Support::test(_flags, flag); }
108 :
109 : //! Resets all format flags to `flags`.
110 : inline void setFlags(FormatFlags flags) noexcept { _flags = flags; }
111 : //! Adds `flags` to format flags.
112 : inline void addFlags(FormatFlags flags) noexcept { _flags |= flags; }
113 : //! Removes `flags` from format flags.
114 : inline void clearFlags(FormatFlags flags) noexcept { _flags &= ~flags; }
115 :
116 : //! Returns indentation for the given indentation `group`.
117 0 : inline uint8_t indentation(FormatIndentationGroup group) const noexcept { return _indentation[group]; }
118 : //! Sets indentation for the given indentation `group`.
119 : inline void setIndentation(FormatIndentationGroup group, uint32_t n) noexcept { _indentation[group] = uint8_t(n); }
120 : //! Resets indentation for the given indentation `group` to zero.
121 : inline void resetIndentation(FormatIndentationGroup group) noexcept { _indentation[group] = uint8_t(0); }
122 :
123 : //! Returns pading for the given padding `group`.
124 0 : inline size_t padding(FormatPaddingGroup group) const noexcept { return _padding[group]; }
125 : //! Sets pading for the given padding `group`.
126 : inline void setPadding(FormatPaddingGroup group, size_t n) noexcept { _padding[group] = uint16_t(n); }
127 : //! Resets pading for the given padding `group` to zero, which means that a default padding will be used
128 : //! based on the target architecture properties.
129 : inline void resetPadding(FormatPaddingGroup group) noexcept { _padding[group] = uint16_t(0); }
130 :
131 : //! \}
132 : };
133 :
134 : //! Provides formatting functionality to format operands, instructions, and nodes.
135 : namespace Formatter {
136 :
137 : #ifndef ASMJIT_NO_LOGGING
138 :
139 : //! Appends a formatted `typeId` to the output string `sb`.
140 : ASMJIT_API Error formatTypeId(
141 : String& sb,
142 : TypeId typeId) noexcept;
143 :
144 : //! Appends a formatted `featureId` to the output string `sb`.
145 : //!
146 : //! See \ref CpuFeatures.
147 : ASMJIT_API Error formatFeature(
148 : String& sb,
149 : Arch arch,
150 : uint32_t featureId) noexcept;
151 :
152 : //! Appends a formatted register to the output string `sb`.
153 : //!
154 : //! \note Emitter is optional, but it's required to format virtual registers, which won't be formatted properly
155 : //! if the `emitter` is not provided.
156 : ASMJIT_API Error formatRegister(
157 : String& sb,
158 : FormatFlags formatFlags,
159 : const BaseEmitter* emitter,
160 : Arch arch,
161 : RegType regType,
162 : uint32_t regId) noexcept;
163 :
164 : //! Appends a formatted label to the output string `sb`.
165 : //!
166 : //! \note Emitter is optional, but it's required to format named labels properly, otherwise the formatted as
167 : //! it is an anonymous label.
168 : ASMJIT_API Error formatLabel(
169 : String& sb,
170 : FormatFlags formatFlags,
171 : const BaseEmitter* emitter,
172 : uint32_t labelId) noexcept;
173 :
174 : //! Appends a formatted operand to the output string `sb`.
175 : //!
176 : //! \note Emitter is optional, but it's required to format named labels and virtual registers. See
177 : //! \ref formatRegister() and \ref formatLabel() for more details.
178 : ASMJIT_API Error formatOperand(
179 : String& sb,
180 : FormatFlags formatFlags,
181 : const BaseEmitter* emitter,
182 : Arch arch,
183 : const Operand_& op) noexcept;
184 :
185 : //! Appends a formatted data-type to the output string `sb`.
186 : ASMJIT_API Error formatDataType(
187 : String& sb,
188 : FormatFlags formatFlags,
189 : Arch arch,
190 : TypeId typeId) noexcept;
191 :
192 : //! Appends a formatted data to the output string `sb`.
193 : ASMJIT_API Error formatData(
194 : String& sb,
195 : FormatFlags formatFlags,
196 : Arch arch,
197 : TypeId typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;
198 :
199 : //! Appends a formatted instruction to the output string `sb`.
200 : //!
201 : //! \note Emitter is optional, but it's required to format named labels and virtual registers. See
202 : //! \ref formatRegister() and \ref formatLabel() for more details.
203 : ASMJIT_API Error formatInstruction(
204 : String& sb,
205 : FormatFlags formatFlags,
206 : const BaseEmitter* emitter,
207 : Arch arch,
208 : const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;
209 :
210 : #ifndef ASMJIT_NO_BUILDER
211 : //! Appends a formatted node to the output string `sb`.
212 : //!
213 : //! The `node` must belong to the provided `builder`.
214 : ASMJIT_API Error formatNode(
215 : String& sb,
216 : const FormatOptions& formatOptions,
217 : const BaseBuilder* builder,
218 : const BaseNode* node) noexcept;
219 :
220 : //! Appends formatted nodes to the output string `sb`.
221 : //!
222 : //! All nodes that are part of the given `builder` will be appended.
223 : ASMJIT_API Error formatNodeList(
224 : String& sb,
225 : const FormatOptions& formatOptions,
226 : const BaseBuilder* builder) noexcept;
227 :
228 : //! Appends formatted nodes to the output string `sb`.
229 : //!
230 : //! This function works the same as \ref formatNode(), but appends more nodes to the output string,
231 : //! separating each node with a newline '\n' character.
232 : ASMJIT_API Error formatNodeList(
233 : String& sb,
234 : const FormatOptions& formatOptions,
235 : const BaseBuilder* builder,
236 : const BaseNode* begin,
237 : const BaseNode* end) noexcept;
238 : #endif
239 :
240 : #endif
241 :
242 : } // {Formatter}
243 :
244 : //! \}
245 :
246 : ASMJIT_END_NAMESPACE
247 :
248 : #endif // ASMJIT_CORE_FORMATTER_H_INCLUDED
249 :
250 : #endif // __PLUMED_HAS_ASMJIT
|