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