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 
1068d967d9SColin LeMahieu #include "Hexagon.h"
1188ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonBaseInfo.h"
121174fea3SColin LeMahieu #include "MCTargetDesc/HexagonMCInstrInfo.h"
1388ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonMCTargetDesc.h"
1468d967d9SColin LeMahieu 
1588ebb9e2SColin LeMahieu #include "llvm/MC/MCContext.h"
1688ebb9e2SColin LeMahieu #include "llvm/MC/MCDisassembler.h"
1788ebb9e2SColin LeMahieu #include "llvm/MC/MCExpr.h"
1888ebb9e2SColin LeMahieu #include "llvm/MC/MCFixedLenDisassembler.h"
1988ebb9e2SColin LeMahieu #include "llvm/MC/MCInst.h"
2088ebb9e2SColin LeMahieu #include "llvm/MC/MCInstrDesc.h"
2188ebb9e2SColin LeMahieu #include "llvm/MC/MCSubtargetInfo.h"
2288ebb9e2SColin LeMahieu #include "llvm/Support/Debug.h"
23d9903888SChandler Carruth #include "llvm/Support/Endian.h"
2488ebb9e2SColin LeMahieu #include "llvm/Support/ErrorHandling.h"
2588ebb9e2SColin LeMahieu #include "llvm/Support/LEB128.h"
2688ebb9e2SColin LeMahieu #include "llvm/Support/TargetRegistry.h"
27d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h"
2888ebb9e2SColin LeMahieu #include <array>
29d9903888SChandler Carruth #include <vector>
3088ebb9e2SColin LeMahieu 
3188ebb9e2SColin LeMahieu using namespace llvm;
3268d967d9SColin LeMahieu using namespace Hexagon;
3388ebb9e2SColin LeMahieu 
3488ebb9e2SColin LeMahieu #define DEBUG_TYPE "hexagon-disassembler"
3588ebb9e2SColin LeMahieu 
36db085665SHans Wennborg // Pull DecodeStatus and its enum values into the global namespace.
37db085665SHans Wennborg typedef llvm::MCDisassembler::DecodeStatus DecodeStatus;
3888ebb9e2SColin LeMahieu 
3988ebb9e2SColin LeMahieu namespace {
4088ebb9e2SColin LeMahieu /// \brief Hexagon disassembler for all Hexagon platforms.
4188ebb9e2SColin LeMahieu class HexagonDisassembler : public MCDisassembler {
4288ebb9e2SColin LeMahieu public:
4368d967d9SColin LeMahieu   std::unique_ptr<MCInst *> CurrentBundle;
4488ebb9e2SColin LeMahieu   HexagonDisassembler(MCSubtargetInfo const &STI, MCContext &Ctx)
4568d967d9SColin LeMahieu       : MCDisassembler(STI, Ctx), CurrentBundle(new MCInst *) {}
4688ebb9e2SColin LeMahieu 
4768d967d9SColin LeMahieu   DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
4868d967d9SColin LeMahieu                                     ArrayRef<uint8_t> Bytes, uint64_t Address,
4968d967d9SColin LeMahieu                                     raw_ostream &VStream, raw_ostream &CStream,
5068d967d9SColin LeMahieu                                     bool &Complete) const;
514aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
527fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
534aa6bea7SRafael Espindola                               raw_ostream &VStream,
544aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
5588ebb9e2SColin LeMahieu };
56f00654e3SAlexander Kornienko }
5788ebb9e2SColin LeMahieu 
58ff370ed9SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
59be8c453dSColin LeMahieu                                                uint64_t Address,
60be8c453dSColin LeMahieu                                                const void *Decoder);
61*7c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
62*7c958713SColin LeMahieu                                                    uint64_t Address,
63*7c958713SColin LeMahieu                                                    const void *Decoder);
64*7c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
65*7c958713SColin LeMahieu                                                   uint64_t Address,
66*7c958713SColin LeMahieu                                                   const void *Decoder);
67*7c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
68*7c958713SColin LeMahieu                                                   uint64_t Address,
69*7c958713SColin LeMahieu                                                   const void *Decoder);
70*7c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
71*7c958713SColin LeMahieu                                                    uint64_t Address,
72*7c958713SColin LeMahieu                                                    const void *Decoder);
73f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
74be8c453dSColin LeMahieu                                                uint64_t Address,
75be8c453dSColin LeMahieu                                                const void *Decoder);
76404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
77be8c453dSColin LeMahieu                                                  uint64_t Address,
78be8c453dSColin LeMahieu                                                  void const *Decoder);
79be8c453dSColin LeMahieu 
80be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
81be8c453dSColin LeMahieu                                  raw_ostream &os);
82be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst);
83f3db884eSColin LeMahieu 
841e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
851e9d1d76SColin LeMahieu                                   const void *Decoder);
861e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
871e9d1d76SColin LeMahieu                                   const void *Decoder);
881e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
891e9d1d76SColin LeMahieu                                     const void *Decoder);
901e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
911e9d1d76SColin LeMahieu                                     const void *Decoder);
921e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
931e9d1d76SColin LeMahieu                                     const void *Decoder);
941e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
951e9d1d76SColin LeMahieu                                     const void *Decoder);
961e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
971e9d1d76SColin LeMahieu                                   const void *Decoder);
981e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
991e9d1d76SColin LeMahieu                                  const void *Decoder);
1001e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1011e9d1d76SColin LeMahieu                                    const void *Decoder);
1021e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1031e9d1d76SColin LeMahieu                                    const void *Decoder);
1041e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1051e9d1d76SColin LeMahieu                                    const void *Decoder);
1061e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1071e9d1d76SColin LeMahieu                                    const void *Decoder);
1081e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1091e9d1d76SColin LeMahieu                                    const void *Decoder);
110*7c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
111*7c958713SColin LeMahieu                                    const void *Decoder);
112*7c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
113*7c958713SColin LeMahieu                                    const void *Decoder);
1141e9d1d76SColin LeMahieu 
115efa74e02SColin LeMahieu static const uint16_t IntRegDecoderTable[] = {
116efa74e02SColin LeMahieu     Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
117efa74e02SColin LeMahieu     Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
118efa74e02SColin LeMahieu     Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
119efa74e02SColin LeMahieu     Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
120efa74e02SColin LeMahieu     Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
121efa74e02SColin LeMahieu     Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
122efa74e02SColin LeMahieu     Hexagon::R30, Hexagon::R31};
123efa74e02SColin LeMahieu 
124efa74e02SColin LeMahieu static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
125efa74e02SColin LeMahieu                                                Hexagon::P2, Hexagon::P3};
126efa74e02SColin LeMahieu 
127383c36e3SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
128383c36e3SColin LeMahieu                                         const uint16_t Table[], size_t Size) {
129383c36e3SColin LeMahieu   if (RegNo < Size) {
130e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Table[RegNo]));
131383c36e3SColin LeMahieu     return MCDisassembler::Success;
132be8c453dSColin LeMahieu   } else
133383c36e3SColin LeMahieu     return MCDisassembler::Fail;
134383c36e3SColin LeMahieu }
135383c36e3SColin LeMahieu 
136efa74e02SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
137efa74e02SColin LeMahieu                                                uint64_t /*Address*/,
138efa74e02SColin LeMahieu                                                void const *Decoder) {
139efa74e02SColin LeMahieu   if (RegNo > 31)
140efa74e02SColin LeMahieu     return MCDisassembler::Fail;
141efa74e02SColin LeMahieu 
142efa74e02SColin LeMahieu   unsigned Register = IntRegDecoderTable[RegNo];
143e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
144efa74e02SColin LeMahieu   return MCDisassembler::Success;
145efa74e02SColin LeMahieu }
146efa74e02SColin LeMahieu 
147f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
148be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
149be8c453dSColin LeMahieu                                                const void *Decoder) {
150f3db884eSColin LeMahieu   static const uint16_t CtrlRegDecoderTable[] = {
151f3db884eSColin LeMahieu       Hexagon::SA0,  Hexagon::LC0,        Hexagon::SA1,  Hexagon::LC1,
152f3db884eSColin LeMahieu       Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6,   Hexagon::C7,
153f3db884eSColin LeMahieu       Hexagon::USR,  Hexagon::PC,         Hexagon::UGP,  Hexagon::GP,
154be8c453dSColin LeMahieu       Hexagon::CS0,  Hexagon::CS1,        Hexagon::UPCL, Hexagon::UPCH};
155f3db884eSColin LeMahieu 
156f3db884eSColin LeMahieu   if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
157f3db884eSColin LeMahieu     return MCDisassembler::Fail;
158f3db884eSColin LeMahieu 
159f3db884eSColin LeMahieu   if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
160f3db884eSColin LeMahieu     return MCDisassembler::Fail;
161f3db884eSColin LeMahieu 
162f3db884eSColin LeMahieu   unsigned Register = CtrlRegDecoderTable[RegNo];
163e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
164f3db884eSColin LeMahieu   return MCDisassembler::Success;
165f3db884eSColin LeMahieu }
166f3db884eSColin LeMahieu 
167404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
168be8c453dSColin LeMahieu                                                  uint64_t /*Address*/,
169be8c453dSColin LeMahieu                                                  void const *Decoder) {
170404d5b24SColin LeMahieu   static const uint16_t CtrlReg64DecoderTable[] = {
171be8c453dSColin LeMahieu       Hexagon::C1_0,       Hexagon::NoRegister, Hexagon::C3_2,
172be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::NoRegister, Hexagon::NoRegister,
173be8c453dSColin LeMahieu       Hexagon::C7_6,       Hexagon::NoRegister, Hexagon::C9_8,
174be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::C11_10,     Hexagon::NoRegister,
175be8c453dSColin LeMahieu       Hexagon::CS,         Hexagon::NoRegister, Hexagon::UPC,
176be8c453dSColin LeMahieu       Hexagon::NoRegister};
177404d5b24SColin LeMahieu 
178404d5b24SColin LeMahieu   if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0]))
179404d5b24SColin LeMahieu     return MCDisassembler::Fail;
180404d5b24SColin LeMahieu 
181404d5b24SColin LeMahieu   if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
182404d5b24SColin LeMahieu     return MCDisassembler::Fail;
183404d5b24SColin LeMahieu 
184404d5b24SColin LeMahieu   unsigned Register = CtrlReg64DecoderTable[RegNo];
185e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
186404d5b24SColin LeMahieu   return MCDisassembler::Success;
187404d5b24SColin LeMahieu }
188404d5b24SColin LeMahieu 
189ff370ed9SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
190be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
191be8c453dSColin LeMahieu                                                const void *Decoder) {
192ff370ed9SColin LeMahieu   unsigned Register = 0;
193ff370ed9SColin LeMahieu   switch (RegNo) {
194ff370ed9SColin LeMahieu   case 0:
195ff370ed9SColin LeMahieu     Register = Hexagon::M0;
196ff370ed9SColin LeMahieu     break;
197ff370ed9SColin LeMahieu   case 1:
198ff370ed9SColin LeMahieu     Register = Hexagon::M1;
199ff370ed9SColin LeMahieu     break;
200ff370ed9SColin LeMahieu   default:
201ff370ed9SColin LeMahieu     return MCDisassembler::Fail;
202ff370ed9SColin LeMahieu   }
203e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
204ff370ed9SColin LeMahieu   return MCDisassembler::Success;
205ff370ed9SColin LeMahieu }
206ff370ed9SColin LeMahieu 
207383c36e3SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
208be8c453dSColin LeMahieu                                                   uint64_t /*Address*/,
209be8c453dSColin LeMahieu                                                   const void *Decoder) {
210383c36e3SColin LeMahieu   static const uint16_t DoubleRegDecoderTable[] = {
211383c36e3SColin LeMahieu       Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
212383c36e3SColin LeMahieu       Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
213383c36e3SColin LeMahieu       Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
214be8c453dSColin LeMahieu       Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
215383c36e3SColin LeMahieu 
216be8c453dSColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
217383c36e3SColin LeMahieu                               sizeof(DoubleRegDecoderTable)));
218383c36e3SColin LeMahieu }
219383c36e3SColin LeMahieu 
220efa74e02SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
221efa74e02SColin LeMahieu                                                 uint64_t /*Address*/,
222efa74e02SColin LeMahieu                                                 void const *Decoder) {
223efa74e02SColin LeMahieu   if (RegNo > 3)
224efa74e02SColin LeMahieu     return MCDisassembler::Fail;
225efa74e02SColin LeMahieu 
226efa74e02SColin LeMahieu   unsigned Register = PredRegDecoderTable[RegNo];
227e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
228efa74e02SColin LeMahieu   return MCDisassembler::Success;
229efa74e02SColin LeMahieu }
230efa74e02SColin LeMahieu 
23188ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc"
23288ebb9e2SColin LeMahieu 
23388ebb9e2SColin LeMahieu static MCDisassembler *createHexagonDisassembler(Target const &T,
23488ebb9e2SColin LeMahieu                                                  MCSubtargetInfo const &STI,
23588ebb9e2SColin LeMahieu                                                  MCContext &Ctx) {
23688ebb9e2SColin LeMahieu   return new HexagonDisassembler(STI, Ctx);
23788ebb9e2SColin LeMahieu }
23888ebb9e2SColin LeMahieu 
23988ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() {
24088ebb9e2SColin LeMahieu   TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
24188ebb9e2SColin LeMahieu                                          createHexagonDisassembler);
24288ebb9e2SColin LeMahieu }
24388ebb9e2SColin LeMahieu 
24488ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
2457fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
24688ebb9e2SColin LeMahieu                                                  uint64_t Address,
24788ebb9e2SColin LeMahieu                                                  raw_ostream &os,
24888ebb9e2SColin LeMahieu                                                  raw_ostream &cs) const {
24968d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
25068d967d9SColin LeMahieu   bool Complete = false;
25168d967d9SColin LeMahieu   Size = 0;
2524aa6bea7SRafael Espindola 
25368d967d9SColin LeMahieu   *CurrentBundle = &MI;
254f97999dcSCameron Esfahani   MI.clear();
25568d967d9SColin LeMahieu   MI.setOpcode(Hexagon::BUNDLE);
25668d967d9SColin LeMahieu   MI.addOperand(MCOperand::createImm(0));
257be8c453dSColin LeMahieu   while (Result == Success && Complete == false) {
25868d967d9SColin LeMahieu     if (Bytes.size() < HEXAGON_INSTR_SIZE)
25968d967d9SColin LeMahieu       return MCDisassembler::Fail;
26068d967d9SColin LeMahieu     MCInst *Inst = new (getContext()) MCInst;
26168d967d9SColin LeMahieu     Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
26268d967d9SColin LeMahieu     MI.addOperand(MCOperand::createInst(Inst));
26368d967d9SColin LeMahieu     Size += HEXAGON_INSTR_SIZE;
26468d967d9SColin LeMahieu     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
26568d967d9SColin LeMahieu   }
26668d967d9SColin LeMahieu   return Result;
26768d967d9SColin LeMahieu }
26868d967d9SColin LeMahieu 
26968d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction(
27068d967d9SColin LeMahieu     MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
27168d967d9SColin LeMahieu     raw_ostream &os, raw_ostream &cs, bool &Complete) const {
27268d967d9SColin LeMahieu   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
27368d967d9SColin LeMahieu 
27468d967d9SColin LeMahieu   uint32_t Instruction =
27588ebb9e2SColin LeMahieu       llvm::support::endian::read<uint32_t, llvm::support::little,
27688ebb9e2SColin LeMahieu                                   llvm::support::unaligned>(Bytes.data());
27788ebb9e2SColin LeMahieu 
27868d967d9SColin LeMahieu   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
27968d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
28068d967d9SColin LeMahieu       HexagonII::INST_PARSE_LOOP_END) {
28168d967d9SColin LeMahieu     if (BundleSize == 0)
28268d967d9SColin LeMahieu       HexagonMCInstrInfo::setInnerLoop(MCB);
28368d967d9SColin LeMahieu     else if (BundleSize == 1)
28468d967d9SColin LeMahieu       HexagonMCInstrInfo::setOuterLoop(MCB);
28568d967d9SColin LeMahieu     else
28668d967d9SColin LeMahieu       return DecodeStatus::Fail;
28768d967d9SColin LeMahieu   }
28868d967d9SColin LeMahieu 
28968d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
29068d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
291be8c453dSColin LeMahieu       HexagonII::INST_PARSE_DUPLEX) {
292be8c453dSColin LeMahieu     // Determine the instruction class of each instruction in the duplex.
293be8c453dSColin LeMahieu     unsigned duplexIClass, IClassLow, IClassHigh;
294be8c453dSColin LeMahieu 
295be8c453dSColin LeMahieu     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
296be8c453dSColin LeMahieu     switch (duplexIClass) {
297be8c453dSColin LeMahieu     default:
298be8c453dSColin LeMahieu       return MCDisassembler::Fail;
299be8c453dSColin LeMahieu     case 0:
300be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
301be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
302be8c453dSColin LeMahieu       break;
303be8c453dSColin LeMahieu     case 1:
304be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
305be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
306be8c453dSColin LeMahieu       break;
307be8c453dSColin LeMahieu     case 2:
308be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
309be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
310be8c453dSColin LeMahieu       break;
311be8c453dSColin LeMahieu     case 3:
312be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_A;
313be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
314be8c453dSColin LeMahieu       break;
315be8c453dSColin LeMahieu     case 4:
316be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
317be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
318be8c453dSColin LeMahieu       break;
319be8c453dSColin LeMahieu     case 5:
320be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
321be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
322be8c453dSColin LeMahieu       break;
323be8c453dSColin LeMahieu     case 6:
324be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
325be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
326be8c453dSColin LeMahieu       break;
327be8c453dSColin LeMahieu     case 7:
328be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
329be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
330be8c453dSColin LeMahieu       break;
331be8c453dSColin LeMahieu     case 8:
332be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
333be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
334be8c453dSColin LeMahieu       break;
335be8c453dSColin LeMahieu     case 9:
336be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
337be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
338be8c453dSColin LeMahieu       break;
339be8c453dSColin LeMahieu     case 10:
340be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
341be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
342be8c453dSColin LeMahieu       break;
343be8c453dSColin LeMahieu     case 11:
344be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
345be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
346be8c453dSColin LeMahieu       break;
347be8c453dSColin LeMahieu     case 12:
348be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
349be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
350be8c453dSColin LeMahieu       break;
351be8c453dSColin LeMahieu     case 13:
352be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
353be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
354be8c453dSColin LeMahieu       break;
355be8c453dSColin LeMahieu     case 14:
356be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
357be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S2;
358be8c453dSColin LeMahieu       break;
359be8c453dSColin LeMahieu     }
360be8c453dSColin LeMahieu 
361be8c453dSColin LeMahieu     // Set the MCInst to be a duplex instruction. Which one doesn't matter.
362be8c453dSColin LeMahieu     MI.setOpcode(Hexagon::DuplexIClass0);
363be8c453dSColin LeMahieu 
364be8c453dSColin LeMahieu     // Decode each instruction in the duplex.
365be8c453dSColin LeMahieu     // Create an MCInst for each instruction.
366be8c453dSColin LeMahieu     unsigned instLow = Instruction & 0x1fff;
367be8c453dSColin LeMahieu     unsigned instHigh = (Instruction >> 16) & 0x1fff;
368be8c453dSColin LeMahieu     unsigned opLow;
369be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
370be8c453dSColin LeMahieu         MCDisassembler::Success)
371be8c453dSColin LeMahieu       return MCDisassembler::Fail;
372be8c453dSColin LeMahieu     unsigned opHigh;
373be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
374be8c453dSColin LeMahieu         MCDisassembler::Success)
375be8c453dSColin LeMahieu       return MCDisassembler::Fail;
376be8c453dSColin LeMahieu     MCInst *MILow = new (getContext()) MCInst;
377be8c453dSColin LeMahieu     MILow->setOpcode(opLow);
378be8c453dSColin LeMahieu     MCInst *MIHigh = new (getContext()) MCInst;
379be8c453dSColin LeMahieu     MIHigh->setOpcode(opHigh);
380be8c453dSColin LeMahieu     AddSubinstOperands(MILow, opLow, instLow);
381be8c453dSColin LeMahieu     AddSubinstOperands(MIHigh, opHigh, instHigh);
382be8c453dSColin LeMahieu     // see ConvertToSubInst() in
383be8c453dSColin LeMahieu     // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
384be8c453dSColin LeMahieu 
385be8c453dSColin LeMahieu     // Add the duplex instruction MCInsts as operands to the passed in MCInst.
386be8c453dSColin LeMahieu     MCOperand OPLow = MCOperand::createInst(MILow);
387be8c453dSColin LeMahieu     MCOperand OPHigh = MCOperand::createInst(MIHigh);
388be8c453dSColin LeMahieu     MI.addOperand(OPLow);
389be8c453dSColin LeMahieu     MI.addOperand(OPHigh);
390be8c453dSColin LeMahieu     Complete = true;
391be8c453dSColin LeMahieu   } else {
392be8c453dSColin LeMahieu     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
39368d967d9SColin LeMahieu         HexagonII::INST_PARSE_PACKET_END)
39468d967d9SColin LeMahieu       Complete = true;
39568d967d9SColin LeMahieu     // Calling the auto-generated decoder function.
39668d967d9SColin LeMahieu     Result =
39768d967d9SColin LeMahieu         decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
398be8c453dSColin LeMahieu   }
39968d967d9SColin LeMahieu 
4005d6f03bdSColin LeMahieu   return Result;
40188ebb9e2SColin LeMahieu }
402*7c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
403*7c958713SColin LeMahieu                                                    uint64_t Address,
404*7c958713SColin LeMahieu                                                    const void *Decoder) {
405*7c958713SColin LeMahieu   return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
406*7c958713SColin LeMahieu }
407*7c958713SColin LeMahieu 
408*7c958713SColin LeMahieu 
409*7c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
410*7c958713SColin LeMahieu                                                   uint64_t /*Address*/,
411*7c958713SColin LeMahieu                                                   const void *Decoder) {
412*7c958713SColin LeMahieu   static const uint16_t VecRegDecoderTable[] = {
413*7c958713SColin LeMahieu       Hexagon::V0,  Hexagon::V1,  Hexagon::V2,  Hexagon::V3,  Hexagon::V4,
414*7c958713SColin LeMahieu       Hexagon::V5,  Hexagon::V6,  Hexagon::V7,  Hexagon::V8,  Hexagon::V9,
415*7c958713SColin LeMahieu       Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
416*7c958713SColin LeMahieu       Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
417*7c958713SColin LeMahieu       Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
418*7c958713SColin LeMahieu       Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
419*7c958713SColin LeMahieu       Hexagon::V30, Hexagon::V31};
420*7c958713SColin LeMahieu 
421*7c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, VecRegDecoderTable,
422*7c958713SColin LeMahieu                               sizeof(VecRegDecoderTable)));
423*7c958713SColin LeMahieu }
424*7c958713SColin LeMahieu 
425*7c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
426*7c958713SColin LeMahieu                                                   uint64_t /*Address*/,
427*7c958713SColin LeMahieu                                                   const void *Decoder) {
428*7c958713SColin LeMahieu   static const uint16_t VecDblRegDecoderTable[] = {
429*7c958713SColin LeMahieu       Hexagon::W0,  Hexagon::W1,  Hexagon::W2,  Hexagon::W3,
430*7c958713SColin LeMahieu       Hexagon::W4,  Hexagon::W5,  Hexagon::W6,  Hexagon::W7,
431*7c958713SColin LeMahieu       Hexagon::W8,  Hexagon::W9,  Hexagon::W10, Hexagon::W11,
432*7c958713SColin LeMahieu       Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
433*7c958713SColin LeMahieu 
434*7c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, VecDblRegDecoderTable,
435*7c958713SColin LeMahieu                               sizeof(VecDblRegDecoderTable)));
436*7c958713SColin LeMahieu }
437*7c958713SColin LeMahieu 
438*7c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
439*7c958713SColin LeMahieu                                                    uint64_t /*Address*/,
440*7c958713SColin LeMahieu                                                    const void *Decoder) {
441*7c958713SColin LeMahieu   static const uint16_t VecPredRegDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
442*7c958713SColin LeMahieu                                                     Hexagon::Q2, Hexagon::Q3};
443*7c958713SColin LeMahieu 
444*7c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, VecPredRegDecoderTable,
445*7c958713SColin LeMahieu                               sizeof(VecPredRegDecoderTable)));
446*7c958713SColin LeMahieu }
447be8c453dSColin LeMahieu 
4481e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
4491e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
4501e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<16>(tmp);
4511e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4521e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4531e9d1d76SColin LeMahieu }
4541e9d1d76SColin LeMahieu 
4551e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
4561e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
4571e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
4581e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4591e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4601e9d1d76SColin LeMahieu }
4611e9d1d76SColin LeMahieu 
4621e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
4631e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4641e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<11>(tmp);
4651e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4661e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4671e9d1d76SColin LeMahieu }
4681e9d1d76SColin LeMahieu 
4691e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
4701e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4711e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
4721e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4731e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4741e9d1d76SColin LeMahieu }
4751e9d1d76SColin LeMahieu 
4761e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
4771e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4781e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<13>(tmp);
4791e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4801e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4811e9d1d76SColin LeMahieu }
4821e9d1d76SColin LeMahieu 
4831e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
4841e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4851e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<14>(tmp);
4861e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4871e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4881e9d1d76SColin LeMahieu }
4891e9d1d76SColin LeMahieu 
4901e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
4911e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
4921e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<10>(tmp);
4931e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4941e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4951e9d1d76SColin LeMahieu }
4961e9d1d76SColin LeMahieu 
4971e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/,
4981e9d1d76SColin LeMahieu                                  const void *Decoder) {
4991e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<8>(tmp);
5001e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5011e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5021e9d1d76SColin LeMahieu }
5031e9d1d76SColin LeMahieu 
5041e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
5051e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
5061e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
5071e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5081e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5091e9d1d76SColin LeMahieu }
5101e9d1d76SColin LeMahieu 
5111e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
5121e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
5131e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<4>(tmp);
5141e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5151e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5161e9d1d76SColin LeMahieu }
5171e9d1d76SColin LeMahieu 
5181e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
5191e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
5201e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<5>(tmp);
5211e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5221e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5231e9d1d76SColin LeMahieu }
5241e9d1d76SColin LeMahieu 
5251e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
5261e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
5271e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
5281e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5291e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5301e9d1d76SColin LeMahieu }
5311e9d1d76SColin LeMahieu 
5321e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
5331e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
5341e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<7>(tmp);
5351e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
5361e9d1d76SColin LeMahieu   return MCDisassembler::Success;
5371e9d1d76SColin LeMahieu }
5381e9d1d76SColin LeMahieu 
539*7c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp,
540*7c958713SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
541*7c958713SColin LeMahieu   uint64_t imm = SignExtend64<10>(tmp);
542*7c958713SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
543*7c958713SColin LeMahieu   return MCDisassembler::Success;
544*7c958713SColin LeMahieu }
545*7c958713SColin LeMahieu 
546*7c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp,
547*7c958713SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
548*7c958713SColin LeMahieu   uint64_t imm = SignExtend64<9>(tmp);
549*7c958713SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
550*7c958713SColin LeMahieu   return MCDisassembler::Success;
551*7c958713SColin LeMahieu }
552*7c958713SColin LeMahieu 
553be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
554be8c453dSColin LeMahieu enum subInstBinaryValues {
555be8c453dSColin LeMahieu   V4_SA1_addi_BITS = 0x0000,
556be8c453dSColin LeMahieu   V4_SA1_addi_MASK = 0x1800,
557be8c453dSColin LeMahieu   V4_SA1_addrx_BITS = 0x1800,
558be8c453dSColin LeMahieu   V4_SA1_addrx_MASK = 0x1f00,
559be8c453dSColin LeMahieu   V4_SA1_addsp_BITS = 0x0c00,
560be8c453dSColin LeMahieu   V4_SA1_addsp_MASK = 0x1c00,
561be8c453dSColin LeMahieu   V4_SA1_and1_BITS = 0x1200,
562be8c453dSColin LeMahieu   V4_SA1_and1_MASK = 0x1f00,
563be8c453dSColin LeMahieu   V4_SA1_clrf_BITS = 0x1a70,
564be8c453dSColin LeMahieu   V4_SA1_clrf_MASK = 0x1e70,
565be8c453dSColin LeMahieu   V4_SA1_clrfnew_BITS = 0x1a50,
566be8c453dSColin LeMahieu   V4_SA1_clrfnew_MASK = 0x1e70,
567be8c453dSColin LeMahieu   V4_SA1_clrt_BITS = 0x1a60,
568be8c453dSColin LeMahieu   V4_SA1_clrt_MASK = 0x1e70,
569be8c453dSColin LeMahieu   V4_SA1_clrtnew_BITS = 0x1a40,
570be8c453dSColin LeMahieu   V4_SA1_clrtnew_MASK = 0x1e70,
571be8c453dSColin LeMahieu   V4_SA1_cmpeqi_BITS = 0x1900,
572be8c453dSColin LeMahieu   V4_SA1_cmpeqi_MASK = 0x1f00,
573be8c453dSColin LeMahieu   V4_SA1_combine0i_BITS = 0x1c00,
574be8c453dSColin LeMahieu   V4_SA1_combine0i_MASK = 0x1d18,
575be8c453dSColin LeMahieu   V4_SA1_combine1i_BITS = 0x1c08,
576be8c453dSColin LeMahieu   V4_SA1_combine1i_MASK = 0x1d18,
577be8c453dSColin LeMahieu   V4_SA1_combine2i_BITS = 0x1c10,
578be8c453dSColin LeMahieu   V4_SA1_combine2i_MASK = 0x1d18,
579be8c453dSColin LeMahieu   V4_SA1_combine3i_BITS = 0x1c18,
580be8c453dSColin LeMahieu   V4_SA1_combine3i_MASK = 0x1d18,
581be8c453dSColin LeMahieu   V4_SA1_combinerz_BITS = 0x1d08,
582be8c453dSColin LeMahieu   V4_SA1_combinerz_MASK = 0x1d08,
583be8c453dSColin LeMahieu   V4_SA1_combinezr_BITS = 0x1d00,
584be8c453dSColin LeMahieu   V4_SA1_combinezr_MASK = 0x1d08,
585be8c453dSColin LeMahieu   V4_SA1_dec_BITS = 0x1300,
586be8c453dSColin LeMahieu   V4_SA1_dec_MASK = 0x1f00,
587be8c453dSColin LeMahieu   V4_SA1_inc_BITS = 0x1100,
588be8c453dSColin LeMahieu   V4_SA1_inc_MASK = 0x1f00,
589be8c453dSColin LeMahieu   V4_SA1_seti_BITS = 0x0800,
590be8c453dSColin LeMahieu   V4_SA1_seti_MASK = 0x1c00,
591be8c453dSColin LeMahieu   V4_SA1_setin1_BITS = 0x1a00,
592be8c453dSColin LeMahieu   V4_SA1_setin1_MASK = 0x1e40,
593be8c453dSColin LeMahieu   V4_SA1_sxtb_BITS = 0x1500,
594be8c453dSColin LeMahieu   V4_SA1_sxtb_MASK = 0x1f00,
595be8c453dSColin LeMahieu   V4_SA1_sxth_BITS = 0x1400,
596be8c453dSColin LeMahieu   V4_SA1_sxth_MASK = 0x1f00,
597be8c453dSColin LeMahieu   V4_SA1_tfr_BITS = 0x1000,
598be8c453dSColin LeMahieu   V4_SA1_tfr_MASK = 0x1f00,
599be8c453dSColin LeMahieu   V4_SA1_zxtb_BITS = 0x1700,
600be8c453dSColin LeMahieu   V4_SA1_zxtb_MASK = 0x1f00,
601be8c453dSColin LeMahieu   V4_SA1_zxth_BITS = 0x1600,
602be8c453dSColin LeMahieu   V4_SA1_zxth_MASK = 0x1f00,
603be8c453dSColin LeMahieu   V4_SL1_loadri_io_BITS = 0x0000,
604be8c453dSColin LeMahieu   V4_SL1_loadri_io_MASK = 0x1000,
605be8c453dSColin LeMahieu   V4_SL1_loadrub_io_BITS = 0x1000,
606be8c453dSColin LeMahieu   V4_SL1_loadrub_io_MASK = 0x1000,
607be8c453dSColin LeMahieu   V4_SL2_deallocframe_BITS = 0x1f00,
608be8c453dSColin LeMahieu   V4_SL2_deallocframe_MASK = 0x1fc0,
609be8c453dSColin LeMahieu   V4_SL2_jumpr31_BITS = 0x1fc0,
610be8c453dSColin LeMahieu   V4_SL2_jumpr31_MASK = 0x1fc4,
611be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_BITS = 0x1fc5,
612be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_MASK = 0x1fc7,
613be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
614be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
615be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_BITS = 0x1fc4,
616be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_MASK = 0x1fc7,
617be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
618be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
619be8c453dSColin LeMahieu   V4_SL2_loadrb_io_BITS = 0x1000,
620be8c453dSColin LeMahieu   V4_SL2_loadrb_io_MASK = 0x1800,
621be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_BITS = 0x1e00,
622be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_MASK = 0x1f00,
623be8c453dSColin LeMahieu   V4_SL2_loadrh_io_BITS = 0x0000,
624be8c453dSColin LeMahieu   V4_SL2_loadrh_io_MASK = 0x1800,
625be8c453dSColin LeMahieu   V4_SL2_loadri_sp_BITS = 0x1c00,
626be8c453dSColin LeMahieu   V4_SL2_loadri_sp_MASK = 0x1e00,
627be8c453dSColin LeMahieu   V4_SL2_loadruh_io_BITS = 0x0800,
628be8c453dSColin LeMahieu   V4_SL2_loadruh_io_MASK = 0x1800,
629be8c453dSColin LeMahieu   V4_SL2_return_BITS = 0x1f40,
630be8c453dSColin LeMahieu   V4_SL2_return_MASK = 0x1fc4,
631be8c453dSColin LeMahieu   V4_SL2_return_f_BITS = 0x1f45,
632be8c453dSColin LeMahieu   V4_SL2_return_f_MASK = 0x1fc7,
633be8c453dSColin LeMahieu   V4_SL2_return_fnew_BITS = 0x1f47,
634be8c453dSColin LeMahieu   V4_SL2_return_fnew_MASK = 0x1fc7,
635be8c453dSColin LeMahieu   V4_SL2_return_t_BITS = 0x1f44,
636be8c453dSColin LeMahieu   V4_SL2_return_t_MASK = 0x1fc7,
637be8c453dSColin LeMahieu   V4_SL2_return_tnew_BITS = 0x1f46,
638be8c453dSColin LeMahieu   V4_SL2_return_tnew_MASK = 0x1fc7,
639be8c453dSColin LeMahieu   V4_SS1_storeb_io_BITS = 0x1000,
640be8c453dSColin LeMahieu   V4_SS1_storeb_io_MASK = 0x1000,
641be8c453dSColin LeMahieu   V4_SS1_storew_io_BITS = 0x0000,
642be8c453dSColin LeMahieu   V4_SS1_storew_io_MASK = 0x1000,
643be8c453dSColin LeMahieu   V4_SS2_allocframe_BITS = 0x1c00,
644be8c453dSColin LeMahieu   V4_SS2_allocframe_MASK = 0x1e00,
645be8c453dSColin LeMahieu   V4_SS2_storebi0_BITS = 0x1200,
646be8c453dSColin LeMahieu   V4_SS2_storebi0_MASK = 0x1f00,
647be8c453dSColin LeMahieu   V4_SS2_storebi1_BITS = 0x1300,
648be8c453dSColin LeMahieu   V4_SS2_storebi1_MASK = 0x1f00,
649be8c453dSColin LeMahieu   V4_SS2_stored_sp_BITS = 0x0a00,
650be8c453dSColin LeMahieu   V4_SS2_stored_sp_MASK = 0x1e00,
651be8c453dSColin LeMahieu   V4_SS2_storeh_io_BITS = 0x0000,
652be8c453dSColin LeMahieu   V4_SS2_storeh_io_MASK = 0x1800,
653be8c453dSColin LeMahieu   V4_SS2_storew_sp_BITS = 0x0800,
654be8c453dSColin LeMahieu   V4_SS2_storew_sp_MASK = 0x1e00,
655be8c453dSColin LeMahieu   V4_SS2_storewi0_BITS = 0x1000,
656be8c453dSColin LeMahieu   V4_SS2_storewi0_MASK = 0x1f00,
657be8c453dSColin LeMahieu   V4_SS2_storewi1_BITS = 0x1100,
658be8c453dSColin LeMahieu   V4_SS2_storewi1_MASK = 0x1f00
659be8c453dSColin LeMahieu };
660be8c453dSColin LeMahieu 
661be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
662be8c453dSColin LeMahieu                                  raw_ostream &os) {
663be8c453dSColin LeMahieu   switch (IClass) {
664be8c453dSColin LeMahieu   case HexagonII::HSIG_L1:
665be8c453dSColin LeMahieu     if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
666be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadri_io;
667be8c453dSColin LeMahieu     else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
668be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadrub_io;
669be8c453dSColin LeMahieu     else {
670be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
671be8c453dSColin LeMahieu       return MCDisassembler::Fail;
672be8c453dSColin LeMahieu     }
673be8c453dSColin LeMahieu     break;
674be8c453dSColin LeMahieu   case HexagonII::HSIG_L2:
675be8c453dSColin LeMahieu     if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
676be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_deallocframe;
677be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
678be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31;
679be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
680be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_f;
681be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
682be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_fnew;
683be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
684be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_t;
685be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
686be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_tnew;
687be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
688be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrb_io;
689be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
690be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrd_sp;
691be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
692be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrh_io;
693be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
694be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadri_sp;
695be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
696be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadruh_io;
697be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
698be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return;
699be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
700be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_f;
701be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
702be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_fnew;
703be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
704be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_t;
705be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
706be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_tnew;
707be8c453dSColin LeMahieu     else {
708be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
709be8c453dSColin LeMahieu       return MCDisassembler::Fail;
710be8c453dSColin LeMahieu     }
711be8c453dSColin LeMahieu     break;
712be8c453dSColin LeMahieu   case HexagonII::HSIG_A:
713be8c453dSColin LeMahieu     if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
714be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addi;
715be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
716be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addrx;
717be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
718be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addsp;
719be8c453dSColin LeMahieu     else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
720be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_and1;
721be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
722be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrf;
723be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
724be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrfnew;
725be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
726be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrt;
727be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
728be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrtnew;
729be8c453dSColin LeMahieu     else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
730be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_cmpeqi;
731be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
732be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine0i;
733be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
734be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine1i;
735be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
736be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine2i;
737be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
738be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine3i;
739be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
740be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinerz;
741be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
742be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinezr;
743be8c453dSColin LeMahieu     else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
744be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_dec;
745be8c453dSColin LeMahieu     else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
746be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_inc;
747be8c453dSColin LeMahieu     else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
748be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_seti;
749be8c453dSColin LeMahieu     else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
750be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_setin1;
751be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
752be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxtb;
753be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
754be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxth;
755be8c453dSColin LeMahieu     else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
756be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_tfr;
757be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
758be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxtb;
759be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
760be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxth;
761be8c453dSColin LeMahieu     else {
762be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
763be8c453dSColin LeMahieu       return MCDisassembler::Fail;
764be8c453dSColin LeMahieu     }
765be8c453dSColin LeMahieu     break;
766be8c453dSColin LeMahieu   case HexagonII::HSIG_S1:
767be8c453dSColin LeMahieu     if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
768be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storeb_io;
769be8c453dSColin LeMahieu     else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
770be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storew_io;
771be8c453dSColin LeMahieu     else {
772be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
773be8c453dSColin LeMahieu       return MCDisassembler::Fail;
774be8c453dSColin LeMahieu     }
775be8c453dSColin LeMahieu     break;
776be8c453dSColin LeMahieu   case HexagonII::HSIG_S2:
777be8c453dSColin LeMahieu     if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
778be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_allocframe;
779be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
780be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi0;
781be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
782be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi1;
783be8c453dSColin LeMahieu     else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
784be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_stored_sp;
785be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
786be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storeh_io;
787be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
788be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storew_sp;
789be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
790be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi0;
791be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
792be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi1;
793be8c453dSColin LeMahieu     else {
794be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
795be8c453dSColin LeMahieu       return MCDisassembler::Fail;
796be8c453dSColin LeMahieu     }
797be8c453dSColin LeMahieu     break;
798be8c453dSColin LeMahieu   default:
799be8c453dSColin LeMahieu     os << "<unknown>";
800be8c453dSColin LeMahieu     return MCDisassembler::Fail;
801be8c453dSColin LeMahieu   }
802be8c453dSColin LeMahieu   return MCDisassembler::Success;
803be8c453dSColin LeMahieu }
804be8c453dSColin LeMahieu 
805be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
806be8c453dSColin LeMahieu   if (encoded_reg < 8)
807be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg;
808be8c453dSColin LeMahieu   else if (encoded_reg < 16)
809be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg + 8;
810be8c453dSColin LeMahieu   return Hexagon::NoRegister;
811be8c453dSColin LeMahieu }
812be8c453dSColin LeMahieu 
813be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
814be8c453dSColin LeMahieu   if (encoded_dreg < 4)
815be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg;
816be8c453dSColin LeMahieu   else if (encoded_dreg < 8)
817be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg + 4;
818be8c453dSColin LeMahieu   return Hexagon::NoRegister;
819be8c453dSColin LeMahieu }
820be8c453dSColin LeMahieu 
821be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) {
822be8c453dSColin LeMahieu   int64_t operand;
823be8c453dSColin LeMahieu   MCOperand Op;
824be8c453dSColin LeMahieu   switch (opcode) {
825be8c453dSColin LeMahieu   case Hexagon::V4_SL2_deallocframe:
826be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31:
827be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_f:
828be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_fnew:
829be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_t:
830be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_tnew:
831be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return:
832be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_f:
833be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_fnew:
834be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_t:
835be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_tnew:
836be8c453dSColin LeMahieu     // no operands for these instructions
837be8c453dSColin LeMahieu     break;
838be8c453dSColin LeMahieu   case Hexagon::V4_SS2_allocframe:
839be8c453dSColin LeMahieu     // u 8-4{5_3}
840be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 3;
841be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
842be8c453dSColin LeMahieu     MI->addOperand(Op);
843be8c453dSColin LeMahieu     break;
844be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadri_io:
845be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8{4_2}
846be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
847be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
848be8c453dSColin LeMahieu     MI->addOperand(Op);
849be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
850be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
851be8c453dSColin LeMahieu     MI->addOperand(Op);
852be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 6;
853be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
854be8c453dSColin LeMahieu     MI->addOperand(Op);
855be8c453dSColin LeMahieu     break;
856be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadrub_io:
857be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8
858be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
859be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
860be8c453dSColin LeMahieu     MI->addOperand(Op);
861be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
862be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
863be8c453dSColin LeMahieu     MI->addOperand(Op);
864be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
865be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
866be8c453dSColin LeMahieu     MI->addOperand(Op);
867be8c453dSColin LeMahieu     break;
868be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrb_io:
869be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8
870be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
871be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
872be8c453dSColin LeMahieu     MI->addOperand(Op);
873be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
874be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
875be8c453dSColin LeMahieu     MI->addOperand(Op);
876be8c453dSColin LeMahieu     operand = (inst & 0x700) >> 8;
877be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
878be8c453dSColin LeMahieu     MI->addOperand(Op);
879be8c453dSColin LeMahieu     break;
880be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrh_io:
881be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadruh_io:
882be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8{3_1}
883be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
884be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
885be8c453dSColin LeMahieu     MI->addOperand(Op);
886be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
887be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
888be8c453dSColin LeMahieu     MI->addOperand(Op);
889be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
890be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
891be8c453dSColin LeMahieu     MI->addOperand(Op);
892be8c453dSColin LeMahieu     break;
893be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrd_sp:
894be8c453dSColin LeMahieu     // Rdd 2-0, u 7-3{5_3}
895be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
896be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
897be8c453dSColin LeMahieu     MI->addOperand(Op);
898be8c453dSColin LeMahieu     operand = ((inst & 0x0f8) >> 3) << 3;
899be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
900be8c453dSColin LeMahieu     MI->addOperand(Op);
901be8c453dSColin LeMahieu     break;
902be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadri_sp:
903be8c453dSColin LeMahieu     // Rd 3-0, u 8-4{5_2}
904be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
905be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
906be8c453dSColin LeMahieu     MI->addOperand(Op);
907be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
908be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
909be8c453dSColin LeMahieu     MI->addOperand(Op);
910be8c453dSColin LeMahieu     break;
911be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addi:
912be8c453dSColin LeMahieu     // Rx 3-0 (x2), s7 10-4
913be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
914be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
915be8c453dSColin LeMahieu     MI->addOperand(Op);
916be8c453dSColin LeMahieu     MI->addOperand(Op);
917be8c453dSColin LeMahieu     operand = SignExtend64<7>((inst & 0x7f0) >> 4);
918be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
919be8c453dSColin LeMahieu     MI->addOperand(Op);
920be8c453dSColin LeMahieu     break;
921be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addrx:
922be8c453dSColin LeMahieu     // Rx 3-0 (x2), Rs 7-4
923be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
924be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
925be8c453dSColin LeMahieu     MI->addOperand(Op);
926be8c453dSColin LeMahieu     MI->addOperand(Op);
927be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
928be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
929be8c453dSColin LeMahieu     MI->addOperand(Op);
930be8c453dSColin LeMahieu   case Hexagon::V4_SA1_and1:
931be8c453dSColin LeMahieu   case Hexagon::V4_SA1_dec:
932be8c453dSColin LeMahieu   case Hexagon::V4_SA1_inc:
933be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxtb:
934be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxth:
935be8c453dSColin LeMahieu   case Hexagon::V4_SA1_tfr:
936be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxtb:
937be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxth:
938be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4
939be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
940be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
941be8c453dSColin LeMahieu     MI->addOperand(Op);
942be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
943be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
944be8c453dSColin LeMahieu     MI->addOperand(Op);
945be8c453dSColin LeMahieu     break;
946be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addsp:
947be8c453dSColin LeMahieu     // Rd 3-0, u 9-4{6_2}
948be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
949be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
950be8c453dSColin LeMahieu     MI->addOperand(Op);
951be8c453dSColin LeMahieu     operand = ((inst & 0x3f0) >> 4) << 2;
952be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
953be8c453dSColin LeMahieu     MI->addOperand(Op);
954be8c453dSColin LeMahieu     break;
955be8c453dSColin LeMahieu   case Hexagon::V4_SA1_seti:
956be8c453dSColin LeMahieu     // Rd 3-0, u 9-4
957be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
958be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
959be8c453dSColin LeMahieu     MI->addOperand(Op);
960be8c453dSColin LeMahieu     operand = (inst & 0x3f0) >> 4;
961be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
962be8c453dSColin LeMahieu     MI->addOperand(Op);
963be8c453dSColin LeMahieu     break;
964be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrf:
965be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrfnew:
966be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrt:
967be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrtnew:
968be8c453dSColin LeMahieu   case Hexagon::V4_SA1_setin1:
969be8c453dSColin LeMahieu     // Rd 3-0
970be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
971be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
972be8c453dSColin LeMahieu     MI->addOperand(Op);
973be8c453dSColin LeMahieu     break;
974be8c453dSColin LeMahieu   case Hexagon::V4_SA1_cmpeqi:
975be8c453dSColin LeMahieu     // Rs 7-4, u 1-0
976be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
977be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
978be8c453dSColin LeMahieu     MI->addOperand(Op);
979be8c453dSColin LeMahieu     operand = inst & 0x3;
980be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
981be8c453dSColin LeMahieu     MI->addOperand(Op);
982be8c453dSColin LeMahieu     break;
983be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine0i:
984be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine1i:
985be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine2i:
986be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine3i:
987be8c453dSColin LeMahieu     // Rdd 2-0, u 6-5
988be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
989be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
990be8c453dSColin LeMahieu     MI->addOperand(Op);
991be8c453dSColin LeMahieu     operand = (inst & 0x060) >> 5;
992be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
993be8c453dSColin LeMahieu     MI->addOperand(Op);
994be8c453dSColin LeMahieu     break;
995be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinerz:
996be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinezr:
997be8c453dSColin LeMahieu     // Rdd 2-0, Rs 7-4
998be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
999be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1000be8c453dSColin LeMahieu     MI->addOperand(Op);
1001be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1002be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1003be8c453dSColin LeMahieu     MI->addOperand(Op);
1004be8c453dSColin LeMahieu     break;
1005be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storeb_io:
1006be8c453dSColin LeMahieu     // Rs 7-4, u 11-8, Rt 3-0
1007be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1008be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1009be8c453dSColin LeMahieu     MI->addOperand(Op);
1010be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
1011be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1012be8c453dSColin LeMahieu     MI->addOperand(Op);
1013be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1014be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1015be8c453dSColin LeMahieu     MI->addOperand(Op);
1016be8c453dSColin LeMahieu     break;
1017be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storew_io:
1018be8c453dSColin LeMahieu     // Rs 7-4, u 11-8{4_2}, Rt 3-0
1019be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1020be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1021be8c453dSColin LeMahieu     MI->addOperand(Op);
1022be8c453dSColin LeMahieu     operand = ((inst & 0xf00) >> 8) << 2;
1023be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1024be8c453dSColin LeMahieu     MI->addOperand(Op);
1025be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1026be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1027be8c453dSColin LeMahieu     MI->addOperand(Op);
1028be8c453dSColin LeMahieu     break;
1029be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi0:
1030be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi1:
1031be8c453dSColin LeMahieu     // Rs 7-4, u 3-0
1032be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1033be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1034be8c453dSColin LeMahieu     MI->addOperand(Op);
1035be8c453dSColin LeMahieu     operand = inst & 0xf;
1036be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1037be8c453dSColin LeMahieu     MI->addOperand(Op);
1038be8c453dSColin LeMahieu     break;
1039be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi0:
1040be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi1:
1041be8c453dSColin LeMahieu     // Rs 7-4, u 3-0{4_2}
1042be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1043be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1044be8c453dSColin LeMahieu     MI->addOperand(Op);
1045be8c453dSColin LeMahieu     operand = (inst & 0xf) << 2;
1046be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1047be8c453dSColin LeMahieu     MI->addOperand(Op);
1048be8c453dSColin LeMahieu     break;
1049be8c453dSColin LeMahieu   case Hexagon::V4_SS2_stored_sp:
1050be8c453dSColin LeMahieu     // s 8-3{6_3}, Rtt 2-0
1051be8c453dSColin LeMahieu     operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
1052be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1053be8c453dSColin LeMahieu     MI->addOperand(Op);
1054be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
1055be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1056be8c453dSColin LeMahieu     MI->addOperand(Op);
1057be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storeh_io:
1058be8c453dSColin LeMahieu     // Rs 7-4, u 10-8{3_1}, Rt 3-0
1059be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1060be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1061be8c453dSColin LeMahieu     MI->addOperand(Op);
1062be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
1063be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1064be8c453dSColin LeMahieu     MI->addOperand(Op);
1065be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1066be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1067be8c453dSColin LeMahieu     MI->addOperand(Op);
1068be8c453dSColin LeMahieu     break;
1069be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storew_sp:
1070be8c453dSColin LeMahieu     // u 8-4{5_2}, Rd 3-0
1071be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
1072be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
1073be8c453dSColin LeMahieu     MI->addOperand(Op);
1074be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1075be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1076be8c453dSColin LeMahieu     MI->addOperand(Op);
1077be8c453dSColin LeMahieu     break;
1078be8c453dSColin LeMahieu   default:
1079be8c453dSColin LeMahieu     // don't crash with an invalid subinstruction
1080be8c453dSColin LeMahieu     // llvm_unreachable("Invalid subinstruction in duplex instruction");
1081be8c453dSColin LeMahieu     break;
1082be8c453dSColin LeMahieu   }
1083be8c453dSColin LeMahieu }
1084