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 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 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 } 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> 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 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 168480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonDisassembler() { 1690b57cec5SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(), 1700b57cec5SDimitry Andric createHexagonDisassembler); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry 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 2080b57cec5SDimitry 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 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 302480093f4SDimitry 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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