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/MCDisassembler/MCDisassembler.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCFixedLenDisassembler.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/Support/Endian.h"
25 #include "llvm/Support/MathExtras.h"
26 #include "llvm/Support/TargetRegistry.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(void const *Decoder
) {
82 return *static_cast<HexagonDisassembler
const *>(Decoder
);
85 static void signedDecoder(MCInst
&MI
, unsigned tmp
, const void *Decoder
) {
86 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
87 int64_t FullValue
= fullValue(Disassembler
, MI
, SignExtend64
<T
>(tmp
));
88 int64_t Extended
= SignExtend64
<32>(FullValue
);
89 HexagonMCInstrInfo::addConstant(MI
, Extended
, Disassembler
.getContext());
93 // Forward declare these because the auto-generated code will reference them.
94 // Definitions are further down.
96 static DecodeStatus
DecodeIntRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
99 static DecodeStatus
DecodeGeneralSubRegsRegisterClass(MCInst
&Inst
,
102 const void *Decoder
);
103 static DecodeStatus
DecodeIntRegsLow8RegisterClass(MCInst
&Inst
, unsigned RegNo
,
105 const void *Decoder
);
106 static DecodeStatus
DecodeHvxVRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
108 const void *Decoder
);
109 static DecodeStatus
DecodeDoubleRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
111 const void *Decoder
);
113 DecodeGeneralDoubleLow8RegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
114 uint64_t Address
, const void *Decoder
);
115 static DecodeStatus
DecodeHvxWRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
117 const void *Decoder
);
118 static DecodeStatus
DecodeHvxVQRRegisterClass(MCInst
&Inst
,
121 const void *Decoder
);
122 static DecodeStatus
DecodePredRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
124 const void *Decoder
);
125 static DecodeStatus
DecodeHvxQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
127 const void *Decoder
);
128 static DecodeStatus
DecodeCtrRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
130 const void *Decoder
);
131 static DecodeStatus
DecodeGuestRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
133 const void *Decoder
);
134 static DecodeStatus
DecodeModRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
136 const void *Decoder
);
137 static DecodeStatus
DecodeCtrRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
139 const void *Decoder
);
140 static DecodeStatus
DecodeGuestRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
142 const void *Decoder
);
144 static DecodeStatus
unsignedImmDecoder(MCInst
&MI
, unsigned tmp
,
145 uint64_t Address
, const void *Decoder
);
146 static DecodeStatus
s32_0ImmDecoder(MCInst
&MI
, unsigned tmp
,
147 uint64_t /*Address*/, const void *Decoder
);
148 static DecodeStatus
brtargetDecoder(MCInst
&MI
, unsigned tmp
, uint64_t Address
,
149 const void *Decoder
);
150 #include "HexagonDepDecoders.inc"
151 #include "HexagonGenDisassemblerTables.inc"
153 static MCDisassembler
*createHexagonDisassembler(const Target
&T
,
154 const MCSubtargetInfo
&STI
,
156 return new HexagonDisassembler(STI
, Ctx
, T
.createMCInstrInfo());
159 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeHexagonDisassembler() {
160 TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
161 createHexagonDisassembler
);
164 DecodeStatus
HexagonDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
165 ArrayRef
<uint8_t> Bytes
,
167 raw_ostream
&cs
) const {
168 DecodeStatus Result
= DecodeStatus::Success
;
169 bool Complete
= false;
172 *CurrentBundle
= &MI
;
173 MI
.setOpcode(Hexagon::BUNDLE
);
174 MI
.addOperand(MCOperand::createImm(0));
175 while (Result
== Success
&& !Complete
) {
176 if (Bytes
.size() < HEXAGON_INSTR_SIZE
)
177 return MCDisassembler::Fail
;
178 MCInst
*Inst
= getContext().createMCInst();
179 Result
= getSingleInstruction(*Inst
, MI
, Bytes
, Address
, cs
, Complete
);
180 MI
.addOperand(MCOperand::createInst(Inst
));
181 Size
+= HEXAGON_INSTR_SIZE
;
182 Bytes
= Bytes
.slice(HEXAGON_INSTR_SIZE
);
184 if (Result
== MCDisassembler::Fail
)
186 if (Size
> HEXAGON_MAX_PACKET_SIZE
)
187 return MCDisassembler::Fail
;
189 const auto ArchSTI
= Hexagon_MC::getArchSubtarget(&STI
);
190 const auto STI_
= (ArchSTI
!= nullptr) ? *ArchSTI
: STI
;
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
;
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
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 ());
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
)));
284 case Hexagon::SA1_dec
:
285 MI
.insert(MI
.begin() + 2,
286 MCOperand::createExpr(MCConstantExpr::create(-1, Context
)));
293 DecodeStatus
HexagonDisassembler::getSingleInstruction(MCInst
&MI
, MCInst
&MCB
,
294 ArrayRef
<uint8_t> Bytes
,
297 bool &Complete
) const {
298 assert(Bytes
.size() >= HEXAGON_INSTR_SIZE
);
300 uint32_t Instruction
= support::endian::read32le(Bytes
.data());
302 auto BundleSize
= HexagonMCInstrInfo::bundleSize(MCB
);
303 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
304 HexagonII::INST_PARSE_LOOP_END
) {
306 HexagonMCInstrInfo::setInnerLoop(MCB
);
307 else if (BundleSize
== 1)
308 HexagonMCInstrInfo::setOuterLoop(MCB
);
310 return DecodeStatus::Fail
;
313 CurrentExtender
= HexagonMCInstrInfo::extenderForIndex(
314 MCB
, HexagonMCInstrInfo::bundleSize(MCB
));
316 DecodeStatus Result
= DecodeStatus::Fail
;
317 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
318 HexagonII::INST_PARSE_DUPLEX
) {
319 unsigned duplexIClass
;
320 uint8_t const *DecodeLow
, *DecodeHigh
;
321 duplexIClass
= ((Instruction
>> 28) & 0xe) | ((Instruction
>> 13) & 0x1);
322 switch (duplexIClass
) {
324 return MCDisassembler::Fail
;
326 DecodeLow
= DecoderTableSUBINSN_L132
;
327 DecodeHigh
= DecoderTableSUBINSN_L132
;
330 DecodeLow
= DecoderTableSUBINSN_L232
;
331 DecodeHigh
= DecoderTableSUBINSN_L132
;
334 DecodeLow
= DecoderTableSUBINSN_L232
;
335 DecodeHigh
= DecoderTableSUBINSN_L232
;
338 DecodeLow
= DecoderTableSUBINSN_A32
;
339 DecodeHigh
= DecoderTableSUBINSN_A32
;
342 DecodeLow
= DecoderTableSUBINSN_L132
;
343 DecodeHigh
= DecoderTableSUBINSN_A32
;
346 DecodeLow
= DecoderTableSUBINSN_L232
;
347 DecodeHigh
= DecoderTableSUBINSN_A32
;
350 DecodeLow
= DecoderTableSUBINSN_S132
;
351 DecodeHigh
= DecoderTableSUBINSN_A32
;
354 DecodeLow
= DecoderTableSUBINSN_S232
;
355 DecodeHigh
= DecoderTableSUBINSN_A32
;
358 DecodeLow
= DecoderTableSUBINSN_S132
;
359 DecodeHigh
= DecoderTableSUBINSN_L132
;
362 DecodeLow
= DecoderTableSUBINSN_S132
;
363 DecodeHigh
= DecoderTableSUBINSN_L232
;
366 DecodeLow
= DecoderTableSUBINSN_S132
;
367 DecodeHigh
= DecoderTableSUBINSN_S132
;
370 DecodeLow
= DecoderTableSUBINSN_S232
;
371 DecodeHigh
= DecoderTableSUBINSN_S132
;
374 DecodeLow
= DecoderTableSUBINSN_S232
;
375 DecodeHigh
= DecoderTableSUBINSN_L132
;
378 DecodeLow
= DecoderTableSUBINSN_S232
;
379 DecodeHigh
= DecoderTableSUBINSN_L232
;
382 DecodeLow
= DecoderTableSUBINSN_S232
;
383 DecodeHigh
= DecoderTableSUBINSN_S232
;
386 MI
.setOpcode(Hexagon::DuplexIClass0
+ duplexIClass
);
387 MCInst
*MILow
= getContext().createMCInst();
388 MCInst
*MIHigh
= getContext().createMCInst();
389 auto TmpExtender
= CurrentExtender
;
391 nullptr; // constant extenders in duplex must always be in slot 1
392 Result
= decodeInstruction(DecodeLow
, *MILow
, Instruction
& 0x1fff, Address
,
394 CurrentExtender
= TmpExtender
;
395 if (Result
!= DecodeStatus::Success
)
396 return DecodeStatus::Fail
;
397 adjustDuplex(*MILow
, getContext());
398 Result
= decodeInstruction(
399 DecodeHigh
, *MIHigh
, (Instruction
>> 16) & 0x1fff, Address
, this, STI
);
400 if (Result
!= DecodeStatus::Success
)
401 return DecodeStatus::Fail
;
402 adjustDuplex(*MIHigh
, getContext());
403 MCOperand OPLow
= MCOperand::createInst(MILow
);
404 MCOperand OPHigh
= MCOperand::createInst(MIHigh
);
405 MI
.addOperand(OPLow
);
406 MI
.addOperand(OPHigh
);
409 if ((Instruction
& HexagonII::INST_PARSE_MASK
) ==
410 HexagonII::INST_PARSE_PACKET_END
)
413 if (CurrentExtender
!= nullptr)
414 Result
= decodeInstruction(DecoderTableMustExtend32
, MI
, Instruction
,
417 if (Result
!= MCDisassembler::Success
)
418 Result
= decodeInstruction(DecoderTable32
, MI
, Instruction
, Address
, this,
421 if (Result
!= MCDisassembler::Success
&&
422 STI
.getFeatureBits()[Hexagon::ExtensionHVX
])
423 Result
= decodeInstruction(DecoderTableEXT_mmvec32
, MI
, Instruction
,
428 switch (MI
.getOpcode()) {
429 case Hexagon::J4_cmpeqn1_f_jumpnv_nt
:
430 case Hexagon::J4_cmpeqn1_f_jumpnv_t
:
431 case Hexagon::J4_cmpeqn1_fp0_jump_nt
:
432 case Hexagon::J4_cmpeqn1_fp0_jump_t
:
433 case Hexagon::J4_cmpeqn1_fp1_jump_nt
:
434 case Hexagon::J4_cmpeqn1_fp1_jump_t
:
435 case Hexagon::J4_cmpeqn1_t_jumpnv_nt
:
436 case Hexagon::J4_cmpeqn1_t_jumpnv_t
:
437 case Hexagon::J4_cmpeqn1_tp0_jump_nt
:
438 case Hexagon::J4_cmpeqn1_tp0_jump_t
:
439 case Hexagon::J4_cmpeqn1_tp1_jump_nt
:
440 case Hexagon::J4_cmpeqn1_tp1_jump_t
:
441 case Hexagon::J4_cmpgtn1_f_jumpnv_nt
:
442 case Hexagon::J4_cmpgtn1_f_jumpnv_t
:
443 case Hexagon::J4_cmpgtn1_fp0_jump_nt
:
444 case Hexagon::J4_cmpgtn1_fp0_jump_t
:
445 case Hexagon::J4_cmpgtn1_fp1_jump_nt
:
446 case Hexagon::J4_cmpgtn1_fp1_jump_t
:
447 case Hexagon::J4_cmpgtn1_t_jumpnv_nt
:
448 case Hexagon::J4_cmpgtn1_t_jumpnv_t
:
449 case Hexagon::J4_cmpgtn1_tp0_jump_nt
:
450 case Hexagon::J4_cmpgtn1_tp0_jump_t
:
451 case Hexagon::J4_cmpgtn1_tp1_jump_nt
:
452 case Hexagon::J4_cmpgtn1_tp1_jump_t
:
453 MI
.insert(MI
.begin() + 1,
454 MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
460 if (HexagonMCInstrInfo::isNewValue(*MCII
, MI
)) {
461 unsigned OpIndex
= HexagonMCInstrInfo::getNewValueOp(*MCII
, MI
);
462 MCOperand
&MCO
= MI
.getOperand(OpIndex
);
463 assert(MCO
.isReg() && "New value consumers must be registers");
465 getContext().getRegisterInfo()->getEncodingValue(MCO
.getReg());
466 if ((Register
& 0x6) == 0)
467 // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
468 return MCDisassembler::Fail
;
469 unsigned Lookback
= (Register
& 0x6) >> 1;
471 bool Vector
= HexagonMCInstrInfo::isVector(*MCII
, MI
);
472 bool PrevVector
= false;
473 auto Instructions
= HexagonMCInstrInfo::bundleInstructions(**CurrentBundle
);
474 auto i
= Instructions
.end() - 1;
475 for (auto n
= Instructions
.begin() - 1;; --i
, ++Offset
) {
477 // Couldn't find producer
478 return MCDisassembler::Fail
;
479 bool CurrentVector
= HexagonMCInstrInfo::isVector(*MCII
, *i
->getInst());
480 if (Vector
&& !CurrentVector
)
481 // Skip scalars when calculating distances for vectors
483 if (HexagonMCInstrInfo::isImmext(*i
->getInst()) && (Vector
== PrevVector
))
485 PrevVector
= CurrentVector
;
486 if (Offset
== Lookback
)
489 auto const &Inst
= *i
->getInst();
490 bool SubregBit
= (Register
& 0x1) != 0;
491 if (HexagonMCInstrInfo::hasNewValue2(*MCII
, Inst
)) {
492 // If subreg bit is set we're selecting the second produced newvalue
493 unsigned Producer
= SubregBit
?
494 HexagonMCInstrInfo::getNewValueOperand(*MCII
, Inst
).getReg() :
495 HexagonMCInstrInfo::getNewValueOperand2(*MCII
, Inst
).getReg();
496 assert(Producer
!= Hexagon::NoRegister
);
497 MCO
.setReg(Producer
);
498 } else if (HexagonMCInstrInfo::hasNewValue(*MCII
, Inst
)) {
500 HexagonMCInstrInfo::getNewValueOperand(*MCII
, Inst
).getReg();
502 if (HexagonMCInstrInfo::IsVecRegPair(Producer
)) {
503 const bool Rev
= HexagonMCInstrInfo::IsReverseVecRegPair(Producer
);
504 const unsigned ProdPairIndex
=
505 Rev
? Producer
- Hexagon::WR0
: Producer
- Hexagon::W0
;
506 Producer
= (ProdPairIndex
<< 1) + SubregBit
+ Hexagon::V0
;
507 } else if (SubregBit
)
508 // Hexagon PRM 10.11 New-value operands
509 // Nt[0] is reserved and should always be encoded as zero.
510 return MCDisassembler::Fail
;
511 assert(Producer
!= Hexagon::NoRegister
);
512 MCO
.setReg(Producer
);
514 return MCDisassembler::Fail
;
517 if (CurrentExtender
!= nullptr) {
518 MCInst
const &Inst
= HexagonMCInstrInfo::isDuplex(*MCII
, MI
)
519 ? *MI
.getOperand(1).getInst()
521 if (!HexagonMCInstrInfo::isExtendable(*MCII
, Inst
) &&
522 !HexagonMCInstrInfo::isExtended(*MCII
, Inst
))
523 return MCDisassembler::Fail
;
528 static DecodeStatus
DecodeRegisterClass(MCInst
&Inst
, unsigned RegNo
,
529 ArrayRef
<MCPhysReg
> Table
) {
530 if (RegNo
< Table
.size()) {
531 Inst
.addOperand(MCOperand::createReg(Table
[RegNo
]));
532 return MCDisassembler::Success
;
535 return MCDisassembler::Fail
;
538 static DecodeStatus
DecodeIntRegsLow8RegisterClass(MCInst
&Inst
, unsigned RegNo
,
540 const void *Decoder
) {
541 return DecodeIntRegsRegisterClass(Inst
, RegNo
, Address
, Decoder
);
544 static DecodeStatus
DecodeIntRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
546 const void *Decoder
) {
547 static const MCPhysReg IntRegDecoderTable
[] = {
548 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
, Hexagon::R4
,
549 Hexagon::R5
, Hexagon::R6
, Hexagon::R7
, Hexagon::R8
, Hexagon::R9
,
550 Hexagon::R10
, Hexagon::R11
, Hexagon::R12
, Hexagon::R13
, Hexagon::R14
,
551 Hexagon::R15
, Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
552 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
, Hexagon::R24
,
553 Hexagon::R25
, Hexagon::R26
, Hexagon::R27
, Hexagon::R28
, Hexagon::R29
,
554 Hexagon::R30
, Hexagon::R31
};
556 return DecodeRegisterClass(Inst
, RegNo
, IntRegDecoderTable
);
559 static DecodeStatus
DecodeGeneralSubRegsRegisterClass(MCInst
&Inst
,
562 const void *Decoder
) {
563 static const MCPhysReg GeneralSubRegDecoderTable
[] = {
564 Hexagon::R0
, Hexagon::R1
, Hexagon::R2
, Hexagon::R3
,
565 Hexagon::R4
, Hexagon::R5
, Hexagon::R6
, Hexagon::R7
,
566 Hexagon::R16
, Hexagon::R17
, Hexagon::R18
, Hexagon::R19
,
567 Hexagon::R20
, Hexagon::R21
, Hexagon::R22
, Hexagon::R23
,
570 return DecodeRegisterClass(Inst
, RegNo
, GeneralSubRegDecoderTable
);
573 static DecodeStatus
DecodeHvxVRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
574 uint64_t /*Address*/,
575 const void *Decoder
) {
576 static const MCPhysReg HvxVRDecoderTable
[] = {
577 Hexagon::V0
, Hexagon::V1
, Hexagon::V2
, Hexagon::V3
, Hexagon::V4
,
578 Hexagon::V5
, Hexagon::V6
, Hexagon::V7
, Hexagon::V8
, Hexagon::V9
,
579 Hexagon::V10
, Hexagon::V11
, Hexagon::V12
, Hexagon::V13
, Hexagon::V14
,
580 Hexagon::V15
, Hexagon::V16
, Hexagon::V17
, Hexagon::V18
, Hexagon::V19
,
581 Hexagon::V20
, Hexagon::V21
, Hexagon::V22
, Hexagon::V23
, Hexagon::V24
,
582 Hexagon::V25
, Hexagon::V26
, Hexagon::V27
, Hexagon::V28
, Hexagon::V29
,
583 Hexagon::V30
, Hexagon::V31
};
585 return DecodeRegisterClass(Inst
, RegNo
, HvxVRDecoderTable
);
588 static DecodeStatus
DecodeDoubleRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
589 uint64_t /*Address*/,
590 const void *Decoder
) {
591 static const MCPhysReg DoubleRegDecoderTable
[] = {
592 Hexagon::D0
, Hexagon::D1
, Hexagon::D2
, Hexagon::D3
,
593 Hexagon::D4
, Hexagon::D5
, Hexagon::D6
, Hexagon::D7
,
594 Hexagon::D8
, Hexagon::D9
, Hexagon::D10
, Hexagon::D11
,
595 Hexagon::D12
, Hexagon::D13
, Hexagon::D14
, Hexagon::D15
};
597 return DecodeRegisterClass(Inst
, RegNo
>> 1, DoubleRegDecoderTable
);
600 static DecodeStatus
DecodeGeneralDoubleLow8RegsRegisterClass(
601 MCInst
&Inst
, unsigned RegNo
, uint64_t /*Address*/, const void *Decoder
) {
602 static const MCPhysReg GeneralDoubleLow8RegDecoderTable
[] = {
603 Hexagon::D0
, Hexagon::D1
, Hexagon::D2
, Hexagon::D3
,
604 Hexagon::D8
, Hexagon::D9
, Hexagon::D10
, Hexagon::D11
};
606 return DecodeRegisterClass(Inst
, RegNo
, GeneralDoubleLow8RegDecoderTable
);
609 static DecodeStatus
DecodeHvxWRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
610 uint64_t /*Address*/,
611 const void *Decoder
) {
612 static const MCPhysReg HvxWRDecoderTable
[] = {
613 Hexagon::W0
, Hexagon::WR0
, Hexagon::W1
, Hexagon::WR1
, Hexagon::W2
,
614 Hexagon::WR2
, Hexagon::W3
, Hexagon::WR3
, Hexagon::W4
, Hexagon::WR4
,
615 Hexagon::W5
, Hexagon::WR5
, Hexagon::W6
, Hexagon::WR6
, Hexagon::W7
,
616 Hexagon::WR7
, Hexagon::W8
, Hexagon::WR8
, Hexagon::W9
, Hexagon::WR9
,
617 Hexagon::W10
, Hexagon::WR10
, Hexagon::W11
, Hexagon::WR11
, Hexagon::W12
,
618 Hexagon::WR12
, Hexagon::W13
, Hexagon::WR13
, Hexagon::W14
, Hexagon::WR14
,
619 Hexagon::W15
, Hexagon::WR15
,
622 return DecodeRegisterClass(Inst
, RegNo
, HvxWRDecoderTable
);
625 LLVM_ATTRIBUTE_UNUSED
// Suppress warning temporarily.
626 static DecodeStatus
DecodeHvxVQRRegisterClass(MCInst
&Inst
,
628 uint64_t /*Address*/,
629 const void *Decoder
) {
630 static const MCPhysReg HvxVQRDecoderTable
[] = {
631 Hexagon::VQ0
, Hexagon::VQ1
, Hexagon::VQ2
, Hexagon::VQ3
,
632 Hexagon::VQ4
, Hexagon::VQ5
, Hexagon::VQ6
, Hexagon::VQ7
};
634 return DecodeRegisterClass(Inst
, RegNo
>> 2, HvxVQRDecoderTable
);
637 static DecodeStatus
DecodePredRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
638 uint64_t /*Address*/,
639 const void *Decoder
) {
640 static const MCPhysReg PredRegDecoderTable
[] = {Hexagon::P0
, Hexagon::P1
,
641 Hexagon::P2
, Hexagon::P3
};
643 return DecodeRegisterClass(Inst
, RegNo
, PredRegDecoderTable
);
646 static DecodeStatus
DecodeHvxQRRegisterClass(MCInst
&Inst
, unsigned RegNo
,
647 uint64_t /*Address*/,
648 const void *Decoder
) {
649 static const MCPhysReg HvxQRDecoderTable
[] = {Hexagon::Q0
, Hexagon::Q1
,
650 Hexagon::Q2
, Hexagon::Q3
};
652 return DecodeRegisterClass(Inst
, RegNo
, HvxQRDecoderTable
);
655 static DecodeStatus
DecodeCtrRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
656 uint64_t /*Address*/,
657 const void *Decoder
) {
658 using namespace Hexagon
;
660 static const MCPhysReg CtrlRegDecoderTable
[] = {
661 /* 0 */ SA0
, LC0
, SA1
, LC1
,
662 /* 4 */ P3_0
, C5
, M0
, M1
,
663 /* 8 */ USR
, PC
, UGP
, GP
,
664 /* 12 */ CS0
, CS1
, UPCYCLELO
, UPCYCLEHI
,
665 /* 16 */ FRAMELIMIT
, FRAMEKEY
, PKTCOUNTLO
, PKTCOUNTHI
,
668 /* 28 */ 0, 0, UTIMERLO
, UTIMERHI
671 if (RegNo
>= array_lengthof(CtrlRegDecoderTable
))
672 return MCDisassembler::Fail
;
674 static_assert(NoRegister
== 0, "Expecting NoRegister to be 0");
675 if (CtrlRegDecoderTable
[RegNo
] == NoRegister
)
676 return MCDisassembler::Fail
;
678 unsigned Register
= CtrlRegDecoderTable
[RegNo
];
679 Inst
.addOperand(MCOperand::createReg(Register
));
680 return MCDisassembler::Success
;
683 static DecodeStatus
DecodeCtrRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
684 uint64_t /*Address*/,
685 const void *Decoder
) {
686 using namespace Hexagon
;
688 static const MCPhysReg CtrlReg64DecoderTable
[] = {
689 /* 0 */ C1_0
, 0, C3_2
, 0,
690 /* 4 */ C5_4
, 0, C7_6
, 0,
691 /* 8 */ C9_8
, 0, C11_10
, 0,
692 /* 12 */ CS
, 0, UPCYCLE
, 0,
693 /* 16 */ C17_16
, 0, PKTCOUNT
, 0,
696 /* 28 */ 0, 0, UTIMER
, 0
699 if (RegNo
>= array_lengthof(CtrlReg64DecoderTable
))
700 return MCDisassembler::Fail
;
702 static_assert(NoRegister
== 0, "Expecting NoRegister to be 0");
703 if (CtrlReg64DecoderTable
[RegNo
] == NoRegister
)
704 return MCDisassembler::Fail
;
706 unsigned Register
= CtrlReg64DecoderTable
[RegNo
];
707 Inst
.addOperand(MCOperand::createReg(Register
));
708 return MCDisassembler::Success
;
711 static DecodeStatus
DecodeModRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
712 uint64_t /*Address*/,
713 const void *Decoder
) {
714 unsigned Register
= 0;
717 Register
= Hexagon::M0
;
720 Register
= Hexagon::M1
;
723 return MCDisassembler::Fail
;
725 Inst
.addOperand(MCOperand::createReg(Register
));
726 return MCDisassembler::Success
;
729 static DecodeStatus
unsignedImmDecoder(MCInst
&MI
, unsigned tmp
,
730 uint64_t /*Address*/,
731 const void *Decoder
) {
732 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
733 int64_t FullValue
= fullValue(Disassembler
, MI
, tmp
);
734 assert(FullValue
>= 0 && "Negative in unsigned decoder");
735 HexagonMCInstrInfo::addConstant(MI
, FullValue
, Disassembler
.getContext());
736 return MCDisassembler::Success
;
739 static DecodeStatus
s32_0ImmDecoder(MCInst
&MI
, unsigned tmp
,
740 uint64_t /*Address*/, const void *Decoder
) {
741 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
742 unsigned Bits
= HexagonMCInstrInfo::getExtentBits(*Disassembler
.MCII
, MI
);
743 tmp
= SignExtend64(tmp
, Bits
);
744 signedDecoder
<32>(MI
, tmp
, Decoder
);
745 return MCDisassembler::Success
;
748 // custom decoder for various jump/call immediates
749 static DecodeStatus
brtargetDecoder(MCInst
&MI
, unsigned tmp
, uint64_t Address
,
750 const void *Decoder
) {
751 HexagonDisassembler
const &Disassembler
= disassembler(Decoder
);
752 unsigned Bits
= HexagonMCInstrInfo::getExtentBits(*Disassembler
.MCII
, MI
);
753 // r13_2 is not extendable, so if there are no extent bits, it's r13_2
756 uint64_t FullValue
= fullValue(Disassembler
, MI
, SignExtend64(tmp
, Bits
));
757 uint32_t Extended
= FullValue
+ Address
;
758 if (!Disassembler
.tryAddingSymbolicOperand(MI
, Extended
, Address
, true, 0, 4))
759 HexagonMCInstrInfo::addConstant(MI
, Extended
, Disassembler
.getContext());
760 return MCDisassembler::Success
;
763 static DecodeStatus
DecodeGuestRegsRegisterClass(MCInst
&Inst
, unsigned RegNo
,
764 uint64_t /*Address*/,
765 const void *Decoder
) {
766 using namespace Hexagon
;
768 static const MCPhysReg GuestRegDecoderTable
[] = {
769 /* 0 */ GELR
, GSR
, GOSP
, G3
,
770 /* 4 */ G4
, G5
, G6
, G7
,
771 /* 8 */ G8
, G9
, G10
, G11
,
772 /* 12 */ G12
, G13
, G14
, G15
,
773 /* 16 */ GPMUCNT4
, GPMUCNT5
, GPMUCNT6
, GPMUCNT7
,
774 /* 20 */ G20
, G21
, G22
, G23
,
775 /* 24 */ GPCYCLELO
, GPCYCLEHI
, GPMUCNT0
, GPMUCNT1
,
776 /* 28 */ GPMUCNT2
, GPMUCNT3
, G30
, G31
779 if (RegNo
>= array_lengthof(GuestRegDecoderTable
))
780 return MCDisassembler::Fail
;
781 if (GuestRegDecoderTable
[RegNo
] == Hexagon::NoRegister
)
782 return MCDisassembler::Fail
;
784 unsigned Register
= GuestRegDecoderTable
[RegNo
];
785 Inst
.addOperand(MCOperand::createReg(Register
));
786 return MCDisassembler::Success
;
789 static DecodeStatus
DecodeGuestRegs64RegisterClass(MCInst
&Inst
, unsigned RegNo
,
790 uint64_t /*Address*/,
791 const void *Decoder
) {
792 using namespace Hexagon
;
794 static const MCPhysReg GuestReg64DecoderTable
[] = {
795 /* 0 */ G1_0
, 0, G3_2
, 0,
796 /* 4 */ G5_4
, 0, G7_6
, 0,
797 /* 8 */ G9_8
, 0, G11_10
, 0,
798 /* 12 */ G13_12
, 0, G15_14
, 0,
799 /* 16 */ G17_16
, 0, G19_18
, 0,
800 /* 20 */ G21_20
, 0, G23_22
, 0,
801 /* 24 */ G25_24
, 0, G27_26
, 0,
802 /* 28 */ G29_28
, 0, G31_30
, 0
805 if (RegNo
>= array_lengthof(GuestReg64DecoderTable
))
806 return MCDisassembler::Fail
;
807 if (GuestReg64DecoderTable
[RegNo
] == Hexagon::NoRegister
)
808 return MCDisassembler::Fail
;
810 unsigned Register
= GuestReg64DecoderTable
[RegNo
];
811 Inst
.addOperand(MCOperand::createReg(Register
));
812 return MCDisassembler::Success
;