File: | lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp |
Warning: | line 396, column 14 Forming reference to null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===// | |||
2 | // | |||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |||
4 | // See https://llvm.org/LICENSE.txt for license information. | |||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |||
6 | // | |||
7 | //===----------------------------------------------------------------------===// | |||
8 | ||||
9 | #define DEBUG_TYPE"hexagon-disassembler" "hexagon-disassembler" | |||
10 | ||||
11 | #include "MCTargetDesc/HexagonBaseInfo.h" | |||
12 | #include "MCTargetDesc/HexagonMCChecker.h" | |||
13 | #include "MCTargetDesc/HexagonMCInstrInfo.h" | |||
14 | #include "MCTargetDesc/HexagonMCTargetDesc.h" | |||
15 | #include "TargetInfo/HexagonTargetInfo.h" | |||
16 | #include "llvm/ADT/ArrayRef.h" | |||
17 | #include "llvm/ADT/STLExtras.h" | |||
18 | #include "llvm/MC/MCContext.h" | |||
19 | #include "llvm/MC/MCDisassembler/MCDisassembler.h" | |||
20 | #include "llvm/MC/MCExpr.h" | |||
21 | #include "llvm/MC/MCFixedLenDisassembler.h" | |||
22 | #include "llvm/MC/MCInst.h" | |||
23 | #include "llvm/MC/MCInstrInfo.h" | |||
24 | #include "llvm/MC/MCRegisterInfo.h" | |||
25 | #include "llvm/MC/MCSubtargetInfo.h" | |||
26 | #include "llvm/Support/Endian.h" | |||
27 | #include "llvm/Support/MathExtras.h" | |||
28 | #include "llvm/Support/TargetRegistry.h" | |||
29 | #include "llvm/Support/raw_ostream.h" | |||
30 | #include <cassert> | |||
31 | #include <cstddef> | |||
32 | #include <cstdint> | |||
33 | #include <memory> | |||
34 | ||||
35 | using namespace llvm; | |||
36 | using namespace Hexagon; | |||
37 | ||||
38 | using DecodeStatus = MCDisassembler::DecodeStatus; | |||
39 | ||||
40 | namespace { | |||
41 | ||||
42 | /// Hexagon disassembler for all Hexagon platforms. | |||
43 | class HexagonDisassembler : public MCDisassembler { | |||
44 | public: | |||
45 | std::unique_ptr<MCInstrInfo const> const MCII; | |||
46 | std::unique_ptr<MCInst *> CurrentBundle; | |||
47 | mutable MCInst const *CurrentExtender; | |||
48 | ||||
49 | HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, | |||
50 | MCInstrInfo const *MCII) | |||
51 | : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *), | |||
52 | CurrentExtender(nullptr) {} | |||
53 | ||||
54 | DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB, | |||
55 | ArrayRef<uint8_t> Bytes, uint64_t Address, | |||
56 | raw_ostream &VStream, raw_ostream &CStream, | |||
57 | bool &Complete) const; | |||
58 | DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, | |||
59 | ArrayRef<uint8_t> Bytes, uint64_t Address, | |||
60 | raw_ostream &VStream, | |||
61 | raw_ostream &CStream) const override; | |||
62 | void remapInstruction(MCInst &Instr) const; | |||
63 | }; | |||
64 | ||||
65 | static uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI, | |||
66 | int64_t Value) { | |||
67 | MCInstrInfo MCII = *Disassembler.MCII; | |||
68 | if (!Disassembler.CurrentExtender || | |||
69 | MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI)) | |||
70 | return Value; | |||
71 | unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); | |||
72 | uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f; | |||
73 | int64_t Bits; | |||
74 | bool Success = | |||
75 | Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute( | |||
76 | Bits); | |||
77 | assert(Success)((Success) ? static_cast<void> (0) : __assert_fail ("Success" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 77, __PRETTY_FUNCTION__)); | |||
78 | (void)Success; | |||
79 | uint64_t Upper26 = static_cast<uint64_t>(Bits); | |||
80 | uint64_t Operand = Upper26 | Lower6; | |||
81 | return Operand; | |||
82 | } | |||
83 | static HexagonDisassembler const &disassembler(void const *Decoder) { | |||
84 | return *static_cast<HexagonDisassembler const *>(Decoder); | |||
85 | } | |||
86 | template <size_t T> | |||
87 | static void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) { | |||
88 | HexagonDisassembler const &Disassembler = disassembler(Decoder); | |||
89 | int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp)); | |||
90 | int64_t Extended = SignExtend64<32>(FullValue); | |||
91 | HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); | |||
92 | } | |||
93 | } | |||
94 | ||||
95 | // Forward declare these because the auto-generated code will reference them. | |||
96 | // Definitions are further down. | |||
97 | ||||
98 | static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
99 | uint64_t Address, | |||
100 | const void *Decoder); | |||
101 | static DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst, | |||
102 | unsigned RegNo, | |||
103 | uint64_t Address, | |||
104 | const void *Decoder); | |||
105 | static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, | |||
106 | uint64_t Address, | |||
107 | const void *Decoder); | |||
108 | static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
109 | uint64_t Address, | |||
110 | const void *Decoder); | |||
111 | static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
112 | uint64_t Address, | |||
113 | const void *Decoder); | |||
114 | static DecodeStatus | |||
115 | DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
116 | uint64_t Address, const void *Decoder); | |||
117 | static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
118 | uint64_t Address, | |||
119 | const void *Decoder); | |||
120 | static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, | |||
121 | unsigned RegNo, | |||
122 | uint64_t Address, | |||
123 | const void *Decoder); | |||
124 | static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
125 | uint64_t Address, | |||
126 | const void *Decoder); | |||
127 | static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
128 | uint64_t Address, | |||
129 | const void *Decoder); | |||
130 | static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
131 | uint64_t Address, | |||
132 | const void *Decoder); | |||
133 | static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
134 | uint64_t Address, | |||
135 | const void *Decoder); | |||
136 | static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
137 | uint64_t Address, | |||
138 | const void *Decoder); | |||
139 | static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, | |||
140 | uint64_t Address, | |||
141 | const void *Decoder); | |||
142 | static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, | |||
143 | uint64_t Address, | |||
144 | const void *Decoder); | |||
145 | ||||
146 | static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, | |||
147 | uint64_t Address, const void *Decoder); | |||
148 | static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp, | |||
149 | uint64_t /*Address*/, const void *Decoder); | |||
150 | static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, | |||
151 | const void *Decoder); | |||
152 | #include "HexagonDepDecoders.inc" | |||
153 | #include "HexagonGenDisassemblerTables.inc" | |||
154 | ||||
155 | static MCDisassembler *createHexagonDisassembler(const Target &T, | |||
156 | const MCSubtargetInfo &STI, | |||
157 | MCContext &Ctx) { | |||
158 | return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo()); | |||
159 | } | |||
160 | ||||
161 | extern "C" void LLVMInitializeHexagonDisassembler() { | |||
162 | TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(), | |||
163 | createHexagonDisassembler); | |||
164 | } | |||
165 | ||||
166 | DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, | |||
167 | ArrayRef<uint8_t> Bytes, | |||
168 | uint64_t Address, | |||
169 | raw_ostream &os, | |||
170 | raw_ostream &cs) const { | |||
171 | DecodeStatus Result = DecodeStatus::Success; | |||
172 | bool Complete = false; | |||
173 | Size = 0; | |||
174 | ||||
175 | *CurrentBundle = &MI; | |||
176 | MI.setOpcode(Hexagon::BUNDLE); | |||
177 | MI.addOperand(MCOperand::createImm(0)); | |||
178 | while (Result == Success && !Complete) { | |||
179 | if (Bytes.size() < HEXAGON_INSTR_SIZE4) | |||
180 | return MCDisassembler::Fail; | |||
181 | MCInst *Inst = new (getContext()) MCInst; | |||
182 | Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete); | |||
183 | MI.addOperand(MCOperand::createInst(Inst)); | |||
184 | Size += HEXAGON_INSTR_SIZE4; | |||
185 | Bytes = Bytes.slice(HEXAGON_INSTR_SIZE4); | |||
186 | } | |||
187 | if (Result == MCDisassembler::Fail) | |||
188 | return Result; | |||
189 | if (Size > HEXAGON_MAX_PACKET_SIZE(4 * 4)) | |||
190 | return MCDisassembler::Fail; | |||
191 | HexagonMCChecker Checker(getContext(), *MCII, STI, MI, | |||
192 | *getContext().getRegisterInfo(), false); | |||
193 | if (!Checker.check()) | |||
194 | return MCDisassembler::Fail; | |||
195 | remapInstruction(MI); | |||
196 | return MCDisassembler::Success; | |||
197 | } | |||
198 | ||||
199 | void HexagonDisassembler::remapInstruction(MCInst &Instr) const { | |||
200 | for (auto I: HexagonMCInstrInfo::bundleInstructions(Instr)) { | |||
201 | auto &MI = const_cast<MCInst &>(*I.getInst()); | |||
202 | switch (MI.getOpcode()) { | |||
203 | case Hexagon::S2_allocframe: | |||
204 | if (MI.getOperand(0).getReg() == Hexagon::R29) { | |||
205 | MI.setOpcode(Hexagon::S6_allocframe_to_raw); | |||
206 | MI.erase(MI.begin () + 1); | |||
207 | MI.erase(MI.begin ()); | |||
208 | } | |||
209 | break; | |||
210 | case Hexagon::L2_deallocframe: | |||
211 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
212 | MI.getOperand(1).getReg() == Hexagon::R30) { | |||
213 | MI.setOpcode(L6_deallocframe_map_to_raw); | |||
214 | MI.erase(MI.begin () + 1); | |||
215 | MI.erase(MI.begin ()); | |||
216 | } | |||
217 | break; | |||
218 | case Hexagon::L4_return: | |||
219 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
220 | MI.getOperand(1).getReg() == Hexagon::R30) { | |||
221 | MI.setOpcode(L6_return_map_to_raw); | |||
222 | MI.erase(MI.begin () + 1); | |||
223 | MI.erase(MI.begin ()); | |||
224 | } | |||
225 | break; | |||
226 | case Hexagon::L4_return_t: | |||
227 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
228 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
229 | MI.setOpcode(L4_return_map_to_raw_t); | |||
230 | MI.erase(MI.begin () + 2); | |||
231 | MI.erase(MI.begin ()); | |||
232 | } | |||
233 | break; | |||
234 | case Hexagon::L4_return_f: | |||
235 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
236 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
237 | MI.setOpcode(L4_return_map_to_raw_f); | |||
238 | MI.erase(MI.begin () + 2); | |||
239 | MI.erase(MI.begin ()); | |||
240 | } | |||
241 | break; | |||
242 | case Hexagon::L4_return_tnew_pt: | |||
243 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
244 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
245 | MI.setOpcode(L4_return_map_to_raw_tnew_pt); | |||
246 | MI.erase(MI.begin () + 2); | |||
247 | MI.erase(MI.begin ()); | |||
248 | } | |||
249 | break; | |||
250 | case Hexagon::L4_return_fnew_pt: | |||
251 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
252 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
253 | MI.setOpcode(L4_return_map_to_raw_fnew_pt); | |||
254 | MI.erase(MI.begin () + 2); | |||
255 | MI.erase(MI.begin ()); | |||
256 | } | |||
257 | break; | |||
258 | case Hexagon::L4_return_tnew_pnt: | |||
259 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
260 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
261 | MI.setOpcode(L4_return_map_to_raw_tnew_pnt); | |||
262 | MI.erase(MI.begin () + 2); | |||
263 | MI.erase(MI.begin ()); | |||
264 | } | |||
265 | break; | |||
266 | case Hexagon::L4_return_fnew_pnt: | |||
267 | if (MI.getOperand(0).getReg() == Hexagon::D15 && | |||
268 | MI.getOperand(2).getReg() == Hexagon::R30) { | |||
269 | MI.setOpcode(L4_return_map_to_raw_fnew_pnt); | |||
270 | MI.erase(MI.begin () + 2); | |||
271 | MI.erase(MI.begin ()); | |||
272 | } | |||
273 | break; | |||
274 | } | |||
275 | } | |||
276 | } | |||
277 | ||||
278 | static void adjustDuplex(MCInst &MI, MCContext &Context) { | |||
279 | switch (MI.getOpcode()) { | |||
280 | case Hexagon::SA1_setin1: | |||
281 | MI.insert(MI.begin() + 1, | |||
282 | MCOperand::createExpr(MCConstantExpr::create(-1, Context))); | |||
283 | break; | |||
284 | case Hexagon::SA1_dec: | |||
285 | MI.insert(MI.begin() + 2, | |||
286 | MCOperand::createExpr(MCConstantExpr::create(-1, Context))); | |||
287 | break; | |||
288 | default: | |||
289 | break; | |||
290 | } | |||
291 | } | |||
292 | ||||
293 | DecodeStatus HexagonDisassembler::getSingleInstruction( | |||
294 | MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address, | |||
295 | raw_ostream &os, raw_ostream &cs, bool &Complete) const { | |||
296 | assert(Bytes.size() >= HEXAGON_INSTR_SIZE)((Bytes.size() >= 4) ? static_cast<void> (0) : __assert_fail ("Bytes.size() >= HEXAGON_INSTR_SIZE", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 296, __PRETTY_FUNCTION__)); | |||
| ||||
297 | ||||
298 | uint32_t Instruction = support::endian::read32le(Bytes.data()); | |||
299 | ||||
300 | auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB); | |||
301 | if ((Instruction & HexagonII::INST_PARSE_MASK) == | |||
302 | HexagonII::INST_PARSE_LOOP_END) { | |||
303 | if (BundleSize == 0) | |||
304 | HexagonMCInstrInfo::setInnerLoop(MCB); | |||
305 | else if (BundleSize == 1) | |||
306 | HexagonMCInstrInfo::setOuterLoop(MCB); | |||
307 | else | |||
308 | return DecodeStatus::Fail; | |||
309 | } | |||
310 | ||||
311 | CurrentExtender = HexagonMCInstrInfo::extenderForIndex( | |||
312 | MCB, HexagonMCInstrInfo::bundleSize(MCB)); | |||
313 | ||||
314 | DecodeStatus Result = DecodeStatus::Fail; | |||
315 | if ((Instruction & HexagonII::INST_PARSE_MASK) == | |||
316 | HexagonII::INST_PARSE_DUPLEX) { | |||
317 | unsigned duplexIClass; | |||
318 | uint8_t const *DecodeLow, *DecodeHigh; | |||
319 | duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1); | |||
320 | switch (duplexIClass) { | |||
321 | default: | |||
322 | return MCDisassembler::Fail; | |||
323 | case 0: | |||
324 | DecodeLow = DecoderTableSUBINSN_L132; | |||
325 | DecodeHigh = DecoderTableSUBINSN_L132; | |||
326 | break; | |||
327 | case 1: | |||
328 | DecodeLow = DecoderTableSUBINSN_L232; | |||
329 | DecodeHigh = DecoderTableSUBINSN_L132; | |||
330 | break; | |||
331 | case 2: | |||
332 | DecodeLow = DecoderTableSUBINSN_L232; | |||
333 | DecodeHigh = DecoderTableSUBINSN_L232; | |||
334 | break; | |||
335 | case 3: | |||
336 | DecodeLow = DecoderTableSUBINSN_A32; | |||
337 | DecodeHigh = DecoderTableSUBINSN_A32; | |||
338 | break; | |||
339 | case 4: | |||
340 | DecodeLow = DecoderTableSUBINSN_L132; | |||
341 | DecodeHigh = DecoderTableSUBINSN_A32; | |||
342 | break; | |||
343 | case 5: | |||
344 | DecodeLow = DecoderTableSUBINSN_L232; | |||
345 | DecodeHigh = DecoderTableSUBINSN_A32; | |||
346 | break; | |||
347 | case 6: | |||
348 | DecodeLow = DecoderTableSUBINSN_S132; | |||
349 | DecodeHigh = DecoderTableSUBINSN_A32; | |||
350 | break; | |||
351 | case 7: | |||
352 | DecodeLow = DecoderTableSUBINSN_S232; | |||
353 | DecodeHigh = DecoderTableSUBINSN_A32; | |||
354 | break; | |||
355 | case 8: | |||
356 | DecodeLow = DecoderTableSUBINSN_S132; | |||
357 | DecodeHigh = DecoderTableSUBINSN_L132; | |||
358 | break; | |||
359 | case 9: | |||
360 | DecodeLow = DecoderTableSUBINSN_S132; | |||
361 | DecodeHigh = DecoderTableSUBINSN_L232; | |||
362 | break; | |||
363 | case 10: | |||
364 | DecodeLow = DecoderTableSUBINSN_S132; | |||
365 | DecodeHigh = DecoderTableSUBINSN_S132; | |||
366 | break; | |||
367 | case 11: | |||
368 | DecodeLow = DecoderTableSUBINSN_S232; | |||
369 | DecodeHigh = DecoderTableSUBINSN_S132; | |||
370 | break; | |||
371 | case 12: | |||
372 | DecodeLow = DecoderTableSUBINSN_S232; | |||
373 | DecodeHigh = DecoderTableSUBINSN_L132; | |||
374 | break; | |||
375 | case 13: | |||
376 | DecodeLow = DecoderTableSUBINSN_S232; | |||
377 | DecodeHigh = DecoderTableSUBINSN_L232; | |||
378 | break; | |||
379 | case 14: | |||
380 | DecodeLow = DecoderTableSUBINSN_S232; | |||
381 | DecodeHigh = DecoderTableSUBINSN_S232; | |||
382 | break; | |||
383 | } | |||
384 | MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass); | |||
385 | MCInst *MILow = new (getContext()) MCInst; | |||
386 | MCInst *MIHigh = new (getContext()) MCInst; | |||
387 | auto TmpExtender = CurrentExtender; | |||
388 | CurrentExtender = | |||
389 | nullptr; // constant extenders in duplex must always be in slot 1 | |||
390 | Result = decodeInstruction(DecodeLow, *MILow, Instruction & 0x1fff, Address, | |||
391 | this, STI); | |||
392 | CurrentExtender = TmpExtender; | |||
393 | if (Result != DecodeStatus::Success) | |||
394 | return DecodeStatus::Fail; | |||
395 | adjustDuplex(*MILow, getContext()); | |||
396 | Result = decodeInstruction( | |||
| ||||
397 | DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff, Address, this, STI); | |||
398 | if (Result != DecodeStatus::Success) | |||
399 | return DecodeStatus::Fail; | |||
400 | adjustDuplex(*MIHigh, getContext()); | |||
401 | MCOperand OPLow = MCOperand::createInst(MILow); | |||
402 | MCOperand OPHigh = MCOperand::createInst(MIHigh); | |||
403 | MI.addOperand(OPLow); | |||
404 | MI.addOperand(OPHigh); | |||
405 | Complete = true; | |||
406 | } else { | |||
407 | if ((Instruction & HexagonII::INST_PARSE_MASK) == | |||
408 | HexagonII::INST_PARSE_PACKET_END) | |||
409 | Complete = true; | |||
410 | ||||
411 | if (CurrentExtender != nullptr) | |||
412 | Result = decodeInstruction(DecoderTableMustExtend32, MI, Instruction, | |||
413 | Address, this, STI); | |||
414 | ||||
415 | if (Result != MCDisassembler::Success) | |||
416 | Result = decodeInstruction(DecoderTable32, MI, Instruction, Address, this, | |||
417 | STI); | |||
418 | ||||
419 | if (Result != MCDisassembler::Success && | |||
420 | STI.getFeatureBits()[Hexagon::ExtensionHVX]) | |||
421 | Result = decodeInstruction(DecoderTableEXT_mmvec32, MI, Instruction, | |||
422 | Address, this, STI); | |||
423 | ||||
424 | } | |||
425 | ||||
426 | switch (MI.getOpcode()) { | |||
427 | case Hexagon::J4_cmpeqn1_f_jumpnv_nt: | |||
428 | case Hexagon::J4_cmpeqn1_f_jumpnv_t: | |||
429 | case Hexagon::J4_cmpeqn1_fp0_jump_nt: | |||
430 | case Hexagon::J4_cmpeqn1_fp0_jump_t: | |||
431 | case Hexagon::J4_cmpeqn1_fp1_jump_nt: | |||
432 | case Hexagon::J4_cmpeqn1_fp1_jump_t: | |||
433 | case Hexagon::J4_cmpeqn1_t_jumpnv_nt: | |||
434 | case Hexagon::J4_cmpeqn1_t_jumpnv_t: | |||
435 | case Hexagon::J4_cmpeqn1_tp0_jump_nt: | |||
436 | case Hexagon::J4_cmpeqn1_tp0_jump_t: | |||
437 | case Hexagon::J4_cmpeqn1_tp1_jump_nt: | |||
438 | case Hexagon::J4_cmpeqn1_tp1_jump_t: | |||
439 | case Hexagon::J4_cmpgtn1_f_jumpnv_nt: | |||
440 | case Hexagon::J4_cmpgtn1_f_jumpnv_t: | |||
441 | case Hexagon::J4_cmpgtn1_fp0_jump_nt: | |||
442 | case Hexagon::J4_cmpgtn1_fp0_jump_t: | |||
443 | case Hexagon::J4_cmpgtn1_fp1_jump_nt: | |||
444 | case Hexagon::J4_cmpgtn1_fp1_jump_t: | |||
445 | case Hexagon::J4_cmpgtn1_t_jumpnv_nt: | |||
446 | case Hexagon::J4_cmpgtn1_t_jumpnv_t: | |||
447 | case Hexagon::J4_cmpgtn1_tp0_jump_nt: | |||
448 | case Hexagon::J4_cmpgtn1_tp0_jump_t: | |||
449 | case Hexagon::J4_cmpgtn1_tp1_jump_nt: | |||
450 | case Hexagon::J4_cmpgtn1_tp1_jump_t: | |||
451 | MI.insert(MI.begin() + 1, | |||
452 | MCOperand::createExpr(MCConstantExpr::create(-1, getContext()))); | |||
453 | break; | |||
454 | default: | |||
455 | break; | |||
456 | } | |||
457 | ||||
458 | if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) { | |||
459 | unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI); | |||
460 | MCOperand &MCO = MI.getOperand(OpIndex); | |||
461 | assert(MCO.isReg() && "New value consumers must be registers")((MCO.isReg() && "New value consumers must be registers" ) ? static_cast<void> (0) : __assert_fail ("MCO.isReg() && \"New value consumers must be registers\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 461, __PRETTY_FUNCTION__)); | |||
462 | unsigned Register = | |||
463 | getContext().getRegisterInfo()->getEncodingValue(MCO.getReg()); | |||
464 | if ((Register & 0x6) == 0) | |||
465 | // HexagonPRM 10.11 Bit 1-2 == 0 is reserved | |||
466 | return MCDisassembler::Fail; | |||
467 | unsigned Lookback = (Register & 0x6) >> 1; | |||
468 | unsigned Offset = 1; | |||
469 | bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI); | |||
470 | bool PrevVector = false; | |||
471 | auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle); | |||
472 | auto i = Instructions.end() - 1; | |||
473 | for (auto n = Instructions.begin() - 1;; --i, ++Offset) { | |||
474 | if (i == n) | |||
475 | // Couldn't find producer | |||
476 | return MCDisassembler::Fail; | |||
477 | bool CurrentVector = HexagonMCInstrInfo::isVector(*MCII, *i->getInst()); | |||
478 | if (Vector && !CurrentVector) | |||
479 | // Skip scalars when calculating distances for vectors | |||
480 | ++Lookback; | |||
481 | if (HexagonMCInstrInfo::isImmext(*i->getInst()) && (Vector == PrevVector)) | |||
482 | ++Lookback; | |||
483 | PrevVector = CurrentVector; | |||
484 | if (Offset == Lookback) | |||
485 | break; | |||
486 | } | |||
487 | auto const &Inst = *i->getInst(); | |||
488 | bool SubregBit = (Register & 0x1) != 0; | |||
489 | if (HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) { | |||
490 | // If subreg bit is set we're selecting the second produced newvalue | |||
491 | unsigned Producer = SubregBit ? | |||
492 | HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg() : | |||
493 | HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg(); | |||
494 | assert(Producer != Hexagon::NoRegister)((Producer != Hexagon::NoRegister) ? static_cast<void> ( 0) : __assert_fail ("Producer != Hexagon::NoRegister", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 494, __PRETTY_FUNCTION__)); | |||
495 | MCO.setReg(Producer); | |||
496 | } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) { | |||
497 | unsigned Producer = | |||
498 | HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg(); | |||
499 | if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) | |||
500 | Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0; | |||
501 | else if (SubregBit) | |||
502 | // Hexagon PRM 10.11 New-value operands | |||
503 | // Nt[0] is reserved and should always be encoded as zero. | |||
504 | return MCDisassembler::Fail; | |||
505 | assert(Producer != Hexagon::NoRegister)((Producer != Hexagon::NoRegister) ? static_cast<void> ( 0) : __assert_fail ("Producer != Hexagon::NoRegister", "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 505, __PRETTY_FUNCTION__)); | |||
506 | MCO.setReg(Producer); | |||
507 | } else | |||
508 | return MCDisassembler::Fail; | |||
509 | } | |||
510 | ||||
511 | if (CurrentExtender != nullptr) { | |||
512 | MCInst const &Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) | |||
513 | ? *MI.getOperand(1).getInst() | |||
514 | : MI; | |||
515 | if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) && | |||
516 | !HexagonMCInstrInfo::isExtended(*MCII, Inst)) | |||
517 | return MCDisassembler::Fail; | |||
518 | } | |||
519 | return Result; | |||
520 | } | |||
521 | ||||
522 | static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, | |||
523 | ArrayRef<MCPhysReg> Table) { | |||
524 | if (RegNo < Table.size()) { | |||
525 | Inst.addOperand(MCOperand::createReg(Table[RegNo])); | |||
526 | return MCDisassembler::Success; | |||
527 | } | |||
528 | ||||
529 | return MCDisassembler::Fail; | |||
530 | } | |||
531 | ||||
532 | static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, | |||
533 | uint64_t Address, | |||
534 | const void *Decoder) { | |||
535 | return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); | |||
536 | } | |||
537 | ||||
538 | static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
539 | uint64_t Address, | |||
540 | const void *Decoder) { | |||
541 | static const MCPhysReg IntRegDecoderTable[] = { | |||
542 | Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, | |||
543 | Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, | |||
544 | Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, | |||
545 | Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, | |||
546 | Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, | |||
547 | Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, | |||
548 | Hexagon::R30, Hexagon::R31}; | |||
549 | ||||
550 | return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable); | |||
551 | } | |||
552 | ||||
553 | static DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst, | |||
554 | unsigned RegNo, | |||
555 | uint64_t Address, | |||
556 | const void *Decoder) { | |||
557 | static const MCPhysReg GeneralSubRegDecoderTable[] = { | |||
558 | Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, | |||
559 | Hexagon::R4, Hexagon::R5, Hexagon::R6, Hexagon::R7, | |||
560 | Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, | |||
561 | Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, | |||
562 | }; | |||
563 | ||||
564 | return DecodeRegisterClass(Inst, RegNo, GeneralSubRegDecoderTable); | |||
565 | } | |||
566 | ||||
567 | static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
568 | uint64_t /*Address*/, | |||
569 | const void *Decoder) { | |||
570 | static const MCPhysReg HvxVRDecoderTable[] = { | |||
571 | Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4, | |||
572 | Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9, | |||
573 | Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14, | |||
574 | Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19, | |||
575 | Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24, | |||
576 | Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29, | |||
577 | Hexagon::V30, Hexagon::V31}; | |||
578 | ||||
579 | return DecodeRegisterClass(Inst, RegNo, HvxVRDecoderTable); | |||
580 | } | |||
581 | ||||
582 | static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
583 | uint64_t /*Address*/, | |||
584 | const void *Decoder) { | |||
585 | static const MCPhysReg DoubleRegDecoderTable[] = { | |||
586 | Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, | |||
587 | Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, | |||
588 | Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, | |||
589 | Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15}; | |||
590 | ||||
591 | return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable); | |||
592 | } | |||
593 | ||||
594 | static DecodeStatus DecodeGeneralDoubleLow8RegsRegisterClass( | |||
595 | MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, const void *Decoder) { | |||
596 | static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = { | |||
597 | Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, | |||
598 | Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11}; | |||
599 | ||||
600 | return DecodeRegisterClass(Inst, RegNo, GeneralDoubleLow8RegDecoderTable); | |||
601 | } | |||
602 | ||||
603 | static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
604 | uint64_t /*Address*/, | |||
605 | const void *Decoder) { | |||
606 | static const MCPhysReg HvxWRDecoderTable[] = { | |||
607 | Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3, | |||
608 | Hexagon::W4, Hexagon::W5, Hexagon::W6, Hexagon::W7, | |||
609 | Hexagon::W8, Hexagon::W9, Hexagon::W10, Hexagon::W11, | |||
610 | Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15}; | |||
611 | ||||
612 | return (DecodeRegisterClass(Inst, RegNo >> 1, HvxWRDecoderTable)); | |||
613 | } | |||
614 | ||||
615 | LLVM_ATTRIBUTE_UNUSED__attribute__((__unused__)) // Suppress warning temporarily. | |||
616 | static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, | |||
617 | unsigned RegNo, | |||
618 | uint64_t /*Address*/, | |||
619 | const void *Decoder) { | |||
620 | static const MCPhysReg HvxVQRDecoderTable[] = { | |||
621 | Hexagon::VQ0, Hexagon::VQ1, Hexagon::VQ2, Hexagon::VQ3, | |||
622 | Hexagon::VQ4, Hexagon::VQ5, Hexagon::VQ6, Hexagon::VQ7}; | |||
623 | ||||
624 | return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable); | |||
625 | } | |||
626 | ||||
627 | static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
628 | uint64_t /*Address*/, | |||
629 | const void *Decoder) { | |||
630 | static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, | |||
631 | Hexagon::P2, Hexagon::P3}; | |||
632 | ||||
633 | return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable); | |||
634 | } | |||
635 | ||||
636 | static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, | |||
637 | uint64_t /*Address*/, | |||
638 | const void *Decoder) { | |||
639 | static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1, | |||
640 | Hexagon::Q2, Hexagon::Q3}; | |||
641 | ||||
642 | return DecodeRegisterClass(Inst, RegNo, HvxQRDecoderTable); | |||
643 | } | |||
644 | ||||
645 | static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
646 | uint64_t /*Address*/, | |||
647 | const void *Decoder) { | |||
648 | using namespace Hexagon; | |||
649 | ||||
650 | static const MCPhysReg CtrlRegDecoderTable[] = { | |||
651 | /* 0 */ SA0, LC0, SA1, LC1, | |||
652 | /* 4 */ P3_0, C5, M0, M1, | |||
653 | /* 8 */ USR, PC, UGP, GP, | |||
654 | /* 12 */ CS0, CS1, UPCYCLELO, UPCYCLEHI, | |||
655 | /* 16 */ FRAMELIMIT, FRAMEKEY, PKTCOUNTLO, PKTCOUNTHI, | |||
656 | /* 20 */ 0, 0, 0, 0, | |||
657 | /* 24 */ 0, 0, 0, 0, | |||
658 | /* 28 */ 0, 0, UTIMERLO, UTIMERHI | |||
659 | }; | |||
660 | ||||
661 | if (RegNo >= array_lengthof(CtrlRegDecoderTable)) | |||
662 | return MCDisassembler::Fail; | |||
663 | ||||
664 | static_assert(NoRegister == 0, "Expecting NoRegister to be 0"); | |||
665 | if (CtrlRegDecoderTable[RegNo] == NoRegister) | |||
666 | return MCDisassembler::Fail; | |||
667 | ||||
668 | unsigned Register = CtrlRegDecoderTable[RegNo]; | |||
669 | Inst.addOperand(MCOperand::createReg(Register)); | |||
670 | return MCDisassembler::Success; | |||
671 | } | |||
672 | ||||
673 | static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, | |||
674 | uint64_t /*Address*/, | |||
675 | const void *Decoder) { | |||
676 | using namespace Hexagon; | |||
677 | ||||
678 | static const MCPhysReg CtrlReg64DecoderTable[] = { | |||
679 | /* 0 */ C1_0, 0, C3_2, 0, | |||
680 | /* 4 */ C5_4, 0, C7_6, 0, | |||
681 | /* 8 */ C9_8, 0, C11_10, 0, | |||
682 | /* 12 */ CS, 0, UPCYCLE, 0, | |||
683 | /* 16 */ C17_16, 0, PKTCOUNT, 0, | |||
684 | /* 20 */ 0, 0, 0, 0, | |||
685 | /* 24 */ 0, 0, 0, 0, | |||
686 | /* 28 */ 0, 0, UTIMER, 0 | |||
687 | }; | |||
688 | ||||
689 | if (RegNo >= array_lengthof(CtrlReg64DecoderTable)) | |||
690 | return MCDisassembler::Fail; | |||
691 | ||||
692 | static_assert(NoRegister == 0, "Expecting NoRegister to be 0"); | |||
693 | if (CtrlReg64DecoderTable[RegNo] == NoRegister) | |||
694 | return MCDisassembler::Fail; | |||
695 | ||||
696 | unsigned Register = CtrlReg64DecoderTable[RegNo]; | |||
697 | Inst.addOperand(MCOperand::createReg(Register)); | |||
698 | return MCDisassembler::Success; | |||
699 | } | |||
700 | ||||
701 | static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
702 | uint64_t /*Address*/, | |||
703 | const void *Decoder) { | |||
704 | unsigned Register = 0; | |||
705 | switch (RegNo) { | |||
706 | case 0: | |||
707 | Register = Hexagon::M0; | |||
708 | break; | |||
709 | case 1: | |||
710 | Register = Hexagon::M1; | |||
711 | break; | |||
712 | default: | |||
713 | return MCDisassembler::Fail; | |||
714 | } | |||
715 | Inst.addOperand(MCOperand::createReg(Register)); | |||
716 | return MCDisassembler::Success; | |||
717 | } | |||
718 | ||||
719 | static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, | |||
720 | uint64_t /*Address*/, | |||
721 | const void *Decoder) { | |||
722 | HexagonDisassembler const &Disassembler = disassembler(Decoder); | |||
723 | int64_t FullValue = fullValue(Disassembler, MI, tmp); | |||
724 | assert(FullValue >= 0 && "Negative in unsigned decoder")((FullValue >= 0 && "Negative in unsigned decoder" ) ? static_cast<void> (0) : __assert_fail ("FullValue >= 0 && \"Negative in unsigned decoder\"" , "/build/llvm-toolchain-snapshot-9~svn362543/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp" , 724, __PRETTY_FUNCTION__)); | |||
725 | HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext()); | |||
726 | return MCDisassembler::Success; | |||
727 | } | |||
728 | ||||
729 | static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp, | |||
730 | uint64_t /*Address*/, const void *Decoder) { | |||
731 | HexagonDisassembler const &Disassembler = disassembler(Decoder); | |||
732 | unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI); | |||
733 | tmp = SignExtend64(tmp, Bits); | |||
734 | signedDecoder<32>(MI, tmp, Decoder); | |||
735 | return MCDisassembler::Success; | |||
736 | } | |||
737 | ||||
738 | // custom decoder for various jump/call immediates | |||
739 | static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, | |||
740 | const void *Decoder) { | |||
741 | HexagonDisassembler const &Disassembler = disassembler(Decoder); | |||
742 | unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI); | |||
743 | // r13_2 is not extendable, so if there are no extent bits, it's r13_2 | |||
744 | if (Bits == 0) | |||
745 | Bits = 15; | |||
746 | uint64_t FullValue = fullValue(Disassembler, MI, SignExtend64(tmp, Bits)); | |||
747 | uint32_t Extended = FullValue + Address; | |||
748 | if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 0, 4)) | |||
749 | HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); | |||
750 | return MCDisassembler::Success; | |||
751 | } | |||
752 | ||||
753 | static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, | |||
754 | uint64_t /*Address*/, | |||
755 | const void *Decoder) { | |||
756 | using namespace Hexagon; | |||
757 | ||||
758 | static const MCPhysReg GuestRegDecoderTable[] = { | |||
759 | /* 0 */ GELR, GSR, GOSP, G3, | |||
760 | /* 4 */ G4, G5, G6, G7, | |||
761 | /* 8 */ G8, G9, G10, G11, | |||
762 | /* 12 */ G12, G13, G14, G15, | |||
763 | /* 16 */ GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7, | |||
764 | /* 20 */ G20, G21, G22, G23, | |||
765 | /* 24 */ GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1, | |||
766 | /* 28 */ GPMUCNT2, GPMUCNT3, G30, G31 | |||
767 | }; | |||
768 | ||||
769 | if (RegNo >= array_lengthof(GuestRegDecoderTable)) | |||
770 | return MCDisassembler::Fail; | |||
771 | if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister) | |||
772 | return MCDisassembler::Fail; | |||
773 | ||||
774 | unsigned Register = GuestRegDecoderTable[RegNo]; | |||
775 | Inst.addOperand(MCOperand::createReg(Register)); | |||
776 | return MCDisassembler::Success; | |||
777 | } | |||
778 | ||||
779 | static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, | |||
780 | uint64_t /*Address*/, | |||
781 | const void *Decoder) { | |||
782 | using namespace Hexagon; | |||
783 | ||||
784 | static const MCPhysReg GuestReg64DecoderTable[] = { | |||
785 | /* 0 */ G1_0, 0, G3_2, 0, | |||
786 | /* 4 */ G5_4, 0, G7_6, 0, | |||
787 | /* 8 */ G9_8, 0, G11_10, 0, | |||
788 | /* 12 */ G13_12, 0, G15_14, 0, | |||
789 | /* 16 */ G17_16, 0, G19_18, 0, | |||
790 | /* 20 */ G21_20, 0, G23_22, 0, | |||
791 | /* 24 */ G25_24, 0, G27_26, 0, | |||
792 | /* 28 */ G29_28, 0, G31_30, 0 | |||
793 | }; | |||
794 | ||||
795 | if (RegNo >= array_lengthof(GuestReg64DecoderTable)) | |||
796 | return MCDisassembler::Fail; | |||
797 | if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister) | |||
798 | return MCDisassembler::Fail; | |||
799 | ||||
800 | unsigned Register = GuestReg64DecoderTable[RegNo]; | |||
801 | Inst.addOperand(MCOperand::createReg(Register)); | |||
802 | return MCDisassembler::Success; | |||
803 | } |