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 : #include "api-build_p.h"
8 : #ifndef ASMJIT_NO_LOGGING
9 :
10 : #include "misc_p.h"
11 : #include "support.h"
12 : #include "a64formatter_p.h"
13 : #include "a64instapi_p.h"
14 : #include "a64instdb_p.h"
15 : #include "a64operand.h"
16 :
17 : #ifndef ASMJIT_NO_COMPILER
18 : #include "compiler.h"
19 : #endif
20 :
21 : ASMJIT_BEGIN_SUB_NAMESPACE(a64)
22 :
23 : // a64::FormatterInternal - Format Register
24 : // ========================================
25 :
26 0 : ASMJIT_FAVOR_SIZE Error FormatterInternal::formatRegister(
27 : String& sb,
28 : FormatFlags flags,
29 : const BaseEmitter* emitter,
30 : Arch arch,
31 : RegType regType,
32 : uint32_t rId,
33 : uint32_t elementType,
34 : uint32_t elementIndex) noexcept {
35 :
36 : DebugUtils::unused(flags);
37 : DebugUtils::unused(arch);
38 :
39 : static const char bhsdq[] = "bhsdq";
40 :
41 : bool virtRegFormatted = false;
42 :
43 : #ifndef ASMJIT_NO_COMPILER
44 0 : if (Operand::isVirtId(rId)) {
45 0 : if (emitter && emitter->isCompiler()) {
46 : const BaseCompiler* cc = static_cast<const BaseCompiler*>(emitter);
47 0 : if (cc->isVirtIdValid(rId)) {
48 0 : VirtReg* vReg = cc->virtRegById(rId);
49 : ASMJIT_ASSERT(vReg != nullptr);
50 :
51 : const char* name = vReg->name();
52 0 : if (name && name[0] != '\0')
53 0 : ASMJIT_PROPAGATE(sb.append(name));
54 : else
55 0 : ASMJIT_PROPAGATE(sb.appendFormat("%%%u", unsigned(Operand::virtIdToIndex(rId))));
56 :
57 : virtRegFormatted = true;
58 : }
59 : }
60 : }
61 : #else
62 : DebugUtils::unused(emitter, flags);
63 : #endif
64 :
65 : if (!virtRegFormatted) {
66 0 : char letter = '\0';
67 0 : switch (regType) {
68 0 : case RegType::kARM_GpW:
69 0 : if (rId == Gp::kIdZr)
70 0 : return sb.append("wzr");
71 0 : if (rId == Gp::kIdSp)
72 0 : return sb.append("wsp");
73 :
74 0 : letter = 'w';
75 0 : break;
76 :
77 0 : case RegType::kARM_GpX:
78 0 : if (rId == Gp::kIdZr)
79 0 : return sb.append("xzr");
80 0 : if (rId == Gp::kIdSp)
81 0 : return sb.append("sp");
82 :
83 0 : letter = 'x';
84 0 : break;
85 :
86 0 : case RegType::kARM_VecB:
87 : case RegType::kARM_VecH:
88 : case RegType::kARM_VecS:
89 : case RegType::kARM_VecD:
90 : case RegType::kARM_VecV:
91 0 : letter = bhsdq[uint32_t(regType) - uint32_t(RegType::kARM_VecB)];
92 0 : if (elementType)
93 0 : letter = 'v';
94 : break;
95 :
96 0 : default:
97 0 : ASMJIT_PROPAGATE(sb.appendFormat("<Reg-%u>?$u", uint32_t(regType), rId));
98 : break;
99 : }
100 :
101 0 : if (letter)
102 0 : ASMJIT_PROPAGATE(sb.appendFormat("%c%u", letter, rId));
103 : }
104 :
105 0 : if (elementType) {
106 : char elementLetter = '\0';
107 0 : uint32_t elementCount = 0;
108 :
109 0 : switch (elementType) {
110 0 : case Vec::kElementTypeB:
111 0 : elementLetter = 'b';
112 0 : elementCount = 16;
113 0 : break;
114 :
115 0 : case Vec::kElementTypeH:
116 0 : elementLetter = 'h';
117 0 : elementCount = 8;
118 0 : break;
119 :
120 0 : case Vec::kElementTypeS:
121 0 : elementLetter = 's';
122 0 : elementCount = 4;
123 0 : break;
124 :
125 0 : case Vec::kElementTypeD:
126 0 : elementLetter = 'd';
127 0 : elementCount = 2;
128 0 : break;
129 :
130 0 : default:
131 0 : return sb.append(".<Unknown>");
132 : }
133 :
134 0 : if (elementLetter) {
135 0 : if (elementIndex == 0xFFFFFFFFu) {
136 0 : if (regType == RegType::kARM_VecD)
137 0 : elementCount /= 2u;
138 0 : ASMJIT_PROPAGATE(sb.appendFormat(".%u%c", elementCount, elementLetter));
139 : }
140 : else {
141 0 : ASMJIT_PROPAGATE(sb.appendFormat(".%c[%u]", elementLetter, elementIndex));
142 : }
143 : }
144 : }
145 :
146 : return kErrorOk;
147 : }
148 :
149 : // a64::FormatterInternal - Format Operand
150 : // =======================================
151 :
152 0 : ASMJIT_FAVOR_SIZE Error FormatterInternal::formatOperand(
153 : String& sb,
154 : FormatFlags flags,
155 : const BaseEmitter* emitter,
156 : Arch arch,
157 : const Operand_& op) noexcept {
158 :
159 0 : if (op.isReg()) {
160 : const BaseReg& reg = op.as<BaseReg>();
161 :
162 : uint32_t elementType = op.as<Vec>().elementType();
163 : uint32_t elementIndex = op.as<Vec>().elementIndex();
164 :
165 0 : if (!op.as<Vec>().hasElementIndex())
166 : elementIndex = 0xFFFFFFFFu;
167 :
168 0 : return formatRegister(sb, flags, emitter, arch, reg.type(), reg.id(), elementType, elementIndex);
169 : }
170 :
171 0 : if (op.isMem()) {
172 : const Mem& m = op.as<Mem>();
173 0 : ASMJIT_PROPAGATE(sb.append('['));
174 :
175 0 : if (m.hasBase()) {
176 0 : if (m.hasBaseLabel()) {
177 0 : ASMJIT_PROPAGATE(Formatter::formatLabel(sb, flags, emitter, m.baseId()));
178 : }
179 : else {
180 : FormatFlags modifiedFlags = flags;
181 0 : if (m.isRegHome()) {
182 0 : ASMJIT_PROPAGATE(sb.append('&'));
183 : modifiedFlags &= ~FormatFlags::kRegCasts;
184 : }
185 0 : ASMJIT_PROPAGATE(formatRegister(sb, modifiedFlags, emitter, arch, m.baseType(), m.baseId()));
186 : }
187 : }
188 : else {
189 : // ARM really requires base.
190 0 : if (m.hasIndex() || m.hasOffset()) {
191 0 : ASMJIT_PROPAGATE(sb.append("<None>"));
192 : }
193 : }
194 :
195 : // The post index makes it look like there was another operand, but it's
196 : // still the part of AsmJit's `arm::Mem` operand so it's consistent with
197 : // other architectures.
198 0 : if (m.isPostIndex())
199 0 : ASMJIT_PROPAGATE(sb.append(']'));
200 :
201 0 : if (m.hasIndex()) {
202 0 : ASMJIT_PROPAGATE(sb.append(", "));
203 0 : ASMJIT_PROPAGATE(formatRegister(sb, flags, emitter, arch, m.indexType(), m.indexId()));
204 : }
205 :
206 0 : if (m.hasOffset()) {
207 0 : ASMJIT_PROPAGATE(sb.append(", "));
208 :
209 0 : int64_t off = int64_t(m.offset());
210 : uint32_t base = 10;
211 :
212 0 : if (Support::test(flags, FormatFlags::kHexOffsets) && uint64_t(off) > 9)
213 : base = 16;
214 :
215 : if (base == 10) {
216 0 : ASMJIT_PROPAGATE(sb.appendInt(off, base));
217 : }
218 : else {
219 0 : ASMJIT_PROPAGATE(sb.append("0x"));
220 0 : ASMJIT_PROPAGATE(sb.appendUInt(uint64_t(off), base));
221 : }
222 : }
223 :
224 0 : if (m.hasShift()) {
225 0 : ASMJIT_PROPAGATE(sb.append(' '));
226 0 : if (!m.isPreOrPost())
227 0 : ASMJIT_PROPAGATE(formatShiftOp(sb, (ShiftOp)m.predicate()));
228 0 : ASMJIT_PROPAGATE(sb.appendFormat(" %u", m.shift()));
229 : }
230 :
231 0 : if (!m.isPostIndex())
232 0 : ASMJIT_PROPAGATE(sb.append(']'));
233 :
234 0 : if (m.isPreIndex())
235 0 : ASMJIT_PROPAGATE(sb.append('!'));
236 :
237 0 : return kErrorOk;
238 : }
239 :
240 0 : if (op.isImm()) {
241 : const Imm& i = op.as<Imm>();
242 : int64_t val = i.value();
243 :
244 0 : if (Support::test(flags, FormatFlags::kHexImms) && uint64_t(val) > 9) {
245 0 : ASMJIT_PROPAGATE(sb.append("0x"));
246 0 : return sb.appendUInt(uint64_t(val), 16);
247 : }
248 : else {
249 0 : return sb.appendInt(val, 10);
250 : }
251 : }
252 :
253 0 : if (op.isLabel()) {
254 0 : return Formatter::formatLabel(sb, flags, emitter, op.id());
255 : }
256 :
257 0 : return sb.append("<None>");
258 : }
259 :
260 : // a64::FormatterInternal - Format Instruction
261 : // ===========================================
262 :
263 0 : ASMJIT_FAVOR_SIZE Error FormatterInternal::formatInstruction(
264 : String& sb,
265 : FormatFlags flags,
266 : const BaseEmitter* emitter,
267 : Arch arch,
268 : const BaseInst& inst, const Operand_* operands, size_t opCount) noexcept {
269 :
270 : DebugUtils::unused(arch);
271 :
272 : // Format instruction options and instruction mnemonic.
273 : InstId instId = inst.realId();
274 0 : if (instId < Inst::_kIdCount)
275 0 : ASMJIT_PROPAGATE(InstInternal::instIdToString(arch, instId, sb));
276 : else
277 0 : ASMJIT_PROPAGATE(sb.appendFormat("[InstId=#%u]", unsigned(instId)));
278 :
279 : CondCode cc = inst.armCondCode();
280 0 : if (cc != CondCode::kAL) {
281 0 : ASMJIT_PROPAGATE(sb.append('.'));
282 0 : ASMJIT_PROPAGATE(formatCondCode(sb, cc));
283 : }
284 :
285 0 : for (uint32_t i = 0; i < opCount; i++) {
286 0 : const Operand_& op = operands[i];
287 0 : if (op.isNone())
288 : break;
289 :
290 0 : ASMJIT_PROPAGATE(sb.append(i == 0 ? " " : ", "));
291 0 : ASMJIT_PROPAGATE(formatOperand(sb, flags, emitter, arch, op));
292 : }
293 :
294 : return kErrorOk;
295 : }
296 :
297 : ASMJIT_END_SUB_NAMESPACE
298 :
299 : #endif // !ASMJIT_NO_LOGGING
300 :
301 : #endif // __PLUMED_HAS_ASMJIT
|