Welcome to mirror list, hosted at ThFree Co, Russian Federation.

formatter.h « core « asmjit « src - github.com/asmjit/asmjit.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 513d7640b27e81367c7f988223a36ae5008345ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
// AsmJit - Machine code generation for C++
//
//  * Official AsmJit Home Page: https://asmjit.com
//  * Official Github Repository: https://github.com/asmjit/asmjit
//
// Copyright (c) 2008-2020 The AsmJit Authors
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
//    claim that you wrote the original software. If you use this software
//    in a product, an acknowledgment in the product documentation would be
//    appreciated but is not required.
// 2. Altered source versions must be plainly marked as such, and must not be
//    misrepresented as being the original software.
// 3. This notice may not be removed or altered from any source distribution.

#ifndef ASMJIT_CORE_FORMATTER_H_INCLUDED
#define ASMJIT_CORE_FORMATTER_H_INCLUDED

#include "../core/inst.h"
#include "../core/string.h"

#ifndef ASMJIT_NO_LOGGING

ASMJIT_BEGIN_NAMESPACE

//! \addtogroup asmjit_logging
//! \{

// ============================================================================
// [Forward Declarations]
// ============================================================================

class BaseEmitter;
struct Operand_;

#ifndef ASMJIT_NO_BUILDER
class BaseBuilder;
class BaseNode;
#endif

#ifndef ASMJIT_NO_COMPILER
class BaseCompiler;
#endif

// ============================================================================
// [asmjit::FormatOptions]
// ============================================================================

//! Formatting options used by \ref Logger and \ref Formatter.
class FormatOptions {
public:
  //! Format flags, see \ref Flags.
  uint32_t _flags;
  //! Indentation by type, see \ref IndentationType.
  uint8_t _indentation[4];

  //! Flags can enable a logging feature.
  enum Flags : uint32_t {
    //! No flags.
    kNoFlags = 0u,

    //! Show also binary form of each logged instruction (Assembler).
    kFlagMachineCode = 0x00000001u,
    //! Show a text explanation of some immediate values.
    kFlagExplainImms = 0x00000002u,
    //! Use hexadecimal notation of immediate values.
    kFlagHexImms = 0x00000004u,
    //! Use hexadecimal notation of address offsets.
    kFlagHexOffsets = 0x00000008u,
    //! Show casts between virtual register types (Compiler).
    kFlagRegCasts = 0x00000010u,
    //! Show positions associated with nodes (Compiler).
    kFlagPositions = 0x00000020u,
    //! Annotate nodes that are lowered by passes.
    kFlagAnnotations = 0x00000040u,

    // TODO: These must go, keep this only for formatting.
    //! Show an additional output from passes.
    kFlagDebugPasses = 0x00000080u,
    //! Show an additional output from RA.
    kFlagDebugRA = 0x00000100u
  };

  //! Describes indentation type of code, label, or comment in logger output.
  enum IndentationType : uint32_t {
    //! Indentation used for instructions and directives.
    kIndentationCode = 0u,
    //! Indentation used for labels and function nodes.
    kIndentationLabel = 1u,
    //! Indentation used for comments (not inline comments).
    kIndentationComment = 2u,
    //! \cond INTERNAL
    //! Reserved for future use.
    kIndentationReserved = 3u
    //! \endcond
  };

  //! \name Construction & Destruction
  //! \{

  //! Creates a default-initialized FormatOptions.
  constexpr FormatOptions() noexcept
    : _flags(0),
      _indentation { 0, 0, 0, 0 } {}

  constexpr FormatOptions(const FormatOptions& other) noexcept = default;
  inline FormatOptions& operator=(const FormatOptions& other) noexcept = default;

  //! Resets FormatOptions to its default initialized state.
  inline void reset() noexcept {
    _flags = 0;
    _indentation[0] = 0;
    _indentation[1] = 0;
    _indentation[2] = 0;
    _indentation[3] = 0;
  }

  //! \}

  //! \name Accessors
  //! \{

  //! Returns format flags.
  constexpr uint32_t flags() const noexcept { return _flags; }
  //! Tests whether the given `flag` is set in format flags.
  constexpr bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
  //! Resets all format flags to `flags`.
  inline void setFlags(uint32_t flags) noexcept { _flags = flags; }
  //! Adds `flags` to format flags.
  inline void addFlags(uint32_t flags) noexcept { _flags |= flags; }
  //! Removes `flags` from format flags.
  inline void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }

  //! Returns indentation for the given `type`, see \ref IndentationType.
  constexpr uint8_t indentation(uint32_t type) const noexcept { return _indentation[type]; }
  //! Sets indentation for the given `type`, see \ref IndentationType.
  inline void setIndentation(uint32_t type, uint32_t n) noexcept { _indentation[type] = uint8_t(n); }
  //! Resets indentation for the given `type` to zero.
  inline void resetIndentation(uint32_t type) noexcept { _indentation[type] = uint8_t(0); }

  //! \}
};

// ============================================================================
// [asmjit::Formatter]
// ============================================================================

//! Provides formatting functionality to format operands, instructions, and nodes.
namespace Formatter {

//! Appends a formatted `typeId` to the output string `sb`.
ASMJIT_API Error formatTypeId(
  String& sb,
  uint32_t typeId) noexcept;

//! Appends a formatted `featureId` to the output string `sb`.
//!
//! See \ref BaseFeatures.
ASMJIT_API Error formatFeature(
  String& sb,
  uint32_t arch,
  uint32_t featureId) noexcept;

//! Appends a formatted register to the output string `sb`.
//!
//! \note Emitter is optional, but it's required to format virtual registers,
//! which won't be formatted properly if the `emitter` is not provided.
ASMJIT_API Error formatRegister(
  String& sb,
  uint32_t formatFlags,
  const BaseEmitter* emitter,
  uint32_t arch,
  uint32_t regType,
  uint32_t regId) noexcept;

//! Appends a formatted label to the output string `sb`.
//!
//! \note Emitter is optional, but it's required to format named labels
//! properly, otherwise the formatted as it is an anonymous label.
ASMJIT_API Error formatLabel(
  String& sb,
  uint32_t formatFlags,
  const BaseEmitter* emitter,
  uint32_t labelId) noexcept;

//! Appends a formatted operand to the output string `sb`.
//!
//! \note Emitter is optional, but it's required to format named labels and
//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
//! more details.
ASMJIT_API Error formatOperand(
  String& sb,
  uint32_t formatFlags,
  const BaseEmitter* emitter,
  uint32_t arch,
  const Operand_& op) noexcept;

//! Appends a formatted data-type to the output string `sb`.
ASMJIT_API Error formatDataType(
  String& sb,
  uint32_t formatFlags,
  uint32_t arch,
  uint32_t typeId) noexcept;

//! Appends a formatted data to the output string `sb`.
ASMJIT_API Error formatData(
  String& sb,
  uint32_t formatFlags,
  uint32_t arch,
  uint32_t typeId, const void* data, size_t itemCount, size_t repeatCount = 1) noexcept;

//! Appends a formatted instruction to the output string `sb`.
//!
//! \note Emitter is optional, but it's required to format named labels and
//! virtual registers. See \ref formatRegister() and \ref formatLabel() for
//! more details.
ASMJIT_API Error formatInstruction(
  String& sb,
  uint32_t formatFlags,
  const BaseEmitter* emitter,
  uint32_t arch,
  const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept;

#ifndef ASMJIT_NO_BUILDER
//! Appends a formatted node to the output string `sb`.
//!
//! The `node` must belong to the provided `builder`.
ASMJIT_API Error formatNode(
  String& sb,
  uint32_t formatFlags,
  const BaseBuilder* builder,
  const BaseNode* node) noexcept;

//! Appends formatted nodes to the output string `sb`.
//!
//! All nodes that are part of the given `builder` will be appended.
ASMJIT_API Error formatNodeList(
  String& sb,
  uint32_t formatFlags,
  const BaseBuilder* builder) noexcept;

//! Appends formatted nodes to the output string `sb`.
//!
//! This function works the same as \ref formatNode(), but appends more nodes
//! to the output string, separating each node with a newline '\n' character.
ASMJIT_API Error formatNodeList(
  String& sb,
  uint32_t formatFlags,
  const BaseBuilder* builder,
  const BaseNode* begin,
  const BaseNode* end) noexcept;
#endif

} // {Formatter}

//! \}

ASMJIT_END_NAMESPACE

#endif

#endif // ASMJIT_CORE_FORMATTER_H_INCLUDED