10 #define DEBUG_TYPE "hexagon-disassembler" 36 using namespace Hexagon;
45 std::unique_ptr<MCInstrInfo const>
const MCII;
46 std::unique_ptr<MCInst *> CurrentBundle;
47 mutable MCInst const *CurrentExtender;
52 CurrentExtender(
nullptr) {}
57 bool &Complete)
const;
65 static uint64_t fullValue(HexagonDisassembler
const &Disassembler,
MCInst &
MI,
68 if (!Disassembler.CurrentExtender ||
75 Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute(
79 uint64_t Upper26 =
static_cast<uint64_t
>(
Bits);
80 uint64_t Operand = Upper26 | Lower6;
83 static HexagonDisassembler
const &disassembler(
void const *Decoder) {
84 return *
static_cast<HexagonDisassembler
const *
>(Decoder);
87 static void signedDecoder(
MCInst &MI,
unsigned tmp,
const void *Decoder) {
88 HexagonDisassembler
const &Disassembler = disassembler(Decoder);
89 int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp));
90 int64_t Extended = SignExtend64<32>(FullValue);
100 const void *Decoder);
104 const void *Decoder);
107 const void *Decoder);
110 const void *Decoder);
113 const void *Decoder);
116 uint64_t
Address,
const void *Decoder);
119 const void *Decoder);
123 const void *Decoder);
126 const void *Decoder);
129 const void *Decoder);
132 const void *Decoder);
135 const void *Decoder);
138 const void *Decoder);
141 const void *Decoder);
144 const void *Decoder);
147 uint64_t
Address,
const void *Decoder);
149 uint64_t ,
const void *Decoder);
151 const void *Decoder);
153 #include "HexagonGenDisassemblerTables.inc" 172 bool Complete =
false;
175 *CurrentBundle = &
MI;
178 while (Result ==
Success && !Complete) {
182 Result = getSingleInstruction(*Inst, MI, Bytes,
Address, os, cs, Complete);
192 *getContext().getRegisterInfo(),
false);
193 if (!Checker.
check())
201 auto &MI =
const_cast<MCInst &
>(*
I.getInst());
203 case Hexagon::S2_allocframe:
205 MI.
setOpcode(Hexagon::S6_allocframe_to_raw);
210 case Hexagon::L2_deallocframe:
213 MI.
setOpcode(L6_deallocframe_map_to_raw);
218 case Hexagon::L4_return:
226 case Hexagon::L4_return_t:
234 case Hexagon::L4_return_f:
242 case Hexagon::L4_return_tnew_pt:
245 MI.
setOpcode(L4_return_map_to_raw_tnew_pt);
250 case Hexagon::L4_return_fnew_pt:
253 MI.
setOpcode(L4_return_map_to_raw_fnew_pt);
258 case Hexagon::L4_return_tnew_pnt:
261 MI.
setOpcode(L4_return_map_to_raw_tnew_pnt);
266 case Hexagon::L4_return_fnew_pnt:
269 MI.
setOpcode(L4_return_map_to_raw_fnew_pnt);
280 case Hexagon::SA1_setin1:
284 case Hexagon::SA1_dec:
305 else if (BundleSize == 1)
315 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
317 unsigned duplexIClass;
318 uint8_t
const *DecodeLow, *DecodeHigh;
319 duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
320 switch (duplexIClass) {
324 DecodeLow = DecoderTableSUBINSN_L132;
325 DecodeHigh = DecoderTableSUBINSN_L132;
328 DecodeLow = DecoderTableSUBINSN_L232;
329 DecodeHigh = DecoderTableSUBINSN_L132;
332 DecodeLow = DecoderTableSUBINSN_L232;
333 DecodeHigh = DecoderTableSUBINSN_L232;
336 DecodeLow = DecoderTableSUBINSN_A32;
337 DecodeHigh = DecoderTableSUBINSN_A32;
340 DecodeLow = DecoderTableSUBINSN_L132;
341 DecodeHigh = DecoderTableSUBINSN_A32;
344 DecodeLow = DecoderTableSUBINSN_L232;
345 DecodeHigh = DecoderTableSUBINSN_A32;
348 DecodeLow = DecoderTableSUBINSN_S132;
349 DecodeHigh = DecoderTableSUBINSN_A32;
352 DecodeLow = DecoderTableSUBINSN_S232;
353 DecodeHigh = DecoderTableSUBINSN_A32;
356 DecodeLow = DecoderTableSUBINSN_S132;
357 DecodeHigh = DecoderTableSUBINSN_L132;
360 DecodeLow = DecoderTableSUBINSN_S132;
361 DecodeHigh = DecoderTableSUBINSN_L232;
364 DecodeLow = DecoderTableSUBINSN_S132;
365 DecodeHigh = DecoderTableSUBINSN_S132;
368 DecodeLow = DecoderTableSUBINSN_S232;
369 DecodeHigh = DecoderTableSUBINSN_S132;
372 DecodeLow = DecoderTableSUBINSN_S232;
373 DecodeHigh = DecoderTableSUBINSN_L132;
376 DecodeLow = DecoderTableSUBINSN_S232;
377 DecodeHigh = DecoderTableSUBINSN_L232;
380 DecodeLow = DecoderTableSUBINSN_S232;
381 DecodeHigh = DecoderTableSUBINSN_S232;
384 MI.
setOpcode(Hexagon::DuplexIClass0 + duplexIClass);
387 auto TmpExtender = CurrentExtender;
392 CurrentExtender = TmpExtender;
397 DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff,
Address,
this, STI);
407 if ((Instruction & HexagonII::INST_PARSE_MASK) ==
411 if (CurrentExtender !=
nullptr)
420 STI.getFeatureBits()[Hexagon::ExtensionHVX])
427 case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
428 case Hexagon::J4_cmpeqn1_f_jumpnv_t:
429 case Hexagon::J4_cmpeqn1_fp0_jump_nt:
430 case Hexagon::J4_cmpeqn1_fp0_jump_t:
431 case Hexagon::J4_cmpeqn1_fp1_jump_nt:
432 case Hexagon::J4_cmpeqn1_fp1_jump_t:
433 case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
434 case Hexagon::J4_cmpeqn1_t_jumpnv_t:
435 case Hexagon::J4_cmpeqn1_tp0_jump_nt:
436 case Hexagon::J4_cmpeqn1_tp0_jump_t:
437 case Hexagon::J4_cmpeqn1_tp1_jump_nt:
438 case Hexagon::J4_cmpeqn1_tp1_jump_t:
439 case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
440 case Hexagon::J4_cmpgtn1_f_jumpnv_t:
441 case Hexagon::J4_cmpgtn1_fp0_jump_nt:
442 case Hexagon::J4_cmpgtn1_fp0_jump_t:
443 case Hexagon::J4_cmpgtn1_fp1_jump_nt:
444 case Hexagon::J4_cmpgtn1_fp1_jump_t:
445 case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
446 case Hexagon::J4_cmpgtn1_t_jumpnv_t:
447 case Hexagon::J4_cmpgtn1_tp0_jump_nt:
448 case Hexagon::J4_cmpgtn1_tp0_jump_t:
449 case Hexagon::J4_cmpgtn1_tp1_jump_nt:
450 case Hexagon::J4_cmpgtn1_tp1_jump_t:
461 assert(MCO.
isReg() &&
"New value consumers must be registers");
463 getContext().getRegisterInfo()->getEncodingValue(MCO.
getReg());
464 if ((Register & 0x6) == 0)
467 unsigned Lookback = (Register & 0x6) >> 1;
470 bool PrevVector =
false;
472 auto i = Instructions.end() - 1;
473 for (
auto n = Instructions.begin() - 1;; --i, ++
Offset) {
478 if (Vector && !CurrentVector)
483 PrevVector = CurrentVector;
484 if (Offset == Lookback)
487 auto const &Inst = *i->getInst();
488 bool SubregBit = (Register & 0x1) != 0;
491 unsigned Producer = SubregBit ?
494 assert(Producer != Hexagon::NoRegister);
499 if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
500 Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0;
505 assert(Producer != Hexagon::NoRegister);
511 if (CurrentExtender !=
nullptr) {
524 if (RegNo < Table.
size()) {
534 const void *Decoder) {
540 const void *Decoder) {
543 Hexagon::R5,
Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9,
544 Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
545 Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
546 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
547 Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
548 Hexagon::R30, Hexagon::R31};
556 const void *Decoder) {
557 static const MCPhysReg GeneralSubRegDecoderTable[] = {
558 Hexagon::R0, Hexagon::R1,
Hexagon::R2, Hexagon::R3,
560 Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
561 Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
569 const void *Decoder) {
570 static const MCPhysReg HvxVRDecoderTable[] = {
572 Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9,
573 Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
574 Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
575 Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
576 Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
577 Hexagon::V30, Hexagon::V31};
584 const void *Decoder) {
585 static const MCPhysReg DoubleRegDecoderTable[] = {
586 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
587 Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7,
588 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11,
589 Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
595 MCInst &Inst,
unsigned RegNo, uint64_t ,
const void *Decoder) {
596 static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = {
597 Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3,
598 Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11};
605 const void *Decoder) {
606 static const MCPhysReg HvxWRDecoderTable[] = {
607 Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3,
608 Hexagon::W4, Hexagon::W5, Hexagon::W6, Hexagon::W7,
609 Hexagon::W8, Hexagon::W9, Hexagon::W10, Hexagon::W11,
610 Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
619 const void *Decoder) {
620 static const MCPhysReg HvxVQRDecoderTable[] = {
621 Hexagon::VQ0, Hexagon::VQ1, Hexagon::VQ2, Hexagon::VQ3,
622 Hexagon::VQ4, Hexagon::VQ5, Hexagon::VQ6, Hexagon::VQ7};
629 const void *Decoder) {
630 static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
631 Hexagon::P2, Hexagon::P3};
638 const void *Decoder) {
639 static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
640 Hexagon::Q2, Hexagon::Q3};
647 const void *Decoder) {
648 using namespace Hexagon;
650 static const MCPhysReg CtrlRegDecoderTable[] = {
654 CS0, CS1, UPCYCLELO, UPCYCLEHI,
655 FRAMELIMIT, FRAMEKEY, PKTCOUNTLO, PKTCOUNTHI,
658 0, 0, UTIMERLO, UTIMERHI
664 static_assert(NoRegister == 0,
"Expecting NoRegister to be 0");
665 if (CtrlRegDecoderTable[RegNo] == NoRegister)
668 unsigned Register = CtrlRegDecoderTable[RegNo];
675 const void *Decoder) {
676 using namespace Hexagon;
678 static const MCPhysReg CtrlReg64DecoderTable[] = {
683 C17_16, 0, PKTCOUNT, 0,
692 static_assert(NoRegister == 0,
"Expecting NoRegister to be 0");
693 if (CtrlReg64DecoderTable[RegNo] == NoRegister)
696 unsigned Register = CtrlReg64DecoderTable[RegNo];
703 const void *Decoder) {
707 Register = Hexagon::M0;
710 Register = Hexagon::M1;
721 const void *Decoder) {
722 HexagonDisassembler
const &Disassembler = disassembler(Decoder);
723 int64_t FullValue = fullValue(Disassembler, MI, tmp);
724 assert(FullValue >= 0 &&
"Negative in unsigned decoder");
730 uint64_t ,
const void *Decoder) {
731 HexagonDisassembler
const &Disassembler = disassembler(Decoder);
734 signedDecoder<32>(
MI, tmp, Decoder);
740 const void *Decoder) {
741 HexagonDisassembler
const &Disassembler = disassembler(Decoder);
746 uint64_t FullValue = fullValue(Disassembler, MI,
SignExtend64(tmp, Bits));
747 uint32_t Extended = FullValue + Address;
748 if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address,
true, 0, 4))
755 const void *Decoder) {
756 using namespace Hexagon;
758 static const MCPhysReg GuestRegDecoderTable[] = {
763 GPMUCNT4, GPMUCNT5, GPMUCNT6, GPMUCNT7,
765 GPCYCLELO, GPCYCLEHI, GPMUCNT0, GPMUCNT1,
766 GPMUCNT2, GPMUCNT3, G30, G31
771 if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister)
774 unsigned Register = GuestRegDecoderTable[RegNo];
781 const void *Decoder) {
782 using namespace Hexagon;
784 static const MCPhysReg GuestReg64DecoderTable[] = {
788 G13_12, 0, G15_14, 0,
789 G17_16, 0, G19_18, 0,
790 G21_20, 0, G23_22, 0,
791 G25_24, 0, G27_26, 0,
797 if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister)
800 unsigned Register = GuestReg64DecoderTable[RegNo];
static MCDisassembler * createHexagonDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
bool isDuplex(MCInstrInfo const &MCII, MCInst const &MCI)
unsigned short getNewValueOp(MCInstrInfo const &MCII, MCInst const &MCI)
This class represents lattice values for constants.
static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t, const void *Decoder)
DecodeStatus
Ternary decode status.
static MCOperand createExpr(const MCExpr *Val)
Superclass for all disassemblers.
static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
MCOperand const & getNewValueOperand(MCInstrInfo const &MCII, MCInst const &MCI)
#define HEXAGON_INSTR_SIZE
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
bool isNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn expects newly produced value.
void setInnerLoop(MCInst &MCI)
bool isImmext(MCInst const &MCI)
static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static MCOperand createReg(unsigned Reg)
static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
iterator_range< Hexagon::PacketIterator > bundleInstructions(MCInstrInfo const &MCII, MCInst const &MCI)
MCInst const * extenderForIndex(MCInst const &MCB, size_t Index)
unsigned getReg() const
Returns the register number.
Context object for machine code objects.
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
const MCInst * getInst() const
bool hasNewValue2(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a second value.
iterator insert(iterator I, const MCOperand &Op)
Instances of this class represent a single low-level machine instruction.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void remapInstruction(Instruction *I, ValueToValueMapTy &VMap)
Convert the instruction operands from referencing the current values into those specified by VMap...
static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
size_t size() const
size - Get the array size.
#define HEXAGON_MAX_PACKET_SIZE
MCOperand const & getNewValueOperand2(MCInstrInfo const &MCII, MCInst const &MCI)
Interface to description of machine instruction set.
void setOuterLoop(MCInst &MCI)
static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, ArrayRef< MCPhysReg > Table)
static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
void LLVMInitializeHexagonDisassembler()
unsigned short getExtendableOp(MCInstrInfo const &MCII, MCInst const &MCI)
static DecodeStatus DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static const unsigned IntRegDecoderTable[]
void setOpcode(unsigned Op)
bool isExtendable(MCInstrInfo const &MCII, MCInst const &MCI)
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
const MCOperand & getOperand(unsigned i) const
constexpr size_t array_lengthof(T(&)[N])
Find the length of an array.
static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Promote Memory to Register
static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static void adjustDuplex(MCInst &MI, MCContext &Context)
Target - Wrapper for Target specific information.
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array...
bool isExtended(MCInstrInfo const &MCII, MCInst const &MCI)
static MCOperand createInst(const MCInst *Val)
static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
uint32_t read32le(const void *P)
Generic base class for all target subtargets.
size_t bundleSize(MCInst const &MCI)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
bool check(bool FullCheck=true)
void setReg(unsigned Reg)
Set the register number.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
bool hasNewValue(MCInstrInfo const &MCII, MCInst const &MCI)
Return whether the insn produces a value.
#define LLVM_ATTRIBUTE_UNUSED
unsigned getOpcode() const
static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
unsigned getExtentAlignment(MCInstrInfo const &MCII, MCInst const &MCI)
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Target & getTheHexagonTarget()
void addConstant(MCInst &MI, uint64_t Value, MCContext &Context)
unsigned getExtentBits(MCInstrInfo const &MCII, MCInst const &MCI)