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 107cd08927SColin LeMahieu #define DEBUG_TYPE "hexagon-disassembler" 117cd08927SColin LeMahieu 1268d967d9SColin LeMahieu #include "Hexagon.h" 1388ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonBaseInfo.h" 147cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCChecker.h" 1588ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonMCTargetDesc.h" 167cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCInstrInfo.h" 177cd08927SColin LeMahieu #include "MCTargetDesc/HexagonInstPrinter.h" 187cd08927SColin LeMahieu #include "llvm/ADT/StringExtras.h" 19f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h" 207cd08927SColin 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" 257cd08927SColin 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" 30d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h" 317cd08927SColin LeMahieu #include "llvm/Support/TargetRegistry.h" 3288ebb9e2SColin LeMahieu 3388ebb9e2SColin LeMahieu using namespace llvm; 3468d967d9SColin LeMahieu using namespace Hexagon; 3588ebb9e2SColin LeMahieu 367cd08927SColin LeMahieu typedef MCDisassembler::DecodeStatus DecodeStatus; 3788ebb9e2SColin LeMahieu 3888ebb9e2SColin LeMahieu namespace { 3988ebb9e2SColin LeMahieu /// \brief Hexagon disassembler for all Hexagon platforms. 4088ebb9e2SColin LeMahieu class HexagonDisassembler : public MCDisassembler { 4188ebb9e2SColin LeMahieu public: 427cd08927SColin LeMahieu std::unique_ptr<MCInstrInfo const> const MCII; 4368d967d9SColin LeMahieu std::unique_ptr<MCInst *> CurrentBundle; 447cd08927SColin LeMahieu HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 457cd08927SColin LeMahieu MCInstrInfo const *MCII) 467cd08927SColin LeMahieu : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *) {} 4788ebb9e2SColin LeMahieu 4868d967d9SColin LeMahieu DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB, 4968d967d9SColin LeMahieu ArrayRef<uint8_t> Bytes, uint64_t Address, 5068d967d9SColin LeMahieu raw_ostream &VStream, raw_ostream &CStream, 5168d967d9SColin LeMahieu bool &Complete) const; 524aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 537fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 544aa6bea7SRafael Espindola raw_ostream &VStream, 554aa6bea7SRafael Espindola raw_ostream &CStream) const override; 567cd08927SColin LeMahieu 577cd08927SColin LeMahieu void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const; 587cd08927SColin LeMahieu void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) const; 5988ebb9e2SColin LeMahieu }; 60f00654e3SAlexander Kornienko } 6188ebb9e2SColin LeMahieu 627cd08927SColin LeMahieu // Forward declare these because the auto-generated code will reference them. 637cd08927SColin LeMahieu // Definitions are further down. 647cd08927SColin LeMahieu 657cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 66be8c453dSColin LeMahieu uint64_t Address, 67be8c453dSColin LeMahieu const void *Decoder); 687c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, 697c958713SColin LeMahieu uint64_t Address, 707c958713SColin LeMahieu const void *Decoder); 717c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo, 727c958713SColin LeMahieu uint64_t Address, 737c958713SColin LeMahieu const void *Decoder); 747cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 757cd08927SColin LeMahieu uint64_t Address, 767cd08927SColin LeMahieu const void *Decoder); 777c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo, 787c958713SColin LeMahieu uint64_t Address, 797c958713SColin LeMahieu const void *Decoder); 807cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 817cd08927SColin LeMahieu uint64_t Address, 827cd08927SColin LeMahieu const void *Decoder); 837c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 847c958713SColin LeMahieu uint64_t Address, 857c958713SColin LeMahieu const void *Decoder); 86f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 87be8c453dSColin LeMahieu uint64_t Address, 88be8c453dSColin LeMahieu const void *Decoder); 897cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 907cd08927SColin LeMahieu uint64_t Address, 917cd08927SColin LeMahieu const void *Decoder); 92404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, 93be8c453dSColin LeMahieu uint64_t Address, 947cd08927SColin LeMahieu const void *Decoder); 957cd08927SColin LeMahieu 967cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn); 977cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn, 98be8c453dSColin LeMahieu void const *Decoder); 99be8c453dSColin LeMahieu 100be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op, 101be8c453dSColin LeMahieu raw_ostream &os); 102f3db884eSColin LeMahieu 1037cd08927SColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg); 1047cd08927SColin LeMahieu 1057cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, 1067cd08927SColin LeMahieu uint64_t Address, const void *Decoder); 107654dc11bSKrzysztof Parzyszek static DecodeStatus s16_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1081e9d1d76SColin LeMahieu const void *Decoder); 109654dc11bSKrzysztof Parzyszek static DecodeStatus s12_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1101e9d1d76SColin LeMahieu const void *Decoder); 1111e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1121e9d1d76SColin LeMahieu const void *Decoder); 1131e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1141e9d1d76SColin LeMahieu const void *Decoder); 1151e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1161e9d1d76SColin LeMahieu const void *Decoder); 1171e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1181e9d1d76SColin LeMahieu const void *Decoder); 119654dc11bSKrzysztof Parzyszek static DecodeStatus s10_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1201e9d1d76SColin LeMahieu const void *Decoder); 121654dc11bSKrzysztof Parzyszek static DecodeStatus s8_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1221e9d1d76SColin LeMahieu const void *Decoder); 1231e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1241e9d1d76SColin LeMahieu const void *Decoder); 1251e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1261e9d1d76SColin LeMahieu const void *Decoder); 1271e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1281e9d1d76SColin LeMahieu const void *Decoder); 1291e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1301e9d1d76SColin LeMahieu const void *Decoder); 1311e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1321e9d1d76SColin LeMahieu const void *Decoder); 1337c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1347c958713SColin LeMahieu const void *Decoder); 1357c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1367c958713SColin LeMahieu const void *Decoder); 1377cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 1387cd08927SColin LeMahieu const void *Decoder); 139efa74e02SColin LeMahieu 14088ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc" 14188ebb9e2SColin LeMahieu 1427cd08927SColin LeMahieu static MCDisassembler *createHexagonDisassembler(const Target &T, 1437cd08927SColin LeMahieu const MCSubtargetInfo &STI, 14488ebb9e2SColin LeMahieu MCContext &Ctx) { 1457cd08927SColin LeMahieu return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo()); 14688ebb9e2SColin LeMahieu } 14788ebb9e2SColin LeMahieu 14888ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() { 149f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(), 15088ebb9e2SColin LeMahieu createHexagonDisassembler); 15188ebb9e2SColin LeMahieu } 15288ebb9e2SColin LeMahieu 15388ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 1547fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 15588ebb9e2SColin LeMahieu uint64_t Address, 15688ebb9e2SColin LeMahieu raw_ostream &os, 15788ebb9e2SColin LeMahieu raw_ostream &cs) const { 15868d967d9SColin LeMahieu DecodeStatus Result = DecodeStatus::Success; 15968d967d9SColin LeMahieu bool Complete = false; 16068d967d9SColin LeMahieu Size = 0; 1614aa6bea7SRafael Espindola 16268d967d9SColin LeMahieu *CurrentBundle = &MI; 163f0af6e52SColin LeMahieu MI = HexagonMCInstrInfo::createBundle(); 164be8c453dSColin LeMahieu while (Result == Success && Complete == false) { 16568d967d9SColin LeMahieu if (Bytes.size() < HEXAGON_INSTR_SIZE) 16668d967d9SColin LeMahieu return MCDisassembler::Fail; 16768d967d9SColin LeMahieu MCInst *Inst = new (getContext()) MCInst; 16868d967d9SColin LeMahieu Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete); 16968d967d9SColin LeMahieu MI.addOperand(MCOperand::createInst(Inst)); 17068d967d9SColin LeMahieu Size += HEXAGON_INSTR_SIZE; 17168d967d9SColin LeMahieu Bytes = Bytes.slice(HEXAGON_INSTR_SIZE); 17268d967d9SColin LeMahieu } 1737cd08927SColin LeMahieu if(Result == MCDisassembler::Fail) 17468d967d9SColin LeMahieu return Result; 1757cd08927SColin LeMahieu HexagonMCChecker Checker (*MCII, STI, MI, MI, *getContext().getRegisterInfo()); 1767cd08927SColin LeMahieu if(!Checker.check()) 1777cd08927SColin LeMahieu return MCDisassembler::Fail; 1787cd08927SColin LeMahieu return MCDisassembler::Success; 1797cd08927SColin LeMahieu } 1807cd08927SColin LeMahieu 1817cd08927SColin LeMahieu namespace { 1827cd08927SColin LeMahieu HexagonDisassembler const &disassembler(void const *Decoder) { 1837cd08927SColin LeMahieu return *static_cast<HexagonDisassembler const *>(Decoder); 1847cd08927SColin LeMahieu } 1857cd08927SColin LeMahieu MCContext &contextFromDecoder(void const *Decoder) { 1867cd08927SColin LeMahieu return disassembler(Decoder).getContext(); 1877cd08927SColin LeMahieu } 18868d967d9SColin LeMahieu } 18968d967d9SColin LeMahieu 19068d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction( 19168d967d9SColin LeMahieu MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address, 19268d967d9SColin LeMahieu raw_ostream &os, raw_ostream &cs, bool &Complete) const { 19368d967d9SColin LeMahieu assert(Bytes.size() >= HEXAGON_INSTR_SIZE); 19468d967d9SColin LeMahieu 19568d967d9SColin LeMahieu uint32_t Instruction = 1967cd08927SColin LeMahieu (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0); 19788ebb9e2SColin LeMahieu 19868d967d9SColin LeMahieu auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB); 19968d967d9SColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 20068d967d9SColin LeMahieu HexagonII::INST_PARSE_LOOP_END) { 20168d967d9SColin LeMahieu if (BundleSize == 0) 20268d967d9SColin LeMahieu HexagonMCInstrInfo::setInnerLoop(MCB); 20368d967d9SColin LeMahieu else if (BundleSize == 1) 20468d967d9SColin LeMahieu HexagonMCInstrInfo::setOuterLoop(MCB); 20568d967d9SColin LeMahieu else 20668d967d9SColin LeMahieu return DecodeStatus::Fail; 20768d967d9SColin LeMahieu } 20868d967d9SColin LeMahieu 20968d967d9SColin LeMahieu DecodeStatus Result = DecodeStatus::Success; 21068d967d9SColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 211be8c453dSColin LeMahieu HexagonII::INST_PARSE_DUPLEX) { 212be8c453dSColin LeMahieu // Determine the instruction class of each instruction in the duplex. 213be8c453dSColin LeMahieu unsigned duplexIClass, IClassLow, IClassHigh; 214be8c453dSColin LeMahieu 215be8c453dSColin LeMahieu duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1); 216be8c453dSColin LeMahieu switch (duplexIClass) { 217be8c453dSColin LeMahieu default: 218be8c453dSColin LeMahieu return MCDisassembler::Fail; 219be8c453dSColin LeMahieu case 0: 220be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L1; 221be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 222be8c453dSColin LeMahieu break; 223be8c453dSColin LeMahieu case 1: 224be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 225be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 226be8c453dSColin LeMahieu break; 227be8c453dSColin LeMahieu case 2: 228be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 229be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 230be8c453dSColin LeMahieu break; 231be8c453dSColin LeMahieu case 3: 232be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_A; 233be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 234be8c453dSColin LeMahieu break; 235be8c453dSColin LeMahieu case 4: 236be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L1; 237be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 238be8c453dSColin LeMahieu break; 239be8c453dSColin LeMahieu case 5: 240be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_L2; 241be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 242be8c453dSColin LeMahieu break; 243be8c453dSColin LeMahieu case 6: 244be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 245be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 246be8c453dSColin LeMahieu break; 247be8c453dSColin LeMahieu case 7: 248be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 249be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_A; 250be8c453dSColin LeMahieu break; 251be8c453dSColin LeMahieu case 8: 252be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 253be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 254be8c453dSColin LeMahieu break; 255be8c453dSColin LeMahieu case 9: 256be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 257be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 258be8c453dSColin LeMahieu break; 259be8c453dSColin LeMahieu case 10: 260be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S1; 261be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S1; 262be8c453dSColin LeMahieu break; 263be8c453dSColin LeMahieu case 11: 264be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 265be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S1; 266be8c453dSColin LeMahieu break; 267be8c453dSColin LeMahieu case 12: 268be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 269be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L1; 270be8c453dSColin LeMahieu break; 271be8c453dSColin LeMahieu case 13: 272be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 273be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_L2; 274be8c453dSColin LeMahieu break; 275be8c453dSColin LeMahieu case 14: 276be8c453dSColin LeMahieu IClassLow = HexagonII::HSIG_S2; 277be8c453dSColin LeMahieu IClassHigh = HexagonII::HSIG_S2; 278be8c453dSColin LeMahieu break; 279be8c453dSColin LeMahieu } 280be8c453dSColin LeMahieu 281be8c453dSColin LeMahieu // Set the MCInst to be a duplex instruction. Which one doesn't matter. 282be8c453dSColin LeMahieu MI.setOpcode(Hexagon::DuplexIClass0); 283be8c453dSColin LeMahieu 284be8c453dSColin LeMahieu // Decode each instruction in the duplex. 285be8c453dSColin LeMahieu // Create an MCInst for each instruction. 286be8c453dSColin LeMahieu unsigned instLow = Instruction & 0x1fff; 287be8c453dSColin LeMahieu unsigned instHigh = (Instruction >> 16) & 0x1fff; 288be8c453dSColin LeMahieu unsigned opLow; 289be8c453dSColin LeMahieu if (GetSubinstOpcode(IClassLow, instLow, opLow, os) != 290be8c453dSColin LeMahieu MCDisassembler::Success) 291be8c453dSColin LeMahieu return MCDisassembler::Fail; 292be8c453dSColin LeMahieu unsigned opHigh; 293be8c453dSColin LeMahieu if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) != 294be8c453dSColin LeMahieu MCDisassembler::Success) 295be8c453dSColin LeMahieu return MCDisassembler::Fail; 296be8c453dSColin LeMahieu MCInst *MILow = new (getContext()) MCInst; 297be8c453dSColin LeMahieu MILow->setOpcode(opLow); 298be8c453dSColin LeMahieu MCInst *MIHigh = new (getContext()) MCInst; 299be8c453dSColin LeMahieu MIHigh->setOpcode(opHigh); 3007cd08927SColin LeMahieu addSubinstOperands(MILow, opLow, instLow); 3017cd08927SColin LeMahieu addSubinstOperands(MIHigh, opHigh, instHigh); 302be8c453dSColin LeMahieu // see ConvertToSubInst() in 303be8c453dSColin LeMahieu // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp 304be8c453dSColin LeMahieu 305be8c453dSColin LeMahieu // Add the duplex instruction MCInsts as operands to the passed in MCInst. 306be8c453dSColin LeMahieu MCOperand OPLow = MCOperand::createInst(MILow); 307be8c453dSColin LeMahieu MCOperand OPHigh = MCOperand::createInst(MIHigh); 308be8c453dSColin LeMahieu MI.addOperand(OPLow); 309be8c453dSColin LeMahieu MI.addOperand(OPHigh); 310be8c453dSColin LeMahieu Complete = true; 311be8c453dSColin LeMahieu } else { 312be8c453dSColin LeMahieu if ((Instruction & HexagonII::INST_PARSE_MASK) == 31368d967d9SColin LeMahieu HexagonII::INST_PARSE_PACKET_END) 31468d967d9SColin LeMahieu Complete = true; 31568d967d9SColin LeMahieu // Calling the auto-generated decoder function. 31668d967d9SColin LeMahieu Result = 31768d967d9SColin LeMahieu decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI); 3187cd08927SColin LeMahieu 3197cd08927SColin LeMahieu // If a, "standard" insn isn't found check special cases. 3207cd08927SColin LeMahieu if (MCDisassembler::Success != Result || 3217cd08927SColin LeMahieu MI.getOpcode() == Hexagon::A4_ext) { 3227cd08927SColin LeMahieu Result = decodeImmext(MI, Instruction, this); 3237cd08927SColin LeMahieu if (MCDisassembler::Success != Result) { 3247cd08927SColin LeMahieu Result = decodeSpecial(MI, Instruction); 3257cd08927SColin LeMahieu } 3267cd08927SColin LeMahieu } else { 3277cd08927SColin LeMahieu // If the instruction is a compound instruction, register values will 3287cd08927SColin LeMahieu // follow the duplex model, so the register values in the MCInst are 3297cd08927SColin LeMahieu // incorrect. If the instruction is a compound, loop through the 3307cd08927SColin LeMahieu // operands and change registers appropriately. 3317cd08927SColin LeMahieu if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) == 3327cd08927SColin LeMahieu HexagonII::TypeCOMPOUND) { 3337cd08927SColin LeMahieu for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last; ++i) { 3347cd08927SColin LeMahieu if (i->isReg()) { 3357cd08927SColin LeMahieu unsigned reg = i->getReg() - Hexagon::R0; 3367cd08927SColin LeMahieu i->setReg(getRegFromSubinstEncoding(reg)); 3377cd08927SColin LeMahieu } 3387cd08927SColin LeMahieu } 3397cd08927SColin LeMahieu } 3407cd08927SColin LeMahieu } 341be8c453dSColin LeMahieu } 34268d967d9SColin LeMahieu 343*81707549SColin LeMahieu switch(MI.getOpcode()) { 344*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_f_jumpnv_nt: 345*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_f_jumpnv_t: 346*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_fp0_jump_nt: 347*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_fp0_jump_t: 348*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_fp1_jump_nt: 349*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_fp1_jump_t: 350*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_t_jumpnv_nt: 351*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_t_jumpnv_t: 352*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_tp0_jump_nt: 353*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_tp0_jump_t: 354*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_tp1_jump_nt: 355*81707549SColin LeMahieu case Hexagon::J4_cmpeqn1_tp1_jump_t: 356*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_f_jumpnv_nt: 357*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_f_jumpnv_t: 358*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_fp0_jump_nt: 359*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_fp0_jump_t: 360*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_fp1_jump_nt: 361*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_fp1_jump_t: 362*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_t_jumpnv_nt: 363*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_t_jumpnv_t: 364*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_tp0_jump_nt: 365*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_tp0_jump_t: 366*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_tp1_jump_nt: 367*81707549SColin LeMahieu case Hexagon::J4_cmpgtn1_tp1_jump_t: 368*81707549SColin LeMahieu MI.insert(MI.begin() + 1, MCOperand::createExpr(MCConstantExpr::create(-1, getContext()))); 369*81707549SColin LeMahieu break; 370*81707549SColin LeMahieu default: 371*81707549SColin LeMahieu break; 372*81707549SColin LeMahieu } 373*81707549SColin LeMahieu 3747cd08927SColin LeMahieu if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) { 3757cd08927SColin LeMahieu unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI); 3767cd08927SColin LeMahieu MCOperand &MCO = MI.getOperand(OpIndex); 3777cd08927SColin LeMahieu assert(MCO.isReg() && "New value consumers must be registers"); 3787cd08927SColin LeMahieu unsigned Register = 3797cd08927SColin LeMahieu getContext().getRegisterInfo()->getEncodingValue(MCO.getReg()); 3807cd08927SColin LeMahieu if ((Register & 0x6) == 0) 3817cd08927SColin LeMahieu // HexagonPRM 10.11 Bit 1-2 == 0 is reserved 3827cd08927SColin LeMahieu return MCDisassembler::Fail; 3837cd08927SColin LeMahieu unsigned Lookback = (Register & 0x6) >> 1; 3847cd08927SColin LeMahieu unsigned Offset = 1; 3857cd08927SColin LeMahieu bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI); 3867cd08927SColin LeMahieu auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle); 3877cd08927SColin LeMahieu auto i = Instructions.end() - 1; 3887cd08927SColin LeMahieu for (auto n = Instructions.begin() - 1;; --i, ++Offset) { 3897cd08927SColin LeMahieu if (i == n) 3907cd08927SColin LeMahieu // Couldn't find producer 3917cd08927SColin LeMahieu return MCDisassembler::Fail; 3927cd08927SColin LeMahieu if (Vector && !HexagonMCInstrInfo::isVector(*MCII, *i->getInst())) 3937cd08927SColin LeMahieu // Skip scalars when calculating distances for vectors 3947cd08927SColin LeMahieu ++Lookback; 3957cd08927SColin LeMahieu if (HexagonMCInstrInfo::isImmext(*i->getInst())) 3967cd08927SColin LeMahieu ++Lookback; 3977cd08927SColin LeMahieu if (Offset == Lookback) 3987cd08927SColin LeMahieu break; 3997cd08927SColin LeMahieu } 4007cd08927SColin LeMahieu auto const &Inst = *i->getInst(); 4017cd08927SColin LeMahieu bool SubregBit = (Register & 0x1) != 0; 4027cd08927SColin LeMahieu if (SubregBit && HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) { 4037cd08927SColin LeMahieu // If subreg bit is set we're selecting the second produced newvalue 4047cd08927SColin LeMahieu unsigned Producer = 4057cd08927SColin LeMahieu HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg(); 4067cd08927SColin LeMahieu assert(Producer != Hexagon::NoRegister); 4077cd08927SColin LeMahieu MCO.setReg(Producer); 4087cd08927SColin LeMahieu } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) { 4097cd08927SColin LeMahieu unsigned Producer = 4107cd08927SColin LeMahieu HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg(); 4117cd08927SColin LeMahieu if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15) 4127cd08927SColin LeMahieu Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0; 4137cd08927SColin LeMahieu else if (SubregBit) 4146fdfa3dcSColin LeMahieu // Hexagon PRM 10.11 New-value operands 4156fdfa3dcSColin LeMahieu // Nt[0] is reserved and should always be encoded as zero. 4167cd08927SColin LeMahieu return MCDisassembler::Fail; 4177cd08927SColin LeMahieu assert(Producer != Hexagon::NoRegister); 4187cd08927SColin LeMahieu MCO.setReg(Producer); 4197cd08927SColin LeMahieu } else 4207cd08927SColin LeMahieu return MCDisassembler::Fail; 4217cd08927SColin LeMahieu } 4227cd08927SColin LeMahieu 4237cd08927SColin LeMahieu adjustExtendedInstructions(MI, MCB); 4247cd08927SColin LeMahieu MCInst const *Extender = 4257cd08927SColin LeMahieu HexagonMCInstrInfo::extenderForIndex(MCB, 4267cd08927SColin LeMahieu HexagonMCInstrInfo::bundleSize(MCB)); 4277cd08927SColin LeMahieu if(Extender != nullptr) { 4287cd08927SColin LeMahieu MCInst const & Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) ? 4297cd08927SColin LeMahieu *MI.getOperand(1).getInst() : MI; 4307cd08927SColin LeMahieu if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) && 4317cd08927SColin LeMahieu !HexagonMCInstrInfo::isExtended(*MCII, Inst)) 4327cd08927SColin LeMahieu return MCDisassembler::Fail; 4337cd08927SColin LeMahieu } 4345d6f03bdSColin LeMahieu return Result; 43588ebb9e2SColin LeMahieu } 4367cd08927SColin LeMahieu 4377cd08927SColin LeMahieu void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI, 4387cd08927SColin LeMahieu MCInst const &MCB) const { 4397cd08927SColin LeMahieu if (!HexagonMCInstrInfo::hasExtenderForIndex( 4407cd08927SColin LeMahieu MCB, HexagonMCInstrInfo::bundleSize(MCB))) { 4417cd08927SColin LeMahieu unsigned opcode; 4427cd08927SColin LeMahieu // This code is used by the disassembler to disambiguate between GP 4437cd08927SColin LeMahieu // relative and absolute addressing instructions since they both have 4447cd08927SColin LeMahieu // same encoding bits. However, an absolute addressing instruction must 4457cd08927SColin LeMahieu // follow an immediate extender. Disassembler alwaus select absolute 4467cd08927SColin LeMahieu // addressing instructions first and uses this code to change them into 4477cd08927SColin LeMahieu // GP relative instruction in the absence of the corresponding immediate 4487cd08927SColin LeMahieu // extender. 4497cd08927SColin LeMahieu switch (MCI.getOpcode()) { 4509675de5bSColin LeMahieu case Hexagon::PS_storerbabs: 4517cd08927SColin LeMahieu opcode = Hexagon::S2_storerbgp; 4527cd08927SColin LeMahieu break; 4539675de5bSColin LeMahieu case Hexagon::PS_storerhabs: 4547cd08927SColin LeMahieu opcode = Hexagon::S2_storerhgp; 4557cd08927SColin LeMahieu break; 4569675de5bSColin LeMahieu case Hexagon::PS_storerfabs: 4577cd08927SColin LeMahieu opcode = Hexagon::S2_storerfgp; 4587cd08927SColin LeMahieu break; 4599675de5bSColin LeMahieu case Hexagon::PS_storeriabs: 4607cd08927SColin LeMahieu opcode = Hexagon::S2_storerigp; 4617cd08927SColin LeMahieu break; 4629675de5bSColin LeMahieu case Hexagon::PS_storerbnewabs: 4637cd08927SColin LeMahieu opcode = Hexagon::S2_storerbnewgp; 4647cd08927SColin LeMahieu break; 4659675de5bSColin LeMahieu case Hexagon::PS_storerhnewabs: 4667cd08927SColin LeMahieu opcode = Hexagon::S2_storerhnewgp; 4677cd08927SColin LeMahieu break; 4689675de5bSColin LeMahieu case Hexagon::PS_storerinewabs: 4697cd08927SColin LeMahieu opcode = Hexagon::S2_storerinewgp; 4707cd08927SColin LeMahieu break; 4719675de5bSColin LeMahieu case Hexagon::PS_storerdabs: 4727cd08927SColin LeMahieu opcode = Hexagon::S2_storerdgp; 4737cd08927SColin LeMahieu break; 4749675de5bSColin LeMahieu case Hexagon::PS_loadrbabs: 4757cd08927SColin LeMahieu opcode = Hexagon::L2_loadrbgp; 4767cd08927SColin LeMahieu break; 4779675de5bSColin LeMahieu case Hexagon::PS_loadrubabs: 4787cd08927SColin LeMahieu opcode = Hexagon::L2_loadrubgp; 4797cd08927SColin LeMahieu break; 4809675de5bSColin LeMahieu case Hexagon::PS_loadrhabs: 4817cd08927SColin LeMahieu opcode = Hexagon::L2_loadrhgp; 4827cd08927SColin LeMahieu break; 4839675de5bSColin LeMahieu case Hexagon::PS_loadruhabs: 4847cd08927SColin LeMahieu opcode = Hexagon::L2_loadruhgp; 4857cd08927SColin LeMahieu break; 4869675de5bSColin LeMahieu case Hexagon::PS_loadriabs: 4877cd08927SColin LeMahieu opcode = Hexagon::L2_loadrigp; 4887cd08927SColin LeMahieu break; 4899675de5bSColin LeMahieu case Hexagon::PS_loadrdabs: 4907cd08927SColin LeMahieu opcode = Hexagon::L2_loadrdgp; 4917cd08927SColin LeMahieu break; 4927cd08927SColin LeMahieu default: 4937cd08927SColin LeMahieu opcode = MCI.getOpcode(); 4947cd08927SColin LeMahieu } 4957cd08927SColin LeMahieu MCI.setOpcode(opcode); 4967cd08927SColin LeMahieu } 4977cd08927SColin LeMahieu } 4987cd08927SColin LeMahieu 4997cd08927SColin LeMahieu namespace llvm { 5007cd08927SColin LeMahieu extern const MCInstrDesc HexagonInsts[]; 5017cd08927SColin LeMahieu } 5027cd08927SColin LeMahieu 5037cd08927SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo, 504e5e035a3SCraig Topper ArrayRef<MCPhysReg> Table) { 5053da000c0SCraig Topper if (RegNo < Table.size()) { 5067cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Table[RegNo])); 5077cd08927SColin LeMahieu return MCDisassembler::Success; 5083da000c0SCraig Topper } 5093da000c0SCraig Topper 5107cd08927SColin LeMahieu return MCDisassembler::Fail; 5117cd08927SColin LeMahieu } 5127cd08927SColin LeMahieu 5137c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo, 5147c958713SColin LeMahieu uint64_t Address, 5157c958713SColin LeMahieu const void *Decoder) { 5167c958713SColin LeMahieu return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder); 5177c958713SColin LeMahieu } 5187c958713SColin LeMahieu 5197cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5207cd08927SColin LeMahieu uint64_t Address, 5217cd08927SColin LeMahieu const void *Decoder) { 522e5e035a3SCraig Topper static const MCPhysReg IntRegDecoderTable[] = { 5237cd08927SColin LeMahieu Hexagon::R0, Hexagon::R1, Hexagon::R2, Hexagon::R3, Hexagon::R4, 5247cd08927SColin LeMahieu Hexagon::R5, Hexagon::R6, Hexagon::R7, Hexagon::R8, Hexagon::R9, 5257cd08927SColin LeMahieu Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14, 5267cd08927SColin LeMahieu Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19, 5277cd08927SColin LeMahieu Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24, 5287cd08927SColin LeMahieu Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29, 5297cd08927SColin LeMahieu Hexagon::R30, Hexagon::R31}; 5307cd08927SColin LeMahieu 531e5e035a3SCraig Topper return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable); 5327cd08927SColin LeMahieu } 5337c958713SColin LeMahieu 5347c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5357c958713SColin LeMahieu uint64_t /*Address*/, 5367c958713SColin LeMahieu const void *Decoder) { 537e5e035a3SCraig Topper static const MCPhysReg VecRegDecoderTable[] = { 5387c958713SColin LeMahieu Hexagon::V0, Hexagon::V1, Hexagon::V2, Hexagon::V3, Hexagon::V4, 5397c958713SColin LeMahieu Hexagon::V5, Hexagon::V6, Hexagon::V7, Hexagon::V8, Hexagon::V9, 5407c958713SColin LeMahieu Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14, 5417c958713SColin LeMahieu Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19, 5427c958713SColin LeMahieu Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24, 5437c958713SColin LeMahieu Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29, 5447c958713SColin LeMahieu Hexagon::V30, Hexagon::V31}; 5457c958713SColin LeMahieu 546e5e035a3SCraig Topper return DecodeRegisterClass(Inst, RegNo, VecRegDecoderTable); 5477c958713SColin LeMahieu } 5487c958713SColin LeMahieu 5497cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5507cd08927SColin LeMahieu uint64_t /*Address*/, 5517cd08927SColin LeMahieu const void *Decoder) { 552e5e035a3SCraig Topper static const MCPhysReg DoubleRegDecoderTable[] = { 5537cd08927SColin LeMahieu Hexagon::D0, Hexagon::D1, Hexagon::D2, Hexagon::D3, 5547cd08927SColin LeMahieu Hexagon::D4, Hexagon::D5, Hexagon::D6, Hexagon::D7, 5557cd08927SColin LeMahieu Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11, 5567cd08927SColin LeMahieu Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15}; 5577cd08927SColin LeMahieu 558e5e035a3SCraig Topper return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable); 5597cd08927SColin LeMahieu } 5607cd08927SColin LeMahieu 5617c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5627c958713SColin LeMahieu uint64_t /*Address*/, 5637c958713SColin LeMahieu const void *Decoder) { 564e5e035a3SCraig Topper static const MCPhysReg VecDblRegDecoderTable[] = { 5657c958713SColin LeMahieu Hexagon::W0, Hexagon::W1, Hexagon::W2, Hexagon::W3, 5667c958713SColin LeMahieu Hexagon::W4, Hexagon::W5, Hexagon::W6, Hexagon::W7, 5677c958713SColin LeMahieu Hexagon::W8, Hexagon::W9, Hexagon::W10, Hexagon::W11, 5687c958713SColin LeMahieu Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15}; 5697c958713SColin LeMahieu 5703da000c0SCraig Topper return (DecodeRegisterClass(Inst, RegNo >> 1, VecDblRegDecoderTable)); 5717c958713SColin LeMahieu } 5727c958713SColin LeMahieu 5737cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5747cd08927SColin LeMahieu uint64_t /*Address*/, 5757cd08927SColin LeMahieu const void *Decoder) { 576e5e035a3SCraig Topper static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1, 5777cd08927SColin LeMahieu Hexagon::P2, Hexagon::P3}; 5787cd08927SColin LeMahieu 579e5e035a3SCraig Topper return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable); 5807cd08927SColin LeMahieu } 5817cd08927SColin LeMahieu 5827c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5837c958713SColin LeMahieu uint64_t /*Address*/, 5847c958713SColin LeMahieu const void *Decoder) { 585e5e035a3SCraig Topper static const MCPhysReg VecPredRegDecoderTable[] = {Hexagon::Q0, Hexagon::Q1, 5867c958713SColin LeMahieu Hexagon::Q2, Hexagon::Q3}; 5877c958713SColin LeMahieu 588e5e035a3SCraig Topper return DecodeRegisterClass(Inst, RegNo, VecPredRegDecoderTable); 5897c958713SColin LeMahieu } 590be8c453dSColin LeMahieu 5917cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo, 5927cd08927SColin LeMahieu uint64_t /*Address*/, 5937cd08927SColin LeMahieu const void *Decoder) { 594e5e035a3SCraig Topper static const MCPhysReg CtrlRegDecoderTable[] = { 5957cd08927SColin LeMahieu Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1, 5967cd08927SColin LeMahieu Hexagon::P3_0, Hexagon::C5, Hexagon::C6, Hexagon::C7, 5977cd08927SColin LeMahieu Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP, 5987cd08927SColin LeMahieu Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPC 5997cd08927SColin LeMahieu }; 6007cd08927SColin LeMahieu 6016261e1b9SCraig Topper if (RegNo >= array_lengthof(CtrlRegDecoderTable)) 6027cd08927SColin LeMahieu return MCDisassembler::Fail; 6037cd08927SColin LeMahieu 6047cd08927SColin LeMahieu if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister) 6057cd08927SColin LeMahieu return MCDisassembler::Fail; 6067cd08927SColin LeMahieu 6077cd08927SColin LeMahieu unsigned Register = CtrlRegDecoderTable[RegNo]; 6087cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 6097cd08927SColin LeMahieu return MCDisassembler::Success; 6107cd08927SColin LeMahieu } 6117cd08927SColin LeMahieu 6127cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo, 6137cd08927SColin LeMahieu uint64_t /*Address*/, 6147cd08927SColin LeMahieu const void *Decoder) { 615e5e035a3SCraig Topper static const MCPhysReg CtrlReg64DecoderTable[] = { 6167cd08927SColin LeMahieu Hexagon::C1_0, Hexagon::NoRegister, 6177cd08927SColin LeMahieu Hexagon::C3_2, Hexagon::NoRegister, 6187cd08927SColin LeMahieu Hexagon::C7_6, Hexagon::NoRegister, 6197cd08927SColin LeMahieu Hexagon::C9_8, Hexagon::NoRegister, 6207cd08927SColin LeMahieu Hexagon::C11_10, Hexagon::NoRegister, 6217cd08927SColin LeMahieu Hexagon::CS, Hexagon::NoRegister, 6227cd08927SColin LeMahieu Hexagon::UPC, Hexagon::NoRegister 6237cd08927SColin LeMahieu }; 6247cd08927SColin LeMahieu 6256261e1b9SCraig Topper if (RegNo >= array_lengthof(CtrlReg64DecoderTable)) 6267cd08927SColin LeMahieu return MCDisassembler::Fail; 6277cd08927SColin LeMahieu 6287cd08927SColin LeMahieu if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister) 6297cd08927SColin LeMahieu return MCDisassembler::Fail; 6307cd08927SColin LeMahieu 6317cd08927SColin LeMahieu unsigned Register = CtrlReg64DecoderTable[RegNo]; 6327cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 6337cd08927SColin LeMahieu return MCDisassembler::Success; 6347cd08927SColin LeMahieu } 6357cd08927SColin LeMahieu 6367cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo, 6377cd08927SColin LeMahieu uint64_t /*Address*/, 6387cd08927SColin LeMahieu const void *Decoder) { 6397cd08927SColin LeMahieu unsigned Register = 0; 6407cd08927SColin LeMahieu switch (RegNo) { 6417cd08927SColin LeMahieu case 0: 6427cd08927SColin LeMahieu Register = Hexagon::M0; 6437cd08927SColin LeMahieu break; 6447cd08927SColin LeMahieu case 1: 6457cd08927SColin LeMahieu Register = Hexagon::M1; 6467cd08927SColin LeMahieu break; 6477cd08927SColin LeMahieu default: 6487cd08927SColin LeMahieu return MCDisassembler::Fail; 6497cd08927SColin LeMahieu } 6507cd08927SColin LeMahieu Inst.addOperand(MCOperand::createReg(Register)); 6517cd08927SColin LeMahieu return MCDisassembler::Success; 6527cd08927SColin LeMahieu } 6537cd08927SColin LeMahieu 6547cd08927SColin LeMahieu namespace { 6557cd08927SColin LeMahieu uint32_t fullValue(MCInstrInfo const &MCII, 6567cd08927SColin LeMahieu MCInst &MCB, 6577cd08927SColin LeMahieu MCInst &MI, 6587cd08927SColin LeMahieu int64_t Value) { 6597cd08927SColin LeMahieu MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex( 6607cd08927SColin LeMahieu MCB, HexagonMCInstrInfo::bundleSize(MCB)); 6617cd08927SColin LeMahieu if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI)) 6627cd08927SColin LeMahieu return Value; 6637cd08927SColin LeMahieu unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI); 6647cd08927SColin LeMahieu uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f; 6657cd08927SColin LeMahieu int64_t Bits; 6667cd08927SColin LeMahieu bool Success = Extender->getOperand(0).getExpr()->evaluateAsAbsolute(Bits); 6677cd08927SColin LeMahieu assert(Success);(void)Success; 6687cd08927SColin LeMahieu uint32_t Upper26 = static_cast<uint32_t>(Bits); 6697cd08927SColin LeMahieu uint32_t Operand = Upper26 | Lower6; 6707cd08927SColin LeMahieu return Operand; 6717cd08927SColin LeMahieu } 6727cd08927SColin LeMahieu template <size_t T> 6737cd08927SColin LeMahieu void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) { 6747cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 6757cd08927SColin LeMahieu int64_t FullValue = fullValue(*Disassembler.MCII, 6767cd08927SColin LeMahieu **Disassembler.CurrentBundle, 6777cd08927SColin LeMahieu MI, SignExtend64<T>(tmp)); 6787cd08927SColin LeMahieu int64_t Extended = SignExtend64<32>(FullValue); 6797cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Extended, 6807cd08927SColin LeMahieu Disassembler.getContext()); 6817cd08927SColin LeMahieu } 6827cd08927SColin LeMahieu } 6837cd08927SColin LeMahieu 6847cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp, 6857cd08927SColin LeMahieu uint64_t /*Address*/, 6867cd08927SColin LeMahieu const void *Decoder) { 6877cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 6887cd08927SColin LeMahieu int64_t FullValue = fullValue(*Disassembler.MCII, 6897cd08927SColin LeMahieu **Disassembler.CurrentBundle, 6907cd08927SColin LeMahieu MI, tmp); 6917cd08927SColin LeMahieu assert(FullValue >= 0 && "Negative in unsigned decoder"); 6927cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext()); 6937cd08927SColin LeMahieu return MCDisassembler::Success; 6947cd08927SColin LeMahieu } 6957cd08927SColin LeMahieu 696654dc11bSKrzysztof Parzyszek static DecodeStatus s16_0ImmDecoder(MCInst &MI, unsigned tmp, 6971e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 6987cd08927SColin LeMahieu signedDecoder<16>(MI, tmp, Decoder); 6991e9d1d76SColin LeMahieu return MCDisassembler::Success; 7001e9d1d76SColin LeMahieu } 7011e9d1d76SColin LeMahieu 702654dc11bSKrzysztof Parzyszek static DecodeStatus s12_0ImmDecoder(MCInst &MI, unsigned tmp, 7031e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7047cd08927SColin LeMahieu signedDecoder<12>(MI, tmp, Decoder); 7051e9d1d76SColin LeMahieu return MCDisassembler::Success; 7061e9d1d76SColin LeMahieu } 7071e9d1d76SColin LeMahieu 7081e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, 7091e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7107cd08927SColin LeMahieu signedDecoder<11>(MI, tmp, Decoder); 7111e9d1d76SColin LeMahieu return MCDisassembler::Success; 7121e9d1d76SColin LeMahieu } 7131e9d1d76SColin LeMahieu 7141e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, 7151e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7167cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, SignExtend64<12>(tmp), contextFromDecoder(Decoder)); 7171e9d1d76SColin LeMahieu return MCDisassembler::Success; 7181e9d1d76SColin LeMahieu } 7191e9d1d76SColin LeMahieu 7201e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, 7211e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7227cd08927SColin LeMahieu signedDecoder<13>(MI, tmp, Decoder); 7231e9d1d76SColin LeMahieu return MCDisassembler::Success; 7241e9d1d76SColin LeMahieu } 7251e9d1d76SColin LeMahieu 7261e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, 7271e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7287cd08927SColin LeMahieu signedDecoder<14>(MI, tmp, Decoder); 7291e9d1d76SColin LeMahieu return MCDisassembler::Success; 7301e9d1d76SColin LeMahieu } 7311e9d1d76SColin LeMahieu 732654dc11bSKrzysztof Parzyszek static DecodeStatus s10_0ImmDecoder(MCInst &MI, unsigned tmp, 7331e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7347cd08927SColin LeMahieu signedDecoder<10>(MI, tmp, Decoder); 7351e9d1d76SColin LeMahieu return MCDisassembler::Success; 7361e9d1d76SColin LeMahieu } 7371e9d1d76SColin LeMahieu 738654dc11bSKrzysztof Parzyszek static DecodeStatus s8_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/, 7391e9d1d76SColin LeMahieu const void *Decoder) { 7407cd08927SColin LeMahieu signedDecoder<8>(MI, tmp, Decoder); 7411e9d1d76SColin LeMahieu return MCDisassembler::Success; 7421e9d1d76SColin LeMahieu } 7431e9d1d76SColin LeMahieu 7441e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, 7451e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7467cd08927SColin LeMahieu signedDecoder<6>(MI, tmp, Decoder); 7471e9d1d76SColin LeMahieu return MCDisassembler::Success; 7481e9d1d76SColin LeMahieu } 7491e9d1d76SColin LeMahieu 7501e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, 7511e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7527cd08927SColin LeMahieu signedDecoder<4>(MI, tmp, Decoder); 7531e9d1d76SColin LeMahieu return MCDisassembler::Success; 7541e9d1d76SColin LeMahieu } 7551e9d1d76SColin LeMahieu 7561e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, 7571e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7587cd08927SColin LeMahieu signedDecoder<5>(MI, tmp, Decoder); 7591e9d1d76SColin LeMahieu return MCDisassembler::Success; 7601e9d1d76SColin LeMahieu } 7611e9d1d76SColin LeMahieu 7621e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, 7631e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7647cd08927SColin LeMahieu signedDecoder<6>(MI, tmp, Decoder); 7651e9d1d76SColin LeMahieu return MCDisassembler::Success; 7661e9d1d76SColin LeMahieu } 7671e9d1d76SColin LeMahieu 7681e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, 7691e9d1d76SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7707cd08927SColin LeMahieu signedDecoder<7>(MI, tmp, Decoder); 7711e9d1d76SColin LeMahieu return MCDisassembler::Success; 7721e9d1d76SColin LeMahieu } 7731e9d1d76SColin LeMahieu 7747c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, 7757c958713SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7767cd08927SColin LeMahieu signedDecoder<10>(MI, tmp, Decoder); 7777c958713SColin LeMahieu return MCDisassembler::Success; 7787c958713SColin LeMahieu } 7797c958713SColin LeMahieu 7807c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, 7817c958713SColin LeMahieu uint64_t /*Address*/, const void *Decoder) { 7827cd08927SColin LeMahieu signedDecoder<19>(MI, tmp, Decoder); 7837c958713SColin LeMahieu return MCDisassembler::Success; 7847c958713SColin LeMahieu } 7857c958713SColin LeMahieu 7867cd08927SColin LeMahieu // custom decoder for various jump/call immediates 7877cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address, 7887cd08927SColin LeMahieu const void *Decoder) { 7897cd08927SColin LeMahieu HexagonDisassembler const &Disassembler = disassembler(Decoder); 7907cd08927SColin LeMahieu unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI); 7917cd08927SColin LeMahieu // r13_2 is not extendable, so if there are no extent bits, it's r13_2 7927cd08927SColin LeMahieu if (Bits == 0) 7937cd08927SColin LeMahieu Bits = 15; 7947cd08927SColin LeMahieu uint32_t FullValue = fullValue(*Disassembler.MCII, 7957cd08927SColin LeMahieu **Disassembler.CurrentBundle, 7967cd08927SColin LeMahieu MI, SignExtend64(tmp, Bits)); 7977cd08927SColin LeMahieu int64_t Extended = SignExtend64<32>(FullValue) + Address; 7987cd08927SColin LeMahieu if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 7997cd08927SColin LeMahieu 0, 4)) 8007cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext()); 8017cd08927SColin LeMahieu return MCDisassembler::Success; 8027cd08927SColin LeMahieu } 8037cd08927SColin LeMahieu 8047cd08927SColin LeMahieu // Addressing mode dependent load store opcode map. 8057cd08927SColin LeMahieu // - If an insn is preceded by an extender the address is absolute. 8067cd08927SColin LeMahieu // - memw(##symbol) = r0 8077cd08927SColin LeMahieu // - If an insn is not preceded by an extender the address is GP relative. 8087cd08927SColin LeMahieu // - memw(gp + #symbol) = r0 8097cd08927SColin LeMahieu // Please note that the instructions must be ordered in the descending order 8107cd08927SColin LeMahieu // of their opcode. 8117cd08927SColin LeMahieu // HexagonII::INST_ICLASS_ST 812d824f5f0SCraig Topper static const unsigned int StoreConditionalOpcodeData[][2] = { 8137cd08927SColin LeMahieu {S4_pstorerdfnew_abs, 0xafc02084}, 8147cd08927SColin LeMahieu {S4_pstorerdtnew_abs, 0xafc02080}, 8157cd08927SColin LeMahieu {S4_pstorerdf_abs, 0xafc00084}, 8167cd08927SColin LeMahieu {S4_pstorerdt_abs, 0xafc00080}, 8177cd08927SColin LeMahieu {S4_pstorerinewfnew_abs, 0xafa03084}, 8187cd08927SColin LeMahieu {S4_pstorerinewtnew_abs, 0xafa03080}, 8197cd08927SColin LeMahieu {S4_pstorerhnewfnew_abs, 0xafa02884}, 8207cd08927SColin LeMahieu {S4_pstorerhnewtnew_abs, 0xafa02880}, 8217cd08927SColin LeMahieu {S4_pstorerbnewfnew_abs, 0xafa02084}, 8227cd08927SColin LeMahieu {S4_pstorerbnewtnew_abs, 0xafa02080}, 8237cd08927SColin LeMahieu {S4_pstorerinewf_abs, 0xafa01084}, 8247cd08927SColin LeMahieu {S4_pstorerinewt_abs, 0xafa01080}, 8257cd08927SColin LeMahieu {S4_pstorerhnewf_abs, 0xafa00884}, 8267cd08927SColin LeMahieu {S4_pstorerhnewt_abs, 0xafa00880}, 8277cd08927SColin LeMahieu {S4_pstorerbnewf_abs, 0xafa00084}, 8287cd08927SColin LeMahieu {S4_pstorerbnewt_abs, 0xafa00080}, 8297cd08927SColin LeMahieu {S4_pstorerifnew_abs, 0xaf802084}, 8307cd08927SColin LeMahieu {S4_pstoreritnew_abs, 0xaf802080}, 8317cd08927SColin LeMahieu {S4_pstorerif_abs, 0xaf800084}, 8327cd08927SColin LeMahieu {S4_pstorerit_abs, 0xaf800080}, 8337cd08927SColin LeMahieu {S4_pstorerhfnew_abs, 0xaf402084}, 8347cd08927SColin LeMahieu {S4_pstorerhtnew_abs, 0xaf402080}, 8357cd08927SColin LeMahieu {S4_pstorerhf_abs, 0xaf400084}, 8367cd08927SColin LeMahieu {S4_pstorerht_abs, 0xaf400080}, 8377cd08927SColin LeMahieu {S4_pstorerbfnew_abs, 0xaf002084}, 8387cd08927SColin LeMahieu {S4_pstorerbtnew_abs, 0xaf002080}, 8397cd08927SColin LeMahieu {S4_pstorerbf_abs, 0xaf000084}, 8407cd08927SColin LeMahieu {S4_pstorerbt_abs, 0xaf000080}}; 8417cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD 8427cd08927SColin LeMahieu 8437cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD_ST_2 8449675de5bSColin LeMahieu static unsigned int LoadStoreOpcodeData[][2] = {{PS_loadrdabs, 0x49c00000}, 8459675de5bSColin LeMahieu {PS_loadriabs, 0x49800000}, 8469675de5bSColin LeMahieu {PS_loadruhabs, 0x49600000}, 8479675de5bSColin LeMahieu {PS_loadrhabs, 0x49400000}, 8489675de5bSColin LeMahieu {PS_loadrubabs, 0x49200000}, 8499675de5bSColin LeMahieu {PS_loadrbabs, 0x49000000}, 8509675de5bSColin LeMahieu {PS_storerdabs, 0x48c00000}, 8519675de5bSColin LeMahieu {PS_storerinewabs, 0x48a01000}, 8529675de5bSColin LeMahieu {PS_storerhnewabs, 0x48a00800}, 8539675de5bSColin LeMahieu {PS_storerbnewabs, 0x48a00000}, 8549675de5bSColin LeMahieu {PS_storeriabs, 0x48800000}, 8559675de5bSColin LeMahieu {PS_storerfabs, 0x48600000}, 8569675de5bSColin LeMahieu {PS_storerhabs, 0x48400000}, 8579675de5bSColin LeMahieu {PS_storerbabs, 0x48000000}}; 858d824f5f0SCraig Topper static const size_t NumCondS = array_lengthof(StoreConditionalOpcodeData); 859d824f5f0SCraig Topper static const size_t NumLS = array_lengthof(LoadStoreOpcodeData); 8607cd08927SColin LeMahieu 8617cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) { 8627cd08927SColin LeMahieu 8637cd08927SColin LeMahieu unsigned MachineOpcode = 0; 8647cd08927SColin LeMahieu unsigned LLVMOpcode = 0; 8657cd08927SColin LeMahieu 8667cd08927SColin LeMahieu if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_ST) { 867d824f5f0SCraig Topper for (size_t i = 0; i < NumCondS; ++i) { 8687cd08927SColin LeMahieu if ((insn & StoreConditionalOpcodeData[i][1]) == 8697cd08927SColin LeMahieu StoreConditionalOpcodeData[i][1]) { 8707cd08927SColin LeMahieu MachineOpcode = StoreConditionalOpcodeData[i][1]; 8717cd08927SColin LeMahieu LLVMOpcode = StoreConditionalOpcodeData[i][0]; 8727cd08927SColin LeMahieu break; 8737cd08927SColin LeMahieu } 8747cd08927SColin LeMahieu } 8757cd08927SColin LeMahieu } 8767cd08927SColin LeMahieu if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_LD_ST_2) { 877d824f5f0SCraig Topper for (size_t i = 0; i < NumLS; ++i) { 8787cd08927SColin LeMahieu if ((insn & LoadStoreOpcodeData[i][1]) == LoadStoreOpcodeData[i][1]) { 8797cd08927SColin LeMahieu MachineOpcode = LoadStoreOpcodeData[i][1]; 8807cd08927SColin LeMahieu LLVMOpcode = LoadStoreOpcodeData[i][0]; 8817cd08927SColin LeMahieu break; 8827cd08927SColin LeMahieu } 8837cd08927SColin LeMahieu } 8847cd08927SColin LeMahieu } 8857cd08927SColin LeMahieu 8867cd08927SColin LeMahieu if (MachineOpcode) { 8877cd08927SColin LeMahieu unsigned Value = 0; 8887cd08927SColin LeMahieu unsigned shift = 0; 8897cd08927SColin LeMahieu MI.setOpcode(LLVMOpcode); 8907cd08927SColin LeMahieu // Remove the parse bits from the insn. 8917cd08927SColin LeMahieu insn &= ~HexagonII::INST_PARSE_MASK; 8927cd08927SColin LeMahieu 8937cd08927SColin LeMahieu switch (LLVMOpcode) { 8947cd08927SColin LeMahieu default: 8957cd08927SColin LeMahieu return MCDisassembler::Fail; 8967cd08927SColin LeMahieu break; 8977cd08927SColin LeMahieu 8987cd08927SColin LeMahieu case Hexagon::S4_pstorerdf_abs: 8997cd08927SColin LeMahieu case Hexagon::S4_pstorerdt_abs: 9007cd08927SColin LeMahieu case Hexagon::S4_pstorerdfnew_abs: 9017cd08927SColin LeMahieu case Hexagon::S4_pstorerdtnew_abs: { 9027cd08927SColin LeMahieu // op: Pv 9037cd08927SColin LeMahieu Value = insn & UINT64_C(3); 9047cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 9057cd08927SColin LeMahieu // op: u6 9067cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 9077cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 9087cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 9097cd08927SColin LeMahieu // op: Rtt 9107cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 9117cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 9127cd08927SColin LeMahieu break; 9137cd08927SColin LeMahieu } 9147cd08927SColin LeMahieu 9157cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewf_abs: 9167cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewt_abs: 9177cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewfnew_abs: 9187cd08927SColin LeMahieu case Hexagon::S4_pstorerbnewtnew_abs: 9197cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewf_abs: 9207cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewt_abs: 9217cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewfnew_abs: 9227cd08927SColin LeMahieu case Hexagon::S4_pstorerhnewtnew_abs: 9237cd08927SColin LeMahieu case Hexagon::S4_pstorerinewf_abs: 9247cd08927SColin LeMahieu case Hexagon::S4_pstorerinewt_abs: 9257cd08927SColin LeMahieu case Hexagon::S4_pstorerinewfnew_abs: 9267cd08927SColin LeMahieu case Hexagon::S4_pstorerinewtnew_abs: { 9277cd08927SColin LeMahieu // op: Pv 9287cd08927SColin LeMahieu Value = insn & UINT64_C(3); 9297cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 9307cd08927SColin LeMahieu // op: u6 9317cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 9327cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 9337cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 9347cd08927SColin LeMahieu // op: Nt 9357cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(7); 9367cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 9377cd08927SColin LeMahieu break; 9387cd08927SColin LeMahieu } 9397cd08927SColin LeMahieu 9407cd08927SColin LeMahieu case Hexagon::S4_pstorerbf_abs: 9417cd08927SColin LeMahieu case Hexagon::S4_pstorerbt_abs: 9427cd08927SColin LeMahieu case Hexagon::S4_pstorerbfnew_abs: 9437cd08927SColin LeMahieu case Hexagon::S4_pstorerbtnew_abs: 9447cd08927SColin LeMahieu case Hexagon::S4_pstorerhf_abs: 9457cd08927SColin LeMahieu case Hexagon::S4_pstorerht_abs: 9467cd08927SColin LeMahieu case Hexagon::S4_pstorerhfnew_abs: 9477cd08927SColin LeMahieu case Hexagon::S4_pstorerhtnew_abs: 9487cd08927SColin LeMahieu case Hexagon::S4_pstorerif_abs: 9497cd08927SColin LeMahieu case Hexagon::S4_pstorerit_abs: 9507cd08927SColin LeMahieu case Hexagon::S4_pstorerifnew_abs: 9517cd08927SColin LeMahieu case Hexagon::S4_pstoreritnew_abs: { 9527cd08927SColin LeMahieu // op: Pv 9537cd08927SColin LeMahieu Value = insn & UINT64_C(3); 9547cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 9557cd08927SColin LeMahieu // op: u6 9567cd08927SColin LeMahieu Value = (insn >> 12) & UINT64_C(48); 9577cd08927SColin LeMahieu Value |= (insn >> 3) & UINT64_C(15); 9587cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 9597cd08927SColin LeMahieu // op: Rt 9607cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 9617cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 9627cd08927SColin LeMahieu break; 9637cd08927SColin LeMahieu } 9647cd08927SColin LeMahieu 9657cd08927SColin LeMahieu case Hexagon::L4_ploadrdf_abs: 9667cd08927SColin LeMahieu case Hexagon::L4_ploadrdt_abs: 9677cd08927SColin LeMahieu case Hexagon::L4_ploadrdfnew_abs: 9687cd08927SColin LeMahieu case Hexagon::L4_ploadrdtnew_abs: { 9697cd08927SColin LeMahieu // op: Rdd 9707cd08927SColin LeMahieu Value = insn & UINT64_C(31); 9717cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 9727cd08927SColin LeMahieu // op: Pt 9737cd08927SColin LeMahieu Value = ((insn >> 9) & UINT64_C(3)); 9747cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 9757cd08927SColin LeMahieu // op: u6 9767cd08927SColin LeMahieu Value = ((insn >> 15) & UINT64_C(62)); 9777cd08927SColin LeMahieu Value |= ((insn >> 8) & UINT64_C(1)); 9787cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 9797cd08927SColin LeMahieu break; 9807cd08927SColin LeMahieu } 9817cd08927SColin LeMahieu 9827cd08927SColin LeMahieu case Hexagon::L4_ploadrbf_abs: 9837cd08927SColin LeMahieu case Hexagon::L4_ploadrbt_abs: 9847cd08927SColin LeMahieu case Hexagon::L4_ploadrbfnew_abs: 9857cd08927SColin LeMahieu case Hexagon::L4_ploadrbtnew_abs: 9867cd08927SColin LeMahieu case Hexagon::L4_ploadrhf_abs: 9877cd08927SColin LeMahieu case Hexagon::L4_ploadrht_abs: 9887cd08927SColin LeMahieu case Hexagon::L4_ploadrhfnew_abs: 9897cd08927SColin LeMahieu case Hexagon::L4_ploadrhtnew_abs: 9907cd08927SColin LeMahieu case Hexagon::L4_ploadrubf_abs: 9917cd08927SColin LeMahieu case Hexagon::L4_ploadrubt_abs: 9927cd08927SColin LeMahieu case Hexagon::L4_ploadrubfnew_abs: 9937cd08927SColin LeMahieu case Hexagon::L4_ploadrubtnew_abs: 9947cd08927SColin LeMahieu case Hexagon::L4_ploadruhf_abs: 9957cd08927SColin LeMahieu case Hexagon::L4_ploadruht_abs: 9967cd08927SColin LeMahieu case Hexagon::L4_ploadruhfnew_abs: 9977cd08927SColin LeMahieu case Hexagon::L4_ploadruhtnew_abs: 9987cd08927SColin LeMahieu case Hexagon::L4_ploadrif_abs: 9997cd08927SColin LeMahieu case Hexagon::L4_ploadrit_abs: 10007cd08927SColin LeMahieu case Hexagon::L4_ploadrifnew_abs: 10017cd08927SColin LeMahieu case Hexagon::L4_ploadritnew_abs: 10027cd08927SColin LeMahieu // op: Rd 10037cd08927SColin LeMahieu Value = insn & UINT64_C(31); 10047cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 10057cd08927SColin LeMahieu // op: Pt 10067cd08927SColin LeMahieu Value = (insn >> 9) & UINT64_C(3); 10077cd08927SColin LeMahieu DecodePredRegsRegisterClass(MI, Value, 0, 0); 10087cd08927SColin LeMahieu // op: u6 10097cd08927SColin LeMahieu Value = (insn >> 15) & UINT64_C(62); 10107cd08927SColin LeMahieu Value |= (insn >> 8) & UINT64_C(1); 10117cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value)); 10127cd08927SColin LeMahieu break; 10137cd08927SColin LeMahieu 10147cd08927SColin LeMahieu // op: g16_2 10159675de5bSColin LeMahieu case (Hexagon::PS_loadriabs): 10167cd08927SColin LeMahieu ++shift; 10177cd08927SColin LeMahieu // op: g16_1 10189675de5bSColin LeMahieu case Hexagon::PS_loadrhabs: 10199675de5bSColin LeMahieu case Hexagon::PS_loadruhabs: 10207cd08927SColin LeMahieu ++shift; 10217cd08927SColin LeMahieu // op: g16_0 10229675de5bSColin LeMahieu case Hexagon::PS_loadrbabs: 10239675de5bSColin LeMahieu case Hexagon::PS_loadrubabs: { 10247cd08927SColin LeMahieu // op: Rd 10257cd08927SColin LeMahieu Value |= insn & UINT64_C(31); 10267cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 10277cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 10287cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 10297cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(511); 10307cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 10317cd08927SColin LeMahieu break; 10327cd08927SColin LeMahieu } 10337cd08927SColin LeMahieu 10349675de5bSColin LeMahieu case Hexagon::PS_loadrdabs: { 10357cd08927SColin LeMahieu Value = insn & UINT64_C(31); 10367cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 10377cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 10387cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 10397cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(511); 10407cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << 3)); 10417cd08927SColin LeMahieu break; 10427cd08927SColin LeMahieu } 10437cd08927SColin LeMahieu 10449675de5bSColin LeMahieu case Hexagon::PS_storerdabs: { 10457cd08927SColin LeMahieu // op: g16_3 10467cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 10477cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 10487cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 10497cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 10507cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << 3)); 10517cd08927SColin LeMahieu // op: Rtt 10527cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 10537cd08927SColin LeMahieu DecodeDoubleRegsRegisterClass(MI, Value, 0, 0); 10547cd08927SColin LeMahieu break; 10557cd08927SColin LeMahieu } 10567cd08927SColin LeMahieu 10577cd08927SColin LeMahieu // op: g16_2 10589675de5bSColin LeMahieu case Hexagon::PS_storerinewabs: 10597cd08927SColin LeMahieu ++shift; 10607cd08927SColin LeMahieu // op: g16_1 10619675de5bSColin LeMahieu case Hexagon::PS_storerhnewabs: 10627cd08927SColin LeMahieu ++shift; 10637cd08927SColin LeMahieu // op: g16_0 10649675de5bSColin LeMahieu case Hexagon::PS_storerbnewabs: { 10657cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 10667cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 10677cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 10687cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 10697cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 10707cd08927SColin LeMahieu // op: Nt 10717cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(7); 10727cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 10737cd08927SColin LeMahieu break; 10747cd08927SColin LeMahieu } 10757cd08927SColin LeMahieu 10767cd08927SColin LeMahieu // op: g16_2 10779675de5bSColin LeMahieu case Hexagon::PS_storeriabs: 10787cd08927SColin LeMahieu ++shift; 10797cd08927SColin LeMahieu // op: g16_1 10809675de5bSColin LeMahieu case Hexagon::PS_storerhabs: 10819675de5bSColin LeMahieu case Hexagon::PS_storerfabs: 10827cd08927SColin LeMahieu ++shift; 10837cd08927SColin LeMahieu // op: g16_0 10849675de5bSColin LeMahieu case Hexagon::PS_storerbabs: { 10857cd08927SColin LeMahieu Value = (insn >> 11) & UINT64_C(49152); 10867cd08927SColin LeMahieu Value |= (insn >> 7) & UINT64_C(15872); 10877cd08927SColin LeMahieu Value |= (insn >> 5) & UINT64_C(256); 10887cd08927SColin LeMahieu Value |= insn & UINT64_C(255); 10897cd08927SColin LeMahieu MI.addOperand(MCOperand::createImm(Value << shift)); 10907cd08927SColin LeMahieu // op: Rt 10917cd08927SColin LeMahieu Value = (insn >> 8) & UINT64_C(31); 10927cd08927SColin LeMahieu DecodeIntRegsRegisterClass(MI, Value, 0, 0); 10937cd08927SColin LeMahieu break; 10947cd08927SColin LeMahieu } 10957cd08927SColin LeMahieu } 10967cd08927SColin LeMahieu return MCDisassembler::Success; 10977cd08927SColin LeMahieu } 10987cd08927SColin LeMahieu return MCDisassembler::Fail; 10997cd08927SColin LeMahieu } 11007cd08927SColin LeMahieu 11017cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn, 11027cd08927SColin LeMahieu void const *Decoder) { 11037cd08927SColin LeMahieu 11047cd08927SColin LeMahieu // Instruction Class for a constant a extender: bits 31:28 = 0x0000 11057cd08927SColin LeMahieu if ((~insn & 0xf0000000) == 0xf0000000) { 11067cd08927SColin LeMahieu unsigned Value; 11077cd08927SColin LeMahieu // 27:16 High 12 bits of 26-bit extender. 11087cd08927SColin LeMahieu Value = (insn & 0x0fff0000) << 4; 11097cd08927SColin LeMahieu // 13:0 Low 14 bits of 26-bit extender. 11107cd08927SColin LeMahieu Value |= ((insn & 0x3fff) << 6); 11117cd08927SColin LeMahieu MI.setOpcode(Hexagon::A4_ext); 11127cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(MI, Value, contextFromDecoder(Decoder)); 11137cd08927SColin LeMahieu return MCDisassembler::Success; 11147cd08927SColin LeMahieu } 11157cd08927SColin LeMahieu return MCDisassembler::Fail; 11167cd08927SColin LeMahieu } 11177cd08927SColin LeMahieu 1118be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td 1119be8c453dSColin LeMahieu enum subInstBinaryValues { 11208ed1aee9SColin LeMahieu SA1_addi_BITS = 0x0000, 11218ed1aee9SColin LeMahieu SA1_addi_MASK = 0x1800, 11228ed1aee9SColin LeMahieu SA1_addrx_BITS = 0x1800, 11238ed1aee9SColin LeMahieu SA1_addrx_MASK = 0x1f00, 11248ed1aee9SColin LeMahieu SA1_addsp_BITS = 0x0c00, 11258ed1aee9SColin LeMahieu SA1_addsp_MASK = 0x1c00, 11268ed1aee9SColin LeMahieu SA1_and1_BITS = 0x1200, 11278ed1aee9SColin LeMahieu SA1_and1_MASK = 0x1f00, 11288ed1aee9SColin LeMahieu SA1_clrf_BITS = 0x1a70, 11298ed1aee9SColin LeMahieu SA1_clrf_MASK = 0x1e70, 11308ed1aee9SColin LeMahieu SA1_clrfnew_BITS = 0x1a50, 11318ed1aee9SColin LeMahieu SA1_clrfnew_MASK = 0x1e70, 11328ed1aee9SColin LeMahieu SA1_clrt_BITS = 0x1a60, 11338ed1aee9SColin LeMahieu SA1_clrt_MASK = 0x1e70, 11348ed1aee9SColin LeMahieu SA1_clrtnew_BITS = 0x1a40, 11358ed1aee9SColin LeMahieu SA1_clrtnew_MASK = 0x1e70, 11368ed1aee9SColin LeMahieu SA1_cmpeqi_BITS = 0x1900, 11378ed1aee9SColin LeMahieu SA1_cmpeqi_MASK = 0x1f00, 11388ed1aee9SColin LeMahieu SA1_combine0i_BITS = 0x1c00, 11398ed1aee9SColin LeMahieu SA1_combine0i_MASK = 0x1d18, 11408ed1aee9SColin LeMahieu SA1_combine1i_BITS = 0x1c08, 11418ed1aee9SColin LeMahieu SA1_combine1i_MASK = 0x1d18, 11428ed1aee9SColin LeMahieu SA1_combine2i_BITS = 0x1c10, 11438ed1aee9SColin LeMahieu SA1_combine2i_MASK = 0x1d18, 11448ed1aee9SColin LeMahieu SA1_combine3i_BITS = 0x1c18, 11458ed1aee9SColin LeMahieu SA1_combine3i_MASK = 0x1d18, 11468ed1aee9SColin LeMahieu SA1_combinerz_BITS = 0x1d08, 11478ed1aee9SColin LeMahieu SA1_combinerz_MASK = 0x1d08, 11488ed1aee9SColin LeMahieu SA1_combinezr_BITS = 0x1d00, 11498ed1aee9SColin LeMahieu SA1_combinezr_MASK = 0x1d08, 11508ed1aee9SColin LeMahieu SA1_dec_BITS = 0x1300, 11518ed1aee9SColin LeMahieu SA1_dec_MASK = 0x1f00, 11528ed1aee9SColin LeMahieu SA1_inc_BITS = 0x1100, 11538ed1aee9SColin LeMahieu SA1_inc_MASK = 0x1f00, 11548ed1aee9SColin LeMahieu SA1_seti_BITS = 0x0800, 11558ed1aee9SColin LeMahieu SA1_seti_MASK = 0x1c00, 11568ed1aee9SColin LeMahieu SA1_setin1_BITS = 0x1a00, 11578ed1aee9SColin LeMahieu SA1_setin1_MASK = 0x1e40, 11588ed1aee9SColin LeMahieu SA1_sxtb_BITS = 0x1500, 11598ed1aee9SColin LeMahieu SA1_sxtb_MASK = 0x1f00, 11608ed1aee9SColin LeMahieu SA1_sxth_BITS = 0x1400, 11618ed1aee9SColin LeMahieu SA1_sxth_MASK = 0x1f00, 11628ed1aee9SColin LeMahieu SA1_tfr_BITS = 0x1000, 11638ed1aee9SColin LeMahieu SA1_tfr_MASK = 0x1f00, 11648ed1aee9SColin LeMahieu SA1_zxtb_BITS = 0x1700, 11658ed1aee9SColin LeMahieu SA1_zxtb_MASK = 0x1f00, 11668ed1aee9SColin LeMahieu SA1_zxth_BITS = 0x1600, 11678ed1aee9SColin LeMahieu SA1_zxth_MASK = 0x1f00, 11688ed1aee9SColin LeMahieu SL1_loadri_io_BITS = 0x0000, 11698ed1aee9SColin LeMahieu SL1_loadri_io_MASK = 0x1000, 11708ed1aee9SColin LeMahieu SL1_loadrub_io_BITS = 0x1000, 11718ed1aee9SColin LeMahieu SL1_loadrub_io_MASK = 0x1000, 11728ed1aee9SColin LeMahieu SL2_deallocframe_BITS = 0x1f00, 11738ed1aee9SColin LeMahieu SL2_deallocframe_MASK = 0x1fc0, 11748ed1aee9SColin LeMahieu SL2_jumpr31_BITS = 0x1fc0, 11758ed1aee9SColin LeMahieu SL2_jumpr31_MASK = 0x1fc4, 11768ed1aee9SColin LeMahieu SL2_jumpr31_f_BITS = 0x1fc5, 11778ed1aee9SColin LeMahieu SL2_jumpr31_f_MASK = 0x1fc7, 11788ed1aee9SColin LeMahieu SL2_jumpr31_fnew_BITS = 0x1fc7, 11798ed1aee9SColin LeMahieu SL2_jumpr31_fnew_MASK = 0x1fc7, 11808ed1aee9SColin LeMahieu SL2_jumpr31_t_BITS = 0x1fc4, 11818ed1aee9SColin LeMahieu SL2_jumpr31_t_MASK = 0x1fc7, 11828ed1aee9SColin LeMahieu SL2_jumpr31_tnew_BITS = 0x1fc6, 11838ed1aee9SColin LeMahieu SL2_jumpr31_tnew_MASK = 0x1fc7, 11848ed1aee9SColin LeMahieu SL2_loadrb_io_BITS = 0x1000, 11858ed1aee9SColin LeMahieu SL2_loadrb_io_MASK = 0x1800, 11868ed1aee9SColin LeMahieu SL2_loadrd_sp_BITS = 0x1e00, 11878ed1aee9SColin LeMahieu SL2_loadrd_sp_MASK = 0x1f00, 11888ed1aee9SColin LeMahieu SL2_loadrh_io_BITS = 0x0000, 11898ed1aee9SColin LeMahieu SL2_loadrh_io_MASK = 0x1800, 11908ed1aee9SColin LeMahieu SL2_loadri_sp_BITS = 0x1c00, 11918ed1aee9SColin LeMahieu SL2_loadri_sp_MASK = 0x1e00, 11928ed1aee9SColin LeMahieu SL2_loadruh_io_BITS = 0x0800, 11938ed1aee9SColin LeMahieu SL2_loadruh_io_MASK = 0x1800, 11948ed1aee9SColin LeMahieu SL2_return_BITS = 0x1f40, 11958ed1aee9SColin LeMahieu SL2_return_MASK = 0x1fc4, 11968ed1aee9SColin LeMahieu SL2_return_f_BITS = 0x1f45, 11978ed1aee9SColin LeMahieu SL2_return_f_MASK = 0x1fc7, 11988ed1aee9SColin LeMahieu SL2_return_fnew_BITS = 0x1f47, 11998ed1aee9SColin LeMahieu SL2_return_fnew_MASK = 0x1fc7, 12008ed1aee9SColin LeMahieu SL2_return_t_BITS = 0x1f44, 12018ed1aee9SColin LeMahieu SL2_return_t_MASK = 0x1fc7, 12028ed1aee9SColin LeMahieu SL2_return_tnew_BITS = 0x1f46, 12038ed1aee9SColin LeMahieu SL2_return_tnew_MASK = 0x1fc7, 12048ed1aee9SColin LeMahieu SS1_storeb_io_BITS = 0x1000, 12058ed1aee9SColin LeMahieu SS1_storeb_io_MASK = 0x1000, 12068ed1aee9SColin LeMahieu SS1_storew_io_BITS = 0x0000, 12078ed1aee9SColin LeMahieu SS1_storew_io_MASK = 0x1000, 12088ed1aee9SColin LeMahieu SS2_allocframe_BITS = 0x1c00, 12098ed1aee9SColin LeMahieu SS2_allocframe_MASK = 0x1e00, 12108ed1aee9SColin LeMahieu SS2_storebi0_BITS = 0x1200, 12118ed1aee9SColin LeMahieu SS2_storebi0_MASK = 0x1f00, 12128ed1aee9SColin LeMahieu SS2_storebi1_BITS = 0x1300, 12138ed1aee9SColin LeMahieu SS2_storebi1_MASK = 0x1f00, 12148ed1aee9SColin LeMahieu SS2_stored_sp_BITS = 0x0a00, 12158ed1aee9SColin LeMahieu SS2_stored_sp_MASK = 0x1e00, 12168ed1aee9SColin LeMahieu SS2_storeh_io_BITS = 0x0000, 12178ed1aee9SColin LeMahieu SS2_storeh_io_MASK = 0x1800, 12188ed1aee9SColin LeMahieu SS2_storew_sp_BITS = 0x0800, 12198ed1aee9SColin LeMahieu SS2_storew_sp_MASK = 0x1e00, 12208ed1aee9SColin LeMahieu SS2_storewi0_BITS = 0x1000, 12218ed1aee9SColin LeMahieu SS2_storewi0_MASK = 0x1f00, 12228ed1aee9SColin LeMahieu SS2_storewi1_BITS = 0x1100, 12238ed1aee9SColin LeMahieu SS2_storewi1_MASK = 0x1f00 1224be8c453dSColin LeMahieu }; 1225be8c453dSColin LeMahieu 1226be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op, 1227be8c453dSColin LeMahieu raw_ostream &os) { 1228be8c453dSColin LeMahieu switch (IClass) { 1229be8c453dSColin LeMahieu case HexagonII::HSIG_L1: 12308ed1aee9SColin LeMahieu if ((inst & SL1_loadri_io_MASK) == SL1_loadri_io_BITS) 12318ed1aee9SColin LeMahieu op = Hexagon::SL1_loadri_io; 12328ed1aee9SColin LeMahieu else if ((inst & SL1_loadrub_io_MASK) == SL1_loadrub_io_BITS) 12338ed1aee9SColin LeMahieu op = Hexagon::SL1_loadrub_io; 1234be8c453dSColin LeMahieu else { 1235be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1236be8c453dSColin LeMahieu return MCDisassembler::Fail; 1237be8c453dSColin LeMahieu } 1238be8c453dSColin LeMahieu break; 1239be8c453dSColin LeMahieu case HexagonII::HSIG_L2: 12408ed1aee9SColin LeMahieu if ((inst & SL2_deallocframe_MASK) == SL2_deallocframe_BITS) 12418ed1aee9SColin LeMahieu op = Hexagon::SL2_deallocframe; 12428ed1aee9SColin LeMahieu else if ((inst & SL2_jumpr31_MASK) == SL2_jumpr31_BITS) 12438ed1aee9SColin LeMahieu op = Hexagon::SL2_jumpr31; 12448ed1aee9SColin LeMahieu else if ((inst & SL2_jumpr31_f_MASK) == SL2_jumpr31_f_BITS) 12458ed1aee9SColin LeMahieu op = Hexagon::SL2_jumpr31_f; 12468ed1aee9SColin LeMahieu else if ((inst & SL2_jumpr31_fnew_MASK) == SL2_jumpr31_fnew_BITS) 12478ed1aee9SColin LeMahieu op = Hexagon::SL2_jumpr31_fnew; 12488ed1aee9SColin LeMahieu else if ((inst & SL2_jumpr31_t_MASK) == SL2_jumpr31_t_BITS) 12498ed1aee9SColin LeMahieu op = Hexagon::SL2_jumpr31_t; 12508ed1aee9SColin LeMahieu else if ((inst & SL2_jumpr31_tnew_MASK) == SL2_jumpr31_tnew_BITS) 12518ed1aee9SColin LeMahieu op = Hexagon::SL2_jumpr31_tnew; 12528ed1aee9SColin LeMahieu else if ((inst & SL2_loadrb_io_MASK) == SL2_loadrb_io_BITS) 12538ed1aee9SColin LeMahieu op = Hexagon::SL2_loadrb_io; 12548ed1aee9SColin LeMahieu else if ((inst & SL2_loadrd_sp_MASK) == SL2_loadrd_sp_BITS) 12558ed1aee9SColin LeMahieu op = Hexagon::SL2_loadrd_sp; 12568ed1aee9SColin LeMahieu else if ((inst & SL2_loadrh_io_MASK) == SL2_loadrh_io_BITS) 12578ed1aee9SColin LeMahieu op = Hexagon::SL2_loadrh_io; 12588ed1aee9SColin LeMahieu else if ((inst & SL2_loadri_sp_MASK) == SL2_loadri_sp_BITS) 12598ed1aee9SColin LeMahieu op = Hexagon::SL2_loadri_sp; 12608ed1aee9SColin LeMahieu else if ((inst & SL2_loadruh_io_MASK) == SL2_loadruh_io_BITS) 12618ed1aee9SColin LeMahieu op = Hexagon::SL2_loadruh_io; 12628ed1aee9SColin LeMahieu else if ((inst & SL2_return_MASK) == SL2_return_BITS) 12638ed1aee9SColin LeMahieu op = Hexagon::SL2_return; 12648ed1aee9SColin LeMahieu else if ((inst & SL2_return_f_MASK) == SL2_return_f_BITS) 12658ed1aee9SColin LeMahieu op = Hexagon::SL2_return_f; 12668ed1aee9SColin LeMahieu else if ((inst & SL2_return_fnew_MASK) == SL2_return_fnew_BITS) 12678ed1aee9SColin LeMahieu op = Hexagon::SL2_return_fnew; 12688ed1aee9SColin LeMahieu else if ((inst & SL2_return_t_MASK) == SL2_return_t_BITS) 12698ed1aee9SColin LeMahieu op = Hexagon::SL2_return_t; 12708ed1aee9SColin LeMahieu else if ((inst & SL2_return_tnew_MASK) == SL2_return_tnew_BITS) 12718ed1aee9SColin LeMahieu op = Hexagon::SL2_return_tnew; 1272be8c453dSColin LeMahieu else { 1273be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1274be8c453dSColin LeMahieu return MCDisassembler::Fail; 1275be8c453dSColin LeMahieu } 1276be8c453dSColin LeMahieu break; 1277be8c453dSColin LeMahieu case HexagonII::HSIG_A: 12788ed1aee9SColin LeMahieu if ((inst & SA1_addi_MASK) == SA1_addi_BITS) 12798ed1aee9SColin LeMahieu op = Hexagon::SA1_addi; 12808ed1aee9SColin LeMahieu else if ((inst & SA1_addrx_MASK) == SA1_addrx_BITS) 12818ed1aee9SColin LeMahieu op = Hexagon::SA1_addrx; 12828ed1aee9SColin LeMahieu else if ((inst & SA1_addsp_MASK) == SA1_addsp_BITS) 12838ed1aee9SColin LeMahieu op = Hexagon::SA1_addsp; 12848ed1aee9SColin LeMahieu else if ((inst & SA1_and1_MASK) == SA1_and1_BITS) 12858ed1aee9SColin LeMahieu op = Hexagon::SA1_and1; 12868ed1aee9SColin LeMahieu else if ((inst & SA1_clrf_MASK) == SA1_clrf_BITS) 12878ed1aee9SColin LeMahieu op = Hexagon::SA1_clrf; 12888ed1aee9SColin LeMahieu else if ((inst & SA1_clrfnew_MASK) == SA1_clrfnew_BITS) 12898ed1aee9SColin LeMahieu op = Hexagon::SA1_clrfnew; 12908ed1aee9SColin LeMahieu else if ((inst & SA1_clrt_MASK) == SA1_clrt_BITS) 12918ed1aee9SColin LeMahieu op = Hexagon::SA1_clrt; 12928ed1aee9SColin LeMahieu else if ((inst & SA1_clrtnew_MASK) == SA1_clrtnew_BITS) 12938ed1aee9SColin LeMahieu op = Hexagon::SA1_clrtnew; 12948ed1aee9SColin LeMahieu else if ((inst & SA1_cmpeqi_MASK) == SA1_cmpeqi_BITS) 12958ed1aee9SColin LeMahieu op = Hexagon::SA1_cmpeqi; 12968ed1aee9SColin LeMahieu else if ((inst & SA1_combine0i_MASK) == SA1_combine0i_BITS) 12978ed1aee9SColin LeMahieu op = Hexagon::SA1_combine0i; 12988ed1aee9SColin LeMahieu else if ((inst & SA1_combine1i_MASK) == SA1_combine1i_BITS) 12998ed1aee9SColin LeMahieu op = Hexagon::SA1_combine1i; 13008ed1aee9SColin LeMahieu else if ((inst & SA1_combine2i_MASK) == SA1_combine2i_BITS) 13018ed1aee9SColin LeMahieu op = Hexagon::SA1_combine2i; 13028ed1aee9SColin LeMahieu else if ((inst & SA1_combine3i_MASK) == SA1_combine3i_BITS) 13038ed1aee9SColin LeMahieu op = Hexagon::SA1_combine3i; 13048ed1aee9SColin LeMahieu else if ((inst & SA1_combinerz_MASK) == SA1_combinerz_BITS) 13058ed1aee9SColin LeMahieu op = Hexagon::SA1_combinerz; 13068ed1aee9SColin LeMahieu else if ((inst & SA1_combinezr_MASK) == SA1_combinezr_BITS) 13078ed1aee9SColin LeMahieu op = Hexagon::SA1_combinezr; 13088ed1aee9SColin LeMahieu else if ((inst & SA1_dec_MASK) == SA1_dec_BITS) 13098ed1aee9SColin LeMahieu op = Hexagon::SA1_dec; 13108ed1aee9SColin LeMahieu else if ((inst & SA1_inc_MASK) == SA1_inc_BITS) 13118ed1aee9SColin LeMahieu op = Hexagon::SA1_inc; 13128ed1aee9SColin LeMahieu else if ((inst & SA1_seti_MASK) == SA1_seti_BITS) 13138ed1aee9SColin LeMahieu op = Hexagon::SA1_seti; 13148ed1aee9SColin LeMahieu else if ((inst & SA1_setin1_MASK) == SA1_setin1_BITS) 13158ed1aee9SColin LeMahieu op = Hexagon::SA1_setin1; 13168ed1aee9SColin LeMahieu else if ((inst & SA1_sxtb_MASK) == SA1_sxtb_BITS) 13178ed1aee9SColin LeMahieu op = Hexagon::SA1_sxtb; 13188ed1aee9SColin LeMahieu else if ((inst & SA1_sxth_MASK) == SA1_sxth_BITS) 13198ed1aee9SColin LeMahieu op = Hexagon::SA1_sxth; 13208ed1aee9SColin LeMahieu else if ((inst & SA1_tfr_MASK) == SA1_tfr_BITS) 13218ed1aee9SColin LeMahieu op = Hexagon::SA1_tfr; 13228ed1aee9SColin LeMahieu else if ((inst & SA1_zxtb_MASK) == SA1_zxtb_BITS) 13238ed1aee9SColin LeMahieu op = Hexagon::SA1_zxtb; 13248ed1aee9SColin LeMahieu else if ((inst & SA1_zxth_MASK) == SA1_zxth_BITS) 13258ed1aee9SColin LeMahieu op = Hexagon::SA1_zxth; 1326be8c453dSColin LeMahieu else { 1327be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1328be8c453dSColin LeMahieu return MCDisassembler::Fail; 1329be8c453dSColin LeMahieu } 1330be8c453dSColin LeMahieu break; 1331be8c453dSColin LeMahieu case HexagonII::HSIG_S1: 13328ed1aee9SColin LeMahieu if ((inst & SS1_storeb_io_MASK) == SS1_storeb_io_BITS) 13338ed1aee9SColin LeMahieu op = Hexagon::SS1_storeb_io; 13348ed1aee9SColin LeMahieu else if ((inst & SS1_storew_io_MASK) == SS1_storew_io_BITS) 13358ed1aee9SColin LeMahieu op = Hexagon::SS1_storew_io; 1336be8c453dSColin LeMahieu else { 1337be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1338be8c453dSColin LeMahieu return MCDisassembler::Fail; 1339be8c453dSColin LeMahieu } 1340be8c453dSColin LeMahieu break; 1341be8c453dSColin LeMahieu case HexagonII::HSIG_S2: 13428ed1aee9SColin LeMahieu if ((inst & SS2_allocframe_MASK) == SS2_allocframe_BITS) 13438ed1aee9SColin LeMahieu op = Hexagon::SS2_allocframe; 13448ed1aee9SColin LeMahieu else if ((inst & SS2_storebi0_MASK) == SS2_storebi0_BITS) 13458ed1aee9SColin LeMahieu op = Hexagon::SS2_storebi0; 13468ed1aee9SColin LeMahieu else if ((inst & SS2_storebi1_MASK) == SS2_storebi1_BITS) 13478ed1aee9SColin LeMahieu op = Hexagon::SS2_storebi1; 13488ed1aee9SColin LeMahieu else if ((inst & SS2_stored_sp_MASK) == SS2_stored_sp_BITS) 13498ed1aee9SColin LeMahieu op = Hexagon::SS2_stored_sp; 13508ed1aee9SColin LeMahieu else if ((inst & SS2_storeh_io_MASK) == SS2_storeh_io_BITS) 13518ed1aee9SColin LeMahieu op = Hexagon::SS2_storeh_io; 13528ed1aee9SColin LeMahieu else if ((inst & SS2_storew_sp_MASK) == SS2_storew_sp_BITS) 13538ed1aee9SColin LeMahieu op = Hexagon::SS2_storew_sp; 13548ed1aee9SColin LeMahieu else if ((inst & SS2_storewi0_MASK) == SS2_storewi0_BITS) 13558ed1aee9SColin LeMahieu op = Hexagon::SS2_storewi0; 13568ed1aee9SColin LeMahieu else if ((inst & SS2_storewi1_MASK) == SS2_storewi1_BITS) 13578ed1aee9SColin LeMahieu op = Hexagon::SS2_storewi1; 1358be8c453dSColin LeMahieu else { 1359be8c453dSColin LeMahieu os << "<unknown subinstruction>"; 1360be8c453dSColin LeMahieu return MCDisassembler::Fail; 1361be8c453dSColin LeMahieu } 1362be8c453dSColin LeMahieu break; 1363be8c453dSColin LeMahieu default: 1364be8c453dSColin LeMahieu os << "<unknown>"; 1365be8c453dSColin LeMahieu return MCDisassembler::Fail; 1366be8c453dSColin LeMahieu } 1367be8c453dSColin LeMahieu return MCDisassembler::Success; 1368be8c453dSColin LeMahieu } 1369be8c453dSColin LeMahieu 1370be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) { 1371be8c453dSColin LeMahieu if (encoded_reg < 8) 1372be8c453dSColin LeMahieu return Hexagon::R0 + encoded_reg; 1373be8c453dSColin LeMahieu else if (encoded_reg < 16) 1374be8c453dSColin LeMahieu return Hexagon::R0 + encoded_reg + 8; 13757cd08927SColin LeMahieu 13767cd08927SColin LeMahieu // patently false value 1377be8c453dSColin LeMahieu return Hexagon::NoRegister; 1378be8c453dSColin LeMahieu } 1379be8c453dSColin LeMahieu 1380be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) { 1381be8c453dSColin LeMahieu if (encoded_dreg < 4) 1382be8c453dSColin LeMahieu return Hexagon::D0 + encoded_dreg; 1383be8c453dSColin LeMahieu else if (encoded_dreg < 8) 1384be8c453dSColin LeMahieu return Hexagon::D0 + encoded_dreg + 4; 13857cd08927SColin LeMahieu 13867cd08927SColin LeMahieu // patently false value 1387be8c453dSColin LeMahieu return Hexagon::NoRegister; 1388be8c453dSColin LeMahieu } 1389be8c453dSColin LeMahieu 13907cd08927SColin LeMahieu void HexagonDisassembler::addSubinstOperands(MCInst *MI, unsigned opcode, 13917cd08927SColin LeMahieu unsigned inst) const { 1392be8c453dSColin LeMahieu int64_t operand; 1393be8c453dSColin LeMahieu MCOperand Op; 1394be8c453dSColin LeMahieu switch (opcode) { 13958ed1aee9SColin LeMahieu case Hexagon::SL2_deallocframe: 13968ed1aee9SColin LeMahieu case Hexagon::SL2_jumpr31: 13978ed1aee9SColin LeMahieu case Hexagon::SL2_jumpr31_f: 13988ed1aee9SColin LeMahieu case Hexagon::SL2_jumpr31_fnew: 13998ed1aee9SColin LeMahieu case Hexagon::SL2_jumpr31_t: 14008ed1aee9SColin LeMahieu case Hexagon::SL2_jumpr31_tnew: 14018ed1aee9SColin LeMahieu case Hexagon::SL2_return: 14028ed1aee9SColin LeMahieu case Hexagon::SL2_return_f: 14038ed1aee9SColin LeMahieu case Hexagon::SL2_return_fnew: 14048ed1aee9SColin LeMahieu case Hexagon::SL2_return_t: 14058ed1aee9SColin LeMahieu case Hexagon::SL2_return_tnew: 1406be8c453dSColin LeMahieu // no operands for these instructions 1407be8c453dSColin LeMahieu break; 14088ed1aee9SColin LeMahieu case Hexagon::SS2_allocframe: 1409be8c453dSColin LeMahieu // u 8-4{5_3} 1410be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 3; 14117cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1412be8c453dSColin LeMahieu break; 14138ed1aee9SColin LeMahieu case Hexagon::SL1_loadri_io: 1414be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 11-8{4_2} 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 & 0xf00) >> 6; 14227cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1423be8c453dSColin LeMahieu break; 14248ed1aee9SColin LeMahieu case Hexagon::SL1_loadrub_io: 1425be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 11-8 1426be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1427be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1428be8c453dSColin LeMahieu MI->addOperand(Op); 1429be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1430be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1431be8c453dSColin LeMahieu MI->addOperand(Op); 1432be8c453dSColin LeMahieu operand = (inst & 0xf00) >> 8; 14337cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1434be8c453dSColin LeMahieu break; 14358ed1aee9SColin LeMahieu case Hexagon::SL2_loadrb_io: 1436be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 10-8 1437be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1438be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1439be8c453dSColin LeMahieu MI->addOperand(Op); 1440be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1441be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1442be8c453dSColin LeMahieu MI->addOperand(Op); 1443be8c453dSColin LeMahieu operand = (inst & 0x700) >> 8; 14447cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1445be8c453dSColin LeMahieu break; 14468ed1aee9SColin LeMahieu case Hexagon::SL2_loadrh_io: 14478ed1aee9SColin LeMahieu case Hexagon::SL2_loadruh_io: 1448be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4, u 10-8{3_1} 1449be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1450be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1451be8c453dSColin LeMahieu MI->addOperand(Op); 1452be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1453be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1454be8c453dSColin LeMahieu MI->addOperand(Op); 1455be8c453dSColin LeMahieu operand = ((inst & 0x700) >> 8) << 1; 14567cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1457be8c453dSColin LeMahieu break; 14588ed1aee9SColin LeMahieu case Hexagon::SL2_loadrd_sp: 1459be8c453dSColin LeMahieu // Rdd 2-0, u 7-3{5_3} 1460be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1461be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1462be8c453dSColin LeMahieu MI->addOperand(Op); 1463be8c453dSColin LeMahieu operand = ((inst & 0x0f8) >> 3) << 3; 14647cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1465be8c453dSColin LeMahieu break; 14668ed1aee9SColin LeMahieu case Hexagon::SL2_loadri_sp: 1467be8c453dSColin LeMahieu // Rd 3-0, u 8-4{5_2} 1468be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1469be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1470be8c453dSColin LeMahieu MI->addOperand(Op); 1471be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 2; 14727cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1473be8c453dSColin LeMahieu break; 14748ed1aee9SColin LeMahieu case Hexagon::SA1_addi: 1475be8c453dSColin LeMahieu // Rx 3-0 (x2), s7 10-4 1476be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1477be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1478be8c453dSColin LeMahieu MI->addOperand(Op); 1479be8c453dSColin LeMahieu MI->addOperand(Op); 1480be8c453dSColin LeMahieu operand = SignExtend64<7>((inst & 0x7f0) >> 4); 14817cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1482be8c453dSColin LeMahieu break; 14838ed1aee9SColin LeMahieu case Hexagon::SA1_addrx: 1484be8c453dSColin LeMahieu // Rx 3-0 (x2), Rs 7-4 1485be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1486be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1487be8c453dSColin LeMahieu MI->addOperand(Op); 1488be8c453dSColin LeMahieu MI->addOperand(Op); 1489be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1490be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1491be8c453dSColin LeMahieu MI->addOperand(Op); 1492bb0cdfb9SColin LeMahieu break; 14938ed1aee9SColin LeMahieu case Hexagon::SA1_and1: 14948ed1aee9SColin LeMahieu case Hexagon::SA1_dec: 14958ed1aee9SColin LeMahieu case Hexagon::SA1_inc: 14968ed1aee9SColin LeMahieu case Hexagon::SA1_sxtb: 14978ed1aee9SColin LeMahieu case Hexagon::SA1_sxth: 14988ed1aee9SColin LeMahieu case Hexagon::SA1_tfr: 14998ed1aee9SColin LeMahieu case Hexagon::SA1_zxtb: 15008ed1aee9SColin LeMahieu case Hexagon::SA1_zxth: 1501be8c453dSColin LeMahieu // Rd 3-0, Rs 7-4 1502be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1503be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1504be8c453dSColin LeMahieu MI->addOperand(Op); 1505be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1506be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1507be8c453dSColin LeMahieu MI->addOperand(Op); 1508be8c453dSColin LeMahieu break; 15098ed1aee9SColin LeMahieu case Hexagon::SA1_addsp: 1510be8c453dSColin LeMahieu // Rd 3-0, u 9-4{6_2} 1511be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1512be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1513be8c453dSColin LeMahieu MI->addOperand(Op); 1514be8c453dSColin LeMahieu operand = ((inst & 0x3f0) >> 4) << 2; 15157cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1516be8c453dSColin LeMahieu break; 15178ed1aee9SColin LeMahieu case Hexagon::SA1_seti: 1518be8c453dSColin LeMahieu // Rd 3-0, u 9-4 1519be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1520be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1521be8c453dSColin LeMahieu MI->addOperand(Op); 1522be8c453dSColin LeMahieu operand = (inst & 0x3f0) >> 4; 15237cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1524be8c453dSColin LeMahieu break; 15258ed1aee9SColin LeMahieu case Hexagon::SA1_clrf: 15268ed1aee9SColin LeMahieu case Hexagon::SA1_clrfnew: 15278ed1aee9SColin LeMahieu case Hexagon::SA1_clrt: 15288ed1aee9SColin LeMahieu case Hexagon::SA1_clrtnew: 15298ed1aee9SColin LeMahieu case Hexagon::SA1_setin1: 1530be8c453dSColin LeMahieu // Rd 3-0 1531be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1532be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1533be8c453dSColin LeMahieu MI->addOperand(Op); 15348ed1aee9SColin LeMahieu if (opcode == Hexagon::SA1_setin1) 153573e0ad82SKrzysztof Parzyszek break; 153673e0ad82SKrzysztof Parzyszek MI->addOperand(MCOperand::createReg(Hexagon::P0)); 1537be8c453dSColin LeMahieu break; 15388ed1aee9SColin LeMahieu case Hexagon::SA1_cmpeqi: 1539be8c453dSColin LeMahieu // Rs 7-4, u 1-0 1540be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1541be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1542be8c453dSColin LeMahieu MI->addOperand(Op); 1543be8c453dSColin LeMahieu operand = inst & 0x3; 15447cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1545be8c453dSColin LeMahieu break; 15468ed1aee9SColin LeMahieu case Hexagon::SA1_combine0i: 15478ed1aee9SColin LeMahieu case Hexagon::SA1_combine1i: 15488ed1aee9SColin LeMahieu case Hexagon::SA1_combine2i: 15498ed1aee9SColin LeMahieu case Hexagon::SA1_combine3i: 1550be8c453dSColin LeMahieu // Rdd 2-0, u 6-5 1551be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1552be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1553be8c453dSColin LeMahieu MI->addOperand(Op); 1554be8c453dSColin LeMahieu operand = (inst & 0x060) >> 5; 15557cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1556be8c453dSColin LeMahieu break; 15578ed1aee9SColin LeMahieu case Hexagon::SA1_combinerz: 15588ed1aee9SColin LeMahieu case Hexagon::SA1_combinezr: 1559be8c453dSColin LeMahieu // Rdd 2-0, Rs 7-4 1560be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1561be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1562be8c453dSColin LeMahieu MI->addOperand(Op); 1563be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1564be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1565be8c453dSColin LeMahieu MI->addOperand(Op); 1566be8c453dSColin LeMahieu break; 15678ed1aee9SColin LeMahieu case Hexagon::SS1_storeb_io: 1568be8c453dSColin LeMahieu // Rs 7-4, u 11-8, Rt 3-0 1569be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1570be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1571be8c453dSColin LeMahieu MI->addOperand(Op); 1572be8c453dSColin LeMahieu operand = (inst & 0xf00) >> 8; 15737cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1574be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1575be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1576be8c453dSColin LeMahieu MI->addOperand(Op); 1577be8c453dSColin LeMahieu break; 15788ed1aee9SColin LeMahieu case Hexagon::SS1_storew_io: 1579be8c453dSColin LeMahieu // Rs 7-4, u 11-8{4_2}, Rt 3-0 1580be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1581be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1582be8c453dSColin LeMahieu MI->addOperand(Op); 1583be8c453dSColin LeMahieu operand = ((inst & 0xf00) >> 8) << 2; 15847cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1585be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1586be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1587be8c453dSColin LeMahieu MI->addOperand(Op); 1588be8c453dSColin LeMahieu break; 15898ed1aee9SColin LeMahieu case Hexagon::SS2_storebi0: 15908ed1aee9SColin LeMahieu case Hexagon::SS2_storebi1: 1591be8c453dSColin LeMahieu // Rs 7-4, u 3-0 1592be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1593be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1594be8c453dSColin LeMahieu MI->addOperand(Op); 1595be8c453dSColin LeMahieu operand = inst & 0xf; 15967cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1597be8c453dSColin LeMahieu break; 15988ed1aee9SColin LeMahieu case Hexagon::SS2_storewi0: 15998ed1aee9SColin LeMahieu case Hexagon::SS2_storewi1: 1600be8c453dSColin LeMahieu // Rs 7-4, u 3-0{4_2} 1601be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1602be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1603be8c453dSColin LeMahieu MI->addOperand(Op); 1604be8c453dSColin LeMahieu operand = (inst & 0xf) << 2; 16057cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1606be8c453dSColin LeMahieu break; 16078ed1aee9SColin LeMahieu case Hexagon::SS2_stored_sp: 1608be8c453dSColin LeMahieu // s 8-3{6_3}, Rtt 2-0 1609be8c453dSColin LeMahieu operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3); 16107cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1611be8c453dSColin LeMahieu operand = getDRegFromSubinstEncoding(inst & 0x7); 1612be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1613be8c453dSColin LeMahieu MI->addOperand(Op); 1614160f73e3SColin LeMahieu break; 16158ed1aee9SColin LeMahieu case Hexagon::SS2_storeh_io: 1616be8c453dSColin LeMahieu // Rs 7-4, u 10-8{3_1}, Rt 3-0 1617be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4); 1618be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1619be8c453dSColin LeMahieu MI->addOperand(Op); 1620be8c453dSColin LeMahieu operand = ((inst & 0x700) >> 8) << 1; 16217cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1622be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1623be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1624be8c453dSColin LeMahieu MI->addOperand(Op); 1625be8c453dSColin LeMahieu break; 16268ed1aee9SColin LeMahieu case Hexagon::SS2_storew_sp: 1627be8c453dSColin LeMahieu // u 8-4{5_2}, Rd 3-0 1628be8c453dSColin LeMahieu operand = ((inst & 0x1f0) >> 4) << 2; 16297cd08927SColin LeMahieu HexagonMCInstrInfo::addConstant(*MI, operand, getContext()); 1630be8c453dSColin LeMahieu operand = getRegFromSubinstEncoding(inst & 0xf); 1631be8c453dSColin LeMahieu Op = MCOperand::createReg(operand); 1632be8c453dSColin LeMahieu MI->addOperand(Op); 1633be8c453dSColin LeMahieu break; 1634be8c453dSColin LeMahieu default: 1635be8c453dSColin LeMahieu // don't crash with an invalid subinstruction 1636be8c453dSColin LeMahieu // llvm_unreachable("Invalid subinstruction in duplex instruction"); 1637be8c453dSColin LeMahieu break; 1638be8c453dSColin LeMahieu } 1639be8c453dSColin LeMahieu } 1640