xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
10b57cec5SDimitry Andric //===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/HexagonBaseInfo.h"
100b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCChecker.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCInstrInfo.h"
120b57cec5SDimitry Andric #include "MCTargetDesc/HexagonMCTargetDesc.h"
130b57cec5SDimitry Andric #include "TargetInfo/HexagonTargetInfo.h"
140b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
150b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
1781ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
24349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
250b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
260b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
280b57cec5SDimitry Andric #include <cassert>
290b57cec5SDimitry Andric #include <cstddef>
300b57cec5SDimitry Andric #include <cstdint>
310b57cec5SDimitry Andric #include <memory>
320b57cec5SDimitry Andric 
33fe6060f1SDimitry Andric #define DEBUG_TYPE "hexagon-disassembler"
34fe6060f1SDimitry Andric 
350b57cec5SDimitry Andric using namespace llvm;
360b57cec5SDimitry Andric using namespace Hexagon;
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric using DecodeStatus = MCDisassembler::DecodeStatus;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric namespace {
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric /// Hexagon disassembler for all Hexagon platforms.
430b57cec5SDimitry Andric class HexagonDisassembler : public MCDisassembler {
440b57cec5SDimitry Andric public:
450b57cec5SDimitry Andric   std::unique_ptr<MCInstrInfo const> const MCII;
460b57cec5SDimitry Andric   std::unique_ptr<MCInst *> CurrentBundle;
470b57cec5SDimitry Andric   mutable MCInst const *CurrentExtender;
480b57cec5SDimitry Andric 
HexagonDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)490b57cec5SDimitry Andric   HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
500b57cec5SDimitry Andric                       MCInstrInfo const *MCII)
510b57cec5SDimitry Andric       : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *),
520b57cec5SDimitry Andric         CurrentExtender(nullptr) {}
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
550b57cec5SDimitry Andric                                     ArrayRef<uint8_t> Bytes, uint64_t Address,
56480093f4SDimitry Andric                                     raw_ostream &CStream, bool &Complete) const;
570b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
580b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
590b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
600b57cec5SDimitry Andric   void remapInstruction(MCInst &Instr) const;
610b57cec5SDimitry Andric };
620b57cec5SDimitry Andric 
fullValue(HexagonDisassembler const & Disassembler,MCInst & MI,int64_t Value)630b57cec5SDimitry Andric static uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI,
640b57cec5SDimitry Andric                           int64_t Value) {
650b57cec5SDimitry Andric   MCInstrInfo MCII = *Disassembler.MCII;
660b57cec5SDimitry Andric   if (!Disassembler.CurrentExtender ||
670b57cec5SDimitry Andric       MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
680b57cec5SDimitry Andric     return Value;
690b57cec5SDimitry Andric   unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
700b57cec5SDimitry Andric   uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
710b57cec5SDimitry Andric   int64_t Bits;
720b57cec5SDimitry Andric   bool Success =
730b57cec5SDimitry Andric       Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute(
740b57cec5SDimitry Andric           Bits);
750b57cec5SDimitry Andric   assert(Success);
760b57cec5SDimitry Andric   (void)Success;
770b57cec5SDimitry Andric   uint64_t Upper26 = static_cast<uint64_t>(Bits);
780b57cec5SDimitry Andric   uint64_t Operand = Upper26 | Lower6;
790b57cec5SDimitry Andric   return Operand;
800b57cec5SDimitry Andric }
disassembler(const MCDisassembler * Decoder)8181ad6265SDimitry Andric static HexagonDisassembler const &disassembler(const MCDisassembler *Decoder) {
820b57cec5SDimitry Andric   return *static_cast<HexagonDisassembler const *>(Decoder);
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric template <size_t T>
signedDecoder(MCInst & MI,unsigned tmp,const MCDisassembler * Decoder)8581ad6265SDimitry Andric static void signedDecoder(MCInst &MI, unsigned tmp,
8681ad6265SDimitry Andric                           const MCDisassembler *Decoder) {
870b57cec5SDimitry Andric   HexagonDisassembler const &Disassembler = disassembler(Decoder);
880b57cec5SDimitry Andric   int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp));
890b57cec5SDimitry Andric   int64_t Extended = SignExtend64<32>(FullValue);
900b57cec5SDimitry Andric   HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric // Forward declare these because the auto-generated code will reference them.
950b57cec5SDimitry Andric // Definitions are further down.
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
980b57cec5SDimitry Andric                                                uint64_t Address,
9981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
10081ad6265SDimitry Andric static DecodeStatus
10181ad6265SDimitry Andric DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1020b57cec5SDimitry Andric                                   uint64_t Address,
10381ad6265SDimitry Andric                                   const MCDisassembler *Decoder);
10481ad6265SDimitry Andric static DecodeStatus
10581ad6265SDimitry Andric DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
10681ad6265SDimitry Andric                                const MCDisassembler *Decoder);
1070b57cec5SDimitry Andric static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
1080b57cec5SDimitry Andric                                              uint64_t Address,
10981ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
11081ad6265SDimitry Andric static DecodeStatus
11181ad6265SDimitry Andric DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
11281ad6265SDimitry Andric                               const MCDisassembler *Decoder);
1130b57cec5SDimitry Andric static DecodeStatus
1140b57cec5SDimitry Andric DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
11581ad6265SDimitry Andric                                          uint64_t Address,
11681ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
1170b57cec5SDimitry Andric static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
1180b57cec5SDimitry Andric                                              uint64_t Address,
11981ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
12081ad6265SDimitry Andric static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo,
1210b57cec5SDimitry Andric                                               uint64_t Address,
12281ad6265SDimitry Andric                                               const MCDisassembler *Decoder);
1230b57cec5SDimitry Andric static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1240b57cec5SDimitry Andric                                                 uint64_t Address,
12581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder);
1260b57cec5SDimitry Andric static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
1270b57cec5SDimitry Andric                                              uint64_t Address,
12881ad6265SDimitry Andric                                              const MCDisassembler *Decoder);
1290b57cec5SDimitry Andric static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1300b57cec5SDimitry Andric                                                uint64_t Address,
13181ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1320b57cec5SDimitry Andric static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1330b57cec5SDimitry Andric                                                  uint64_t Address,
13481ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
135349cc55cSDimitry Andric static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo,
136349cc55cSDimitry Andric                                                uint64_t Address,
13781ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1380b57cec5SDimitry Andric static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
1390b57cec5SDimitry Andric                                                uint64_t Address,
14081ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
1410b57cec5SDimitry Andric static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
1420b57cec5SDimitry Andric                                                  uint64_t Address,
14381ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
14481ad6265SDimitry Andric static DecodeStatus
14581ad6265SDimitry Andric DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
14681ad6265SDimitry Andric                                const MCDisassembler *Decoder);
147349cc55cSDimitry Andric static DecodeStatus DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
148349cc55cSDimitry Andric                                                  uint64_t Address,
14981ad6265SDimitry Andric                                                  const MCDisassembler *Decoder);
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
15281ad6265SDimitry Andric                                        uint64_t Address,
15381ad6265SDimitry Andric                                        const MCDisassembler *Decoder);
1540b57cec5SDimitry Andric static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
15581ad6265SDimitry Andric                                     uint64_t /*Address*/,
15681ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
1570b57cec5SDimitry Andric static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
15881ad6265SDimitry Andric                                     const MCDisassembler *Decoder);
1590b57cec5SDimitry Andric #include "HexagonDepDecoders.inc"
1600b57cec5SDimitry Andric #include "HexagonGenDisassemblerTables.inc"
1610b57cec5SDimitry Andric 
createHexagonDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)1620b57cec5SDimitry Andric static MCDisassembler *createHexagonDisassembler(const Target &T,
1630b57cec5SDimitry Andric                                                  const MCSubtargetInfo &STI,
1640b57cec5SDimitry Andric                                                  MCContext &Ctx) {
1650b57cec5SDimitry Andric   return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
1660b57cec5SDimitry Andric }
1670b57cec5SDimitry Andric 
LLVMInitializeHexagonDisassembler()168480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonDisassembler() {
1690b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
1700b57cec5SDimitry Andric                                          createHexagonDisassembler);
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & cs) const1730b57cec5SDimitry Andric DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
1740b57cec5SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
1750b57cec5SDimitry Andric                                                  uint64_t Address,
1760b57cec5SDimitry Andric                                                  raw_ostream &cs) const {
1770b57cec5SDimitry Andric   DecodeStatus Result = DecodeStatus::Success;
1780b57cec5SDimitry Andric   bool Complete = false;
1790b57cec5SDimitry Andric   Size = 0;
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   *CurrentBundle = &MI;
1820b57cec5SDimitry Andric   MI.setOpcode(Hexagon::BUNDLE);
1830b57cec5SDimitry Andric   MI.addOperand(MCOperand::createImm(0));
1840b57cec5SDimitry Andric   while (Result == Success && !Complete) {
1850b57cec5SDimitry Andric     if (Bytes.size() < HEXAGON_INSTR_SIZE)
1860b57cec5SDimitry Andric       return MCDisassembler::Fail;
187e8d8bef9SDimitry Andric     MCInst *Inst = getContext().createMCInst();
188480093f4SDimitry Andric     Result = getSingleInstruction(*Inst, MI, Bytes, Address, cs, Complete);
1890b57cec5SDimitry Andric     MI.addOperand(MCOperand::createInst(Inst));
1900b57cec5SDimitry Andric     Size += HEXAGON_INSTR_SIZE;
1910b57cec5SDimitry Andric     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
1920b57cec5SDimitry Andric   }
1930b57cec5SDimitry Andric   if (Result == MCDisassembler::Fail)
1940b57cec5SDimitry Andric     return Result;
1950b57cec5SDimitry Andric   if (Size > HEXAGON_MAX_PACKET_SIZE)
1960b57cec5SDimitry Andric     return MCDisassembler::Fail;
1975ffd83dbSDimitry Andric 
1985ffd83dbSDimitry Andric   const auto ArchSTI = Hexagon_MC::getArchSubtarget(&STI);
1995ffd83dbSDimitry Andric   const auto STI_ = (ArchSTI != nullptr) ? *ArchSTI : STI;
2005ffd83dbSDimitry Andric   HexagonMCChecker Checker(getContext(), *MCII, STI_, MI,
2010b57cec5SDimitry Andric                            *getContext().getRegisterInfo(), false);
2020b57cec5SDimitry Andric   if (!Checker.check())
2030b57cec5SDimitry Andric     return MCDisassembler::Fail;
2040b57cec5SDimitry Andric   remapInstruction(MI);
2050b57cec5SDimitry Andric   return MCDisassembler::Success;
2060b57cec5SDimitry Andric }
2070b57cec5SDimitry Andric 
remapInstruction(MCInst & Instr) const2080b57cec5SDimitry Andric void HexagonDisassembler::remapInstruction(MCInst &Instr) const {
2090b57cec5SDimitry Andric   for (auto I: HexagonMCInstrInfo::bundleInstructions(Instr)) {
2100b57cec5SDimitry Andric     auto &MI = const_cast<MCInst &>(*I.getInst());
2110b57cec5SDimitry Andric     switch (MI.getOpcode()) {
2120b57cec5SDimitry Andric     case Hexagon::S2_allocframe:
2130b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::R29) {
2140b57cec5SDimitry Andric         MI.setOpcode(Hexagon::S6_allocframe_to_raw);
2150b57cec5SDimitry Andric         MI.erase(MI.begin () + 1);
2160b57cec5SDimitry Andric         MI.erase(MI.begin ());
2170b57cec5SDimitry Andric       }
2180b57cec5SDimitry Andric       break;
2190b57cec5SDimitry Andric     case Hexagon::L2_deallocframe:
2200b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2210b57cec5SDimitry Andric           MI.getOperand(1).getReg() == Hexagon::R30) {
2220b57cec5SDimitry Andric         MI.setOpcode(L6_deallocframe_map_to_raw);
2230b57cec5SDimitry Andric         MI.erase(MI.begin () + 1);
2240b57cec5SDimitry Andric         MI.erase(MI.begin ());
2250b57cec5SDimitry Andric       }
2260b57cec5SDimitry Andric       break;
2270b57cec5SDimitry Andric     case Hexagon::L4_return:
2280b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2290b57cec5SDimitry Andric           MI.getOperand(1).getReg() == Hexagon::R30) {
2300b57cec5SDimitry Andric         MI.setOpcode(L6_return_map_to_raw);
2310b57cec5SDimitry Andric         MI.erase(MI.begin () + 1);
2320b57cec5SDimitry Andric         MI.erase(MI.begin ());
2330b57cec5SDimitry Andric       }
2340b57cec5SDimitry Andric       break;
2350b57cec5SDimitry Andric     case Hexagon::L4_return_t:
2360b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2370b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2380b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_t);
2390b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2400b57cec5SDimitry Andric         MI.erase(MI.begin ());
2410b57cec5SDimitry Andric       }
2420b57cec5SDimitry Andric       break;
2430b57cec5SDimitry Andric     case Hexagon::L4_return_f:
2440b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2450b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2460b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_f);
2470b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2480b57cec5SDimitry Andric         MI.erase(MI.begin ());
2490b57cec5SDimitry Andric       }
2500b57cec5SDimitry Andric       break;
2510b57cec5SDimitry Andric     case Hexagon::L4_return_tnew_pt:
2520b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2530b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2540b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_tnew_pt);
2550b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2560b57cec5SDimitry Andric         MI.erase(MI.begin ());
2570b57cec5SDimitry Andric       }
2580b57cec5SDimitry Andric       break;
2590b57cec5SDimitry Andric     case Hexagon::L4_return_fnew_pt:
2600b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2610b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2620b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_fnew_pt);
2630b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2640b57cec5SDimitry Andric         MI.erase(MI.begin ());
2650b57cec5SDimitry Andric       }
2660b57cec5SDimitry Andric       break;
2670b57cec5SDimitry Andric     case Hexagon::L4_return_tnew_pnt:
2680b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2690b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2700b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_tnew_pnt);
2710b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2720b57cec5SDimitry Andric         MI.erase(MI.begin ());
2730b57cec5SDimitry Andric       }
2740b57cec5SDimitry Andric       break;
2750b57cec5SDimitry Andric     case Hexagon::L4_return_fnew_pnt:
2760b57cec5SDimitry Andric       if (MI.getOperand(0).getReg() == Hexagon::D15 &&
2770b57cec5SDimitry Andric           MI.getOperand(2).getReg() == Hexagon::R30) {
2780b57cec5SDimitry Andric         MI.setOpcode(L4_return_map_to_raw_fnew_pnt);
2790b57cec5SDimitry Andric         MI.erase(MI.begin () + 2);
2800b57cec5SDimitry Andric         MI.erase(MI.begin ());
2810b57cec5SDimitry Andric       }
2820b57cec5SDimitry Andric       break;
2830b57cec5SDimitry Andric     }
2840b57cec5SDimitry Andric   }
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric 
adjustDuplex(MCInst & MI,MCContext & Context)2870b57cec5SDimitry Andric static void adjustDuplex(MCInst &MI, MCContext &Context) {
2880b57cec5SDimitry Andric   switch (MI.getOpcode()) {
2890b57cec5SDimitry Andric   case Hexagon::SA1_setin1:
2900b57cec5SDimitry Andric     MI.insert(MI.begin() + 1,
2910b57cec5SDimitry Andric               MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
2920b57cec5SDimitry Andric     break;
2930b57cec5SDimitry Andric   case Hexagon::SA1_dec:
2940b57cec5SDimitry Andric     MI.insert(MI.begin() + 2,
2950b57cec5SDimitry Andric               MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
2960b57cec5SDimitry Andric     break;
2970b57cec5SDimitry Andric   default:
2980b57cec5SDimitry Andric     break;
2990b57cec5SDimitry Andric   }
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric 
getSingleInstruction(MCInst & MI,MCInst & MCB,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & cs,bool & Complete) const302480093f4SDimitry Andric DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
303480093f4SDimitry Andric                                                        ArrayRef<uint8_t> Bytes,
304480093f4SDimitry Andric                                                        uint64_t Address,
305480093f4SDimitry Andric                                                        raw_ostream &cs,
306480093f4SDimitry Andric                                                        bool &Complete) const {
3070b57cec5SDimitry Andric   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   uint32_t Instruction = support::endian::read32le(Bytes.data());
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
3120b57cec5SDimitry Andric   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
3130b57cec5SDimitry Andric       HexagonII::INST_PARSE_LOOP_END) {
3140b57cec5SDimitry Andric     if (BundleSize == 0)
3150b57cec5SDimitry Andric       HexagonMCInstrInfo::setInnerLoop(MCB);
3160b57cec5SDimitry Andric     else if (BundleSize == 1)
3170b57cec5SDimitry Andric       HexagonMCInstrInfo::setOuterLoop(MCB);
3180b57cec5SDimitry Andric     else
3190b57cec5SDimitry Andric       return DecodeStatus::Fail;
3200b57cec5SDimitry Andric   }
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   CurrentExtender = HexagonMCInstrInfo::extenderForIndex(
3230b57cec5SDimitry Andric       MCB, HexagonMCInstrInfo::bundleSize(MCB));
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   DecodeStatus Result = DecodeStatus::Fail;
3260b57cec5SDimitry Andric   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
3270b57cec5SDimitry Andric       HexagonII::INST_PARSE_DUPLEX) {
3280b57cec5SDimitry Andric     unsigned duplexIClass;
3290b57cec5SDimitry Andric     uint8_t const *DecodeLow, *DecodeHigh;
3300b57cec5SDimitry Andric     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
3310b57cec5SDimitry Andric     switch (duplexIClass) {
3320b57cec5SDimitry Andric     default:
3330b57cec5SDimitry Andric       return MCDisassembler::Fail;
3340b57cec5SDimitry Andric     case 0:
3350b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_L132;
3360b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L132;
3370b57cec5SDimitry Andric       break;
3380b57cec5SDimitry Andric     case 1:
3390b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_L232;
3400b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L132;
3410b57cec5SDimitry Andric       break;
3420b57cec5SDimitry Andric     case 2:
3430b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_L232;
3440b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L232;
3450b57cec5SDimitry Andric       break;
3460b57cec5SDimitry Andric     case 3:
3470b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_A32;
3480b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_A32;
3490b57cec5SDimitry Andric       break;
3500b57cec5SDimitry Andric     case 4:
3510b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_L132;
3520b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_A32;
3530b57cec5SDimitry Andric       break;
3540b57cec5SDimitry Andric     case 5:
3550b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_L232;
3560b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_A32;
3570b57cec5SDimitry Andric       break;
3580b57cec5SDimitry Andric     case 6:
3590b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S132;
3600b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_A32;
3610b57cec5SDimitry Andric       break;
3620b57cec5SDimitry Andric     case 7:
3630b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S232;
3640b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_A32;
3650b57cec5SDimitry Andric       break;
3660b57cec5SDimitry Andric     case 8:
3670b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S132;
3680b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L132;
3690b57cec5SDimitry Andric       break;
3700b57cec5SDimitry Andric     case 9:
3710b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S132;
3720b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L232;
3730b57cec5SDimitry Andric       break;
3740b57cec5SDimitry Andric     case 10:
3750b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S132;
3760b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_S132;
3770b57cec5SDimitry Andric       break;
3780b57cec5SDimitry Andric     case 11:
3790b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S232;
3800b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_S132;
3810b57cec5SDimitry Andric       break;
3820b57cec5SDimitry Andric     case 12:
3830b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S232;
3840b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L132;
3850b57cec5SDimitry Andric       break;
3860b57cec5SDimitry Andric     case 13:
3870b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S232;
3880b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_L232;
3890b57cec5SDimitry Andric       break;
3900b57cec5SDimitry Andric     case 14:
3910b57cec5SDimitry Andric       DecodeLow = DecoderTableSUBINSN_S232;
3920b57cec5SDimitry Andric       DecodeHigh = DecoderTableSUBINSN_S232;
3930b57cec5SDimitry Andric       break;
3940b57cec5SDimitry Andric     }
3950b57cec5SDimitry Andric     MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass);
396e8d8bef9SDimitry Andric     MCInst *MILow = getContext().createMCInst();
397e8d8bef9SDimitry Andric     MCInst *MIHigh = getContext().createMCInst();
3980b57cec5SDimitry Andric     auto TmpExtender = CurrentExtender;
3990b57cec5SDimitry Andric     CurrentExtender =
4000b57cec5SDimitry Andric         nullptr; // constant extenders in duplex must always be in slot 1
4010b57cec5SDimitry Andric     Result = decodeInstruction(DecodeLow, *MILow, Instruction & 0x1fff, Address,
4020b57cec5SDimitry Andric                                this, STI);
4030b57cec5SDimitry Andric     CurrentExtender = TmpExtender;
4040b57cec5SDimitry Andric     if (Result != DecodeStatus::Success)
4050b57cec5SDimitry Andric       return DecodeStatus::Fail;
4060b57cec5SDimitry Andric     adjustDuplex(*MILow, getContext());
4070b57cec5SDimitry Andric     Result = decodeInstruction(
4080b57cec5SDimitry Andric         DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff, Address, this, STI);
4090b57cec5SDimitry Andric     if (Result != DecodeStatus::Success)
4100b57cec5SDimitry Andric       return DecodeStatus::Fail;
4110b57cec5SDimitry Andric     adjustDuplex(*MIHigh, getContext());
4120b57cec5SDimitry Andric     MCOperand OPLow = MCOperand::createInst(MILow);
4130b57cec5SDimitry Andric     MCOperand OPHigh = MCOperand::createInst(MIHigh);
4140b57cec5SDimitry Andric     MI.addOperand(OPLow);
4150b57cec5SDimitry Andric     MI.addOperand(OPHigh);
4160b57cec5SDimitry Andric     Complete = true;
4170b57cec5SDimitry Andric   } else {
4180b57cec5SDimitry Andric     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
4190b57cec5SDimitry Andric         HexagonII::INST_PARSE_PACKET_END)
4200b57cec5SDimitry Andric       Complete = true;
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric     if (CurrentExtender != nullptr)
4230b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableMustExtend32, MI, Instruction,
4240b57cec5SDimitry Andric                                  Address, this, STI);
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric     if (Result != MCDisassembler::Success)
4270b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTable32, MI, Instruction, Address, this,
4280b57cec5SDimitry Andric                                  STI);
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric     if (Result != MCDisassembler::Success &&
43106c3fb27SDimitry Andric         STI.hasFeature(Hexagon::ExtensionHVX))
4320b57cec5SDimitry Andric       Result = decodeInstruction(DecoderTableEXT_mmvec32, MI, Instruction,
4330b57cec5SDimitry Andric                                  Address, this, STI);
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   }
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   switch (MI.getOpcode()) {
4380b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
4390b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_f_jumpnv_t:
4400b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_fp0_jump_nt:
4410b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_fp0_jump_t:
4420b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_fp1_jump_nt:
4430b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_fp1_jump_t:
4440b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
4450b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_t_jumpnv_t:
4460b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_tp0_jump_nt:
4470b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_tp0_jump_t:
4480b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_tp1_jump_nt:
4490b57cec5SDimitry Andric   case Hexagon::J4_cmpeqn1_tp1_jump_t:
4500b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
4510b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_f_jumpnv_t:
4520b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_fp0_jump_nt:
4530b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_fp0_jump_t:
4540b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_fp1_jump_nt:
4550b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_fp1_jump_t:
4560b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
4570b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_t_jumpnv_t:
4580b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_tp0_jump_nt:
4590b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_tp0_jump_t:
4600b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_tp1_jump_nt:
4610b57cec5SDimitry Andric   case Hexagon::J4_cmpgtn1_tp1_jump_t:
4620b57cec5SDimitry Andric     MI.insert(MI.begin() + 1,
4630b57cec5SDimitry Andric               MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
4640b57cec5SDimitry Andric     break;
4650b57cec5SDimitry Andric   default:
4660b57cec5SDimitry Andric     break;
4670b57cec5SDimitry Andric   }
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
4700b57cec5SDimitry Andric     unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
4710b57cec5SDimitry Andric     MCOperand &MCO = MI.getOperand(OpIndex);
4720b57cec5SDimitry Andric     assert(MCO.isReg() && "New value consumers must be registers");
4730b57cec5SDimitry Andric     unsigned Register =
4740b57cec5SDimitry Andric         getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
4750b57cec5SDimitry Andric     if ((Register & 0x6) == 0)
4760b57cec5SDimitry Andric       // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
4770b57cec5SDimitry Andric       return MCDisassembler::Fail;
4780b57cec5SDimitry Andric     unsigned Lookback = (Register & 0x6) >> 1;
4790b57cec5SDimitry Andric     unsigned Offset = 1;
4800b57cec5SDimitry Andric     bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
4810b57cec5SDimitry Andric     bool PrevVector = false;
4820b57cec5SDimitry Andric     auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
4830b57cec5SDimitry Andric     auto i = Instructions.end() - 1;
4840b57cec5SDimitry Andric     for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
4850b57cec5SDimitry Andric       if (i == n)
4860b57cec5SDimitry Andric         // Couldn't find producer
4870b57cec5SDimitry Andric         return MCDisassembler::Fail;
4880b57cec5SDimitry Andric       bool CurrentVector = HexagonMCInstrInfo::isVector(*MCII, *i->getInst());
4890b57cec5SDimitry Andric       if (Vector && !CurrentVector)
4900b57cec5SDimitry Andric         // Skip scalars when calculating distances for vectors
4910b57cec5SDimitry Andric         ++Lookback;
4920b57cec5SDimitry Andric       if (HexagonMCInstrInfo::isImmext(*i->getInst()) && (Vector == PrevVector))
4930b57cec5SDimitry Andric         ++Lookback;
4940b57cec5SDimitry Andric       PrevVector = CurrentVector;
4950b57cec5SDimitry Andric       if (Offset == Lookback)
4960b57cec5SDimitry Andric         break;
4970b57cec5SDimitry Andric     }
4980b57cec5SDimitry Andric     auto const &Inst = *i->getInst();
4990b57cec5SDimitry Andric     bool SubregBit = (Register & 0x1) != 0;
5000b57cec5SDimitry Andric     if (HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
5010b57cec5SDimitry Andric       // If subreg bit is set we're selecting the second produced newvalue
5020b57cec5SDimitry Andric       unsigned Producer = SubregBit ?
5030b57cec5SDimitry Andric           HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg() :
5040b57cec5SDimitry Andric           HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
5050b57cec5SDimitry Andric       assert(Producer != Hexagon::NoRegister);
5060b57cec5SDimitry Andric       MCO.setReg(Producer);
5070b57cec5SDimitry Andric     } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
5080b57cec5SDimitry Andric       unsigned Producer =
5090b57cec5SDimitry Andric           HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
5105ffd83dbSDimitry Andric 
5115ffd83dbSDimitry Andric       if (HexagonMCInstrInfo::IsVecRegPair(Producer)) {
5125ffd83dbSDimitry Andric         const bool Rev = HexagonMCInstrInfo::IsReverseVecRegPair(Producer);
5135ffd83dbSDimitry Andric         const unsigned ProdPairIndex =
5145ffd83dbSDimitry Andric             Rev ? Producer - Hexagon::WR0 : Producer - Hexagon::W0;
515*7a6dacacSDimitry Andric         if (Rev)
516*7a6dacacSDimitry Andric           SubregBit = !SubregBit;
5175ffd83dbSDimitry Andric         Producer = (ProdPairIndex << 1) + SubregBit + Hexagon::V0;
5185ffd83dbSDimitry Andric       } else if (SubregBit)
5190b57cec5SDimitry Andric         // Hexagon PRM 10.11 New-value operands
5200b57cec5SDimitry Andric         // Nt[0] is reserved and should always be encoded as zero.
5210b57cec5SDimitry Andric         return MCDisassembler::Fail;
5220b57cec5SDimitry Andric       assert(Producer != Hexagon::NoRegister);
5230b57cec5SDimitry Andric       MCO.setReg(Producer);
5240b57cec5SDimitry Andric     } else
5250b57cec5SDimitry Andric       return MCDisassembler::Fail;
5260b57cec5SDimitry Andric   }
5270b57cec5SDimitry Andric 
5280b57cec5SDimitry Andric   if (CurrentExtender != nullptr) {
5290b57cec5SDimitry Andric     MCInst const &Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI)
5300b57cec5SDimitry Andric                              ? *MI.getOperand(1).getInst()
5310b57cec5SDimitry Andric                              : MI;
5320b57cec5SDimitry Andric     if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
5330b57cec5SDimitry Andric         !HexagonMCInstrInfo::isExtended(*MCII, Inst))
5340b57cec5SDimitry Andric       return MCDisassembler::Fail;
5350b57cec5SDimitry Andric   }
5360b57cec5SDimitry Andric   return Result;
5370b57cec5SDimitry Andric }
5380b57cec5SDimitry Andric 
DecodeRegisterClass(MCInst & Inst,unsigned RegNo,ArrayRef<MCPhysReg> Table)5390b57cec5SDimitry Andric static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
5400b57cec5SDimitry Andric                                         ArrayRef<MCPhysReg> Table) {
5410b57cec5SDimitry Andric   if (RegNo < Table.size()) {
5420b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(Table[RegNo]));
5430b57cec5SDimitry Andric     return MCDisassembler::Success;
5440b57cec5SDimitry Andric   }
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   return MCDisassembler::Fail;
5470b57cec5SDimitry Andric }
5480b57cec5SDimitry Andric 
54981ad6265SDimitry Andric static DecodeStatus
DecodeIntRegsLow8RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)55081ad6265SDimitry Andric DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
55181ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
5520b57cec5SDimitry Andric   return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
DecodeIntRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)5550b57cec5SDimitry Andric static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
5560b57cec5SDimitry Andric                                                uint64_t Address,
55781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
5580b57cec5SDimitry Andric   static const MCPhysReg IntRegDecoderTable[] = {
5590b57cec5SDimitry Andric       Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
5600b57cec5SDimitry Andric       Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
5610b57cec5SDimitry Andric       Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
5620b57cec5SDimitry Andric       Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
5630b57cec5SDimitry Andric       Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
5640b57cec5SDimitry Andric       Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
5650b57cec5SDimitry Andric       Hexagon::R30, Hexagon::R31};
5660b57cec5SDimitry Andric 
5670b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable);
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric 
57081ad6265SDimitry Andric static DecodeStatus
DecodeGeneralSubRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t Address,const MCDisassembler * Decoder)57181ad6265SDimitry Andric DecodeGeneralSubRegsRegisterClass(MCInst &Inst, unsigned RegNo,
5720b57cec5SDimitry Andric                                   uint64_t Address,
57381ad6265SDimitry Andric                                   const MCDisassembler *Decoder) {
5740b57cec5SDimitry Andric   static const MCPhysReg GeneralSubRegDecoderTable[] = {
5750b57cec5SDimitry Andric       Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,
5760b57cec5SDimitry Andric       Hexagon::R4,  Hexagon::R5,  Hexagon::R6,  Hexagon::R7,
5770b57cec5SDimitry Andric       Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
5780b57cec5SDimitry Andric       Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
5790b57cec5SDimitry Andric   };
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, GeneralSubRegDecoderTable);
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric 
DecodeHvxVRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)5840b57cec5SDimitry Andric static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
5850b57cec5SDimitry Andric                                              uint64_t /*Address*/,
58681ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
5870b57cec5SDimitry Andric   static const MCPhysReg HvxVRDecoderTable[] = {
5880b57cec5SDimitry Andric       Hexagon::V0,  Hexagon::V1,  Hexagon::V2,  Hexagon::V3,  Hexagon::V4,
5890b57cec5SDimitry Andric       Hexagon::V5,  Hexagon::V6,  Hexagon::V7,  Hexagon::V8,  Hexagon::V9,
5900b57cec5SDimitry Andric       Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
5910b57cec5SDimitry Andric       Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
5920b57cec5SDimitry Andric       Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
5930b57cec5SDimitry Andric       Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
5940b57cec5SDimitry Andric       Hexagon::V30, Hexagon::V31};
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, HvxVRDecoderTable);
5970b57cec5SDimitry Andric }
5980b57cec5SDimitry Andric 
59981ad6265SDimitry Andric static DecodeStatus
DecodeDoubleRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)60081ad6265SDimitry Andric DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
6010b57cec5SDimitry Andric                               uint64_t /*Address*/,
60281ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
6030b57cec5SDimitry Andric   static const MCPhysReg DoubleRegDecoderTable[] = {
6040b57cec5SDimitry Andric       Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
6050b57cec5SDimitry Andric       Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
6060b57cec5SDimitry Andric       Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
6070b57cec5SDimitry Andric       Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
6080b57cec5SDimitry Andric 
6090b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable);
6100b57cec5SDimitry Andric }
6110b57cec5SDimitry Andric 
61281ad6265SDimitry Andric static DecodeStatus
DecodeGeneralDoubleLow8RegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)61381ad6265SDimitry Andric DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
61481ad6265SDimitry Andric                                          uint64_t /*Address*/,
61581ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
6160b57cec5SDimitry Andric   static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = {
6170b57cec5SDimitry Andric       Hexagon::D0, Hexagon::D1, Hexagon::D2,  Hexagon::D3,
6180b57cec5SDimitry Andric       Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11};
6190b57cec5SDimitry Andric 
6200b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, GeneralDoubleLow8RegDecoderTable);
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric 
DecodeHvxWRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)6230b57cec5SDimitry Andric static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
6240b57cec5SDimitry Andric                                              uint64_t /*Address*/,
62581ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
6260b57cec5SDimitry Andric   static const MCPhysReg HvxWRDecoderTable[] = {
6275ffd83dbSDimitry Andric       Hexagon::W0,   Hexagon::WR0,  Hexagon::W1,   Hexagon::WR1,  Hexagon::W2,
6285ffd83dbSDimitry Andric       Hexagon::WR2,  Hexagon::W3,   Hexagon::WR3,  Hexagon::W4,   Hexagon::WR4,
6295ffd83dbSDimitry Andric       Hexagon::W5,   Hexagon::WR5,  Hexagon::W6,   Hexagon::WR6,  Hexagon::W7,
6305ffd83dbSDimitry Andric       Hexagon::WR7,  Hexagon::W8,   Hexagon::WR8,  Hexagon::W9,   Hexagon::WR9,
6315ffd83dbSDimitry Andric       Hexagon::W10,  Hexagon::WR10, Hexagon::W11,  Hexagon::WR11, Hexagon::W12,
6325ffd83dbSDimitry Andric       Hexagon::WR12, Hexagon::W13,  Hexagon::WR13, Hexagon::W14,  Hexagon::WR14,
6335ffd83dbSDimitry Andric       Hexagon::W15,  Hexagon::WR15,
6345ffd83dbSDimitry Andric   };
6350b57cec5SDimitry Andric 
6365ffd83dbSDimitry Andric   return DecodeRegisterClass(Inst, RegNo, HvxWRDecoderTable);
6370b57cec5SDimitry Andric }
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric LLVM_ATTRIBUTE_UNUSED // Suppress warning temporarily.
64081ad6265SDimitry Andric     static DecodeStatus
DecodeHvxVQRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)64181ad6265SDimitry Andric     DecodeHvxVQRRegisterClass(MCInst &Inst, unsigned RegNo,
6420b57cec5SDimitry Andric                               uint64_t /*Address*/,
64381ad6265SDimitry Andric                               const MCDisassembler *Decoder) {
6440b57cec5SDimitry Andric   static const MCPhysReg HvxVQRDecoderTable[] = {
6450b57cec5SDimitry Andric       Hexagon::VQ0,  Hexagon::VQ1,  Hexagon::VQ2,  Hexagon::VQ3,
6460b57cec5SDimitry Andric       Hexagon::VQ4,  Hexagon::VQ5,  Hexagon::VQ6,  Hexagon::VQ7};
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable);
6490b57cec5SDimitry Andric }
6500b57cec5SDimitry Andric 
DecodePredRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)6510b57cec5SDimitry Andric static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
6520b57cec5SDimitry Andric                                                 uint64_t /*Address*/,
65381ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
6540b57cec5SDimitry Andric   static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
6550b57cec5SDimitry Andric                                                   Hexagon::P2, Hexagon::P3};
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable);
6580b57cec5SDimitry Andric }
6590b57cec5SDimitry Andric 
DecodeHvxQRRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)6600b57cec5SDimitry Andric static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
6610b57cec5SDimitry Andric                                              uint64_t /*Address*/,
66281ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
6630b57cec5SDimitry Andric   static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
6640b57cec5SDimitry Andric                                                 Hexagon::Q2, Hexagon::Q3};
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   return DecodeRegisterClass(Inst, RegNo, HvxQRDecoderTable);
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
DecodeCtrRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)6690b57cec5SDimitry Andric static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
6700b57cec5SDimitry Andric                                                uint64_t /*Address*/,
67181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
6720b57cec5SDimitry Andric   using namespace Hexagon;
6730b57cec5SDimitry Andric 
6740b57cec5SDimitry Andric   static const MCPhysReg CtrlRegDecoderTable[] = {
6750b57cec5SDimitry Andric     /*  0 */  SA0,        LC0,        SA1,        LC1,
6760b57cec5SDimitry Andric     /*  4 */  P3_0,       C5,         M0,         M1,
6770b57cec5SDimitry Andric     /*  8 */  USR,        PC,         UGP,        GP,
6780b57cec5SDimitry Andric     /* 12 */  CS0,        CS1,        UPCYCLELO,  UPCYCLEHI,
6790b57cec5SDimitry Andric     /* 16 */  FRAMELIMIT, FRAMEKEY,   PKTCOUNTLO, PKTCOUNTHI,
6800b57cec5SDimitry Andric     /* 20 */  0,          0,          0,          0,
6810b57cec5SDimitry Andric     /* 24 */  0,          0,          0,          0,
6820b57cec5SDimitry Andric     /* 28 */  0,          0,          UTIMERLO,   UTIMERHI
6830b57cec5SDimitry Andric   };
6840b57cec5SDimitry Andric 
685bdd1243dSDimitry Andric   if (RegNo >= std::size(CtrlRegDecoderTable))
6860b57cec5SDimitry Andric     return MCDisassembler::Fail;
6870b57cec5SDimitry Andric 
6880b57cec5SDimitry Andric   static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
6890b57cec5SDimitry Andric   if (CtrlRegDecoderTable[RegNo] == NoRegister)
6900b57cec5SDimitry Andric     return MCDisassembler::Fail;
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   unsigned Register = CtrlRegDecoderTable[RegNo];
6930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
6940b57cec5SDimitry Andric   return MCDisassembler::Success;
6950b57cec5SDimitry Andric }
6960b57cec5SDimitry Andric 
69781ad6265SDimitry Andric static DecodeStatus
DecodeCtrRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)69881ad6265SDimitry Andric DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
69981ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
7000b57cec5SDimitry Andric   using namespace Hexagon;
7010b57cec5SDimitry Andric 
7020b57cec5SDimitry Andric   static const MCPhysReg CtrlReg64DecoderTable[] = {
7030b57cec5SDimitry Andric     /*  0 */  C1_0,       0,          C3_2,       0,
7040b57cec5SDimitry Andric     /*  4 */  C5_4,       0,          C7_6,       0,
7050b57cec5SDimitry Andric     /*  8 */  C9_8,       0,          C11_10,     0,
7060b57cec5SDimitry Andric     /* 12 */  CS,         0,          UPCYCLE,    0,
7070b57cec5SDimitry Andric     /* 16 */  C17_16,     0,          PKTCOUNT,   0,
7080b57cec5SDimitry Andric     /* 20 */  0,          0,          0,          0,
7090b57cec5SDimitry Andric     /* 24 */  0,          0,          0,          0,
7100b57cec5SDimitry Andric     /* 28 */  0,          0,          UTIMER,     0
7110b57cec5SDimitry Andric   };
7120b57cec5SDimitry Andric 
713bdd1243dSDimitry Andric   if (RegNo >= std::size(CtrlReg64DecoderTable))
7140b57cec5SDimitry Andric     return MCDisassembler::Fail;
7150b57cec5SDimitry Andric 
7160b57cec5SDimitry Andric   static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
7170b57cec5SDimitry Andric   if (CtrlReg64DecoderTable[RegNo] == NoRegister)
7180b57cec5SDimitry Andric     return MCDisassembler::Fail;
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric   unsigned Register = CtrlReg64DecoderTable[RegNo];
7210b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
7220b57cec5SDimitry Andric   return MCDisassembler::Success;
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric 
DecodeModRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)7250b57cec5SDimitry Andric static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
7260b57cec5SDimitry Andric                                                uint64_t /*Address*/,
72781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
7280b57cec5SDimitry Andric   unsigned Register = 0;
7290b57cec5SDimitry Andric   switch (RegNo) {
7300b57cec5SDimitry Andric   case 0:
7310b57cec5SDimitry Andric     Register = Hexagon::M0;
7320b57cec5SDimitry Andric     break;
7330b57cec5SDimitry Andric   case 1:
7340b57cec5SDimitry Andric     Register = Hexagon::M1;
7350b57cec5SDimitry Andric     break;
7360b57cec5SDimitry Andric   default:
7370b57cec5SDimitry Andric     return MCDisassembler::Fail;
7380b57cec5SDimitry Andric   }
7390b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
7400b57cec5SDimitry Andric   return MCDisassembler::Success;
7410b57cec5SDimitry Andric }
7420b57cec5SDimitry Andric 
unsignedImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const MCDisassembler * Decoder)7430b57cec5SDimitry Andric static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
7440b57cec5SDimitry Andric                                        uint64_t /*Address*/,
74581ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
7460b57cec5SDimitry Andric   HexagonDisassembler const &Disassembler = disassembler(Decoder);
7470b57cec5SDimitry Andric   int64_t FullValue = fullValue(Disassembler, MI, tmp);
7480b57cec5SDimitry Andric   assert(FullValue >= 0 && "Negative in unsigned decoder");
7490b57cec5SDimitry Andric   HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
7500b57cec5SDimitry Andric   return MCDisassembler::Success;
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric 
s32_0ImmDecoder(MCInst & MI,unsigned tmp,uint64_t,const MCDisassembler * Decoder)7530b57cec5SDimitry Andric static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
75481ad6265SDimitry Andric                                     uint64_t /*Address*/,
75581ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
7560b57cec5SDimitry Andric   HexagonDisassembler const &Disassembler = disassembler(Decoder);
7570b57cec5SDimitry Andric   unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
7580b57cec5SDimitry Andric   tmp = SignExtend64(tmp, Bits);
7590b57cec5SDimitry Andric   signedDecoder<32>(MI, tmp, Decoder);
7600b57cec5SDimitry Andric   return MCDisassembler::Success;
7610b57cec5SDimitry Andric }
7620b57cec5SDimitry Andric 
7630b57cec5SDimitry Andric // custom decoder for various jump/call immediates
brtargetDecoder(MCInst & MI,unsigned tmp,uint64_t Address,const MCDisassembler * Decoder)7640b57cec5SDimitry Andric static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
76581ad6265SDimitry Andric                                     const MCDisassembler *Decoder) {
7660b57cec5SDimitry Andric   HexagonDisassembler const &Disassembler = disassembler(Decoder);
7670b57cec5SDimitry Andric   unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
7680b57cec5SDimitry Andric   // r13_2 is not extendable, so if there are no extent bits, it's r13_2
7690b57cec5SDimitry Andric   if (Bits == 0)
7700b57cec5SDimitry Andric     Bits = 15;
7710b57cec5SDimitry Andric   uint64_t FullValue = fullValue(Disassembler, MI, SignExtend64(tmp, Bits));
7720b57cec5SDimitry Andric   uint32_t Extended = FullValue + Address;
77381ad6265SDimitry Andric   if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 0, 0,
77481ad6265SDimitry Andric                                              4))
7750b57cec5SDimitry Andric     HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
7760b57cec5SDimitry Andric   return MCDisassembler::Success;
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
779349cc55cSDimitry Andric static const uint16_t SysRegDecoderTable[] = {
780349cc55cSDimitry Andric     Hexagon::SGP0,       Hexagon::SGP1,      Hexagon::STID,
781349cc55cSDimitry Andric     Hexagon::ELR,        Hexagon::BADVA0,    Hexagon::BADVA1,
782349cc55cSDimitry Andric     Hexagon::SSR,        Hexagon::CCR,       Hexagon::HTID,
783349cc55cSDimitry Andric     Hexagon::BADVA,      Hexagon::IMASK,     Hexagon::S11,
784349cc55cSDimitry Andric     Hexagon::S12,        Hexagon::S13,       Hexagon::S14,
785349cc55cSDimitry Andric     Hexagon::S15,        Hexagon::EVB,       Hexagon::MODECTL,
786349cc55cSDimitry Andric     Hexagon::SYSCFG,     Hexagon::S19,       Hexagon::S20,
787349cc55cSDimitry Andric     Hexagon::VID,        Hexagon::S22,       Hexagon::S23,
788349cc55cSDimitry Andric     Hexagon::S24,        Hexagon::S25,       Hexagon::S26,
789349cc55cSDimitry Andric     Hexagon::CFGBASE,    Hexagon::DIAG,      Hexagon::REV,
790349cc55cSDimitry Andric     Hexagon::PCYCLELO,   Hexagon::PCYCLEHI,  Hexagon::ISDBST,
791349cc55cSDimitry Andric     Hexagon::ISDBCFG0,   Hexagon::ISDBCFG1,  Hexagon::S35,
792349cc55cSDimitry Andric     Hexagon::BRKPTPC0,   Hexagon::BRKPTCFG0, Hexagon::BRKPTPC1,
793349cc55cSDimitry Andric     Hexagon::BRKPTCFG1,  Hexagon::ISDBMBXIN, Hexagon::ISDBMBXOUT,
794349cc55cSDimitry Andric     Hexagon::ISDBEN,     Hexagon::ISDBGPR,   Hexagon::S44,
795349cc55cSDimitry Andric     Hexagon::S45,        Hexagon::S46,       Hexagon::S47,
796349cc55cSDimitry Andric     Hexagon::PMUCNT0,    Hexagon::PMUCNT1,   Hexagon::PMUCNT2,
797349cc55cSDimitry Andric     Hexagon::PMUCNT3,    Hexagon::PMUEVTCFG, Hexagon::PMUCFG,
798349cc55cSDimitry Andric     Hexagon::S54,        Hexagon::S55,       Hexagon::S56,
799349cc55cSDimitry Andric     Hexagon::S57,        Hexagon::S58,       Hexagon::S59,
800349cc55cSDimitry Andric     Hexagon::S60,        Hexagon::S61,       Hexagon::S62,
801349cc55cSDimitry Andric     Hexagon::S63,        Hexagon::S64,       Hexagon::S65,
802349cc55cSDimitry Andric     Hexagon::S66,        Hexagon::S67,       Hexagon::S68,
803349cc55cSDimitry Andric     Hexagon::S69,        Hexagon::S70,       Hexagon::S71,
804349cc55cSDimitry Andric     Hexagon::S72,        Hexagon::S73,       Hexagon::S74,
805349cc55cSDimitry Andric     Hexagon::S75,        Hexagon::S76,       Hexagon::S77,
806349cc55cSDimitry Andric     Hexagon::S78,        Hexagon::S79,       Hexagon::S80,
807349cc55cSDimitry Andric };
808349cc55cSDimitry Andric 
DecodeSysRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)809349cc55cSDimitry Andric static DecodeStatus DecodeSysRegsRegisterClass(MCInst &Inst, unsigned RegNo,
810349cc55cSDimitry Andric                                                uint64_t /*Address*/,
81181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
812bdd1243dSDimitry Andric   if (RegNo >= std::size(SysRegDecoderTable))
813349cc55cSDimitry Andric     return MCDisassembler::Fail;
814349cc55cSDimitry Andric 
815349cc55cSDimitry Andric   if (SysRegDecoderTable[RegNo] == Hexagon::NoRegister)
816349cc55cSDimitry Andric     return MCDisassembler::Fail;
817349cc55cSDimitry Andric 
818349cc55cSDimitry Andric   unsigned Register = SysRegDecoderTable[RegNo];
819349cc55cSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
820349cc55cSDimitry Andric   return MCDisassembler::Success;
821349cc55cSDimitry Andric }
822349cc55cSDimitry Andric 
823349cc55cSDimitry Andric static const uint16_t SysReg64DecoderTable[] = {
824349cc55cSDimitry Andric     Hexagon::SGP1_0, Hexagon::S3_2,   Hexagon::S5_4,   Hexagon::S7_6,
825349cc55cSDimitry Andric     Hexagon::S9_8,   Hexagon::S11_10, Hexagon::S13_12, Hexagon::S15_14,
826349cc55cSDimitry Andric     Hexagon::S17_16, Hexagon::S19_18, Hexagon::S21_20, Hexagon::S23_22,
827349cc55cSDimitry Andric     Hexagon::S25_24, Hexagon::S27_26, Hexagon::S29_28, Hexagon::S31_30,
828349cc55cSDimitry Andric     Hexagon::S33_32, Hexagon::S35_34, Hexagon::S37_36, Hexagon::S39_38,
829349cc55cSDimitry Andric     Hexagon::S41_40, Hexagon::S43_42, Hexagon::S45_44, Hexagon::S47_46,
830349cc55cSDimitry Andric     Hexagon::S49_48, Hexagon::S51_50, Hexagon::S53_52, Hexagon::S55_54,
831349cc55cSDimitry Andric     Hexagon::S57_56, Hexagon::S59_58, Hexagon::S61_60, Hexagon::S63_62,
832349cc55cSDimitry Andric     Hexagon::S65_64, Hexagon::S67_66, Hexagon::S69_68, Hexagon::S71_70,
833349cc55cSDimitry Andric     Hexagon::S73_72, Hexagon::S75_74, Hexagon::S77_76, Hexagon::S79_78,
834349cc55cSDimitry Andric };
835349cc55cSDimitry Andric 
83681ad6265SDimitry Andric static DecodeStatus
DecodeSysRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)83781ad6265SDimitry Andric DecodeSysRegs64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
83881ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
839349cc55cSDimitry Andric   RegNo = RegNo >> 1;
840bdd1243dSDimitry Andric   if (RegNo >= std::size(SysReg64DecoderTable))
841349cc55cSDimitry Andric     return MCDisassembler::Fail;
842349cc55cSDimitry Andric 
843349cc55cSDimitry Andric   if (SysReg64DecoderTable[RegNo] == Hexagon::NoRegister)
844349cc55cSDimitry Andric     return MCDisassembler::Fail;
845349cc55cSDimitry Andric 
846349cc55cSDimitry Andric   unsigned Register = SysReg64DecoderTable[RegNo];
847349cc55cSDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
848349cc55cSDimitry Andric   return MCDisassembler::Success;
849349cc55cSDimitry Andric }
850349cc55cSDimitry Andric 
85181ad6265SDimitry Andric static DecodeStatus
DecodeGuestRegsRegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)85281ad6265SDimitry Andric DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t /*Address*/,
85381ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
8540b57cec5SDimitry Andric   using namespace Hexagon;
8550b57cec5SDimitry Andric 
8560b57cec5SDimitry Andric   static const MCPhysReg GuestRegDecoderTable[] = {
8570b57cec5SDimitry Andric     /*  0 */ GELR,      GSR,        GOSP,       G3,
8580b57cec5SDimitry Andric     /*  4 */ G4,        G5,         G6,         G7,
8590b57cec5SDimitry Andric     /*  8 */ G8,        G9,         G10,        G11,
8600b57cec5SDimitry Andric     /* 12 */ G12,       G13,        G14,        G15,
8610b57cec5SDimitry Andric     /* 16 */ GPMUCNT4,  GPMUCNT5,   GPMUCNT6,   GPMUCNT7,
8620b57cec5SDimitry Andric     /* 20 */ G20,       G21,        G22,        G23,
8630b57cec5SDimitry Andric     /* 24 */ GPCYCLELO, GPCYCLEHI,  GPMUCNT0,   GPMUCNT1,
8640b57cec5SDimitry Andric     /* 28 */ GPMUCNT2,  GPMUCNT3,   G30,        G31
8650b57cec5SDimitry Andric   };
8660b57cec5SDimitry Andric 
867bdd1243dSDimitry Andric   if (RegNo >= std::size(GuestRegDecoderTable))
8680b57cec5SDimitry Andric     return MCDisassembler::Fail;
8690b57cec5SDimitry Andric   if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister)
8700b57cec5SDimitry Andric     return MCDisassembler::Fail;
8710b57cec5SDimitry Andric 
8720b57cec5SDimitry Andric   unsigned Register = GuestRegDecoderTable[RegNo];
8730b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
8740b57cec5SDimitry Andric   return MCDisassembler::Success;
8750b57cec5SDimitry Andric }
8760b57cec5SDimitry Andric 
87781ad6265SDimitry Andric static DecodeStatus
DecodeGuestRegs64RegisterClass(MCInst & Inst,unsigned RegNo,uint64_t,const MCDisassembler * Decoder)87881ad6265SDimitry Andric DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
8790b57cec5SDimitry Andric                                uint64_t /*Address*/,
88081ad6265SDimitry Andric                                const MCDisassembler *Decoder) {
8810b57cec5SDimitry Andric   using namespace Hexagon;
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric   static const MCPhysReg GuestReg64DecoderTable[] = {
8840b57cec5SDimitry Andric     /*  0 */ G1_0,      0,          G3_2,       0,
8850b57cec5SDimitry Andric     /*  4 */ G5_4,      0,          G7_6,       0,
8860b57cec5SDimitry Andric     /*  8 */ G9_8,      0,          G11_10,     0,
8870b57cec5SDimitry Andric     /* 12 */ G13_12,    0,          G15_14,     0,
8880b57cec5SDimitry Andric     /* 16 */ G17_16,    0,          G19_18,     0,
8890b57cec5SDimitry Andric     /* 20 */ G21_20,    0,          G23_22,     0,
8900b57cec5SDimitry Andric     /* 24 */ G25_24,    0,          G27_26,     0,
8910b57cec5SDimitry Andric     /* 28 */ G29_28,    0,          G31_30,     0
8920b57cec5SDimitry Andric   };
8930b57cec5SDimitry Andric 
894bdd1243dSDimitry Andric   if (RegNo >= std::size(GuestReg64DecoderTable))
8950b57cec5SDimitry Andric     return MCDisassembler::Fail;
8960b57cec5SDimitry Andric   if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister)
8970b57cec5SDimitry Andric     return MCDisassembler::Fail;
8980b57cec5SDimitry Andric 
8990b57cec5SDimitry Andric   unsigned Register = GuestReg64DecoderTable[RegNo];
9000b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Register));
9010b57cec5SDimitry Andric   return MCDisassembler::Success;
9020b57cec5SDimitry Andric }
903