1 //===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===//
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
7 //===----------------------------------------------------------------------===//
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/ADT/STLExtras.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCDecoderOps.h"
18 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/Endian.h"
26 #include "llvm/Support/MathExtras.h"
27 #include "llvm/Support/raw_ostream.h"
33 #define DEBUG_TYPE "hexagon-disassembler"
36 using namespace Hexagon
;
38 using DecodeStatus
= MCDisassembler::DecodeStatus
;
42 /// Hexagon disassembler for all Hexagon platforms.
43 class HexagonDisassembler
: public MCDisassembler
{
45 std::unique_ptr
<MCInstrInfo
const> const MCII
;
46 std::unique_ptr
<MCInst
*> CurrentBundle
;
47 mutable MCInst
const *CurrentExtender
;
49 HexagonDisassembler(const MCSubtargetInfo
&STI
, MCContext
&Ctx
,
50 MCInstrInfo
const *MCII
)
51 : MCDisassembler(STI
, Ctx
), MCII(MCII
), CurrentBundle(new MCInst
*),
52 CurrentExtender(nullptr) {}
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 void remapInstruction(MCInst
&Instr
) const;
63 static uint64_t fullValue(HexagonDisassembler
const &Disassembler
, MCInst
&MI
,
65 MCInstrInfo MCII
= *Disassembler
.MCII
;
66 if (!Disassembler
.CurrentExtender
||
67 MI
.size() != HexagonMCInstrInfo::getExtendableOp(MCII
, MI
))
69 unsigned Alignment
= HexagonMCInstrInfo::getExtentAlignment(MCII
, MI
);
70 uint32_t Lower6
= static_cast<uint32_t>(Value
>> Alignment
) & 0x3f;
73 Disassembler
.CurrentExtender
->getOperand(0).getExpr()->evaluateAsAbsolute(
77 uint64_t Upper26
= static_cast<uint64_t>(Bits
);
78 uint64_t Operand
= Upper26
| Lower6
;
81 static HexagonDisassembler
const &disassembler(const MCDisassembler
*Decoder
) {
82 return *static_cast<HexagonDisassembler
const *>(Decoder
);
85 static void signedDecoder(MCInst
&MI
, unsigned tmp
,
86 const MCDisassembler
*Decoder
) {
87 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
88 int64_t FullValue
= fullValue(Disassembler
, MI
, SignExtend64
<T
>(tmp
));
89 int64_t Extended
= SignExtend64
<32>(FullValue
);
90 HexagonMCInstrInfo::addConstant(MI
, Extended
, Disassembler
.getContext());
94 // Forward declare these because the auto-generated code will reference them.
95 // Definitions are further down.
97 static DecodeStatus
DecodeIntRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
99 const MCDisassembler
*Decoder
);
101 DecodeGeneralSubRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
103 const MCDisassembler
*Decoder
);
105 DecodeIntRegsLow8RegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t Address
,
106 const MCDisassembler
*Decoder
);
107 static DecodeStatus
DecodeHvxVRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
109 const MCDisassembler
*Decoder
);
111 DecodeDoubleRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t Address
,
112 const MCDisassembler
*Decoder
);
114 DecodeGeneralDoubleLow8RegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
116 const MCDisassembler
*Decoder
);
117 static DecodeStatus
DecodeHvxWRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
119 const MCDisassembler
*Decoder
);
120 static DecodeStatus
DecodeHvxVQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
122 const MCDisassembler
*Decoder
);
123 static DecodeStatus
DecodePredRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
125 const MCDisassembler
*Decoder
);
126 static DecodeStatus
DecodeHvxQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
128 const MCDisassembler
*Decoder
);
129 static DecodeStatus
DecodeCtrRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
131 const MCDisassembler
*Decoder
);
132 static DecodeStatus
DecodeGuestRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
134 const MCDisassembler
*Decoder
);
135 static DecodeStatus
DecodeSysRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
137 const MCDisassembler
*Decoder
);
138 static DecodeStatus
DecodeModRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
140 const MCDisassembler
*Decoder
);
141 static DecodeStatus
DecodeCtrRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
143 const MCDisassembler
*Decoder
);
145 DecodeGuestRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t Address
,
146 const MCDisassembler
*Decoder
);
147 static DecodeStatus
DecodeSysRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
149 const MCDisassembler
*Decoder
);
151 static DecodeStatus
unsignedImmDecoder(MCInst
&MI
, unsigned tmp
,
153 const MCDisassembler
*Decoder
);
154 static DecodeStatus
s32_0ImmDecoder(MCInst
&MI
, unsigned tmp
,
155 uint64_t /*Address*/,
156 const MCDisassembler
*Decoder
);
157 static DecodeStatus
brtargetDecoder(MCInst
&MI
, unsigned tmp
, uint64_t Address
,
158 const MCDisassembler
*Decoder
);
159 #include "HexagonDepDecoders.inc"
160 #include "HexagonGenDisassemblerTables.inc"
162 static MCDisassembler
*createHexagonDisassembler(const Target
&T
,
163 const MCSubtargetInfo
&STI
,
165 return new HexagonDisassembler(STI
, Ctx
, T
.createMCInstrInfo());
168 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeHexagonDisassembler() {
169 TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
170 createHexagonDisassembler
);
173 DecodeStatus
HexagonDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
174 ArrayRef
<uint8_t> Bytes
,
176 raw_ostream
&cs
) const {
177 DecodeStatus Result
= DecodeStatus::Success
;
178 bool Complete
= false;
181 *CurrentBundle
= &MI
;
182 MI
.setOpcode(Hexagon::BUNDLE
);
183 MI
.addOperand(MCOperand::createImm(0));
184 while (Result
== Success
&& !Complete
) {
185 if (Bytes
.size() < HEXAGON_INSTR_SIZE
)
186 return MCDisassembler::Fail
;
187 MCInst
*Inst
= getContext().createMCInst();
188 Result
= getSingleInstruction(*Inst
, MI
, Bytes
, Address
, cs
, Complete
);
189 MI
.addOperand(MCOperand::createInst(Inst
));
190 Size
+= HEXAGON_INSTR_SIZE
;
191 Bytes
= Bytes
.slice(HEXAGON_INSTR_SIZE
);
193 if (Result
== MCDisassembler::Fail
)
195 if (Size
> HEXAGON_MAX_PACKET_SIZE
)
196 return MCDisassembler::Fail
;
198 const auto ArchSTI
= Hexagon_MC::getArchSubtarget(&STI
);
199 const auto STI_
= (ArchSTI
!= nullptr) ? *ArchSTI
: STI
;
200 HexagonMCChecker
Checker(getContext(), *MCII
, STI_
, MI
,
201 *getContext().getRegisterInfo(), false);
202 if (!Checker
.check())
203 return MCDisassembler::Fail
;
204 remapInstruction(MI
);
205 return MCDisassembler::Success
;
208 void HexagonDisassembler::remapInstruction(MCInst
&Instr
) const {
209 for (auto I
: HexagonMCInstrInfo::bundleInstructions(Instr
)) {
210 auto &MI
= const_cast<MCInst
&>(*I
.getInst());
211 switch (MI
.getOpcode()) {
212 case Hexagon::S2_allocframe
:
213 if (MI
.getOperand(0).getReg() == Hexagon::R29
) {
214 MI
.setOpcode(Hexagon::S6_allocframe_to_raw
);
215 MI
.erase(MI
.begin () + 1);
216 MI
.erase(MI
.begin ());
219 case Hexagon::L2_deallocframe
:
220 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
221 MI
.getOperand(1).getReg() == Hexagon::R30
) {
222 MI
.setOpcode(L6_deallocframe_map_to_raw
);
223 MI
.erase(MI
.begin () + 1);
224 MI
.erase(MI
.begin ());
227 case Hexagon::L4_return
:
228 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
229 MI
.getOperand(1).getReg() == Hexagon::R30
) {
230 MI
.setOpcode(L6_return_map_to_raw
);
231 MI
.erase(MI
.begin () + 1);
232 MI
.erase(MI
.begin ());
235 case Hexagon::L4_return_t
:
236 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
237 MI
.getOperand(2).getReg() == Hexagon::R30
) {
238 MI
.setOpcode(L4_return_map_to_raw_t
);
239 MI
.erase(MI
.begin () + 2);
240 MI
.erase(MI
.begin ());
243 case Hexagon::L4_return_f
:
244 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
245 MI
.getOperand(2).getReg() == Hexagon::R30
) {
246 MI
.setOpcode(L4_return_map_to_raw_f
);
247 MI
.erase(MI
.begin () + 2);
248 MI
.erase(MI
.begin ());
251 case Hexagon::L4_return_tnew_pt
:
252 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
253 MI
.getOperand(2).getReg() == Hexagon::R30
) {
254 MI
.setOpcode(L4_return_map_to_raw_tnew_pt
);
255 MI
.erase(MI
.begin () + 2);
256 MI
.erase(MI
.begin ());
259 case Hexagon::L4_return_fnew_pt
:
260 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
261 MI
.getOperand(2).getReg() == Hexagon::R30
) {
262 MI
.setOpcode(L4_return_map_to_raw_fnew_pt
);
263 MI
.erase(MI
.begin () + 2);
264 MI
.erase(MI
.begin ());
267 case Hexagon::L4_return_tnew_pnt
:
268 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
269 MI
.getOperand(2).getReg() == Hexagon::R30
) {
270 MI
.setOpcode(L4_return_map_to_raw_tnew_pnt
);
271 MI
.erase(MI
.begin () + 2);
272 MI
.erase(MI
.begin ());
275 case Hexagon::L4_return_fnew_pnt
:
276 if (MI
.getOperand(0).getReg() == Hexagon::D15
&&
277 MI
.getOperand(2).getReg() == Hexagon::R30
) {
278 MI
.setOpcode(L4_return_map_to_raw_fnew_pnt
);
279 MI
.erase(MI
.begin () + 2);
280 MI
.erase(MI
.begin ());
287 static void adjustDuplex(MCInst
&MI
, MCContext
&Context
) {
288 switch (MI
.getOpcode()) {
289 case Hexagon::SA1_setin1
:
290 MI
.insert(MI
.begin() + 1,
291 MCOperand::createExpr(MCConstantExpr::create(-1, Context
)));
293 case Hexagon::SA1_dec
:
294 MI
.insert(MI
.begin() + 2,
295 MCOperand::createExpr(MCConstantExpr::create(-1, Context
)));
302 DecodeStatus
HexagonDisassembler::getSingleInstruction(MCInst
&MI
, MCInst
&MCB
,
303 ArrayRef
<uint8_t> Bytes
,
306 bool &Complete
) const {
307 assert(Bytes
.size() >= HEXAGON_INSTR_SIZE
);
309 uint32_t Instruction
= support::endian::read32le(Bytes
.data());
311 auto BundleSize
= HexagonMCInstrInfo::bundleSize(MCB
);
312 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
313 HexagonII::INST_PARSE_LOOP_END
) {
315 HexagonMCInstrInfo::setInnerLoop(MCB
);
316 else if (BundleSize
== 1)
317 HexagonMCInstrInfo::setOuterLoop(MCB
);
319 return DecodeStatus::Fail
;
322 CurrentExtender
= HexagonMCInstrInfo::extenderForIndex(
323 MCB
, HexagonMCInstrInfo::bundleSize(MCB
));
325 DecodeStatus Result
= DecodeStatus::Fail
;
326 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
327 HexagonII::INST_PARSE_DUPLEX
) {
328 unsigned duplexIClass
;
329 uint8_t const *DecodeLow
, *DecodeHigh
;
330 duplexIClass
= ((Instruction
>> 28) & 0xe) | ((Instruction
>> 13) & 0x1);
331 switch (duplexIClass
) {
333 return MCDisassembler::Fail
;
335 DecodeLow
= DecoderTableSUBINSN_L132
;
336 DecodeHigh
= DecoderTableSUBINSN_L132
;
339 DecodeLow
= DecoderTableSUBINSN_L232
;
340 DecodeHigh
= DecoderTableSUBINSN_L132
;
343 DecodeLow
= DecoderTableSUBINSN_L232
;
344 DecodeHigh
= DecoderTableSUBINSN_L232
;
347 DecodeLow
= DecoderTableSUBINSN_A32
;
348 DecodeHigh
= DecoderTableSUBINSN_A32
;
351 DecodeLow
= DecoderTableSUBINSN_L132
;
352 DecodeHigh
= DecoderTableSUBINSN_A32
;
355 DecodeLow
= DecoderTableSUBINSN_L232
;
356 DecodeHigh
= DecoderTableSUBINSN_A32
;
359 DecodeLow
= DecoderTableSUBINSN_S132
;
360 DecodeHigh
= DecoderTableSUBINSN_A32
;
363 DecodeLow
= DecoderTableSUBINSN_S232
;
364 DecodeHigh
= DecoderTableSUBINSN_A32
;
367 DecodeLow
= DecoderTableSUBINSN_S132
;
368 DecodeHigh
= DecoderTableSUBINSN_L132
;
371 DecodeLow
= DecoderTableSUBINSN_S132
;
372 DecodeHigh
= DecoderTableSUBINSN_L232
;
375 DecodeLow
= DecoderTableSUBINSN_S132
;
376 DecodeHigh
= DecoderTableSUBINSN_S132
;
379 DecodeLow
= DecoderTableSUBINSN_S232
;
380 DecodeHigh
= DecoderTableSUBINSN_S132
;
383 DecodeLow
= DecoderTableSUBINSN_S232
;
384 DecodeHigh
= DecoderTableSUBINSN_L132
;
387 DecodeLow
= DecoderTableSUBINSN_S232
;
388 DecodeHigh
= DecoderTableSUBINSN_L232
;
391 DecodeLow
= DecoderTableSUBINSN_S232
;
392 DecodeHigh
= DecoderTableSUBINSN_S232
;
395 MI
.setOpcode(Hexagon::DuplexIClass0
+ duplexIClass
);
396 MCInst
*MILow
= getContext().createMCInst();
397 MCInst
*MIHigh
= getContext().createMCInst();
398 auto TmpExtender
= CurrentExtender
;
400 nullptr; // constant extenders in duplex must always be in slot 1
401 Result
= decodeInstruction(DecodeLow
, *MILow
, Instruction
& 0x1fff, Address
,
403 CurrentExtender
= TmpExtender
;
404 if (Result
!= DecodeStatus::Success
)
405 return DecodeStatus::Fail
;
406 adjustDuplex(*MILow
, getContext());
407 Result
= decodeInstruction(
408 DecodeHigh
, *MIHigh
, (Instruction
>> 16) & 0x1fff, Address
, this, STI
);
409 if (Result
!= DecodeStatus::Success
)
410 return DecodeStatus::Fail
;
411 adjustDuplex(*MIHigh
, getContext());
412 MCOperand OPLow
= MCOperand::createInst(MILow
);
413 MCOperand OPHigh
= MCOperand::createInst(MIHigh
);
414 MI
.addOperand(OPLow
);
415 MI
.addOperand(OPHigh
);
418 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
419 HexagonII::INST_PARSE_PACKET_END
)
422 if (CurrentExtender
!= nullptr)
423 Result
= decodeInstruction(DecoderTableMustExtend32
, MI
, Instruction
,
426 if (Result
!= MCDisassembler::Success
)
427 Result
= decodeInstruction(DecoderTable32
, MI
, Instruction
, Address
, this,
430 if (Result
!= MCDisassembler::Success
&&
431 STI
.hasFeature(Hexagon::ExtensionHVX
))
432 Result
= decodeInstruction(DecoderTableEXT_mmvec32
, MI
, Instruction
,
437 switch (MI
.getOpcode()) {
438 case Hexagon::J4_cmpeqn1_f_jumpnv_nt
:
439 case Hexagon::J4_cmpeqn1_f_jumpnv_t
:
440 case Hexagon::J4_cmpeqn1_fp0_jump_nt
:
441 case Hexagon::J4_cmpeqn1_fp0_jump_t
:
442 case Hexagon::J4_cmpeqn1_fp1_jump_nt
:
443 case Hexagon::J4_cmpeqn1_fp1_jump_t
:
444 case Hexagon::J4_cmpeqn1_t_jumpnv_nt
:
445 case Hexagon::J4_cmpeqn1_t_jumpnv_t
:
446 case Hexagon::J4_cmpeqn1_tp0_jump_nt
:
447 case Hexagon::J4_cmpeqn1_tp0_jump_t
:
448 case Hexagon::J4_cmpeqn1_tp1_jump_nt
:
449 case Hexagon::J4_cmpeqn1_tp1_jump_t
:
450 case Hexagon::J4_cmpgtn1_f_jumpnv_nt
:
451 case Hexagon::J4_cmpgtn1_f_jumpnv_t
:
452 case Hexagon::J4_cmpgtn1_fp0_jump_nt
:
453 case Hexagon::J4_cmpgtn1_fp0_jump_t
:
454 case Hexagon::J4_cmpgtn1_fp1_jump_nt
:
455 case Hexagon::J4_cmpgtn1_fp1_jump_t
:
456 case Hexagon::J4_cmpgtn1_t_jumpnv_nt
:
457 case Hexagon::J4_cmpgtn1_t_jumpnv_t
:
458 case Hexagon::J4_cmpgtn1_tp0_jump_nt
:
459 case Hexagon::J4_cmpgtn1_tp0_jump_t
:
460 case Hexagon::J4_cmpgtn1_tp1_jump_nt
:
461 case Hexagon::J4_cmpgtn1_tp1_jump_t
:
462 MI
.insert(MI
.begin() + 1,
463 MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
469 if (HexagonMCInstrInfo::isNewValue(*MCII
, MI
)) {
470 unsigned OpIndex
= HexagonMCInstrInfo::getNewValueOp(*MCII
, MI
);
471 MCOperand
&MCO
= MI
.getOperand(OpIndex
);
472 assert(MCO
.isReg() && "New value consumers must be registers");
474 getContext().getRegisterInfo()->getEncodingValue(MCO
.getReg());
475 if ((Register
& 0x6) == 0)
476 // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
477 return MCDisassembler::Fail
;
478 unsigned Lookback
= (Register
& 0x6) >> 1;
480 bool Vector
= HexagonMCInstrInfo::isVector(*MCII
, MI
);
481 bool PrevVector
= false;
482 auto Instructions
= HexagonMCInstrInfo::bundleInstructions(**CurrentBundle
);
483 auto i
= Instructions
.end() - 1;
484 for (auto n
= Instructions
.begin() - 1;; --i
, ++Offset
) {
486 // Couldn't find producer
487 return MCDisassembler::Fail
;
488 bool CurrentVector
= HexagonMCInstrInfo::isVector(*MCII
, *i
->getInst());
489 if (Vector
&& !CurrentVector
)
490 // Skip scalars when calculating distances for vectors
492 if (HexagonMCInstrInfo::isImmext(*i
->getInst()) && (Vector
== PrevVector
))
494 PrevVector
= CurrentVector
;
495 if (Offset
== Lookback
)
498 auto const &Inst
= *i
->getInst();
499 bool SubregBit
= (Register
& 0x1) != 0;
500 if (HexagonMCInstrInfo::hasNewValue2(*MCII
, Inst
)) {
501 // If subreg bit is set we're selecting the second produced newvalue
502 unsigned Producer
= SubregBit
?
503 HexagonMCInstrInfo::getNewValueOperand(*MCII
, Inst
).getReg() :
504 HexagonMCInstrInfo::getNewValueOperand2(*MCII
, Inst
).getReg();
505 assert(Producer
!= Hexagon::NoRegister
);
506 MCO
.setReg(Producer
);
507 } else if (HexagonMCInstrInfo::hasNewValue(*MCII
, Inst
)) {
509 HexagonMCInstrInfo::getNewValueOperand(*MCII
, Inst
).getReg();
511 if (HexagonMCInstrInfo::IsVecRegPair(Producer
)) {
512 const bool Rev
= HexagonMCInstrInfo::IsReverseVecRegPair(Producer
);
513 const unsigned ProdPairIndex
=
514 Rev
? Producer
- Hexagon::WR0
: Producer
- Hexagon::W0
;
516 SubregBit
= !SubregBit
;
517 Producer
= (ProdPairIndex
<< 1) + SubregBit
+ Hexagon::V0
;
518 } else if (SubregBit
)
519 // Hexagon PRM 10.11 New-value operands
520 // Nt[0] is reserved and should always be encoded as zero.
521 return MCDisassembler::Fail
;
522 assert(Producer
!= Hexagon::NoRegister
);
523 MCO
.setReg(Producer
);
525 return MCDisassembler::Fail
;
528 if (CurrentExtender
!= nullptr) {
529 MCInst
const &Inst
= HexagonMCInstrInfo::isDuplex(*MCII
, MI
)
530 ? *MI
.getOperand(1).getInst()
532 if (!HexagonMCInstrInfo::isExtendable(*MCII
, Inst
) &&
533 !HexagonMCInstrInfo::isExtended(*MCII
, Inst
))
534 return MCDisassembler::Fail
;
539 static DecodeStatus
DecodeRegisterClass(MCInst
&Inst
, unsigned RegNo
,
540 ArrayRef
<MCPhysReg
> Table
) {
541 if (RegNo
< Table
.size()) {
542 Inst
.addOperand(MCOperand::createReg(Table
[RegNo
]));
543 return MCDisassembler::Success
;
546 return MCDisassembler::Fail
;
550 DecodeIntRegsLow8RegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t Address
,
551 const MCDisassembler
*Decoder
) {
552 return DecodeIntRegsRegisterClass(Inst
, RegNo
, Address
, Decoder
);
555 static DecodeStatus
DecodeIntRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
557 const MCDisassembler
*Decoder
) {
558 static const MCPhysReg IntRegDecoderTable
[] = {
559 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
, Hexagon::R4
,
560 Hexagon::R5
, Hexagon::R6
, Hexagon::R7
, Hexagon::R8
, Hexagon::R9
,
561 Hexagon::R10
, Hexagon::R11
, Hexagon::R12
, Hexagon::R13
, Hexagon::R14
,
562 Hexagon::R15
, Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
563 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
, Hexagon::R24
,
564 Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, Hexagon::R28
, Hexagon::R29
,
565 Hexagon::R30
, Hexagon::R31
};
567 return DecodeRegisterClass(Inst
, RegNo
, IntRegDecoderTable
);
571 DecodeGeneralSubRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
573 const MCDisassembler
*Decoder
) {
574 static const MCPhysReg GeneralSubRegDecoderTable
[] = {
575 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
,
576 Hexagon::R4
, Hexagon::R5
, Hexagon::R6
, Hexagon::R7
,
577 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
578 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
581 return DecodeRegisterClass(Inst
, RegNo
, GeneralSubRegDecoderTable
);
584 static DecodeStatus
DecodeHvxVRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
585 uint64_t /*Address*/,
586 const MCDisassembler
*Decoder
) {
587 static const MCPhysReg HvxVRDecoderTable
[] = {
588 Hexagon::V0
, Hexagon::V1
, Hexagon::V2
, Hexagon::V3
, Hexagon::V4
,
589 Hexagon::V5
, Hexagon::V6
, Hexagon::V7
, Hexagon::V8
, Hexagon::V9
,
590 Hexagon::V10
, Hexagon::V11
, Hexagon::V12
, Hexagon::V13
, Hexagon::V14
,
591 Hexagon::V15
, Hexagon::V16
, Hexagon::V17
, Hexagon::V18
, Hexagon::V19
,
592 Hexagon::V20
, Hexagon::V21
, Hexagon::V22
, Hexagon::V23
, Hexagon::V24
,
593 Hexagon::V25
, Hexagon::V26
, Hexagon::V27
, Hexagon::V28
, Hexagon::V29
,
594 Hexagon::V30
, Hexagon::V31
};
596 return DecodeRegisterClass(Inst
, RegNo
, HvxVRDecoderTable
);
600 DecodeDoubleRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
601 uint64_t /*Address*/,
602 const MCDisassembler
*Decoder
) {
603 static const MCPhysReg DoubleRegDecoderTable
[] = {
604 Hexagon::D0
, Hexagon::D1
, Hexagon::D2
, Hexagon::D3
,
605 Hexagon::D4
, Hexagon::D5
, Hexagon::D6
, Hexagon::D7
,
606 Hexagon::D8
, Hexagon::D9
, Hexagon::D10
, Hexagon::D11
,
607 Hexagon::D12
, Hexagon::D13
, Hexagon::D14
, Hexagon::D15
};
609 return DecodeRegisterClass(Inst
, RegNo
>> 1, DoubleRegDecoderTable
);
613 DecodeGeneralDoubleLow8RegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
614 uint64_t /*Address*/,
615 const MCDisassembler
*Decoder
) {
616 static const MCPhysReg GeneralDoubleLow8RegDecoderTable
[] = {
617 Hexagon::D0
, Hexagon::D1
, Hexagon::D2
, Hexagon::D3
,
618 Hexagon::D8
, Hexagon::D9
, Hexagon::D10
, Hexagon::D11
};
620 return DecodeRegisterClass(Inst
, RegNo
, GeneralDoubleLow8RegDecoderTable
);
623 static DecodeStatus
DecodeHvxWRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
624 uint64_t /*Address*/,
625 const MCDisassembler
*Decoder
) {
626 static const MCPhysReg HvxWRDecoderTable
[] = {
627 Hexagon::W0
, Hexagon::WR0
, Hexagon::W1
, Hexagon::WR1
, Hexagon::W2
,
628 Hexagon::WR2
, Hexagon::W3
, Hexagon::WR3
, Hexagon::W4
, Hexagon::WR4
,
629 Hexagon::W5
, Hexagon::WR5
, Hexagon::W6
, Hexagon::WR6
, Hexagon::W7
,
630 Hexagon::WR7
, Hexagon::W8
, Hexagon::WR8
, Hexagon::W9
, Hexagon::WR9
,
631 Hexagon::W10
, Hexagon::WR10
, Hexagon::W11
, Hexagon::WR11
, Hexagon::W12
,
632 Hexagon::WR12
, Hexagon::W13
, Hexagon::WR13
, Hexagon::W14
, Hexagon::WR14
,
633 Hexagon::W15
, Hexagon::WR15
,
636 return DecodeRegisterClass(Inst
, RegNo
, HvxWRDecoderTable
);
639 LLVM_ATTRIBUTE_UNUSED
// Suppress warning temporarily.
641 DecodeHvxVQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
642 uint64_t /*Address*/,
643 const MCDisassembler
*Decoder
) {
644 static const MCPhysReg HvxVQRDecoderTable
[] = {
645 Hexagon::VQ0
, Hexagon::VQ1
, Hexagon::VQ2
, Hexagon::VQ3
,
646 Hexagon::VQ4
, Hexagon::VQ5
, Hexagon::VQ6
, Hexagon::VQ7
};
648 return DecodeRegisterClass(Inst
, RegNo
>> 2, HvxVQRDecoderTable
);
651 static DecodeStatus
DecodePredRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
652 uint64_t /*Address*/,
653 const MCDisassembler
*Decoder
) {
654 static const MCPhysReg PredRegDecoderTable
[] = {Hexagon::P0
, Hexagon::P1
,
655 Hexagon::P2
, Hexagon::P3
};
657 return DecodeRegisterClass(Inst
, RegNo
, PredRegDecoderTable
);
660 static DecodeStatus
DecodeHvxQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
661 uint64_t /*Address*/,
662 const MCDisassembler
*Decoder
) {
663 static const MCPhysReg HvxQRDecoderTable
[] = {Hexagon::Q0
, Hexagon::Q1
,
664 Hexagon::Q2
, Hexagon::Q3
};
666 return DecodeRegisterClass(Inst
, RegNo
, HvxQRDecoderTable
);
669 static DecodeStatus
DecodeCtrRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
670 uint64_t /*Address*/,
671 const MCDisassembler
*Decoder
) {
672 using namespace Hexagon
;
674 static const MCPhysReg CtrlRegDecoderTable
[] = {
675 /* 0 */ SA0
, LC0
, SA1
, LC1
,
676 /* 4 */ P3_0
, C5
, M0
, M1
,
677 /* 8 */ USR
, PC
, UGP
, GP
,
678 /* 12 */ CS0
, CS1
, UPCYCLELO
, UPCYCLEHI
,
679 /* 16 */ FRAMELIMIT
, FRAMEKEY
, PKTCOUNTLO
, PKTCOUNTHI
,
682 /* 28 */ 0, 0, UTIMERLO
, UTIMERHI
685 if (RegNo
>= std::size(CtrlRegDecoderTable
))
686 return MCDisassembler::Fail
;
688 static_assert(NoRegister
== 0, "Expecting NoRegister to be 0");
689 if (CtrlRegDecoderTable
[RegNo
] == NoRegister
)
690 return MCDisassembler::Fail
;
692 unsigned Register
= CtrlRegDecoderTable
[RegNo
];
693 Inst
.addOperand(MCOperand::createReg(Register
));
694 return MCDisassembler::Success
;
698 DecodeCtrRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t /*Address*/,
699 const MCDisassembler
*Decoder
) {
700 using namespace Hexagon
;
702 static const MCPhysReg CtrlReg64DecoderTable
[] = {
703 /* 0 */ C1_0
, 0, C3_2
, 0,
704 /* 4 */ C5_4
, 0, C7_6
, 0,
705 /* 8 */ C9_8
, 0, C11_10
, 0,
706 /* 12 */ CS
, 0, UPCYCLE
, 0,
707 /* 16 */ C17_16
, 0, PKTCOUNT
, 0,
710 /* 28 */ 0, 0, UTIMER
, 0
713 if (RegNo
>= std::size(CtrlReg64DecoderTable
))
714 return MCDisassembler::Fail
;
716 static_assert(NoRegister
== 0, "Expecting NoRegister to be 0");
717 if (CtrlReg64DecoderTable
[RegNo
] == NoRegister
)
718 return MCDisassembler::Fail
;
720 unsigned Register
= CtrlReg64DecoderTable
[RegNo
];
721 Inst
.addOperand(MCOperand::createReg(Register
));
722 return MCDisassembler::Success
;
725 static DecodeStatus
DecodeModRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
726 uint64_t /*Address*/,
727 const MCDisassembler
*Decoder
) {
728 unsigned Register
= 0;
731 Register
= Hexagon::M0
;
734 Register
= Hexagon::M1
;
737 return MCDisassembler::Fail
;
739 Inst
.addOperand(MCOperand::createReg(Register
));
740 return MCDisassembler::Success
;
743 static DecodeStatus
unsignedImmDecoder(MCInst
&MI
, unsigned tmp
,
744 uint64_t /*Address*/,
745 const MCDisassembler
*Decoder
) {
746 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
747 int64_t FullValue
= fullValue(Disassembler
, MI
, tmp
);
748 assert(FullValue
>= 0 && "Negative in unsigned decoder");
749 HexagonMCInstrInfo::addConstant(MI
, FullValue
, Disassembler
.getContext());
750 return MCDisassembler::Success
;
753 static DecodeStatus
s32_0ImmDecoder(MCInst
&MI
, unsigned tmp
,
754 uint64_t /*Address*/,
755 const MCDisassembler
*Decoder
) {
756 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
757 unsigned Bits
= HexagonMCInstrInfo::getExtentBits(*Disassembler
.MCII
, MI
);
758 tmp
= SignExtend64(tmp
, Bits
);
759 signedDecoder
<32>(MI
, tmp
, Decoder
);
760 return MCDisassembler::Success
;
763 // custom decoder for various jump/call immediates
764 static DecodeStatus
brtargetDecoder(MCInst
&MI
, unsigned tmp
, uint64_t Address
,
765 const MCDisassembler
*Decoder
) {
766 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
767 unsigned Bits
= HexagonMCInstrInfo::getExtentBits(*Disassembler
.MCII
, MI
);
768 // r13_2 is not extendable, so if there are no extent bits, it's r13_2
771 uint64_t FullValue
= fullValue(Disassembler
, MI
, SignExtend64(tmp
, Bits
));
772 uint32_t Extended
= FullValue
+ Address
;
773 if (!Disassembler
.tryAddingSymbolicOperand(MI
, Extended
, Address
, true, 0, 0,
775 HexagonMCInstrInfo::addConstant(MI
, Extended
, Disassembler
.getContext());
776 return MCDisassembler::Success
;
779 static const uint16_t SysRegDecoderTable
[] = {
780 Hexagon::SGP0
, Hexagon::SGP1
, Hexagon::STID
,
781 Hexagon::ELR
, Hexagon::BADVA0
, Hexagon::BADVA1
,
782 Hexagon::SSR
, Hexagon::CCR
, Hexagon::HTID
,
783 Hexagon::BADVA
, Hexagon::IMASK
, Hexagon::S11
,
784 Hexagon::S12
, Hexagon::S13
, Hexagon::S14
,
785 Hexagon::S15
, Hexagon::EVB
, Hexagon::MODECTL
,
786 Hexagon::SYSCFG
, Hexagon::S19
, Hexagon::S20
,
787 Hexagon::VID
, Hexagon::S22
, Hexagon::S23
,
788 Hexagon::S24
, Hexagon::S25
, Hexagon::S26
,
789 Hexagon::CFGBASE
, Hexagon::DIAG
, Hexagon::REV
,
790 Hexagon::PCYCLELO
, Hexagon::PCYCLEHI
, Hexagon::ISDBST
,
791 Hexagon::ISDBCFG0
, Hexagon::ISDBCFG1
, Hexagon::S35
,
792 Hexagon::BRKPTPC0
, Hexagon::BRKPTCFG0
, Hexagon::BRKPTPC1
,
793 Hexagon::BRKPTCFG1
, Hexagon::ISDBMBXIN
, Hexagon::ISDBMBXOUT
,
794 Hexagon::ISDBEN
, Hexagon::ISDBGPR
, Hexagon::S44
,
795 Hexagon::S45
, Hexagon::S46
, Hexagon::S47
,
796 Hexagon::PMUCNT0
, Hexagon::PMUCNT1
, Hexagon::PMUCNT2
,
797 Hexagon::PMUCNT3
, Hexagon::PMUEVTCFG
, Hexagon::PMUCFG
,
798 Hexagon::S54
, Hexagon::S55
, Hexagon::S56
,
799 Hexagon::S57
, Hexagon::S58
, Hexagon::S59
,
800 Hexagon::S60
, Hexagon::S61
, Hexagon::S62
,
801 Hexagon::S63
, Hexagon::S64
, Hexagon::S65
,
802 Hexagon::S66
, Hexagon::S67
, Hexagon::S68
,
803 Hexagon::S69
, Hexagon::S70
, Hexagon::S71
,
804 Hexagon::S72
, Hexagon::S73
, Hexagon::S74
,
805 Hexagon::S75
, Hexagon::S76
, Hexagon::S77
,
806 Hexagon::S78
, Hexagon::S79
, Hexagon::S80
,
809 static DecodeStatus
DecodeSysRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
810 uint64_t /*Address*/,
811 const MCDisassembler
*Decoder
) {
812 if (RegNo
>= std::size(SysRegDecoderTable
))
813 return MCDisassembler::Fail
;
815 if (SysRegDecoderTable
[RegNo
] == Hexagon::NoRegister
)
816 return MCDisassembler::Fail
;
818 unsigned Register
= SysRegDecoderTable
[RegNo
];
819 Inst
.addOperand(MCOperand::createReg(Register
));
820 return MCDisassembler::Success
;
823 static const uint16_t SysReg64DecoderTable
[] = {
824 Hexagon::SGP1_0
, Hexagon::S3_2
, Hexagon::S5_4
, Hexagon::S7_6
,
825 Hexagon::S9_8
, Hexagon::S11_10
, Hexagon::S13_12
, Hexagon::S15_14
,
826 Hexagon::S17_16
, Hexagon::S19_18
, Hexagon::S21_20
, Hexagon::S23_22
,
827 Hexagon::S25_24
, Hexagon::S27_26
, Hexagon::S29_28
, Hexagon::S31_30
,
828 Hexagon::S33_32
, Hexagon::S35_34
, Hexagon::S37_36
, Hexagon::S39_38
,
829 Hexagon::S41_40
, Hexagon::S43_42
, Hexagon::S45_44
, Hexagon::S47_46
,
830 Hexagon::S49_48
, Hexagon::S51_50
, Hexagon::S53_52
, Hexagon::S55_54
,
831 Hexagon::S57_56
, Hexagon::S59_58
, Hexagon::S61_60
, Hexagon::S63_62
,
832 Hexagon::S65_64
, Hexagon::S67_66
, Hexagon::S69_68
, Hexagon::S71_70
,
833 Hexagon::S73_72
, Hexagon::S75_74
, Hexagon::S77_76
, Hexagon::S79_78
,
837 DecodeSysRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t /*Address*/,
838 const MCDisassembler
*Decoder
) {
840 if (RegNo
>= std::size(SysReg64DecoderTable
))
841 return MCDisassembler::Fail
;
843 if (SysReg64DecoderTable
[RegNo
] == Hexagon::NoRegister
)
844 return MCDisassembler::Fail
;
846 unsigned Register
= SysReg64DecoderTable
[RegNo
];
847 Inst
.addOperand(MCOperand::createReg(Register
));
848 return MCDisassembler::Success
;
852 DecodeGuestRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
, uint64_t /*Address*/,
853 const MCDisassembler
*Decoder
) {
854 using namespace Hexagon
;
856 static const MCPhysReg GuestRegDecoderTable
[] = {
857 /* 0 */ GELR
, GSR
, GOSP
, G3
,
858 /* 4 */ G4
, G5
, G6
, G7
,
859 /* 8 */ G8
, G9
, G10
, G11
,
860 /* 12 */ G12
, G13
, G14
, G15
,
861 /* 16 */ GPMUCNT4
, GPMUCNT5
, GPMUCNT6
, GPMUCNT7
,
862 /* 20 */ G20
, G21
, G22
, G23
,
863 /* 24 */ GPCYCLELO
, GPCYCLEHI
, GPMUCNT0
, GPMUCNT1
,
864 /* 28 */ GPMUCNT2
, GPMUCNT3
, G30
, G31
867 if (RegNo
>= std::size(GuestRegDecoderTable
))
868 return MCDisassembler::Fail
;
869 if (GuestRegDecoderTable
[RegNo
] == Hexagon::NoRegister
)
870 return MCDisassembler::Fail
;
872 unsigned Register
= GuestRegDecoderTable
[RegNo
];
873 Inst
.addOperand(MCOperand::createReg(Register
));
874 return MCDisassembler::Success
;
878 DecodeGuestRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
879 uint64_t /*Address*/,
880 const MCDisassembler
*Decoder
) {
881 using namespace Hexagon
;
883 static const MCPhysReg GuestReg64DecoderTable
[] = {
884 /* 0 */ G1_0
, 0, G3_2
, 0,
885 /* 4 */ G5_4
, 0, G7_6
, 0,
886 /* 8 */ G9_8
, 0, G11_10
, 0,
887 /* 12 */ G13_12
, 0, G15_14
, 0,
888 /* 16 */ G17_16
, 0, G19_18
, 0,
889 /* 20 */ G21_20
, 0, G23_22
, 0,
890 /* 24 */ G25_24
, 0, G27_26
, 0,
891 /* 28 */ G29_28
, 0, G31_30
, 0
894 if (RegNo
>= std::size(GuestReg64DecoderTable
))
895 return MCDisassembler::Fail
;
896 if (GuestReg64DecoderTable
[RegNo
] == Hexagon::NoRegister
)
897 return MCDisassembler::Fail
;
899 unsigned Register
= GuestReg64DecoderTable
[RegNo
];
900 Inst
.addOperand(MCOperand::createReg(Register
));
901 return MCDisassembler::Success
;