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 #include "MCTargetDesc/HexagonBaseInfo.h"
10 #include "MCTargetDesc/HexagonMCChecker.h"
11 #include "MCTargetDesc/HexagonMCInstrInfo.h"
12 #include "MCTargetDesc/HexagonMCTargetDesc.h"
13 #include "TargetInfo/HexagonTargetInfo.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDecoderOps.h"
17 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/TargetRegistry.h"
24 #include "llvm/Support/Compiler.h"
25 #include "llvm/Support/Endian.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include <cassert>
29 #include <cstddef>
30 #include <cstdint>
31 #include <memory>
32
33 #define DEBUG_TYPE "hexagon-disassembler"
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 mutable std::unique_ptr<MCInst> CurrentBundle;
47 mutable MCInst const *CurrentExtender;
48
HexagonDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)49 HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
50 MCInstrInfo const *MCII)
51 : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(nullptr),
52 CurrentExtender(nullptr) {}
53
54 DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
55 ArrayRef<uint8_t> Bytes, uint64_t Address,
56 raw_ostream &CStream, bool &Complete) const;
57 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
58 ArrayRef<uint8_t> Bytes, uint64_t Address,
59 raw_ostream &CStream) const override;
60
61 DecodeStatus getInstructionBundle(MCInst &Instr, uint64_t &Size,
62 ArrayRef<uint8_t> Bytes, uint64_t Address,
63 raw_ostream &CStream) const override;
64
65 void remapInstruction(MCInst &Instr) const;
66
67 Expected<bool> onSymbolStart(SymbolInfoTy &Symbol, uint64_t &Size,
68 ArrayRef<uint8_t> Bytes,
69 uint64_t Address) const override;
70
71 private:
72 bool makeBundle(ArrayRef<uint8_t> Bytes, uint64_t Address,
73 uint64_t &BytesToSkip, raw_ostream &CS) const;
74
resetBundle() const75 void resetBundle() const {
76 CurrentBundle.reset();
77 CurrentInstruction = nullptr;
78 }
79
80 mutable MCOperand *CurrentInstruction = nullptr;
81 };
82
fullValue(HexagonDisassembler const & Disassembler,MCInst & MI,int64_t Value)83 static uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI,
84 int64_t Value) {
85 MCInstrInfo MCII = *Disassembler.MCII;
86 if (!Disassembler.CurrentExtender ||
87 MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
88 return Value;
89 unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
90 uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
91 int64_t Bits;
92 bool Success =
93 Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute(
94 Bits);
95 assert(Success);
96 (void)Success;
97 uint64_t Upper26 = static_cast<uint64_t>(Bits);
98 uint64_t Operand = Upper26 | Lower6;
99 return Operand;
100 }
disassembler(const MCDisassembler * Decoder)101 static HexagonDisassembler const &disassembler(const MCDisassembler *Decoder) {
102 return *static_cast<HexagonDisassembler const *>(Decoder);
103 }
104 template <size_t T>
signedDecoder(MCInst & MI,unsigned tmp,const MCDisassembler * Decoder)105 static void signedDecoder(MCInst &MI, unsigned tmp,
106 const MCDisassembler *Decoder) {
107 HexagonDisassembler const &Disassembler = disassembler(Decoder);
108 int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp));
109 int64_t Extended = SignExtend64<32>(FullValue);
110 HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
111 }
112 }
113
114 // Forward declare these because the auto-generated code will reference them.
115 // Definitions are further down.
116
117 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
118 uint64_t Address,
119 const MCDisassembler *Decoder);
120 static DecodeStatus
121 DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo,
122 uint64_t Address,
123 const MCDisassembler *Decoder);
124 static DecodeStatus
125 DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
126 const MCDisassembler *Decoder);
127 static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
128 uint64_t Address,
129 const MCDisassembler *Decoder);
130 static DecodeStatus
131 DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
132 const MCDisassembler *Decoder);
133 static DecodeStatus
134 DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
135 uint64_t Address,
136 const MCDisassembler *Decoder);
137 static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
138 uint64_t Address,
139 const MCDisassembler *Decoder);
140 static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo,
141 uint64_t Address,
142 const MCDisassembler *Decoder);
143 static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
144 uint64_t Address,
145 const MCDisassembler *Decoder);
146 static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
147 uint64_t Address,
148 const MCDisassembler *Decoder);
149 static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
150 uint64_t Address,
151 const MCDisassembler *Decoder);
152 static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
153 uint64_t Address,
154 const MCDisassembler *Decoder);
155 static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo,
156 uint64_t Address,
157 const MCDisassembler *Decoder);
158 static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
159 uint64_t Address,
160 const MCDisassembler *Decoder);
161 static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
162 uint64_t Address,
163 const MCDisassembler *Decoder);
164 static DecodeStatus
165 DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
166 const MCDisassembler *Decoder);
167 static DecodeStatus DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
168 uint64_t Address,
169 const MCDisassembler *Decoder);
170
171 static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
172 uint64_t Address,
173 const MCDisassembler *Decoder);
174 static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
175 uint64_t /*Address*/,
176 const MCDisassembler *Decoder);
177 static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
178 const MCDisassembler *Decoder);
179 #include "HexagonDepDecoders.inc"
180 #include "HexagonGenDisassemblerTables.inc"
181
createHexagonDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)182 static MCDisassembler *createHexagonDisassembler(const Target &T,
183 const MCSubtargetInfo &STI,
184 MCContext &Ctx) {
185 return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
186 }
187
188 extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
LLVMInitializeHexagonDisassembler()189 LLVMInitializeHexagonDisassembler() {
190 TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
191 createHexagonDisassembler);
192 }
193
makeBundle(ArrayRef<uint8_t> Bytes,uint64_t Address,uint64_t & BytesToSkip,raw_ostream & CS) const194 bool HexagonDisassembler::makeBundle(ArrayRef<uint8_t> Bytes, uint64_t Address,
195 uint64_t &BytesToSkip,
196 raw_ostream &CS) const {
197 bool Complete = false;
198 DecodeStatus Result = DecodeStatus::Success;
199
200 CurrentBundle.reset(new MCInst);
201 CurrentBundle->setOpcode(Hexagon::BUNDLE);
202 CurrentBundle->addOperand(MCOperand::createImm(0));
203 while (Result == Success && !Complete) {
204 if (Bytes.size() < HEXAGON_INSTR_SIZE)
205 return false;
206 MCInst *Inst = getContext().createMCInst();
207 Result = getSingleInstruction(*Inst, *CurrentBundle, Bytes, Address, CS,
208 Complete);
209 CurrentBundle->addOperand(MCOperand::createInst(Inst));
210 BytesToSkip += HEXAGON_INSTR_SIZE;
211 Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
212 }
213 if (Result == MCDisassembler::Fail)
214 return false;
215 if (BytesToSkip > HEXAGON_MAX_PACKET_SIZE)
216 return false;
217
218 const auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
219 const auto STI_ = (ArchSTI != nullptr) ? *ArchSTI : STI;
220 HexagonMCChecker Checker(getContext(), *MCII, STI_, *CurrentBundle,
221 *getContext().getRegisterInfo(), false);
222 if (!Checker.check())
223 return false;
224 remapInstruction(*CurrentBundle);
225 return true;
226 }
227
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const228 DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
229 ArrayRef<uint8_t> Bytes,
230 uint64_t Address,
231 raw_ostream &CS) const {
232 CommentStream = &CS;
233
234 Size = 0;
235 uint64_t BytesToSkip = 0;
236
237 if (!CurrentBundle) {
238 if (!makeBundle(Bytes, Address, BytesToSkip, CS)) {
239 Size = BytesToSkip;
240 resetBundle();
241 return MCDisassembler::Fail;
242 }
243 CurrentInstruction = (CurrentBundle->begin() + 1);
244 }
245
246 MI = *(CurrentInstruction->getInst());
247 Size = HEXAGON_INSTR_SIZE;
248 if (++CurrentInstruction == CurrentBundle->end())
249 resetBundle();
250 return MCDisassembler::Success;
251 }
252
getInstructionBundle(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const253 DecodeStatus HexagonDisassembler::getInstructionBundle(MCInst &MI,
254 uint64_t &Size,
255 ArrayRef<uint8_t> Bytes,
256 uint64_t Address,
257 raw_ostream &CS) const {
258 CommentStream = &CS;
259 Size = 0;
260 uint64_t BytesToSkip = 0;
261 assert(!CurrentBundle);
262
263 if (!makeBundle(Bytes, Address, BytesToSkip, CS)) {
264 Size = BytesToSkip;
265 resetBundle();
266 return MCDisassembler::Fail;
267 }
268
269 MI = *CurrentBundle;
270 Size = HEXAGON_INSTR_SIZE * HexagonMCInstrInfo::bundleSize(MI);
271 resetBundle();
272
273 return Success;
274 }
275
remapInstruction(MCInst & Instr) const276 void HexagonDisassembler::remapInstruction(MCInst &Instr) const {
277 for (auto I: HexagonMCInstrInfo::bundleInstructions(Instr)) {
278 auto &MI = const_cast<MCInst &>(*I.getInst());
279 switch (MI.getOpcode()) {
280 case Hexagon::S2_allocframe:
281 if (MI.getOperand(0).getReg() == Hexagon::R29) {
282 MI.setOpcode(Hexagon::S6_allocframe_to_raw);
283 MI.erase(MI.begin () + 1);
284 MI.erase(MI.begin ());
285 }
286 break;
287 case Hexagon::L2_deallocframe:
288 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
289 MI.getOperand(1).getReg() == Hexagon::R30) {
290 MI.setOpcode(L6_deallocframe_map_to_raw);
291 MI.erase(MI.begin () + 1);
292 MI.erase(MI.begin ());
293 }
294 break;
295 case Hexagon::L4_return:
296 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
297 MI.getOperand(1).getReg() == Hexagon::R30) {
298 MI.setOpcode(L6_return_map_to_raw);
299 MI.erase(MI.begin () + 1);
300 MI.erase(MI.begin ());
301 }
302 break;
303 case Hexagon::L4_return_t:
304 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
305 MI.getOperand(2).getReg() == Hexagon::R30) {
306 MI.setOpcode(L4_return_map_to_raw_t);
307 MI.erase(MI.begin () + 2);
308 MI.erase(MI.begin ());
309 }
310 break;
311 case Hexagon::L4_return_f:
312 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
313 MI.getOperand(2).getReg() == Hexagon::R30) {
314 MI.setOpcode(L4_return_map_to_raw_f);
315 MI.erase(MI.begin () + 2);
316 MI.erase(MI.begin ());
317 }
318 break;
319 case Hexagon::L4_return_tnew_pt:
320 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
321 MI.getOperand(2).getReg() == Hexagon::R30) {
322 MI.setOpcode(L4_return_map_to_raw_tnew_pt);
323 MI.erase(MI.begin () + 2);
324 MI.erase(MI.begin ());
325 }
326 break;
327 case Hexagon::L4_return_fnew_pt:
328 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
329 MI.getOperand(2).getReg() == Hexagon::R30) {
330 MI.setOpcode(L4_return_map_to_raw_fnew_pt);
331 MI.erase(MI.begin () + 2);
332 MI.erase(MI.begin ());
333 }
334 break;
335 case Hexagon::L4_return_tnew_pnt:
336 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
337 MI.getOperand(2).getReg() == Hexagon::R30) {
338 MI.setOpcode(L4_return_map_to_raw_tnew_pnt);
339 MI.erase(MI.begin () + 2);
340 MI.erase(MI.begin ());
341 }
342 break;
343 case Hexagon::L4_return_fnew_pnt:
344 if (MI.getOperand(0).getReg() == Hexagon::D15 &&
345 MI.getOperand(2).getReg() == Hexagon::R30) {
346 MI.setOpcode(L4_return_map_to_raw_fnew_pnt);
347 MI.erase(MI.begin () + 2);
348 MI.erase(MI.begin ());
349 }
350 break;
351 }
352 }
353 }
354
adjustDuplex(MCInst & MI,MCContext & Context)355 static void adjustDuplex(MCInst &MI, MCContext &Context) {
356 switch (MI.getOpcode()) {
357 case Hexagon::SA1_setin1:
358 MI.insert(MI.begin() + 1,
359 MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
360 break;
361 case Hexagon::SA1_dec:
362 MI.insert(MI.begin() + 2,
363 MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
364 break;
365 default:
366 break;
367 }
368 }
369
getSingleInstruction(MCInst & MI,MCInst & MCB,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & cs,bool & Complete) const370 DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
371 ArrayRef<uint8_t> Bytes,
372 uint64_t Address,
373 raw_ostream &cs,
374 bool &Complete) const {
375 assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
376
377 uint32_t Instruction = support::endian::read32le(Bytes.data());
378
379 auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
380 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
381 HexagonII::INST_PARSE_LOOP_END) {
382 if (BundleSize == 0)
383 HexagonMCInstrInfo::setInnerLoop(MCB);
384 else if (BundleSize == 1)
385 HexagonMCInstrInfo::setOuterLoop(MCB);
386 else
387 return DecodeStatus::Fail;
388 }
389
390 CurrentExtender = HexagonMCInstrInfo::extenderForIndex(
391 MCB, HexagonMCInstrInfo::bundleSize(MCB));
392
393 DecodeStatus Result = DecodeStatus::Fail;
394 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
395 HexagonII::INST_PARSE_DUPLEX) {
396 unsigned duplexIClass;
397 uint8_t const *DecodeLow, *DecodeHigh;
398 duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
399 switch (duplexIClass) {
400 default:
401 return MCDisassembler::Fail;
402 case 0:
403 DecodeLow = DecoderTableSUBINSN_L132;
404 DecodeHigh = DecoderTableSUBINSN_L132;
405 break;
406 case 1:
407 DecodeLow = DecoderTableSUBINSN_L232;
408 DecodeHigh = DecoderTableSUBINSN_L132;
409 break;
410 case 2:
411 DecodeLow = DecoderTableSUBINSN_L232;
412 DecodeHigh = DecoderTableSUBINSN_L232;
413 break;
414 case 3:
415 DecodeLow = DecoderTableSUBINSN_A32;
416 DecodeHigh = DecoderTableSUBINSN_A32;
417 break;
418 case 4:
419 DecodeLow = DecoderTableSUBINSN_L132;
420 DecodeHigh = DecoderTableSUBINSN_A32;
421 break;
422 case 5:
423 DecodeLow = DecoderTableSUBINSN_L232;
424 DecodeHigh = DecoderTableSUBINSN_A32;
425 break;
426 case 6:
427 DecodeLow = DecoderTableSUBINSN_S132;
428 DecodeHigh = DecoderTableSUBINSN_A32;
429 break;
430 case 7:
431 DecodeLow = DecoderTableSUBINSN_S232;
432 DecodeHigh = DecoderTableSUBINSN_A32;
433 break;
434 case 8:
435 DecodeLow = DecoderTableSUBINSN_S132;
436 DecodeHigh = DecoderTableSUBINSN_L132;
437 break;
438 case 9:
439 DecodeLow = DecoderTableSUBINSN_S132;
440 DecodeHigh = DecoderTableSUBINSN_L232;
441 break;
442 case 10:
443 DecodeLow = DecoderTableSUBINSN_S132;
444 DecodeHigh = DecoderTableSUBINSN_S132;
445 break;
446 case 11:
447 DecodeLow = DecoderTableSUBINSN_S232;
448 DecodeHigh = DecoderTableSUBINSN_S132;
449 break;
450 case 12:
451 DecodeLow = DecoderTableSUBINSN_S232;
452 DecodeHigh = DecoderTableSUBINSN_L132;
453 break;
454 case 13:
455 DecodeLow = DecoderTableSUBINSN_S232;
456 DecodeHigh = DecoderTableSUBINSN_L232;
457 break;
458 case 14:
459 DecodeLow = DecoderTableSUBINSN_S232;
460 DecodeHigh = DecoderTableSUBINSN_S232;
461 break;
462 }
463 MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass);
464 MCInst *MILow = getContext().createMCInst();
465 MCInst *MIHigh = getContext().createMCInst();
466 auto TmpExtender = CurrentExtender;
467 CurrentExtender =
468 nullptr; // constant extenders in duplex must always be in slot 1
469 Result = decodeInstruction(DecodeLow, *MILow, Instruction & 0x1fff, Address,
470 this, STI);
471 CurrentExtender = TmpExtender;
472 if (Result != DecodeStatus::Success)
473 return DecodeStatus::Fail;
474 adjustDuplex(*MILow, getContext());
475 Result = decodeInstruction(
476 DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff, Address, this, STI);
477 if (Result != DecodeStatus::Success)
478 return DecodeStatus::Fail;
479 adjustDuplex(*MIHigh, getContext());
480 MCOperand OPLow = MCOperand::createInst(MILow);
481 MCOperand OPHigh = MCOperand::createInst(MIHigh);
482 MI.addOperand(OPLow);
483 MI.addOperand(OPHigh);
484 Complete = true;
485 } else {
486 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
487 HexagonII::INST_PARSE_PACKET_END)
488 Complete = true;
489
490 if (CurrentExtender != nullptr)
491 Result = decodeInstruction(DecoderTableMustExtend32, MI, Instruction,
492 Address, this, STI);
493
494 if (Result != MCDisassembler::Success)
495 Result = decodeInstruction(DecoderTable32, MI, Instruction, Address, this,
496 STI);
497
498 if (Result != MCDisassembler::Success &&
499 STI.hasFeature(Hexagon::ExtensionHVX))
500 Result = decodeInstruction(DecoderTableEXT_mmvec32, MI, Instruction,
501 Address, this, STI);
502
503 }
504
505 switch (MI.getOpcode()) {
506 case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
507 case Hexagon::J4_cmpeqn1_f_jumpnv_t:
508 case Hexagon::J4_cmpeqn1_fp0_jump_nt:
509 case Hexagon::J4_cmpeqn1_fp0_jump_t:
510 case Hexagon::J4_cmpeqn1_fp1_jump_nt:
511 case Hexagon::J4_cmpeqn1_fp1_jump_t:
512 case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
513 case Hexagon::J4_cmpeqn1_t_jumpnv_t:
514 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
515 case Hexagon::J4_cmpeqn1_tp0_jump_t:
516 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
517 case Hexagon::J4_cmpeqn1_tp1_jump_t:
518 case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
519 case Hexagon::J4_cmpgtn1_f_jumpnv_t:
520 case Hexagon::J4_cmpgtn1_fp0_jump_nt:
521 case Hexagon::J4_cmpgtn1_fp0_jump_t:
522 case Hexagon::J4_cmpgtn1_fp1_jump_nt:
523 case Hexagon::J4_cmpgtn1_fp1_jump_t:
524 case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
525 case Hexagon::J4_cmpgtn1_t_jumpnv_t:
526 case Hexagon::J4_cmpgtn1_tp0_jump_nt:
527 case Hexagon::J4_cmpgtn1_tp0_jump_t:
528 case Hexagon::J4_cmpgtn1_tp1_jump_nt:
529 case Hexagon::J4_cmpgtn1_tp1_jump_t:
530 MI.insert(MI.begin() + 1,
531 MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
532 break;
533 case Hexagon::Y4_crswap10:
534 MI.addOperand(MCOperand::createReg(Hexagon::SGP1_0));
535 break;
536 default:
537 break;
538 }
539
540 if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
541 unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
542 MCOperand &MCO = MI.getOperand(OpIndex);
543 assert(MCO.isReg() && "New value consumers must be registers");
544 unsigned Register =
545 getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
546 if ((Register & 0x6) == 0)
547 // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
548 return MCDisassembler::Fail;
549 unsigned Lookback = (Register & 0x6) >> 1;
550 unsigned Offset = 1;
551 bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
552 bool PrevVector = false;
553 auto Instructions = HexagonMCInstrInfo::bundleInstructions(*CurrentBundle);
554 auto i = Instructions.end() - 1;
555 for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
556 if (i == n)
557 // Couldn't find producer
558 return MCDisassembler::Fail;
559 bool CurrentVector = HexagonMCInstrInfo::isVector(*MCII, *i->getInst());
560 if (Vector && !CurrentVector)
561 // Skip scalars when calculating distances for vectors
562 ++Lookback;
563 if (HexagonMCInstrInfo::isImmext(*i->getInst()) && (Vector == PrevVector))
564 ++Lookback;
565 PrevVector = CurrentVector;
566 if (Offset == Lookback)
567 break;
568 }
569 auto const &Inst = *i->getInst();
570 bool SubregBit = (Register & 0x1) != 0;
571 if (HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
572 // If subreg bit is set we're selecting the second produced newvalue
573 MCRegister Producer =
574 SubregBit
575 ? HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg()
576 : HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
577 assert(Producer != Hexagon::NoRegister);
578 MCO.setReg(Producer);
579 } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
580 MCRegister Producer =
581 HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
582
583 if (HexagonMCInstrInfo::IsVecRegPair(Producer)) {
584 const bool Rev = HexagonMCInstrInfo::IsReverseVecRegPair(Producer);
585 const unsigned ProdPairIndex =
586 Rev ? Producer - Hexagon::WR0 : Producer - Hexagon::W0;
587 if (Rev)
588 SubregBit = !SubregBit;
589 Producer = (ProdPairIndex << 1) + SubregBit + Hexagon::V0;
590 } else if (SubregBit)
591 // Hexagon PRM 10.11 New-value operands
592 // Nt[0] is reserved and should always be encoded as zero.
593 return MCDisassembler::Fail;
594 assert(Producer != Hexagon::NoRegister);
595 MCO.setReg(Producer);
596 } else
597 return MCDisassembler::Fail;
598 }
599
600 if (CurrentExtender != nullptr) {
601 MCInst const &Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI)
602 ? *MI.getOperand(1).getInst()
603 : MI;
604 if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
605 !HexagonMCInstrInfo::isExtended(*MCII, Inst))
606 return MCDisassembler::Fail;
607 }
608 return Result;
609 }
610
onSymbolStart(SymbolInfoTy & Symbol,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address) const611 Expected<bool> HexagonDisassembler::onSymbolStart(SymbolInfoTy &Symbol,
612 uint64_t &Size,
613 ArrayRef<uint8_t> Bytes,
614 uint64_t Address) const {
615 // At the start of a symbol, force a fresh packet by resetting any
616 // in-progress bundle state. This prevents packets from straddling label
617 // boundaries when data (e.g. jump tables) appears in between.
618 Size = 0;
619 resetBundle();
620 return true;
621 }
622
DecodeRegisterClass(MCInst & Inst,unsigned RegNo,ArrayRef<MCPhysReg> Table)623 static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
624 ArrayRef<MCPhysReg> Table) {
625 if (RegNo < Table.size()) {
626 Inst.addOperand(MCOperand::createReg(Table[RegNo]));
627 return MCDisassembler::Success;
628 }
629
630 return MCDisassembler::Fail;
631 }
632
633 static DecodeStatus
DecodeIntRegsLow8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)634 DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
635 const MCDisassembler *Decoder) {
636 return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
637 }
638
DecodeIntRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)639 static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
640 uint64_t Address,
641 const MCDisassembler *Decoder) {
642 static const MCPhysReg IntRegDecoderTable[] = {
643 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4,
644 Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
645 Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
646 Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
647 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
648 Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
649 Hexagon::R30, Hexagon::R31};
650
651 return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable);
652 }
653
654 static DecodeStatus
DecodeGeneralSubRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)655 DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo,
656 uint64_t Address,
657 const MCDisassembler *Decoder) {
658 static const MCPhysReg GeneralSubRegDecoderTable[] = {
659 Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3,
660 Hexagon::R4, Hexagon::R5, Hexagon::R6, Hexagon::R7,
661 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
662 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
663 };
664
665 return DecodeRegisterClass(Inst, RegNo, GeneralSubRegDecoderTable);
666 }
667
DecodeHvxVRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)668 static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
669 uint64_t /*Address*/,
670 const MCDisassembler *Decoder) {
671 static const MCPhysReg HvxVRDecoderTable[] = {
672 Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4,
673 Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9,
674 Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
675 Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
676 Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
677 Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
678 Hexagon::V30, Hexagon::V31};
679
680 return DecodeRegisterClass(Inst, RegNo, HvxVRDecoderTable);
681 }
682
683 static DecodeStatus
DecodeDoubleRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)684 DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
685 uint64_t /*Address*/,
686 const MCDisassembler *Decoder) {
687 static const MCPhysReg DoubleRegDecoderTable[] = {
688 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
689 Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7,
690 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11,
691 Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
692
693 return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable);
694 }
695
696 static DecodeStatus
DecodeGeneralDoubleLow8RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)697 DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
698 uint64_t /*Address*/,
699 const MCDisassembler *Decoder) {
700 static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = {
701 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
702 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11};
703
704 return DecodeRegisterClass(Inst, RegNo, GeneralDoubleLow8RegDecoderTable);
705 }
706
DecodeHvxWRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)707 static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
708 uint64_t /*Address*/,
709 const MCDisassembler *Decoder) {
710 static const MCPhysReg HvxWRDecoderTable[] = {
711 Hexagon::W0, Hexagon::WR0, Hexagon::W1, Hexagon::WR1, Hexagon::W2,
712 Hexagon::WR2, Hexagon::W3, Hexagon::WR3, Hexagon::W4, Hexagon::WR4,
713 Hexagon::W5, Hexagon::WR5, Hexagon::W6, Hexagon::WR6, Hexagon::W7,
714 Hexagon::WR7, Hexagon::W8, Hexagon::WR8, Hexagon::W9, Hexagon::WR9,
715 Hexagon::W10, Hexagon::WR10, Hexagon::W11, Hexagon::WR11, Hexagon::W12,
716 Hexagon::WR12, Hexagon::W13, Hexagon::WR13, Hexagon::W14, Hexagon::WR14,
717 Hexagon::W15, Hexagon::WR15,
718 };
719
720 return DecodeRegisterClass(Inst, RegNo, HvxWRDecoderTable);
721 }
722
723 LLVM_ATTRIBUTE_UNUSED // Suppress warning temporarily.
724 static DecodeStatus
DecodeHvxVQRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)725 DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo,
726 uint64_t /*Address*/,
727 const MCDisassembler *Decoder) {
728 static const MCPhysReg HvxVQRDecoderTable[] = {
729 Hexagon::VQ0, Hexagon::VQ1, Hexagon::VQ2, Hexagon::VQ3,
730 Hexagon::VQ4, Hexagon::VQ5, Hexagon::VQ6, Hexagon::VQ7};
731
732 return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable);
733 }
734
DecodePredRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)735 static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
736 uint64_t /*Address*/,
737 const MCDisassembler *Decoder) {
738 static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
739 Hexagon::P2, Hexagon::P3};
740
741 return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable);
742 }
743
DecodeHvxQRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)744 static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
745 uint64_t /*Address*/,
746 const MCDisassembler *Decoder) {
747 static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
748 Hexagon::Q2, Hexagon::Q3};
749
750 return DecodeRegisterClass(Inst, RegNo, HvxQRDecoderTable);
751 }
752
DecodeCtrRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)753 static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
754 uint64_t /*Address*/,
755 const MCDisassembler *Decoder) {
756 using namespace Hexagon;
757
758 static const MCPhysReg CtrlRegDecoderTable[] = {
759 /* 0 */ SA0, LC0, SA1, LC1,
760 /* 4 */ P3_0, C5, M0, M1,
761 /* 8 */ USR, PC, UGP, GP,
762 /* 12 */ CS0, CS1, UPCYCLELO, UPCYCLEHI,
763 /* 16 */ FRAMELIMIT, FRAMEKEY, PKTCOUNTLO, PKTCOUNTHI,
764 /* 20 */ 0, 0, 0, 0,
765 /* 24 */ 0, 0, 0, 0,
766 /* 28 */ 0, 0, UTIMERLO, UTIMERHI
767 };
768
769 if (RegNo >= std::size(CtrlRegDecoderTable))
770 return MCDisassembler::Fail;
771
772 static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
773 if (CtrlRegDecoderTable[RegNo] == NoRegister)
774 return MCDisassembler::Fail;
775
776 unsigned Register = CtrlRegDecoderTable[RegNo];
777 Inst.addOperand(MCOperand::createReg(Register));
778 return MCDisassembler::Success;
779 }
780
781 static DecodeStatus
DecodeCtrRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)782 DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
783 const MCDisassembler *Decoder) {
784 using namespace Hexagon;
785
786 static const MCPhysReg CtrlReg64DecoderTable[] = {
787 /* 0 */ C1_0, 0, C3_2, 0,
788 /* 4 */ C5_4, 0, C7_6, 0,
789 /* 8 */ C9_8, 0, C11_10, 0,
790 /* 12 */ CS, 0, UPCYCLE, 0,
791 /* 16 */ C17_16, 0, PKTCOUNT, 0,
792 /* 20 */ 0, 0, 0, 0,
793 /* 24 */ 0, 0, 0, 0,
794 /* 28 */ 0, 0, UTIMER, 0
795 };
796
797 if (RegNo >= std::size(CtrlReg64DecoderTable))
798 return MCDisassembler::Fail;
799
800 static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
801 if (CtrlReg64DecoderTable[RegNo] == NoRegister)
802 return MCDisassembler::Fail;
803
804 unsigned Register = CtrlReg64DecoderTable[RegNo];
805 Inst.addOperand(MCOperand::createReg(Register));
806 return MCDisassembler::Success;
807 }
808
DecodeModRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)809 static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
810 uint64_t /*Address*/,
811 const MCDisassembler *Decoder) {
812 unsigned Register = 0;
813 switch (RegNo) {
814 case 0:
815 Register = Hexagon::M0;
816 break;
817 case 1:
818 Register = Hexagon::M1;
819 break;
820 default:
821 return MCDisassembler::Fail;
822 }
823 Inst.addOperand(MCOperand::createReg(Register));
824 return MCDisassembler::Success;
825 }
826
unsignedImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const MCDisassembler * Decoder)827 static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
828 uint64_t /*Address*/,
829 const MCDisassembler *Decoder) {
830 HexagonDisassembler const &Disassembler = disassembler(Decoder);
831 int64_t FullValue = fullValue(Disassembler, MI, tmp);
832 assert(FullValue >= 0 && "Negative in unsigned decoder");
833 HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
834 return MCDisassembler::Success;
835 }
836
s32_0ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const MCDisassembler * Decoder)837 static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
838 uint64_t /*Address*/,
839 const MCDisassembler *Decoder) {
840 HexagonDisassembler const &Disassembler = disassembler(Decoder);
841 unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
842 tmp = SignExtend64(tmp, Bits);
843 signedDecoder<32>(MI, tmp, Decoder);
844 return MCDisassembler::Success;
845 }
846
847 // custom decoder for various jump/call immediates
brtargetDecoder(MCInst & MI,unsigned tmp,uint64_t Address,const MCDisassembler * Decoder)848 static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
849 const MCDisassembler *Decoder) {
850 HexagonDisassembler const &Disassembler = disassembler(Decoder);
851 unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
852 // r13_2 is not extendable, so if there are no extent bits, it's r13_2
853 if (Bits == 0)
854 Bits = 15;
855 uint64_t FullValue = fullValue(Disassembler, MI, SignExtend64(tmp, Bits));
856 uint32_t Extended = FullValue + Address;
857 if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 0, 0,
858 4))
859 HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
860 return MCDisassembler::Success;
861 }
862
863 static const uint16_t SysRegDecoderTable[] = {
864 Hexagon::SGP0, Hexagon::SGP1, Hexagon::STID,
865 Hexagon::ELR, Hexagon::BADVA0, Hexagon::BADVA1,
866 Hexagon::SSR, Hexagon::CCR, Hexagon::HTID,
867 Hexagon::BADVA, Hexagon::IMASK, Hexagon::S11,
868 Hexagon::S12, Hexagon::S13, Hexagon::S14,
869 Hexagon::S15, Hexagon::EVB, Hexagon::MODECTL,
870 Hexagon::SYSCFG, Hexagon::S19, Hexagon::S20,
871 Hexagon::VID, Hexagon::S22, Hexagon::S23,
872 Hexagon::S24, Hexagon::S25, Hexagon::S26,
873 Hexagon::CFGBASE, Hexagon::DIAG, Hexagon::REV,
874 Hexagon::PCYCLELO, Hexagon::PCYCLEHI, Hexagon::ISDBST,
875 Hexagon::ISDBCFG0, Hexagon::ISDBCFG1, Hexagon::S35,
876 Hexagon::BRKPTPC0, Hexagon::BRKPTCFG0, Hexagon::BRKPTPC1,
877 Hexagon::BRKPTCFG1, Hexagon::ISDBMBXIN, Hexagon::ISDBMBXOUT,
878 Hexagon::ISDBEN, Hexagon::ISDBGPR, Hexagon::S44,
879 Hexagon::S45, Hexagon::S46, Hexagon::S47,
880 Hexagon::PMUCNT0, Hexagon::PMUCNT1, Hexagon::PMUCNT2,
881 Hexagon::PMUCNT3, Hexagon::PMUEVTCFG, Hexagon::PMUCFG,
882 Hexagon::S54, Hexagon::S55, Hexagon::S56,
883 Hexagon::S57, Hexagon::S58, Hexagon::S59,
884 Hexagon::S60, Hexagon::S61, Hexagon::S62,
885 Hexagon::S63, Hexagon::S64, Hexagon::S65,
886 Hexagon::S66, Hexagon::S67, Hexagon::S68,
887 Hexagon::S69, Hexagon::S70, Hexagon::S71,
888 Hexagon::S72, Hexagon::S73, Hexagon::S74,
889 Hexagon::S75, Hexagon::S76, Hexagon::S77,
890 Hexagon::S78, Hexagon::S79, Hexagon::S80,
891 };
892
DecodeSysRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)893 static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo,
894 uint64_t /*Address*/,
895 const MCDisassembler *Decoder) {
896 if (RegNo >= std::size(SysRegDecoderTable))
897 return MCDisassembler::Fail;
898
899 if (SysRegDecoderTable[RegNo] == Hexagon::NoRegister)
900 return MCDisassembler::Fail;
901
902 unsigned Register = SysRegDecoderTable[RegNo];
903 Inst.addOperand(MCOperand::createReg(Register));
904 return MCDisassembler::Success;
905 }
906
907 static const uint16_t SysReg64DecoderTable[] = {
908 Hexagon::SGP1_0, Hexagon::S3_2, Hexagon::S5_4, Hexagon::S7_6,
909 Hexagon::S9_8, Hexagon::S11_10, Hexagon::S13_12, Hexagon::S15_14,
910 Hexagon::S17_16, Hexagon::S19_18, Hexagon::S21_20, Hexagon::S23_22,
911 Hexagon::S25_24, Hexagon::S27_26, Hexagon::S29_28, Hexagon::S31_30,
912 Hexagon::S33_32, Hexagon::S35_34, Hexagon::S37_36, Hexagon::S39_38,
913 Hexagon::S41_40, Hexagon::S43_42, Hexagon::S45_44, Hexagon::S47_46,
914 Hexagon::S49_48, Hexagon::S51_50, Hexagon::S53_52, Hexagon::S55_54,
915 Hexagon::S57_56, Hexagon::S59_58, Hexagon::S61_60, Hexagon::S63_62,
916 Hexagon::S65_64, Hexagon::S67_66, Hexagon::S69_68, Hexagon::S71_70,
917 Hexagon::S73_72, Hexagon::S75_74, Hexagon::S77_76, Hexagon::S79_78,
918 };
919
920 static DecodeStatus
DecodeSysRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)921 DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
922 const MCDisassembler *Decoder) {
923 RegNo = RegNo >> 1;
924 if (RegNo >= std::size(SysReg64DecoderTable))
925 return MCDisassembler::Fail;
926
927 if (SysReg64DecoderTable[RegNo] == Hexagon::NoRegister)
928 return MCDisassembler::Fail;
929
930 unsigned Register = SysReg64DecoderTable[RegNo];
931 Inst.addOperand(MCOperand::createReg(Register));
932 return MCDisassembler::Success;
933 }
934
935 static DecodeStatus
DecodeGuestRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)936 DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
937 const MCDisassembler *Decoder) {
938 using namespace Hexagon;
939
940 static const MCPhysReg GuestRegDecoderTable[] = {
941 /* 0 */ GELR, GSR, GOSP, G3,
942 /* 4 */ G4, G5, G6, G7,
943 /* 8 */ G8, G9, G10, G11,
944 /* 12 */ G12, G13, G14, G15,
945 /* 16 */ GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7,
946 /* 20 */ G20, G21, G22, G23,
947 /* 24 */ GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1,
948 /* 28 */ GPMUCNT2, GPMUCNT3, G30, G31
949 };
950
951 if (RegNo >= std::size(GuestRegDecoderTable))
952 return MCDisassembler::Fail;
953 if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister)
954 return MCDisassembler::Fail;
955
956 unsigned Register = GuestRegDecoderTable[RegNo];
957 Inst.addOperand(MCOperand::createReg(Register));
958 return MCDisassembler::Success;
959 }
960
961 static DecodeStatus
DecodeGuestRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)962 DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
963 uint64_t /*Address*/,
964 const MCDisassembler *Decoder) {
965 using namespace Hexagon;
966
967 static const MCPhysReg GuestReg64DecoderTable[] = {
968 /* 0 */ G1_0, 0, G3_2, 0,
969 /* 4 */ G5_4, 0, G7_6, 0,
970 /* 8 */ G9_8, 0, G11_10, 0,
971 /* 12 */ G13_12, 0, G15_14, 0,
972 /* 16 */ G17_16, 0, G19_18, 0,
973 /* 20 */ G21_20, 0, G23_22, 0,
974 /* 24 */ G25_24, 0, G27_26, 0,
975 /* 28 */ G29_28, 0, G31_30, 0
976 };
977
978 if (RegNo >= std::size(GuestReg64DecoderTable))
979 return MCDisassembler::Fail;
980 if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister)
981 return MCDisassembler::Fail;
982
983 unsigned Register = GuestReg64DecoderTable[RegNo];
984 Inst.addOperand(MCOperand::createReg(Register));
985 return MCDisassembler::Success;
986 }
987