188ebb9e2SColin LeMahieu //===-- HexagonDisassembler.cpp - Disassembler for Hexagon ISA ------------===// 288ebb9e2SColin LeMahieu // 388ebb9e2SColin LeMahieu // The LLVM Compiler Infrastructure 488ebb9e2SColin LeMahieu // 588ebb9e2SColin LeMahieu // This file is distributed under the University of Illinois Open Source 688ebb9e2SColin LeMahieu // License. See LICENSE.TXT for details. 788ebb9e2SColin LeMahieu // 888ebb9e2SColin LeMahieu //===----------------------------------------------------------------------===// 988ebb9e2SColin LeMahieu 10*7cd08927SColin LeMahieu #define DEBUG_TYPE "hexagon-disassembler" 11*7cd08927SColin LeMahieu 1268d967d9SColin LeMahieu #include "Hexagon.h" 1388ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonBaseInfo.h" 14*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCChecker.h" 1588ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonMCTargetDesc.h" 16*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCInstrInfo.h" 17*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonInstPrinter.h" 18*7cd08927SColin LeMahieu #include "llvm/ADT/StringExtras.h" 1988ebb9e2SColin LeMahieu #include "llvm/MC/MCDisassembler.h" 20*7cd08927SColin LeMahieu #include "llvm/MC/MCContext.h" 2188ebb9e2SColin LeMahieu #include "llvm/MC/MCExpr.h" 2288ebb9e2SColin LeMahieu #include "llvm/MC/MCFixedLenDisassembler.h" 2388ebb9e2SColin LeMahieu #include "llvm/MC/MCInst.h" 2488ebb9e2SColin LeMahieu #include "llvm/MC/MCInstrDesc.h" 25*7cd08927SColin LeMahieu #include "llvm/MC/MCInstrInfo.h" 2688ebb9e2SColin LeMahieu #include "llvm/MC/MCSubtargetInfo.h" 2788ebb9e2SColin LeMahieu #include "llvm/Support/Debug.h" 2888ebb9e2SColin LeMahieu #include "llvm/Support/ErrorHandling.h" 2988ebb9e2SColin LeMahieu #include "llvm/Support/LEB128.h" 30*7cd08927SColin LeMahieu #include "llvm/Support/MemoryObject.h" 31d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h" 32*7cd08927SColin LeMahieu #include "llvm/Support/TargetRegistry.h" 33d9903888SChandler Carruth #include <vector> 3488ebb9e2SColin LeMahieu 3588ebb9e2SColin LeMahieu using namespace llvm; 3668d967d9SColin LeMahieu using namespace Hexagon; 3788ebb9e2SColin LeMahieu 38*7cd08927SColin LeMahieu typedef MCDisassembler::DecodeStatus DecodeStatus; 3988ebb9e2SColin LeMahieu 4088ebb9e2SColin LeMahieu namespace { 4188ebb9e2SColin LeMahieu /// \brief Hexagon disassembler for all Hexagon platforms. 4288ebb9e2SColin LeMahieu class HexagonDisassembler : public MCDisassembler { 4388ebb9e2SColin LeMahieu public: 44*7cd08927SColin LeMahieu std::unique_ptr<MCInstrInfo const> const MCII; 4568d967d9SColin LeMahieu std::unique_ptr<MCInst *> CurrentBundle; 46*7cd08927SColin LeMahieu HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 47*7cd08927SColin LeMahieu MCInstrInfo const *MCII) 48*7cd08927SColin LeMahieu : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *) {} 4988ebb9e2SColin LeMahieu 5068d967d9SColin LeMahieu DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB, 5168d967d9SColin LeMahieu ArrayRef<uint8_t> Bytes, uint64_t Address, 5268d967d9SColin LeMahieu raw_ostream &VStream, raw_ostream &CStream, 5368d967d9SColin LeMahieu bool &Complete) const; 544aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 557fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 564aa6bea7SRafael Espindola raw_ostream &VStream, 574aa6bea7SRafael Espindola raw_ostream &CStream) const override; 58*7cd08927SColin LeMahieu 59*7cd08927SColin LeMahieu void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const; 60*7cd08927SColin LeMahieu void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) const; 6188ebb9e2SColin LeMahieu }; 62f00654e3SAlexander Kornienko } 6388ebb9e2SColin LeMahieu 64*7cd08927SColin LeMahieu // Forward declare these because the auto-generated code will reference them. 65*7cd08927SColin LeMahieu // Definitions are further down. 66*7cd08927SColin LeMahieu 67*7cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 68be8c453dSColin LeMahieu uint64_t Address, 69be8c453dSColin LeMahieu const void *Decoder); 707c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, 717c958713SColin LeMahieu uint64_t Address, 727c958713SColin LeMahieu const void *Decoder); 737c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo, 747c958713SColin LeMahieu uint64_t Address, 757c958713SColin LeMahieu const void *Decoder); 76*7cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 77*7cd08927SColin LeMahieu uint64_t Address, 78*7cd08927SColin LeMahieu const void *Decoder); 797c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo, 807c958713SColin LeMahieu uint64_t Address, 817c958713SColin LeMahieu const void *Decoder); 82*7cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 83*7cd08927SColin LeMahieu uint64_t Address, 84*7cd08927SColin LeMahieu const void *Decoder); 857c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 867c958713SColin LeMahieu uint64_t Address, 877c958713SColin LeMahieu const void *Decoder); 88f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 89be8c453dSColin LeMahieu uint64_t Address, 90be8c453dSColin LeMahieu const void *Decoder); 91*7cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 92*7cd08927SColin LeMahieu uint64_t Address, 93*7cd08927SColin LeMahieu const void *Decoder); 94404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, 95be8c453dSColin LeMahieu uint64_t Address, 96*7cd08927SColin LeMahieu const void *Decoder); 97*7cd08927SColin LeMahieu 98*7cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn); 99*7cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn, 100be8c453dSColin LeMahieu void const *Decoder); 101be8c453dSColin LeMahieu 102be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op, 103be8c453dSColin LeMahieu raw_ostream &os); 104f3db884eSColin LeMahieu 105*7cd08927SColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg); 106*7cd08927SColin LeMahieu 107*7cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, 108*7cd08927SColin LeMahieu uint64_t Address, const void *Decoder); 1091e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1101e9d1d76SColin LeMahieu const void *Decoder); 1111e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1121e9d1d76SColin LeMahieu const void *Decoder); 1131e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1141e9d1d76SColin LeMahieu const void *Decoder); 1151e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1161e9d1d76SColin LeMahieu const void *Decoder); 1171e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1181e9d1d76SColin LeMahieu const void *Decoder); 1191e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1201e9d1d76SColin LeMahieu const void *Decoder); 1211e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1221e9d1d76SColin LeMahieu const void *Decoder); 1231e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1241e9d1d76SColin LeMahieu const void *Decoder); 1251e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1261e9d1d76SColin LeMahieu const void *Decoder); 1271e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1281e9d1d76SColin LeMahieu const void *Decoder); 1291e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1301e9d1d76SColin LeMahieu const void *Decoder); 1311e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1321e9d1d76SColin LeMahieu const void *Decoder); 1331e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1341e9d1d76SColin LeMahieu const void *Decoder); 1357c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1367c958713SColin LeMahieu const void *Decoder); 1377c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1387c958713SColin LeMahieu const void *Decoder); 139*7cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 140*7cd08927SColin LeMahieu const void *Decoder); 141efa74e02SColin LeMahieu 14288ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc" 14388ebb9e2SColin LeMahieu 144*7cd08927SColin LeMahieu static MCDisassembler *createHexagonDisassembler(const Target &T, 145*7cd08927SColin LeMahieu const MCSubtargetInfo &STI, 14688ebb9e2SColin LeMahieu MCContext &Ctx) { 147*7cd08927SColin LeMahieu return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo()); 14888ebb9e2SColin LeMahieu } 14988ebb9e2SColin LeMahieu 15088ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() { 15188ebb9e2SColin LeMahieu TargetRegistry::RegisterMCDisassembler(TheHexagonTarget, 15288ebb9e2SColin LeMahieu createHexagonDisassembler); 15388ebb9e2SColin LeMahieu } 15488ebb9e2SColin LeMahieu 15588ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 1567fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 15788ebb9e2SColin LeMahieu uint64_t Address, 15888ebb9e2SColin LeMahieu raw_ostream &os, 15988ebb9e2SColin LeMahieu raw_ostream &cs) const { 16068d967d9SColin LeMahieu DecodeStatus Result = DecodeStatus::Success; 16168d967d9SColin LeMahieu bool Complete = false; 16268d967d9SColin LeMahieu Size = 0; 1634aa6bea7SRafael Espindola 16468d967d9SColin LeMahieu *CurrentBundle = &MI; 16568d967d9SColin LeMahieu MI.setOpcode(Hexagon::BUNDLE); 16668d967d9SColin LeMahieu MI.addOperand(MCOperand::createImm(0)); 167be8c453dSColin LeMahieu while (Result == Success && Complete == false) { 16868d967d9SColin LeMahieu if (Bytes.size() < HEXAGON_INSTR_SIZE) 16968d967d9SColin LeMahieu return MCDisassembler::Fail; 17068d967d9SColin LeMahieu MCInst *Inst = new (getContext()) MCInst; 17168d967d9SColin LeMahieu Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete); 17268d967d9SColin LeMahieu MI.addOperand(MCOperand::createInst(Inst)); 17368d967d9SColin LeMahieu Size += HEXAGON_INSTR_SIZE; 17468d967d9SColin LeMahieu Bytes = Bytes.slice(HEXAGON_INSTR_SIZE); 17568d967d9SColin LeMahieu } 176*7cd08927SColin LeMahieu if(Result == MCDisassembler::Fail) 17768d967d9SColin LeMahieu return Result; 178*7cd08927SColin LeMahieu HexagonMCChecker Checker (*MCII, STI, MI, MI, *getContext().getRegisterInfo()); 179*7cd08927SColin LeMahieu if(!Checker.check()) 180*7cd08927SColin LeMahieu return MCDisassembler::Fail; 181*7cd08927SColin LeMahieu return MCDisassembler::Success; 182*7cd08927SColin LeMahieu } 183*7cd08927SColin LeMahieu 184*7cd08927SColin LeMahieu namespace { 185*7cd08927SColin LeMahieu HexagonDisassembler const &disassembler(void const *Decoder) { 186*7cd08927SColin LeMahieu return *static_cast<HexagonDisassembler const *>(Decoder); 187*7cd08927SColin LeMahieu } 188*7cd08927SColin LeMahieu MCContext &contextFromDecoder(void const *Decoder) { 189*7cd08927SColin LeMahieu return disassembler(Decoder).getContext(); 190*7cd08927SColin LeMahieu } 19168d967d9SColin LeMahieu } 19268d967d9SColin LeMahieu 19368d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction( 19468d967d9SColin LeMahieu MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address, 19568d967d9SColin LeMahieu raw_ostream &os, raw_ostream &cs, bool &Complete) const { 19668d967d9SColin LeMahieu assert(Bytes.size() >= HEXAGON_INSTR_SIZE); 19768d967d9SColin LeMahieu 19868d967d9SColin LeMahieu uint32_t Instruction = 199*7cd08927SColin LeMahieu (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); 20088ebb9e2SColin LeMahieu 20168d967d9SColin LeMahieu auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB); 20268d967d9SColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 20368d967d9SColin LeMahieu HexagonII::INST_PARSE_LOOP_END) { 20468d967d9SColin LeMahieu if (BundleSize == 0) 20568d967d9SColin LeMahieu HexagonMCInstrInfo::setInnerLoop(MCB); 20668d967d9SColin LeMahieu else if (BundleSize == 1) 20768d967d9SColin LeMahieu HexagonMCInstrInfo::setOuterLoop(MCB); 20868d967d9SColin LeMahieu else 20968d967d9SColin LeMahieu return DecodeStatus::Fail; 21068d967d9SColin LeMahieu } 21168d967d9SColin LeMahieu 21268d967d9SColin LeMahieu DecodeStatus Result = DecodeStatus::Success; 21368d967d9SColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 214be8c453dSColin LeMahieu HexagonII::INST_PARSE_DUPLEX) { 215be8c453dSColin LeMahieu // Determine the instruction class of each instruction in the duplex. 216be8c453dSColin LeMahieu unsigned duplexIClass, IClassLow, IClassHigh; 217be8c453dSColin LeMahieu 218be8c453dSColin LeMahieu duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1); 219be8c453dSColin LeMahieu switch (duplexIClass) { 220be8c453dSColin LeMahieu default: 221be8c453dSColin LeMahieu return MCDisassembler::Fail; 222be8c453dSColin LeMahieu case 0: 223be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L1; 224be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 225be8c453dSColin LeMahieu break; 226be8c453dSColin LeMahieu case 1: 227be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 228be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 229be8c453dSColin LeMahieu break; 230be8c453dSColin LeMahieu case 2: 231be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 232be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 233be8c453dSColin LeMahieu break; 234be8c453dSColin LeMahieu case 3: 235be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_A; 236be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 237be8c453dSColin LeMahieu break; 238be8c453dSColin LeMahieu case 4: 239be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L1; 240be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 241be8c453dSColin LeMahieu break; 242be8c453dSColin LeMahieu case 5: 243be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 244be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 245be8c453dSColin LeMahieu break; 246be8c453dSColin LeMahieu case 6: 247be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 248be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 249be8c453dSColin LeMahieu break; 250be8c453dSColin LeMahieu case 7: 251be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 252be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 253be8c453dSColin LeMahieu break; 254be8c453dSColin LeMahieu case 8: 255be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 256be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 257be8c453dSColin LeMahieu break; 258be8c453dSColin LeMahieu case 9: 259be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 260be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 261be8c453dSColin LeMahieu break; 262be8c453dSColin LeMahieu case 10: 263be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 264be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S1; 265be8c453dSColin LeMahieu break; 266be8c453dSColin LeMahieu case 11: 267be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 268be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S1; 269be8c453dSColin LeMahieu break; 270be8c453dSColin LeMahieu case 12: 271be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 272be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 273be8c453dSColin LeMahieu break; 274be8c453dSColin LeMahieu case 13: 275be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 276be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 277be8c453dSColin LeMahieu break; 278be8c453dSColin LeMahieu case 14: 279be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 280be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S2; 281be8c453dSColin LeMahieu break; 282be8c453dSColin LeMahieu } 283be8c453dSColin LeMahieu 284be8c453dSColin LeMahieu // Set the MCInst to be a duplex instruction. Which one doesn't matter. 285be8c453dSColin LeMahieu MI.setOpcode(Hexagon::DuplexIClass0); 286be8c453dSColin LeMahieu 287be8c453dSColin LeMahieu // Decode each instruction in the duplex. 288be8c453dSColin LeMahieu // Create an MCInst for each instruction. 289be8c453dSColin LeMahieu unsigned instLow = Instruction & 0x1fff; 290be8c453dSColin LeMahieu unsigned instHigh = (Instruction >> 16) & 0x1fff; 291be8c453dSColin LeMahieu unsigned opLow; 292be8c453dSColin LeMahieu if (GetSubinstOpcode(IClassLow, instLow, opLow, os) != 293be8c453dSColin LeMahieu MCDisassembler::Success) 294be8c453dSColin LeMahieu return MCDisassembler::Fail; 295be8c453dSColin LeMahieu unsigned opHigh; 296be8c453dSColin LeMahieu if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) != 297be8c453dSColin LeMahieu MCDisassembler::Success) 298be8c453dSColin LeMahieu return MCDisassembler::Fail; 299be8c453dSColin LeMahieu MCInst *MILow = new (getContext()) MCInst; 300be8c453dSColin LeMahieu MILow->setOpcode(opLow); 301be8c453dSColin LeMahieu MCInst *MIHigh = new (getContext()) MCInst; 302be8c453dSColin LeMahieu MIHigh->setOpcode(opHigh); 303*7cd08927SColin LeMahieu addSubinstOperands(MILow, opLow, instLow); 304*7cd08927SColin LeMahieu addSubinstOperands(MIHigh, opHigh, instHigh); 305be8c453dSColin LeMahieu // see ConvertToSubInst() in 306be8c453dSColin LeMahieu // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp 307be8c453dSColin LeMahieu 308be8c453dSColin LeMahieu // Add the duplex instruction MCInsts as operands to the passed in MCInst. 309be8c453dSColin LeMahieu MCOperand OPLow = MCOperand::createInst(MILow); 310be8c453dSColin LeMahieu MCOperand OPHigh = MCOperand::createInst(MIHigh); 311be8c453dSColin LeMahieu MI.addOperand(OPLow); 312be8c453dSColin LeMahieu MI.addOperand(OPHigh); 313be8c453dSColin LeMahieu Complete = true; 314be8c453dSColin LeMahieu } else { 315be8c453dSColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 31668d967d9SColin LeMahieu HexagonII::INST_PARSE_PACKET_END) 31768d967d9SColin LeMahieu Complete = true; 31868d967d9SColin LeMahieu // Calling the auto-generated decoder function. 31968d967d9SColin LeMahieu Result = 32068d967d9SColin LeMahieu decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI); 321*7cd08927SColin LeMahieu 322*7cd08927SColin LeMahieu // If a, "standard" insn isn't found check special cases. 323*7cd08927SColin LeMahieu if (MCDisassembler::Success != Result || 324*7cd08927SColin LeMahieu MI.getOpcode() == Hexagon::A4_ext) { 325*7cd08927SColin LeMahieu Result = decodeImmext(MI, Instruction, this); 326*7cd08927SColin LeMahieu if (MCDisassembler::Success != Result) { 327*7cd08927SColin LeMahieu Result = decodeSpecial(MI, Instruction); 328*7cd08927SColin LeMahieu } 329*7cd08927SColin LeMahieu } else { 330*7cd08927SColin LeMahieu // If the instruction is a compound instruction, register values will 331*7cd08927SColin LeMahieu // follow the duplex model, so the register values in the MCInst are 332*7cd08927SColin LeMahieu // incorrect. If the instruction is a compound, loop through the 333*7cd08927SColin LeMahieu // operands and change registers appropriately. 334*7cd08927SColin LeMahieu if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) == 335*7cd08927SColin LeMahieu HexagonII::TypeCOMPOUND) { 336*7cd08927SColin LeMahieu for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last; ++i) { 337*7cd08927SColin LeMahieu if (i->isReg()) { 338*7cd08927SColin LeMahieu unsigned reg = i->getReg() - Hexagon::R0; 339*7cd08927SColin LeMahieu i->setReg(getRegFromSubinstEncoding(reg)); 340*7cd08927SColin LeMahieu } 341*7cd08927SColin LeMahieu } 342*7cd08927SColin LeMahieu } 343*7cd08927SColin LeMahieu } 344be8c453dSColin LeMahieu } 34568d967d9SColin LeMahieu 346*7cd08927SColin LeMahieu if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) { 347*7cd08927SColin LeMahieu unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI); 348*7cd08927SColin LeMahieu MCOperand &MCO = MI.getOperand(OpIndex); 349*7cd08927SColin LeMahieu assert(MCO.isReg() && "New value consumers must be registers"); 350*7cd08927SColin LeMahieu unsigned Register = 351*7cd08927SColin LeMahieu getContext().getRegisterInfo()->getEncodingValue(MCO.getReg()); 352*7cd08927SColin LeMahieu if ((Register & 0x6) == 0) 353*7cd08927SColin LeMahieu // HexagonPRM 10.11 Bit 1-2 == 0 is reserved 354*7cd08927SColin LeMahieu return MCDisassembler::Fail; 355*7cd08927SColin LeMahieu unsigned Lookback = (Register & 0x6) >> 1; 356*7cd08927SColin LeMahieu unsigned Offset = 1; 357*7cd08927SColin LeMahieu bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI); 358*7cd08927SColin LeMahieu auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle); 359*7cd08927SColin LeMahieu auto i = Instructions.end() - 1; 360*7cd08927SColin LeMahieu for (auto n = Instructions.begin() - 1;; --i, ++Offset) { 361*7cd08927SColin LeMahieu if (i == n) 362*7cd08927SColin LeMahieu // Couldn't find producer 363*7cd08927SColin LeMahieu return MCDisassembler::Fail; 364*7cd08927SColin LeMahieu if (Vector && !HexagonMCInstrInfo::isVector(*MCII, *i->getInst())) 365*7cd08927SColin LeMahieu // Skip scalars when calculating distances for vectors 366*7cd08927SColin LeMahieu ++Lookback; 367*7cd08927SColin LeMahieu if (HexagonMCInstrInfo::isImmext(*i->getInst())) 368*7cd08927SColin LeMahieu ++Lookback; 369*7cd08927SColin LeMahieu if (Offset == Lookback) 370*7cd08927SColin LeMahieu break; 371*7cd08927SColin LeMahieu } 372*7cd08927SColin LeMahieu auto const &Inst = *i->getInst(); 373*7cd08927SColin LeMahieu bool SubregBit = (Register & 0x1) != 0; 374*7cd08927SColin LeMahieu if (SubregBit && HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) { 375*7cd08927SColin LeMahieu // If subreg bit is set we're selecting the second produced newvalue 376*7cd08927SColin LeMahieu unsigned Producer = 377*7cd08927SColin LeMahieu HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg(); 378*7cd08927SColin LeMahieu assert(Producer != Hexagon::NoRegister); 379*7cd08927SColin LeMahieu MCO.setReg(Producer); 380*7cd08927SColin LeMahieu } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) { 381*7cd08927SColin LeMahieu unsigned Producer = 382*7cd08927SColin LeMahieu HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg(); 383*7cd08927SColin LeMahieu if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) 384*7cd08927SColin LeMahieu Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0; 385*7cd08927SColin LeMahieu else if (SubregBit) 386*7cd08927SColin LeMahieu // Subreg bit should not be set for non-doublevector newvalue producers 387*7cd08927SColin LeMahieu return MCDisassembler::Fail; 388*7cd08927SColin LeMahieu assert(Producer != Hexagon::NoRegister); 389*7cd08927SColin LeMahieu MCO.setReg(Producer); 390*7cd08927SColin LeMahieu } else 391*7cd08927SColin LeMahieu return MCDisassembler::Fail; 392*7cd08927SColin LeMahieu } 393*7cd08927SColin LeMahieu 394*7cd08927SColin LeMahieu adjustExtendedInstructions(MI, MCB); 395*7cd08927SColin LeMahieu MCInst const *Extender = 396*7cd08927SColin LeMahieu HexagonMCInstrInfo::extenderForIndex(MCB, 397*7cd08927SColin LeMahieu HexagonMCInstrInfo::bundleSize(MCB)); 398*7cd08927SColin LeMahieu if(Extender != nullptr) { 399*7cd08927SColin LeMahieu MCInst const & Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) ? 400*7cd08927SColin LeMahieu *MI.getOperand(1).getInst() : MI; 401*7cd08927SColin LeMahieu if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) && 402*7cd08927SColin LeMahieu !HexagonMCInstrInfo::isExtended(*MCII, Inst)) 403*7cd08927SColin LeMahieu return MCDisassembler::Fail; 404*7cd08927SColin LeMahieu } 4055d6f03bdSColin LeMahieu return Result; 40688ebb9e2SColin LeMahieu } 407*7cd08927SColin LeMahieu 408*7cd08927SColin LeMahieu void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI, 409*7cd08927SColin LeMahieu MCInst const &MCB) const { 410*7cd08927SColin LeMahieu if (!HexagonMCInstrInfo::hasExtenderForIndex( 411*7cd08927SColin LeMahieu MCB, HexagonMCInstrInfo::bundleSize(MCB))) { 412*7cd08927SColin LeMahieu unsigned opcode; 413*7cd08927SColin LeMahieu // This code is used by the disassembler to disambiguate between GP 414*7cd08927SColin LeMahieu // relative and absolute addressing instructions since they both have 415*7cd08927SColin LeMahieu // same encoding bits. However, an absolute addressing instruction must 416*7cd08927SColin LeMahieu // follow an immediate extender. Disassembler alwaus select absolute 417*7cd08927SColin LeMahieu // addressing instructions first and uses this code to change them into 418*7cd08927SColin LeMahieu // GP relative instruction in the absence of the corresponding immediate 419*7cd08927SColin LeMahieu // extender. 420*7cd08927SColin LeMahieu switch (MCI.getOpcode()) { 421*7cd08927SColin LeMahieu case Hexagon::S2_storerbabs: 422*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerbgp; 423*7cd08927SColin LeMahieu break; 424*7cd08927SColin LeMahieu case Hexagon::S2_storerhabs: 425*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerhgp; 426*7cd08927SColin LeMahieu break; 427*7cd08927SColin LeMahieu case Hexagon::S2_storerfabs: 428*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerfgp; 429*7cd08927SColin LeMahieu break; 430*7cd08927SColin LeMahieu case Hexagon::S2_storeriabs: 431*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerigp; 432*7cd08927SColin LeMahieu break; 433*7cd08927SColin LeMahieu case Hexagon::S2_storerbnewabs: 434*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerbnewgp; 435*7cd08927SColin LeMahieu break; 436*7cd08927SColin LeMahieu case Hexagon::S2_storerhnewabs: 437*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerhnewgp; 438*7cd08927SColin LeMahieu break; 439*7cd08927SColin LeMahieu case Hexagon::S2_storerinewabs: 440*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerinewgp; 441*7cd08927SColin LeMahieu break; 442*7cd08927SColin LeMahieu case Hexagon::S2_storerdabs: 443*7cd08927SColin LeMahieu opcode = Hexagon::S2_storerdgp; 444*7cd08927SColin LeMahieu break; 445*7cd08927SColin LeMahieu case Hexagon::L4_loadrb_abs: 446*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadrbgp; 447*7cd08927SColin LeMahieu break; 448*7cd08927SColin LeMahieu case Hexagon::L4_loadrub_abs: 449*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadrubgp; 450*7cd08927SColin LeMahieu break; 451*7cd08927SColin LeMahieu case Hexagon::L4_loadrh_abs: 452*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadrhgp; 453*7cd08927SColin LeMahieu break; 454*7cd08927SColin LeMahieu case Hexagon::L4_loadruh_abs: 455*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadruhgp; 456*7cd08927SColin LeMahieu break; 457*7cd08927SColin LeMahieu case Hexagon::L4_loadri_abs: 458*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadrigp; 459*7cd08927SColin LeMahieu break; 460*7cd08927SColin LeMahieu case Hexagon::L4_loadrd_abs: 461*7cd08927SColin LeMahieu opcode = Hexagon::L2_loadrdgp; 462*7cd08927SColin LeMahieu break; 463*7cd08927SColin LeMahieu default: 464*7cd08927SColin LeMahieu opcode = MCI.getOpcode(); 465*7cd08927SColin LeMahieu } 466*7cd08927SColin LeMahieu MCI.setOpcode(opcode); 467*7cd08927SColin LeMahieu } 468*7cd08927SColin LeMahieu } 469*7cd08927SColin LeMahieu 470*7cd08927SColin LeMahieu namespace llvm { 471*7cd08927SColin LeMahieu extern const MCInstrDesc HexagonInsts[]; 472*7cd08927SColin LeMahieu } 473*7cd08927SColin LeMahieu 474*7cd08927SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, 475*7cd08927SColin LeMahieu const uint16_t Table[], size_t Size) { 476*7cd08927SColin LeMahieu if (RegNo < Size) { 477*7cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Table[RegNo])); 478*7cd08927SColin LeMahieu return MCDisassembler::Success; 479*7cd08927SColin LeMahieu } else 480*7cd08927SColin LeMahieu return MCDisassembler::Fail; 481*7cd08927SColin LeMahieu } 482*7cd08927SColin LeMahieu 4837c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, 4847c958713SColin LeMahieu uint64_t Address, 4857c958713SColin LeMahieu const void *Decoder) { 4867c958713SColin LeMahieu return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); 4877c958713SColin LeMahieu } 4887c958713SColin LeMahieu 489*7cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 490*7cd08927SColin LeMahieu uint64_t Address, 491*7cd08927SColin LeMahieu const void *Decoder) { 492*7cd08927SColin LeMahieu static const uint16_t IntRegDecoderTable[] = { 493*7cd08927SColin LeMahieu Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, 494*7cd08927SColin LeMahieu Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, 495*7cd08927SColin LeMahieu Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, 496*7cd08927SColin LeMahieu Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 497*7cd08927SColin LeMahieu Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, 498*7cd08927SColin LeMahieu Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, 499*7cd08927SColin LeMahieu Hexagon::R30, Hexagon::R31}; 500*7cd08927SColin LeMahieu 501*7cd08927SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable, 502*7cd08927SColin LeMahieu sizeof(IntRegDecoderTable))); 503*7cd08927SColin LeMahieu } 5047c958713SColin LeMahieu 5057c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5067c958713SColin LeMahieu uint64_t /*Address*/, 5077c958713SColin LeMahieu const void *Decoder) { 5087c958713SColin LeMahieu static const uint16_t VecRegDecoderTable[] = { 5097c958713SColin LeMahieu Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4, 5107c958713SColin LeMahieu Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9, 5117c958713SColin LeMahieu Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14, 5127c958713SColin LeMahieu Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19, 5137c958713SColin LeMahieu Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24, 5147c958713SColin LeMahieu Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29, 5157c958713SColin LeMahieu Hexagon::V30, Hexagon::V31}; 5167c958713SColin LeMahieu 5177c958713SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo, VecRegDecoderTable, 5187c958713SColin LeMahieu sizeof(VecRegDecoderTable))); 5197c958713SColin LeMahieu } 5207c958713SColin LeMahieu 521*7cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 522*7cd08927SColin LeMahieu uint64_t /*Address*/, 523*7cd08927SColin LeMahieu const void *Decoder) { 524*7cd08927SColin LeMahieu static const uint16_t DoubleRegDecoderTable[] = { 525*7cd08927SColin LeMahieu Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, 526*7cd08927SColin LeMahieu Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, 527*7cd08927SColin LeMahieu Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, 528*7cd08927SColin LeMahieu Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15}; 529*7cd08927SColin LeMahieu 530*7cd08927SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable, 531*7cd08927SColin LeMahieu sizeof(DoubleRegDecoderTable))); 532*7cd08927SColin LeMahieu } 533*7cd08927SColin LeMahieu 5347c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5357c958713SColin LeMahieu uint64_t /*Address*/, 5367c958713SColin LeMahieu const void *Decoder) { 5377c958713SColin LeMahieu static const uint16_t VecDblRegDecoderTable[] = { 5387c958713SColin LeMahieu Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3, 5397c958713SColin LeMahieu Hexagon::W4, Hexagon::W5, Hexagon::W6, Hexagon::W7, 5407c958713SColin LeMahieu Hexagon::W8, Hexagon::W9, Hexagon::W10, Hexagon::W11, 5417c958713SColin LeMahieu Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15}; 5427c958713SColin LeMahieu 5437c958713SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo >> 1, VecDblRegDecoderTable, 5447c958713SColin LeMahieu sizeof(VecDblRegDecoderTable))); 5457c958713SColin LeMahieu } 5467c958713SColin LeMahieu 547*7cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 548*7cd08927SColin LeMahieu uint64_t /*Address*/, 549*7cd08927SColin LeMahieu const void *Decoder) { 550*7cd08927SColin LeMahieu static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, 551*7cd08927SColin LeMahieu Hexagon::P2, Hexagon::P3}; 552*7cd08927SColin LeMahieu 553*7cd08927SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable, 554*7cd08927SColin LeMahieu sizeof(PredRegDecoderTable))); 555*7cd08927SColin LeMahieu } 556*7cd08927SColin LeMahieu 5577c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5587c958713SColin LeMahieu uint64_t /*Address*/, 5597c958713SColin LeMahieu const void *Decoder) { 5607c958713SColin LeMahieu static const uint16_t VecPredRegDecoderTable[] = {Hexagon::Q0, Hexagon::Q1, 5617c958713SColin LeMahieu Hexagon::Q2, Hexagon::Q3}; 5627c958713SColin LeMahieu 5637c958713SColin LeMahieu return (DecodeRegisterClass(Inst, RegNo, VecPredRegDecoderTable, 5647c958713SColin LeMahieu sizeof(VecPredRegDecoderTable))); 5657c958713SColin LeMahieu } 566be8c453dSColin LeMahieu 567*7cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 568*7cd08927SColin LeMahieu uint64_t /*Address*/, 569*7cd08927SColin LeMahieu const void *Decoder) { 570*7cd08927SColin LeMahieu static const uint16_t CtrlRegDecoderTable[] = { 571*7cd08927SColin LeMahieu Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1, 572*7cd08927SColin LeMahieu Hexagon::P3_0, Hexagon::C5, Hexagon::C6, Hexagon::C7, 573*7cd08927SColin LeMahieu Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP, 574*7cd08927SColin LeMahieu Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPC 575*7cd08927SColin LeMahieu }; 576*7cd08927SColin LeMahieu 577*7cd08927SColin LeMahieu if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0])) 578*7cd08927SColin LeMahieu return MCDisassembler::Fail; 579*7cd08927SColin LeMahieu 580*7cd08927SColin LeMahieu if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister) 581*7cd08927SColin LeMahieu return MCDisassembler::Fail; 582*7cd08927SColin LeMahieu 583*7cd08927SColin LeMahieu unsigned Register = CtrlRegDecoderTable[RegNo]; 584*7cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 585*7cd08927SColin LeMahieu return MCDisassembler::Success; 586*7cd08927SColin LeMahieu } 587*7cd08927SColin LeMahieu 588*7cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, 589*7cd08927SColin LeMahieu uint64_t /*Address*/, 590*7cd08927SColin LeMahieu const void *Decoder) { 591*7cd08927SColin LeMahieu static const uint16_t CtrlReg64DecoderTable[] = { 592*7cd08927SColin LeMahieu Hexagon::C1_0, Hexagon::NoRegister, 593*7cd08927SColin LeMahieu Hexagon::C3_2, Hexagon::NoRegister, 594*7cd08927SColin LeMahieu Hexagon::C7_6, Hexagon::NoRegister, 595*7cd08927SColin LeMahieu Hexagon::C9_8, Hexagon::NoRegister, 596*7cd08927SColin LeMahieu Hexagon::C11_10, Hexagon::NoRegister, 597*7cd08927SColin LeMahieu Hexagon::CS, Hexagon::NoRegister, 598*7cd08927SColin LeMahieu Hexagon::UPC, Hexagon::NoRegister 599*7cd08927SColin LeMahieu }; 600*7cd08927SColin LeMahieu 601*7cd08927SColin LeMahieu if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0])) 602*7cd08927SColin LeMahieu return MCDisassembler::Fail; 603*7cd08927SColin LeMahieu 604*7cd08927SColin LeMahieu if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister) 605*7cd08927SColin LeMahieu return MCDisassembler::Fail; 606*7cd08927SColin LeMahieu 607*7cd08927SColin LeMahieu unsigned Register = CtrlReg64DecoderTable[RegNo]; 608*7cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 609*7cd08927SColin LeMahieu return MCDisassembler::Success; 610*7cd08927SColin LeMahieu } 611*7cd08927SColin LeMahieu 612*7cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 613*7cd08927SColin LeMahieu uint64_t /*Address*/, 614*7cd08927SColin LeMahieu const void *Decoder) { 615*7cd08927SColin LeMahieu unsigned Register = 0; 616*7cd08927SColin LeMahieu switch (RegNo) { 617*7cd08927SColin LeMahieu case 0: 618*7cd08927SColin LeMahieu Register = Hexagon::M0; 619*7cd08927SColin LeMahieu break; 620*7cd08927SColin LeMahieu case 1: 621*7cd08927SColin LeMahieu Register = Hexagon::M1; 622*7cd08927SColin LeMahieu break; 623*7cd08927SColin LeMahieu default: 624*7cd08927SColin LeMahieu return MCDisassembler::Fail; 625*7cd08927SColin LeMahieu } 626*7cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 627*7cd08927SColin LeMahieu return MCDisassembler::Success; 628*7cd08927SColin LeMahieu } 629*7cd08927SColin LeMahieu 630*7cd08927SColin LeMahieu namespace { 631*7cd08927SColin LeMahieu uint32_t fullValue(MCInstrInfo const &MCII, 632*7cd08927SColin LeMahieu MCInst &MCB, 633*7cd08927SColin LeMahieu MCInst &MI, 634*7cd08927SColin LeMahieu int64_t Value) { 635*7cd08927SColin LeMahieu MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex( 636*7cd08927SColin LeMahieu MCB, HexagonMCInstrInfo::bundleSize(MCB)); 637*7cd08927SColin LeMahieu if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI)) 638*7cd08927SColin LeMahieu return Value; 639*7cd08927SColin LeMahieu unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 640*7cd08927SColin LeMahieu uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f; 641*7cd08927SColin LeMahieu int64_t Bits; 642*7cd08927SColin LeMahieu bool Success = Extender->getOperand(0).getExpr()->evaluateAsAbsolute(Bits); 643*7cd08927SColin LeMahieu assert(Success);(void)Success; 644*7cd08927SColin LeMahieu uint32_t Upper26 = static_cast<uint32_t>(Bits); 645*7cd08927SColin LeMahieu uint32_t Operand = Upper26 | Lower6; 646*7cd08927SColin LeMahieu return Operand; 647*7cd08927SColin LeMahieu } 648*7cd08927SColin LeMahieu template <size_t T> 649*7cd08927SColin LeMahieu void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) { 650*7cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 651*7cd08927SColin LeMahieu int64_t FullValue = fullValue(*Disassembler.MCII, 652*7cd08927SColin LeMahieu **Disassembler.CurrentBundle, 653*7cd08927SColin LeMahieu MI, SignExtend64<T>(tmp)); 654*7cd08927SColin LeMahieu int64_t Extended = SignExtend64<32>(FullValue); 655*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Extended, 656*7cd08927SColin LeMahieu Disassembler.getContext()); 657*7cd08927SColin LeMahieu } 658*7cd08927SColin LeMahieu } 659*7cd08927SColin LeMahieu 660*7cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, 661*7cd08927SColin LeMahieu uint64_t /*Address*/, 662*7cd08927SColin LeMahieu const void *Decoder) { 663*7cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 664*7cd08927SColin LeMahieu int64_t FullValue = fullValue(*Disassembler.MCII, 665*7cd08927SColin LeMahieu **Disassembler.CurrentBundle, 666*7cd08927SColin LeMahieu MI, tmp); 667*7cd08927SColin LeMahieu assert(FullValue >= 0 && "Negative in unsigned decoder"); 668*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext()); 669*7cd08927SColin LeMahieu return MCDisassembler::Success; 670*7cd08927SColin LeMahieu } 671*7cd08927SColin LeMahieu 6721e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, 6731e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 674*7cd08927SColin LeMahieu signedDecoder<16>(MI, tmp, Decoder); 6751e9d1d76SColin LeMahieu return MCDisassembler::Success; 6761e9d1d76SColin LeMahieu } 6771e9d1d76SColin LeMahieu 6781e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, 6791e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 680*7cd08927SColin LeMahieu signedDecoder<12>(MI, tmp, Decoder); 6811e9d1d76SColin LeMahieu return MCDisassembler::Success; 6821e9d1d76SColin LeMahieu } 6831e9d1d76SColin LeMahieu 6841e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, 6851e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 686*7cd08927SColin LeMahieu signedDecoder<11>(MI, tmp, Decoder); 6871e9d1d76SColin LeMahieu return MCDisassembler::Success; 6881e9d1d76SColin LeMahieu } 6891e9d1d76SColin LeMahieu 6901e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, 6911e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 692*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, SignExtend64<12>(tmp), contextFromDecoder(Decoder)); 6931e9d1d76SColin LeMahieu return MCDisassembler::Success; 6941e9d1d76SColin LeMahieu } 6951e9d1d76SColin LeMahieu 6961e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, 6971e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 698*7cd08927SColin LeMahieu signedDecoder<13>(MI, tmp, Decoder); 6991e9d1d76SColin LeMahieu return MCDisassembler::Success; 7001e9d1d76SColin LeMahieu } 7011e9d1d76SColin LeMahieu 7021e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, 7031e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 704*7cd08927SColin LeMahieu signedDecoder<14>(MI, tmp, Decoder); 7051e9d1d76SColin LeMahieu return MCDisassembler::Success; 7061e9d1d76SColin LeMahieu } 7071e9d1d76SColin LeMahieu 7081e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, 7091e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 710*7cd08927SColin LeMahieu signedDecoder<10>(MI, tmp, Decoder); 7111e9d1d76SColin LeMahieu return MCDisassembler::Success; 7121e9d1d76SColin LeMahieu } 7131e9d1d76SColin LeMahieu 7141e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/, 7151e9d1d76SColin LeMahieu const void *Decoder) { 716*7cd08927SColin LeMahieu signedDecoder<8>(MI, tmp, Decoder); 7171e9d1d76SColin LeMahieu return MCDisassembler::Success; 7181e9d1d76SColin LeMahieu } 7191e9d1d76SColin LeMahieu 7201e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, 7211e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 722*7cd08927SColin LeMahieu signedDecoder<6>(MI, tmp, Decoder); 7231e9d1d76SColin LeMahieu return MCDisassembler::Success; 7241e9d1d76SColin LeMahieu } 7251e9d1d76SColin LeMahieu 7261e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, 7271e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 728*7cd08927SColin LeMahieu signedDecoder<4>(MI, tmp, Decoder); 7291e9d1d76SColin LeMahieu return MCDisassembler::Success; 7301e9d1d76SColin LeMahieu } 7311e9d1d76SColin LeMahieu 7321e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, 7331e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 734*7cd08927SColin LeMahieu signedDecoder<5>(MI, tmp, Decoder); 7351e9d1d76SColin LeMahieu return MCDisassembler::Success; 7361e9d1d76SColin LeMahieu } 7371e9d1d76SColin LeMahieu 7381e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, 7391e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 740*7cd08927SColin LeMahieu signedDecoder<6>(MI, tmp, Decoder); 7411e9d1d76SColin LeMahieu return MCDisassembler::Success; 7421e9d1d76SColin LeMahieu } 7431e9d1d76SColin LeMahieu 7441e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, 7451e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 746*7cd08927SColin LeMahieu signedDecoder<7>(MI, tmp, Decoder); 7471e9d1d76SColin LeMahieu return MCDisassembler::Success; 7481e9d1d76SColin LeMahieu } 7491e9d1d76SColin LeMahieu 7507c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, 7517c958713SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 752*7cd08927SColin LeMahieu signedDecoder<10>(MI, tmp, Decoder); 7537c958713SColin LeMahieu return MCDisassembler::Success; 7547c958713SColin LeMahieu } 7557c958713SColin LeMahieu 7567c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, 7577c958713SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 758*7cd08927SColin LeMahieu signedDecoder<19>(MI, tmp, Decoder); 7597c958713SColin LeMahieu return MCDisassembler::Success; 7607c958713SColin LeMahieu } 7617c958713SColin LeMahieu 762*7cd08927SColin LeMahieu // custom decoder for various jump/call immediates 763*7cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 764*7cd08927SColin LeMahieu const void *Decoder) { 765*7cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 766*7cd08927SColin LeMahieu unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI); 767*7cd08927SColin LeMahieu // r13_2 is not extendable, so if there are no extent bits, it's r13_2 768*7cd08927SColin LeMahieu if (Bits == 0) 769*7cd08927SColin LeMahieu Bits = 15; 770*7cd08927SColin LeMahieu uint32_t FullValue = fullValue(*Disassembler.MCII, 771*7cd08927SColin LeMahieu **Disassembler.CurrentBundle, 772*7cd08927SColin LeMahieu MI, SignExtend64(tmp, Bits)); 773*7cd08927SColin LeMahieu int64_t Extended = SignExtend64<32>(FullValue) + Address; 774*7cd08927SColin LeMahieu if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 775*7cd08927SColin LeMahieu 0, 4)) 776*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); 777*7cd08927SColin LeMahieu return MCDisassembler::Success; 778*7cd08927SColin LeMahieu } 779*7cd08927SColin LeMahieu 780*7cd08927SColin LeMahieu // Addressing mode dependent load store opcode map. 781*7cd08927SColin LeMahieu // - If an insn is preceded by an extender the address is absolute. 782*7cd08927SColin LeMahieu // - memw(##symbol) = r0 783*7cd08927SColin LeMahieu // - If an insn is not preceded by an extender the address is GP relative. 784*7cd08927SColin LeMahieu // - memw(gp + #symbol) = r0 785*7cd08927SColin LeMahieu // Please note that the instructions must be ordered in the descending order 786*7cd08927SColin LeMahieu // of their opcode. 787*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_ST 788*7cd08927SColin LeMahieu static unsigned int StoreConditionalOpcodeData[][2] = { 789*7cd08927SColin LeMahieu {S4_pstorerdfnew_abs, 0xafc02084}, 790*7cd08927SColin LeMahieu {S4_pstorerdtnew_abs, 0xafc02080}, 791*7cd08927SColin LeMahieu {S4_pstorerdf_abs, 0xafc00084}, 792*7cd08927SColin LeMahieu {S4_pstorerdt_abs, 0xafc00080}, 793*7cd08927SColin LeMahieu {S4_pstorerinewfnew_abs, 0xafa03084}, 794*7cd08927SColin LeMahieu {S4_pstorerinewtnew_abs, 0xafa03080}, 795*7cd08927SColin LeMahieu {S4_pstorerhnewfnew_abs, 0xafa02884}, 796*7cd08927SColin LeMahieu {S4_pstorerhnewtnew_abs, 0xafa02880}, 797*7cd08927SColin LeMahieu {S4_pstorerbnewfnew_abs, 0xafa02084}, 798*7cd08927SColin LeMahieu {S4_pstorerbnewtnew_abs, 0xafa02080}, 799*7cd08927SColin LeMahieu {S4_pstorerinewf_abs, 0xafa01084}, 800*7cd08927SColin LeMahieu {S4_pstorerinewt_abs, 0xafa01080}, 801*7cd08927SColin LeMahieu {S4_pstorerhnewf_abs, 0xafa00884}, 802*7cd08927SColin LeMahieu {S4_pstorerhnewt_abs, 0xafa00880}, 803*7cd08927SColin LeMahieu {S4_pstorerbnewf_abs, 0xafa00084}, 804*7cd08927SColin LeMahieu {S4_pstorerbnewt_abs, 0xafa00080}, 805*7cd08927SColin LeMahieu {S4_pstorerifnew_abs, 0xaf802084}, 806*7cd08927SColin LeMahieu {S4_pstoreritnew_abs, 0xaf802080}, 807*7cd08927SColin LeMahieu {S4_pstorerif_abs, 0xaf800084}, 808*7cd08927SColin LeMahieu {S4_pstorerit_abs, 0xaf800080}, 809*7cd08927SColin LeMahieu {S4_pstorerhfnew_abs, 0xaf402084}, 810*7cd08927SColin LeMahieu {S4_pstorerhtnew_abs, 0xaf402080}, 811*7cd08927SColin LeMahieu {S4_pstorerhf_abs, 0xaf400084}, 812*7cd08927SColin LeMahieu {S4_pstorerht_abs, 0xaf400080}, 813*7cd08927SColin LeMahieu {S4_pstorerbfnew_abs, 0xaf002084}, 814*7cd08927SColin LeMahieu {S4_pstorerbtnew_abs, 0xaf002080}, 815*7cd08927SColin LeMahieu {S4_pstorerbf_abs, 0xaf000084}, 816*7cd08927SColin LeMahieu {S4_pstorerbt_abs, 0xaf000080}}; 817*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD 818*7cd08927SColin LeMahieu 819*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD_ST_2 820*7cd08927SColin LeMahieu static unsigned int LoadStoreOpcodeData[][2] = {{L4_loadrd_abs, 0x49c00000}, 821*7cd08927SColin LeMahieu {L4_loadri_abs, 0x49800000}, 822*7cd08927SColin LeMahieu {L4_loadruh_abs, 0x49600000}, 823*7cd08927SColin LeMahieu {L4_loadrh_abs, 0x49400000}, 824*7cd08927SColin LeMahieu {L4_loadrub_abs, 0x49200000}, 825*7cd08927SColin LeMahieu {L4_loadrb_abs, 0x49000000}, 826*7cd08927SColin LeMahieu {S2_storerdabs, 0x48c00000}, 827*7cd08927SColin LeMahieu {S2_storerinewabs, 0x48a01000}, 828*7cd08927SColin LeMahieu {S2_storerhnewabs, 0x48a00800}, 829*7cd08927SColin LeMahieu {S2_storerbnewabs, 0x48a00000}, 830*7cd08927SColin LeMahieu {S2_storeriabs, 0x48800000}, 831*7cd08927SColin LeMahieu {S2_storerfabs, 0x48600000}, 832*7cd08927SColin LeMahieu {S2_storerhabs, 0x48400000}, 833*7cd08927SColin LeMahieu {S2_storerbabs, 0x48000000}}; 834*7cd08927SColin LeMahieu static int NumCondS = 835*7cd08927SColin LeMahieu sizeof(StoreConditionalOpcodeData) / sizeof(StoreConditionalOpcodeData[0]); 836*7cd08927SColin LeMahieu static int NumLS = sizeof(LoadStoreOpcodeData) / sizeof(LoadStoreOpcodeData[0]); 837*7cd08927SColin LeMahieu 838*7cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) { 839*7cd08927SColin LeMahieu 840*7cd08927SColin LeMahieu unsigned MachineOpcode = 0; 841*7cd08927SColin LeMahieu unsigned LLVMOpcode = 0; 842*7cd08927SColin LeMahieu int i; 843*7cd08927SColin LeMahieu 844*7cd08927SColin LeMahieu if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_ST) { 845*7cd08927SColin LeMahieu for (i = 0; i < NumCondS; ++i) { 846*7cd08927SColin LeMahieu if ((insn & StoreConditionalOpcodeData[i][1]) == 847*7cd08927SColin LeMahieu StoreConditionalOpcodeData[i][1]) { 848*7cd08927SColin LeMahieu MachineOpcode = StoreConditionalOpcodeData[i][1]; 849*7cd08927SColin LeMahieu LLVMOpcode = StoreConditionalOpcodeData[i][0]; 850*7cd08927SColin LeMahieu break; 851*7cd08927SColin LeMahieu } 852*7cd08927SColin LeMahieu } 853*7cd08927SColin LeMahieu } 854*7cd08927SColin LeMahieu if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_LD_ST_2) { 855*7cd08927SColin LeMahieu for (i = 0; i < NumLS; ++i) { 856*7cd08927SColin LeMahieu if ((insn & LoadStoreOpcodeData[i][1]) == LoadStoreOpcodeData[i][1]) { 857*7cd08927SColin LeMahieu MachineOpcode = LoadStoreOpcodeData[i][1]; 858*7cd08927SColin LeMahieu LLVMOpcode = LoadStoreOpcodeData[i][0]; 859*7cd08927SColin LeMahieu break; 860*7cd08927SColin LeMahieu } 861*7cd08927SColin LeMahieu } 862*7cd08927SColin LeMahieu } 863*7cd08927SColin LeMahieu 864*7cd08927SColin LeMahieu if (MachineOpcode) { 865*7cd08927SColin LeMahieu unsigned Value = 0; 866*7cd08927SColin LeMahieu unsigned shift = 0; 867*7cd08927SColin LeMahieu MI.setOpcode(LLVMOpcode); 868*7cd08927SColin LeMahieu // Remove the parse bits from the insn. 869*7cd08927SColin LeMahieu insn &= ~HexagonII::INST_PARSE_MASK; 870*7cd08927SColin LeMahieu 871*7cd08927SColin LeMahieu switch (LLVMOpcode) { 872*7cd08927SColin LeMahieu default: 873*7cd08927SColin LeMahieu return MCDisassembler::Fail; 874*7cd08927SColin LeMahieu break; 875*7cd08927SColin LeMahieu 876*7cd08927SColin LeMahieu case Hexagon::S4_pstorerdf_abs: 877*7cd08927SColin LeMahieu case Hexagon::S4_pstorerdt_abs: 878*7cd08927SColin LeMahieu case Hexagon::S4_pstorerdfnew_abs: 879*7cd08927SColin LeMahieu case Hexagon::S4_pstorerdtnew_abs: { 880*7cd08927SColin LeMahieu // op: Pv 881*7cd08927SColin LeMahieu Value = insn & UINT64_C(3); 882*7cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 883*7cd08927SColin LeMahieu // op: u6 884*7cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 885*7cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 886*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 887*7cd08927SColin LeMahieu // op: Rtt 888*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 889*7cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 890*7cd08927SColin LeMahieu break; 891*7cd08927SColin LeMahieu } 892*7cd08927SColin LeMahieu 893*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewf_abs: 894*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewt_abs: 895*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewfnew_abs: 896*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewtnew_abs: 897*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewf_abs: 898*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewt_abs: 899*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewfnew_abs: 900*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewtnew_abs: 901*7cd08927SColin LeMahieu case Hexagon::S4_pstorerinewf_abs: 902*7cd08927SColin LeMahieu case Hexagon::S4_pstorerinewt_abs: 903*7cd08927SColin LeMahieu case Hexagon::S4_pstorerinewfnew_abs: 904*7cd08927SColin LeMahieu case Hexagon::S4_pstorerinewtnew_abs: { 905*7cd08927SColin LeMahieu // op: Pv 906*7cd08927SColin LeMahieu Value = insn & UINT64_C(3); 907*7cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 908*7cd08927SColin LeMahieu // op: u6 909*7cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 910*7cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 911*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 912*7cd08927SColin LeMahieu // op: Nt 913*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(7); 914*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 915*7cd08927SColin LeMahieu break; 916*7cd08927SColin LeMahieu } 917*7cd08927SColin LeMahieu 918*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbf_abs: 919*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbt_abs: 920*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbfnew_abs: 921*7cd08927SColin LeMahieu case Hexagon::S4_pstorerbtnew_abs: 922*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhf_abs: 923*7cd08927SColin LeMahieu case Hexagon::S4_pstorerht_abs: 924*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhfnew_abs: 925*7cd08927SColin LeMahieu case Hexagon::S4_pstorerhtnew_abs: 926*7cd08927SColin LeMahieu case Hexagon::S4_pstorerif_abs: 927*7cd08927SColin LeMahieu case Hexagon::S4_pstorerit_abs: 928*7cd08927SColin LeMahieu case Hexagon::S4_pstorerifnew_abs: 929*7cd08927SColin LeMahieu case Hexagon::S4_pstoreritnew_abs: { 930*7cd08927SColin LeMahieu // op: Pv 931*7cd08927SColin LeMahieu Value = insn & UINT64_C(3); 932*7cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 933*7cd08927SColin LeMahieu // op: u6 934*7cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 935*7cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 936*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 937*7cd08927SColin LeMahieu // op: Rt 938*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 939*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 940*7cd08927SColin LeMahieu break; 941*7cd08927SColin LeMahieu } 942*7cd08927SColin LeMahieu 943*7cd08927SColin LeMahieu case Hexagon::L4_ploadrdf_abs: 944*7cd08927SColin LeMahieu case Hexagon::L4_ploadrdt_abs: 945*7cd08927SColin LeMahieu case Hexagon::L4_ploadrdfnew_abs: 946*7cd08927SColin LeMahieu case Hexagon::L4_ploadrdtnew_abs: { 947*7cd08927SColin LeMahieu // op: Rdd 948*7cd08927SColin LeMahieu Value = insn & UINT64_C(31); 949*7cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 950*7cd08927SColin LeMahieu // op: Pt 951*7cd08927SColin LeMahieu Value = ((insn >> 9) & UINT64_C(3)); 952*7cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 953*7cd08927SColin LeMahieu // op: u6 954*7cd08927SColin LeMahieu Value = ((insn >> 15) & UINT64_C(62)); 955*7cd08927SColin LeMahieu Value |= ((insn >> 8) & UINT64_C(1)); 956*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 957*7cd08927SColin LeMahieu break; 958*7cd08927SColin LeMahieu } 959*7cd08927SColin LeMahieu 960*7cd08927SColin LeMahieu case Hexagon::L4_ploadrbf_abs: 961*7cd08927SColin LeMahieu case Hexagon::L4_ploadrbt_abs: 962*7cd08927SColin LeMahieu case Hexagon::L4_ploadrbfnew_abs: 963*7cd08927SColin LeMahieu case Hexagon::L4_ploadrbtnew_abs: 964*7cd08927SColin LeMahieu case Hexagon::L4_ploadrhf_abs: 965*7cd08927SColin LeMahieu case Hexagon::L4_ploadrht_abs: 966*7cd08927SColin LeMahieu case Hexagon::L4_ploadrhfnew_abs: 967*7cd08927SColin LeMahieu case Hexagon::L4_ploadrhtnew_abs: 968*7cd08927SColin LeMahieu case Hexagon::L4_ploadrubf_abs: 969*7cd08927SColin LeMahieu case Hexagon::L4_ploadrubt_abs: 970*7cd08927SColin LeMahieu case Hexagon::L4_ploadrubfnew_abs: 971*7cd08927SColin LeMahieu case Hexagon::L4_ploadrubtnew_abs: 972*7cd08927SColin LeMahieu case Hexagon::L4_ploadruhf_abs: 973*7cd08927SColin LeMahieu case Hexagon::L4_ploadruht_abs: 974*7cd08927SColin LeMahieu case Hexagon::L4_ploadruhfnew_abs: 975*7cd08927SColin LeMahieu case Hexagon::L4_ploadruhtnew_abs: 976*7cd08927SColin LeMahieu case Hexagon::L4_ploadrif_abs: 977*7cd08927SColin LeMahieu case Hexagon::L4_ploadrit_abs: 978*7cd08927SColin LeMahieu case Hexagon::L4_ploadrifnew_abs: 979*7cd08927SColin LeMahieu case Hexagon::L4_ploadritnew_abs: 980*7cd08927SColin LeMahieu // op: Rd 981*7cd08927SColin LeMahieu Value = insn & UINT64_C(31); 982*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 983*7cd08927SColin LeMahieu // op: Pt 984*7cd08927SColin LeMahieu Value = (insn >> 9) & UINT64_C(3); 985*7cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 986*7cd08927SColin LeMahieu // op: u6 987*7cd08927SColin LeMahieu Value = (insn >> 15) & UINT64_C(62); 988*7cd08927SColin LeMahieu Value |= (insn >> 8) & UINT64_C(1); 989*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 990*7cd08927SColin LeMahieu break; 991*7cd08927SColin LeMahieu 992*7cd08927SColin LeMahieu // op: g16_2 993*7cd08927SColin LeMahieu case (Hexagon::L4_loadri_abs): 994*7cd08927SColin LeMahieu ++shift; 995*7cd08927SColin LeMahieu // op: g16_1 996*7cd08927SColin LeMahieu case Hexagon::L4_loadrh_abs: 997*7cd08927SColin LeMahieu case Hexagon::L4_loadruh_abs: 998*7cd08927SColin LeMahieu ++shift; 999*7cd08927SColin LeMahieu // op: g16_0 1000*7cd08927SColin LeMahieu case Hexagon::L4_loadrb_abs: 1001*7cd08927SColin LeMahieu case Hexagon::L4_loadrub_abs: { 1002*7cd08927SColin LeMahieu // op: Rd 1003*7cd08927SColin LeMahieu Value |= insn & UINT64_C(31); 1004*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 1005*7cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 1006*7cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 1007*7cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(511); 1008*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 1009*7cd08927SColin LeMahieu break; 1010*7cd08927SColin LeMahieu } 1011*7cd08927SColin LeMahieu 1012*7cd08927SColin LeMahieu case Hexagon::L4_loadrd_abs: { 1013*7cd08927SColin LeMahieu Value = insn & UINT64_C(31); 1014*7cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 1015*7cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 1016*7cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 1017*7cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(511); 1018*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << 3)); 1019*7cd08927SColin LeMahieu break; 1020*7cd08927SColin LeMahieu } 1021*7cd08927SColin LeMahieu 1022*7cd08927SColin LeMahieu case Hexagon::S2_storerdabs: { 1023*7cd08927SColin LeMahieu // op: g16_3 1024*7cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 1025*7cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 1026*7cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 1027*7cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 1028*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << 3)); 1029*7cd08927SColin LeMahieu // op: Rtt 1030*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 1031*7cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 1032*7cd08927SColin LeMahieu break; 1033*7cd08927SColin LeMahieu } 1034*7cd08927SColin LeMahieu 1035*7cd08927SColin LeMahieu // op: g16_2 1036*7cd08927SColin LeMahieu case Hexagon::S2_storerinewabs: 1037*7cd08927SColin LeMahieu ++shift; 1038*7cd08927SColin LeMahieu // op: g16_1 1039*7cd08927SColin LeMahieu case Hexagon::S2_storerhnewabs: 1040*7cd08927SColin LeMahieu ++shift; 1041*7cd08927SColin LeMahieu // op: g16_0 1042*7cd08927SColin LeMahieu case Hexagon::S2_storerbnewabs: { 1043*7cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 1044*7cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 1045*7cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 1046*7cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 1047*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 1048*7cd08927SColin LeMahieu // op: Nt 1049*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(7); 1050*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 1051*7cd08927SColin LeMahieu break; 1052*7cd08927SColin LeMahieu } 1053*7cd08927SColin LeMahieu 1054*7cd08927SColin LeMahieu // op: g16_2 1055*7cd08927SColin LeMahieu case Hexagon::S2_storeriabs: 1056*7cd08927SColin LeMahieu ++shift; 1057*7cd08927SColin LeMahieu // op: g16_1 1058*7cd08927SColin LeMahieu case Hexagon::S2_storerhabs: 1059*7cd08927SColin LeMahieu case Hexagon::S2_storerfabs: 1060*7cd08927SColin LeMahieu ++shift; 1061*7cd08927SColin LeMahieu // op: g16_0 1062*7cd08927SColin LeMahieu case Hexagon::S2_storerbabs: { 1063*7cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 1064*7cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 1065*7cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 1066*7cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 1067*7cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 1068*7cd08927SColin LeMahieu // op: Rt 1069*7cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 1070*7cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 1071*7cd08927SColin LeMahieu break; 1072*7cd08927SColin LeMahieu } 1073*7cd08927SColin LeMahieu } 1074*7cd08927SColin LeMahieu return MCDisassembler::Success; 1075*7cd08927SColin LeMahieu } 1076*7cd08927SColin LeMahieu return MCDisassembler::Fail; 1077*7cd08927SColin LeMahieu } 1078*7cd08927SColin LeMahieu 1079*7cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn, 1080*7cd08927SColin LeMahieu void const *Decoder) { 1081*7cd08927SColin LeMahieu 1082*7cd08927SColin LeMahieu // Instruction Class for a constant a extender: bits 31:28 = 0x0000 1083*7cd08927SColin LeMahieu if ((~insn & 0xf0000000) == 0xf0000000) { 1084*7cd08927SColin LeMahieu unsigned Value; 1085*7cd08927SColin LeMahieu // 27:16 High 12 bits of 26-bit extender. 1086*7cd08927SColin LeMahieu Value = (insn & 0x0fff0000) << 4; 1087*7cd08927SColin LeMahieu // 13:0 Low 14 bits of 26-bit extender. 1088*7cd08927SColin LeMahieu Value |= ((insn & 0x3fff) << 6); 1089*7cd08927SColin LeMahieu MI.setOpcode(Hexagon::A4_ext); 1090*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Value, contextFromDecoder(Decoder)); 1091*7cd08927SColin LeMahieu return MCDisassembler::Success; 1092*7cd08927SColin LeMahieu } 1093*7cd08927SColin LeMahieu return MCDisassembler::Fail; 1094*7cd08927SColin LeMahieu } 1095*7cd08927SColin LeMahieu 1096be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td 1097be8c453dSColin LeMahieu enum subInstBinaryValues { 1098be8c453dSColin LeMahieu V4_SA1_addi_BITS = 0x0000, 1099be8c453dSColin LeMahieu V4_SA1_addi_MASK = 0x1800, 1100be8c453dSColin LeMahieu V4_SA1_addrx_BITS = 0x1800, 1101be8c453dSColin LeMahieu V4_SA1_addrx_MASK = 0x1f00, 1102be8c453dSColin LeMahieu V4_SA1_addsp_BITS = 0x0c00, 1103be8c453dSColin LeMahieu V4_SA1_addsp_MASK = 0x1c00, 1104be8c453dSColin LeMahieu V4_SA1_and1_BITS = 0x1200, 1105be8c453dSColin LeMahieu V4_SA1_and1_MASK = 0x1f00, 1106be8c453dSColin LeMahieu V4_SA1_clrf_BITS = 0x1a70, 1107be8c453dSColin LeMahieu V4_SA1_clrf_MASK = 0x1e70, 1108be8c453dSColin LeMahieu V4_SA1_clrfnew_BITS = 0x1a50, 1109be8c453dSColin LeMahieu V4_SA1_clrfnew_MASK = 0x1e70, 1110be8c453dSColin LeMahieu V4_SA1_clrt_BITS = 0x1a60, 1111be8c453dSColin LeMahieu V4_SA1_clrt_MASK = 0x1e70, 1112be8c453dSColin LeMahieu V4_SA1_clrtnew_BITS = 0x1a40, 1113be8c453dSColin LeMahieu V4_SA1_clrtnew_MASK = 0x1e70, 1114be8c453dSColin LeMahieu V4_SA1_cmpeqi_BITS = 0x1900, 1115be8c453dSColin LeMahieu V4_SA1_cmpeqi_MASK = 0x1f00, 1116be8c453dSColin LeMahieu V4_SA1_combine0i_BITS = 0x1c00, 1117be8c453dSColin LeMahieu V4_SA1_combine0i_MASK = 0x1d18, 1118be8c453dSColin LeMahieu V4_SA1_combine1i_BITS = 0x1c08, 1119be8c453dSColin LeMahieu V4_SA1_combine1i_MASK = 0x1d18, 1120be8c453dSColin LeMahieu V4_SA1_combine2i_BITS = 0x1c10, 1121be8c453dSColin LeMahieu V4_SA1_combine2i_MASK = 0x1d18, 1122be8c453dSColin LeMahieu V4_SA1_combine3i_BITS = 0x1c18, 1123be8c453dSColin LeMahieu V4_SA1_combine3i_MASK = 0x1d18, 1124be8c453dSColin LeMahieu V4_SA1_combinerz_BITS = 0x1d08, 1125be8c453dSColin LeMahieu V4_SA1_combinerz_MASK = 0x1d08, 1126be8c453dSColin LeMahieu V4_SA1_combinezr_BITS = 0x1d00, 1127be8c453dSColin LeMahieu V4_SA1_combinezr_MASK = 0x1d08, 1128be8c453dSColin LeMahieu V4_SA1_dec_BITS = 0x1300, 1129be8c453dSColin LeMahieu V4_SA1_dec_MASK = 0x1f00, 1130be8c453dSColin LeMahieu V4_SA1_inc_BITS = 0x1100, 1131be8c453dSColin LeMahieu V4_SA1_inc_MASK = 0x1f00, 1132be8c453dSColin LeMahieu V4_SA1_seti_BITS = 0x0800, 1133be8c453dSColin LeMahieu V4_SA1_seti_MASK = 0x1c00, 1134be8c453dSColin LeMahieu V4_SA1_setin1_BITS = 0x1a00, 1135be8c453dSColin LeMahieu V4_SA1_setin1_MASK = 0x1e40, 1136be8c453dSColin LeMahieu V4_SA1_sxtb_BITS = 0x1500, 1137be8c453dSColin LeMahieu V4_SA1_sxtb_MASK = 0x1f00, 1138be8c453dSColin LeMahieu V4_SA1_sxth_BITS = 0x1400, 1139be8c453dSColin LeMahieu V4_SA1_sxth_MASK = 0x1f00, 1140be8c453dSColin LeMahieu V4_SA1_tfr_BITS = 0x1000, 1141be8c453dSColin LeMahieu V4_SA1_tfr_MASK = 0x1f00, 1142be8c453dSColin LeMahieu V4_SA1_zxtb_BITS = 0x1700, 1143be8c453dSColin LeMahieu V4_SA1_zxtb_MASK = 0x1f00, 1144be8c453dSColin LeMahieu V4_SA1_zxth_BITS = 0x1600, 1145be8c453dSColin LeMahieu V4_SA1_zxth_MASK = 0x1f00, 1146be8c453dSColin LeMahieu V4_SL1_loadri_io_BITS = 0x0000, 1147be8c453dSColin LeMahieu V4_SL1_loadri_io_MASK = 0x1000, 1148be8c453dSColin LeMahieu V4_SL1_loadrub_io_BITS = 0x1000, 1149be8c453dSColin LeMahieu V4_SL1_loadrub_io_MASK = 0x1000, 1150be8c453dSColin LeMahieu V4_SL2_deallocframe_BITS = 0x1f00, 1151be8c453dSColin LeMahieu V4_SL2_deallocframe_MASK = 0x1fc0, 1152be8c453dSColin LeMahieu V4_SL2_jumpr31_BITS = 0x1fc0, 1153be8c453dSColin LeMahieu V4_SL2_jumpr31_MASK = 0x1fc4, 1154be8c453dSColin LeMahieu V4_SL2_jumpr31_f_BITS = 0x1fc5, 1155be8c453dSColin LeMahieu V4_SL2_jumpr31_f_MASK = 0x1fc7, 1156be8c453dSColin LeMahieu V4_SL2_jumpr31_fnew_BITS = 0x1fc7, 1157be8c453dSColin LeMahieu V4_SL2_jumpr31_fnew_MASK = 0x1fc7, 1158be8c453dSColin LeMahieu V4_SL2_jumpr31_t_BITS = 0x1fc4, 1159be8c453dSColin LeMahieu V4_SL2_jumpr31_t_MASK = 0x1fc7, 1160be8c453dSColin LeMahieu V4_SL2_jumpr31_tnew_BITS = 0x1fc6, 1161be8c453dSColin LeMahieu V4_SL2_jumpr31_tnew_MASK = 0x1fc7, 1162be8c453dSColin LeMahieu V4_SL2_loadrb_io_BITS = 0x1000, 1163be8c453dSColin LeMahieu V4_SL2_loadrb_io_MASK = 0x1800, 1164be8c453dSColin LeMahieu V4_SL2_loadrd_sp_BITS = 0x1e00, 1165be8c453dSColin LeMahieu V4_SL2_loadrd_sp_MASK = 0x1f00, 1166be8c453dSColin LeMahieu V4_SL2_loadrh_io_BITS = 0x0000, 1167be8c453dSColin LeMahieu V4_SL2_loadrh_io_MASK = 0x1800, 1168be8c453dSColin LeMahieu V4_SL2_loadri_sp_BITS = 0x1c00, 1169be8c453dSColin LeMahieu V4_SL2_loadri_sp_MASK = 0x1e00, 1170be8c453dSColin LeMahieu V4_SL2_loadruh_io_BITS = 0x0800, 1171be8c453dSColin LeMahieu V4_SL2_loadruh_io_MASK = 0x1800, 1172be8c453dSColin LeMahieu V4_SL2_return_BITS = 0x1f40, 1173be8c453dSColin LeMahieu V4_SL2_return_MASK = 0x1fc4, 1174be8c453dSColin LeMahieu V4_SL2_return_f_BITS = 0x1f45, 1175be8c453dSColin LeMahieu V4_SL2_return_f_MASK = 0x1fc7, 1176be8c453dSColin LeMahieu V4_SL2_return_fnew_BITS = 0x1f47, 1177be8c453dSColin LeMahieu V4_SL2_return_fnew_MASK = 0x1fc7, 1178be8c453dSColin LeMahieu V4_SL2_return_t_BITS = 0x1f44, 1179be8c453dSColin LeMahieu V4_SL2_return_t_MASK = 0x1fc7, 1180be8c453dSColin LeMahieu V4_SL2_return_tnew_BITS = 0x1f46, 1181be8c453dSColin LeMahieu V4_SL2_return_tnew_MASK = 0x1fc7, 1182be8c453dSColin LeMahieu V4_SS1_storeb_io_BITS = 0x1000, 1183be8c453dSColin LeMahieu V4_SS1_storeb_io_MASK = 0x1000, 1184be8c453dSColin LeMahieu V4_SS1_storew_io_BITS = 0x0000, 1185be8c453dSColin LeMahieu V4_SS1_storew_io_MASK = 0x1000, 1186be8c453dSColin LeMahieu V4_SS2_allocframe_BITS = 0x1c00, 1187be8c453dSColin LeMahieu V4_SS2_allocframe_MASK = 0x1e00, 1188be8c453dSColin LeMahieu V4_SS2_storebi0_BITS = 0x1200, 1189be8c453dSColin LeMahieu V4_SS2_storebi0_MASK = 0x1f00, 1190be8c453dSColin LeMahieu V4_SS2_storebi1_BITS = 0x1300, 1191be8c453dSColin LeMahieu V4_SS2_storebi1_MASK = 0x1f00, 1192be8c453dSColin LeMahieu V4_SS2_stored_sp_BITS = 0x0a00, 1193be8c453dSColin LeMahieu V4_SS2_stored_sp_MASK = 0x1e00, 1194be8c453dSColin LeMahieu V4_SS2_storeh_io_BITS = 0x0000, 1195be8c453dSColin LeMahieu V4_SS2_storeh_io_MASK = 0x1800, 1196be8c453dSColin LeMahieu V4_SS2_storew_sp_BITS = 0x0800, 1197be8c453dSColin LeMahieu V4_SS2_storew_sp_MASK = 0x1e00, 1198be8c453dSColin LeMahieu V4_SS2_storewi0_BITS = 0x1000, 1199be8c453dSColin LeMahieu V4_SS2_storewi0_MASK = 0x1f00, 1200be8c453dSColin LeMahieu V4_SS2_storewi1_BITS = 0x1100, 1201be8c453dSColin LeMahieu V4_SS2_storewi1_MASK = 0x1f00 1202be8c453dSColin LeMahieu }; 1203be8c453dSColin LeMahieu 1204be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op, 1205be8c453dSColin LeMahieu raw_ostream &os) { 1206be8c453dSColin LeMahieu switch (IClass) { 1207be8c453dSColin LeMahieu case HexagonII::HSIG_L1: 1208be8c453dSColin LeMahieu if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS) 1209be8c453dSColin LeMahieu op = Hexagon::V4_SL1_loadri_io; 1210be8c453dSColin LeMahieu else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS) 1211be8c453dSColin LeMahieu op = Hexagon::V4_SL1_loadrub_io; 1212be8c453dSColin LeMahieu else { 1213be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1214be8c453dSColin LeMahieu return MCDisassembler::Fail; 1215be8c453dSColin LeMahieu } 1216be8c453dSColin LeMahieu break; 1217be8c453dSColin LeMahieu case HexagonII::HSIG_L2: 1218be8c453dSColin LeMahieu if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS) 1219be8c453dSColin LeMahieu op = Hexagon::V4_SL2_deallocframe; 1220be8c453dSColin LeMahieu else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS) 1221be8c453dSColin LeMahieu op = Hexagon::V4_SL2_jumpr31; 1222be8c453dSColin LeMahieu else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS) 1223be8c453dSColin LeMahieu op = Hexagon::V4_SL2_jumpr31_f; 1224be8c453dSColin LeMahieu else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS) 1225be8c453dSColin LeMahieu op = Hexagon::V4_SL2_jumpr31_fnew; 1226be8c453dSColin LeMahieu else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS) 1227be8c453dSColin LeMahieu op = Hexagon::V4_SL2_jumpr31_t; 1228be8c453dSColin LeMahieu else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS) 1229be8c453dSColin LeMahieu op = Hexagon::V4_SL2_jumpr31_tnew; 1230be8c453dSColin LeMahieu else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS) 1231be8c453dSColin LeMahieu op = Hexagon::V4_SL2_loadrb_io; 1232be8c453dSColin LeMahieu else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS) 1233be8c453dSColin LeMahieu op = Hexagon::V4_SL2_loadrd_sp; 1234be8c453dSColin LeMahieu else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS) 1235be8c453dSColin LeMahieu op = Hexagon::V4_SL2_loadrh_io; 1236be8c453dSColin LeMahieu else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS) 1237be8c453dSColin LeMahieu op = Hexagon::V4_SL2_loadri_sp; 1238be8c453dSColin LeMahieu else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS) 1239be8c453dSColin LeMahieu op = Hexagon::V4_SL2_loadruh_io; 1240be8c453dSColin LeMahieu else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS) 1241be8c453dSColin LeMahieu op = Hexagon::V4_SL2_return; 1242be8c453dSColin LeMahieu else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS) 1243be8c453dSColin LeMahieu op = Hexagon::V4_SL2_return_f; 1244be8c453dSColin LeMahieu else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS) 1245be8c453dSColin LeMahieu op = Hexagon::V4_SL2_return_fnew; 1246be8c453dSColin LeMahieu else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS) 1247be8c453dSColin LeMahieu op = Hexagon::V4_SL2_return_t; 1248be8c453dSColin LeMahieu else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS) 1249be8c453dSColin LeMahieu op = Hexagon::V4_SL2_return_tnew; 1250be8c453dSColin LeMahieu else { 1251be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1252be8c453dSColin LeMahieu return MCDisassembler::Fail; 1253be8c453dSColin LeMahieu } 1254be8c453dSColin LeMahieu break; 1255be8c453dSColin LeMahieu case HexagonII::HSIG_A: 1256be8c453dSColin LeMahieu if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS) 1257be8c453dSColin LeMahieu op = Hexagon::V4_SA1_addi; 1258be8c453dSColin LeMahieu else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS) 1259be8c453dSColin LeMahieu op = Hexagon::V4_SA1_addrx; 1260be8c453dSColin LeMahieu else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS) 1261be8c453dSColin LeMahieu op = Hexagon::V4_SA1_addsp; 1262be8c453dSColin LeMahieu else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS) 1263be8c453dSColin LeMahieu op = Hexagon::V4_SA1_and1; 1264be8c453dSColin LeMahieu else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS) 1265be8c453dSColin LeMahieu op = Hexagon::V4_SA1_clrf; 1266be8c453dSColin LeMahieu else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS) 1267be8c453dSColin LeMahieu op = Hexagon::V4_SA1_clrfnew; 1268be8c453dSColin LeMahieu else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS) 1269be8c453dSColin LeMahieu op = Hexagon::V4_SA1_clrt; 1270be8c453dSColin LeMahieu else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS) 1271be8c453dSColin LeMahieu op = Hexagon::V4_SA1_clrtnew; 1272be8c453dSColin LeMahieu else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS) 1273be8c453dSColin LeMahieu op = Hexagon::V4_SA1_cmpeqi; 1274be8c453dSColin LeMahieu else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS) 1275be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combine0i; 1276be8c453dSColin LeMahieu else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS) 1277be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combine1i; 1278be8c453dSColin LeMahieu else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS) 1279be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combine2i; 1280be8c453dSColin LeMahieu else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS) 1281be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combine3i; 1282be8c453dSColin LeMahieu else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS) 1283be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combinerz; 1284be8c453dSColin LeMahieu else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS) 1285be8c453dSColin LeMahieu op = Hexagon::V4_SA1_combinezr; 1286be8c453dSColin LeMahieu else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS) 1287be8c453dSColin LeMahieu op = Hexagon::V4_SA1_dec; 1288be8c453dSColin LeMahieu else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS) 1289be8c453dSColin LeMahieu op = Hexagon::V4_SA1_inc; 1290be8c453dSColin LeMahieu else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS) 1291be8c453dSColin LeMahieu op = Hexagon::V4_SA1_seti; 1292be8c453dSColin LeMahieu else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS) 1293be8c453dSColin LeMahieu op = Hexagon::V4_SA1_setin1; 1294be8c453dSColin LeMahieu else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS) 1295be8c453dSColin LeMahieu op = Hexagon::V4_SA1_sxtb; 1296be8c453dSColin LeMahieu else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS) 1297be8c453dSColin LeMahieu op = Hexagon::V4_SA1_sxth; 1298be8c453dSColin LeMahieu else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS) 1299be8c453dSColin LeMahieu op = Hexagon::V4_SA1_tfr; 1300be8c453dSColin LeMahieu else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS) 1301be8c453dSColin LeMahieu op = Hexagon::V4_SA1_zxtb; 1302be8c453dSColin LeMahieu else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS) 1303be8c453dSColin LeMahieu op = Hexagon::V4_SA1_zxth; 1304be8c453dSColin LeMahieu else { 1305be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1306be8c453dSColin LeMahieu return MCDisassembler::Fail; 1307be8c453dSColin LeMahieu } 1308be8c453dSColin LeMahieu break; 1309be8c453dSColin LeMahieu case HexagonII::HSIG_S1: 1310be8c453dSColin LeMahieu if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS) 1311be8c453dSColin LeMahieu op = Hexagon::V4_SS1_storeb_io; 1312be8c453dSColin LeMahieu else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS) 1313be8c453dSColin LeMahieu op = Hexagon::V4_SS1_storew_io; 1314be8c453dSColin LeMahieu else { 1315be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1316be8c453dSColin LeMahieu return MCDisassembler::Fail; 1317be8c453dSColin LeMahieu } 1318be8c453dSColin LeMahieu break; 1319be8c453dSColin LeMahieu case HexagonII::HSIG_S2: 1320be8c453dSColin LeMahieu if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS) 1321be8c453dSColin LeMahieu op = Hexagon::V4_SS2_allocframe; 1322be8c453dSColin LeMahieu else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS) 1323be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storebi0; 1324be8c453dSColin LeMahieu else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS) 1325be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storebi1; 1326be8c453dSColin LeMahieu else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS) 1327be8c453dSColin LeMahieu op = Hexagon::V4_SS2_stored_sp; 1328be8c453dSColin LeMahieu else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS) 1329be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storeh_io; 1330be8c453dSColin LeMahieu else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS) 1331be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storew_sp; 1332be8c453dSColin LeMahieu else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS) 1333be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storewi0; 1334be8c453dSColin LeMahieu else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS) 1335be8c453dSColin LeMahieu op = Hexagon::V4_SS2_storewi1; 1336be8c453dSColin LeMahieu else { 1337be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1338be8c453dSColin LeMahieu return MCDisassembler::Fail; 1339be8c453dSColin LeMahieu } 1340be8c453dSColin LeMahieu break; 1341be8c453dSColin LeMahieu default: 1342be8c453dSColin LeMahieu os << "<unknown>"; 1343be8c453dSColin LeMahieu return MCDisassembler::Fail; 1344be8c453dSColin LeMahieu } 1345be8c453dSColin LeMahieu return MCDisassembler::Success; 1346be8c453dSColin LeMahieu } 1347be8c453dSColin LeMahieu 1348be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) { 1349be8c453dSColin LeMahieu if (encoded_reg < 8) 1350be8c453dSColin LeMahieu return Hexagon::R0 + encoded_reg; 1351be8c453dSColin LeMahieu else if (encoded_reg < 16) 1352be8c453dSColin LeMahieu return Hexagon::R0 + encoded_reg + 8; 1353*7cd08927SColin LeMahieu 1354*7cd08927SColin LeMahieu // patently false value 1355be8c453dSColin LeMahieu return Hexagon::NoRegister; 1356be8c453dSColin LeMahieu } 1357be8c453dSColin LeMahieu 1358be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) { 1359be8c453dSColin LeMahieu if (encoded_dreg < 4) 1360be8c453dSColin LeMahieu return Hexagon::D0 + encoded_dreg; 1361be8c453dSColin LeMahieu else if (encoded_dreg < 8) 1362be8c453dSColin LeMahieu return Hexagon::D0 + encoded_dreg + 4; 1363*7cd08927SColin LeMahieu 1364*7cd08927SColin LeMahieu // patently false value 1365be8c453dSColin LeMahieu return Hexagon::NoRegister; 1366be8c453dSColin LeMahieu } 1367be8c453dSColin LeMahieu 1368*7cd08927SColin LeMahieu void HexagonDisassembler::addSubinstOperands(MCInst *MI, unsigned opcode, 1369*7cd08927SColin LeMahieu unsigned inst) const { 1370be8c453dSColin LeMahieu int64_t operand; 1371be8c453dSColin LeMahieu MCOperand Op; 1372be8c453dSColin LeMahieu switch (opcode) { 1373be8c453dSColin LeMahieu case Hexagon::V4_SL2_deallocframe: 1374be8c453dSColin LeMahieu case Hexagon::V4_SL2_jumpr31: 1375be8c453dSColin LeMahieu case Hexagon::V4_SL2_jumpr31_f: 1376be8c453dSColin LeMahieu case Hexagon::V4_SL2_jumpr31_fnew: 1377be8c453dSColin LeMahieu case Hexagon::V4_SL2_jumpr31_t: 1378be8c453dSColin LeMahieu case Hexagon::V4_SL2_jumpr31_tnew: 1379be8c453dSColin LeMahieu case Hexagon::V4_SL2_return: 1380be8c453dSColin LeMahieu case Hexagon::V4_SL2_return_f: 1381be8c453dSColin LeMahieu case Hexagon::V4_SL2_return_fnew: 1382be8c453dSColin LeMahieu case Hexagon::V4_SL2_return_t: 1383be8c453dSColin LeMahieu case Hexagon::V4_SL2_return_tnew: 1384be8c453dSColin LeMahieu // no operands for these instructions 1385be8c453dSColin LeMahieu break; 1386be8c453dSColin LeMahieu case Hexagon::V4_SS2_allocframe: 1387be8c453dSColin LeMahieu // u 8-4{5_3} 1388be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 3; 1389*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1390be8c453dSColin LeMahieu break; 1391be8c453dSColin LeMahieu case Hexagon::V4_SL1_loadri_io: 1392be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 11-8{4_2} 1393be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1394be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1395be8c453dSColin LeMahieu MI->addOperand(Op); 1396be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1397be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1398be8c453dSColin LeMahieu MI->addOperand(Op); 1399be8c453dSColin LeMahieu operand = (inst & 0xf00) >> 6; 1400*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1401be8c453dSColin LeMahieu break; 1402be8c453dSColin LeMahieu case Hexagon::V4_SL1_loadrub_io: 1403be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 11-8 1404be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1405be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1406be8c453dSColin LeMahieu MI->addOperand(Op); 1407be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1408be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1409be8c453dSColin LeMahieu MI->addOperand(Op); 1410be8c453dSColin LeMahieu operand = (inst & 0xf00) >> 8; 1411*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1412be8c453dSColin LeMahieu break; 1413be8c453dSColin LeMahieu case Hexagon::V4_SL2_loadrb_io: 1414be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 10-8 1415be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1416be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1417be8c453dSColin LeMahieu MI->addOperand(Op); 1418be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1419be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1420be8c453dSColin LeMahieu MI->addOperand(Op); 1421be8c453dSColin LeMahieu operand = (inst & 0x700) >> 8; 1422*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1423be8c453dSColin LeMahieu break; 1424be8c453dSColin LeMahieu case Hexagon::V4_SL2_loadrh_io: 1425be8c453dSColin LeMahieu case Hexagon::V4_SL2_loadruh_io: 1426be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 10-8{3_1} 1427be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1428be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1429be8c453dSColin LeMahieu MI->addOperand(Op); 1430be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1431be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1432be8c453dSColin LeMahieu MI->addOperand(Op); 1433be8c453dSColin LeMahieu operand = ((inst & 0x700) >> 8) << 1; 1434*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1435be8c453dSColin LeMahieu break; 1436be8c453dSColin LeMahieu case Hexagon::V4_SL2_loadrd_sp: 1437be8c453dSColin LeMahieu // Rdd 2-0, u 7-3{5_3} 1438be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1439be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1440be8c453dSColin LeMahieu MI->addOperand(Op); 1441be8c453dSColin LeMahieu operand = ((inst & 0x0f8) >> 3) << 3; 1442*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1443be8c453dSColin LeMahieu break; 1444be8c453dSColin LeMahieu case Hexagon::V4_SL2_loadri_sp: 1445be8c453dSColin LeMahieu // Rd 3-0, u 8-4{5_2} 1446be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1447be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1448be8c453dSColin LeMahieu MI->addOperand(Op); 1449be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 2; 1450*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1451be8c453dSColin LeMahieu break; 1452be8c453dSColin LeMahieu case Hexagon::V4_SA1_addi: 1453be8c453dSColin LeMahieu // Rx 3-0 (x2), s7 10-4 1454be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1455be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1456be8c453dSColin LeMahieu MI->addOperand(Op); 1457be8c453dSColin LeMahieu MI->addOperand(Op); 1458be8c453dSColin LeMahieu operand = SignExtend64<7>((inst & 0x7f0) >> 4); 1459*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1460be8c453dSColin LeMahieu break; 1461be8c453dSColin LeMahieu case Hexagon::V4_SA1_addrx: 1462be8c453dSColin LeMahieu // Rx 3-0 (x2), Rs 7-4 1463be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1464be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1465be8c453dSColin LeMahieu MI->addOperand(Op); 1466be8c453dSColin LeMahieu MI->addOperand(Op); 1467be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1468be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1469be8c453dSColin LeMahieu MI->addOperand(Op); 1470be8c453dSColin LeMahieu case Hexagon::V4_SA1_and1: 1471be8c453dSColin LeMahieu case Hexagon::V4_SA1_dec: 1472be8c453dSColin LeMahieu case Hexagon::V4_SA1_inc: 1473be8c453dSColin LeMahieu case Hexagon::V4_SA1_sxtb: 1474be8c453dSColin LeMahieu case Hexagon::V4_SA1_sxth: 1475be8c453dSColin LeMahieu case Hexagon::V4_SA1_tfr: 1476be8c453dSColin LeMahieu case Hexagon::V4_SA1_zxtb: 1477be8c453dSColin LeMahieu case Hexagon::V4_SA1_zxth: 1478be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4 1479be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1480be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1481be8c453dSColin LeMahieu MI->addOperand(Op); 1482be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1483be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1484be8c453dSColin LeMahieu MI->addOperand(Op); 1485be8c453dSColin LeMahieu break; 1486be8c453dSColin LeMahieu case Hexagon::V4_SA1_addsp: 1487be8c453dSColin LeMahieu // Rd 3-0, u 9-4{6_2} 1488be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1489be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1490be8c453dSColin LeMahieu MI->addOperand(Op); 1491be8c453dSColin LeMahieu operand = ((inst & 0x3f0) >> 4) << 2; 1492*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1493be8c453dSColin LeMahieu break; 1494be8c453dSColin LeMahieu case Hexagon::V4_SA1_seti: 1495be8c453dSColin LeMahieu // Rd 3-0, u 9-4 1496be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1497be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1498be8c453dSColin LeMahieu MI->addOperand(Op); 1499be8c453dSColin LeMahieu operand = (inst & 0x3f0) >> 4; 1500*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1501be8c453dSColin LeMahieu break; 1502be8c453dSColin LeMahieu case Hexagon::V4_SA1_clrf: 1503be8c453dSColin LeMahieu case Hexagon::V4_SA1_clrfnew: 1504be8c453dSColin LeMahieu case Hexagon::V4_SA1_clrt: 1505be8c453dSColin LeMahieu case Hexagon::V4_SA1_clrtnew: 1506be8c453dSColin LeMahieu case Hexagon::V4_SA1_setin1: 1507be8c453dSColin LeMahieu // Rd 3-0 1508be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1509be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1510be8c453dSColin LeMahieu MI->addOperand(Op); 1511be8c453dSColin LeMahieu break; 1512be8c453dSColin LeMahieu case Hexagon::V4_SA1_cmpeqi: 1513be8c453dSColin LeMahieu // Rs 7-4, u 1-0 1514be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1515be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1516be8c453dSColin LeMahieu MI->addOperand(Op); 1517be8c453dSColin LeMahieu operand = inst & 0x3; 1518*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1519be8c453dSColin LeMahieu break; 1520be8c453dSColin LeMahieu case Hexagon::V4_SA1_combine0i: 1521be8c453dSColin LeMahieu case Hexagon::V4_SA1_combine1i: 1522be8c453dSColin LeMahieu case Hexagon::V4_SA1_combine2i: 1523be8c453dSColin LeMahieu case Hexagon::V4_SA1_combine3i: 1524be8c453dSColin LeMahieu // Rdd 2-0, u 6-5 1525be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1526be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1527be8c453dSColin LeMahieu MI->addOperand(Op); 1528be8c453dSColin LeMahieu operand = (inst & 0x060) >> 5; 1529*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1530be8c453dSColin LeMahieu break; 1531be8c453dSColin LeMahieu case Hexagon::V4_SA1_combinerz: 1532be8c453dSColin LeMahieu case Hexagon::V4_SA1_combinezr: 1533be8c453dSColin LeMahieu // Rdd 2-0, Rs 7-4 1534be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1535be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1536be8c453dSColin LeMahieu MI->addOperand(Op); 1537be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1538be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1539be8c453dSColin LeMahieu MI->addOperand(Op); 1540be8c453dSColin LeMahieu break; 1541be8c453dSColin LeMahieu case Hexagon::V4_SS1_storeb_io: 1542be8c453dSColin LeMahieu // Rs 7-4, u 11-8, Rt 3-0 1543be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1544be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1545be8c453dSColin LeMahieu MI->addOperand(Op); 1546be8c453dSColin LeMahieu operand = (inst & 0xf00) >> 8; 1547*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1548be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1549be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1550be8c453dSColin LeMahieu MI->addOperand(Op); 1551be8c453dSColin LeMahieu break; 1552be8c453dSColin LeMahieu case Hexagon::V4_SS1_storew_io: 1553be8c453dSColin LeMahieu // Rs 7-4, u 11-8{4_2}, Rt 3-0 1554be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1555be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1556be8c453dSColin LeMahieu MI->addOperand(Op); 1557be8c453dSColin LeMahieu operand = ((inst & 0xf00) >> 8) << 2; 1558*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1559be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1560be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1561be8c453dSColin LeMahieu MI->addOperand(Op); 1562be8c453dSColin LeMahieu break; 1563be8c453dSColin LeMahieu case Hexagon::V4_SS2_storebi0: 1564be8c453dSColin LeMahieu case Hexagon::V4_SS2_storebi1: 1565be8c453dSColin LeMahieu // Rs 7-4, u 3-0 1566be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1567be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1568be8c453dSColin LeMahieu MI->addOperand(Op); 1569be8c453dSColin LeMahieu operand = inst & 0xf; 1570*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1571be8c453dSColin LeMahieu break; 1572be8c453dSColin LeMahieu case Hexagon::V4_SS2_storewi0: 1573be8c453dSColin LeMahieu case Hexagon::V4_SS2_storewi1: 1574be8c453dSColin LeMahieu // Rs 7-4, u 3-0{4_2} 1575be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1576be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1577be8c453dSColin LeMahieu MI->addOperand(Op); 1578be8c453dSColin LeMahieu operand = (inst & 0xf) << 2; 1579*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1580be8c453dSColin LeMahieu break; 1581be8c453dSColin LeMahieu case Hexagon::V4_SS2_stored_sp: 1582be8c453dSColin LeMahieu // s 8-3{6_3}, Rtt 2-0 1583be8c453dSColin LeMahieu operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3); 1584*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1585be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1586be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1587be8c453dSColin LeMahieu MI->addOperand(Op); 1588160f73e3SColin LeMahieu break; 1589be8c453dSColin LeMahieu case Hexagon::V4_SS2_storeh_io: 1590be8c453dSColin LeMahieu // Rs 7-4, u 10-8{3_1}, Rt 3-0 1591be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1592be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1593be8c453dSColin LeMahieu MI->addOperand(Op); 1594be8c453dSColin LeMahieu operand = ((inst & 0x700) >> 8) << 1; 1595*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1596be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1597be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1598be8c453dSColin LeMahieu MI->addOperand(Op); 1599be8c453dSColin LeMahieu break; 1600be8c453dSColin LeMahieu case Hexagon::V4_SS2_storew_sp: 1601be8c453dSColin LeMahieu // u 8-4{5_2}, Rd 3-0 1602be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 2; 1603*7cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1604be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1605be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1606be8c453dSColin LeMahieu MI->addOperand(Op); 1607be8c453dSColin LeMahieu break; 1608be8c453dSColin LeMahieu default: 1609be8c453dSColin LeMahieu // don't crash with an invalid subinstruction 1610be8c453dSColin LeMahieu // llvm_unreachable("Invalid subinstruction in duplex instruction"); 1611be8c453dSColin LeMahieu break; 1612be8c453dSColin LeMahieu } 1613be8c453dSColin LeMahieu } 1614