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 };
5688ebb9e2SColin LeMahieu }
5788ebb9e2SColin LeMahieu 
58ff370ed9SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
59*be8c453dSColin LeMahieu                                                uint64_t Address,
60*be8c453dSColin LeMahieu                                                const void *Decoder);
61f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
62*be8c453dSColin LeMahieu                                                uint64_t Address,
63*be8c453dSColin LeMahieu                                                const void *Decoder);
64404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
65*be8c453dSColin LeMahieu                                                  uint64_t Address,
66*be8c453dSColin LeMahieu                                                  void const *Decoder);
67*be8c453dSColin LeMahieu 
68*be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
69*be8c453dSColin LeMahieu                                  raw_ostream &os);
70*be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst);
71f3db884eSColin LeMahieu 
72efa74e02SColin LeMahieu static const uint16_t IntRegDecoderTable[] = {
73efa74e02SColin LeMahieu     Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
74efa74e02SColin LeMahieu     Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
75efa74e02SColin LeMahieu     Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
76efa74e02SColin LeMahieu     Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
77efa74e02SColin LeMahieu     Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
78efa74e02SColin LeMahieu     Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
79efa74e02SColin LeMahieu     Hexagon::R30, Hexagon::R31};
80efa74e02SColin LeMahieu 
81efa74e02SColin LeMahieu static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
82efa74e02SColin LeMahieu                                                Hexagon::P2, Hexagon::P3};
83efa74e02SColin LeMahieu 
84383c36e3SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
85383c36e3SColin LeMahieu                                         const uint16_t Table[], size_t Size) {
86383c36e3SColin LeMahieu   if (RegNo < Size) {
87e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Table[RegNo]));
88383c36e3SColin LeMahieu     return MCDisassembler::Success;
89*be8c453dSColin LeMahieu   } else
90383c36e3SColin LeMahieu     return MCDisassembler::Fail;
91383c36e3SColin LeMahieu }
92383c36e3SColin LeMahieu 
93efa74e02SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
94efa74e02SColin LeMahieu                                                uint64_t /*Address*/,
95efa74e02SColin LeMahieu                                                void const *Decoder) {
96efa74e02SColin LeMahieu   if (RegNo > 31)
97efa74e02SColin LeMahieu     return MCDisassembler::Fail;
98efa74e02SColin LeMahieu 
99efa74e02SColin LeMahieu   unsigned Register = IntRegDecoderTable[RegNo];
100e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
101efa74e02SColin LeMahieu   return MCDisassembler::Success;
102efa74e02SColin LeMahieu }
103efa74e02SColin LeMahieu 
104f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
105*be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
106*be8c453dSColin LeMahieu                                                const void *Decoder) {
107f3db884eSColin LeMahieu   static const uint16_t CtrlRegDecoderTable[] = {
108f3db884eSColin LeMahieu       Hexagon::SA0,  Hexagon::LC0,        Hexagon::SA1,  Hexagon::LC1,
109f3db884eSColin LeMahieu       Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6,   Hexagon::C7,
110f3db884eSColin LeMahieu       Hexagon::USR,  Hexagon::PC,         Hexagon::UGP,  Hexagon::GP,
111*be8c453dSColin LeMahieu       Hexagon::CS0,  Hexagon::CS1,        Hexagon::UPCL, Hexagon::UPCH};
112f3db884eSColin LeMahieu 
113f3db884eSColin LeMahieu   if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
114f3db884eSColin LeMahieu     return MCDisassembler::Fail;
115f3db884eSColin LeMahieu 
116f3db884eSColin LeMahieu   if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
117f3db884eSColin LeMahieu     return MCDisassembler::Fail;
118f3db884eSColin LeMahieu 
119f3db884eSColin LeMahieu   unsigned Register = CtrlRegDecoderTable[RegNo];
120e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
121f3db884eSColin LeMahieu   return MCDisassembler::Success;
122f3db884eSColin LeMahieu }
123f3db884eSColin LeMahieu 
124404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
125*be8c453dSColin LeMahieu                                                  uint64_t /*Address*/,
126*be8c453dSColin LeMahieu                                                  void const *Decoder) {
127404d5b24SColin LeMahieu   static const uint16_t CtrlReg64DecoderTable[] = {
128*be8c453dSColin LeMahieu       Hexagon::C1_0,       Hexagon::NoRegister, Hexagon::C3_2,
129*be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::NoRegister, Hexagon::NoRegister,
130*be8c453dSColin LeMahieu       Hexagon::C7_6,       Hexagon::NoRegister, Hexagon::C9_8,
131*be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::C11_10,     Hexagon::NoRegister,
132*be8c453dSColin LeMahieu       Hexagon::CS,         Hexagon::NoRegister, Hexagon::UPC,
133*be8c453dSColin LeMahieu       Hexagon::NoRegister};
134404d5b24SColin LeMahieu 
135404d5b24SColin LeMahieu   if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0]))
136404d5b24SColin LeMahieu     return MCDisassembler::Fail;
137404d5b24SColin LeMahieu 
138404d5b24SColin LeMahieu   if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
139404d5b24SColin LeMahieu     return MCDisassembler::Fail;
140404d5b24SColin LeMahieu 
141404d5b24SColin LeMahieu   unsigned Register = CtrlReg64DecoderTable[RegNo];
142e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
143404d5b24SColin LeMahieu   return MCDisassembler::Success;
144404d5b24SColin LeMahieu }
145404d5b24SColin LeMahieu 
146ff370ed9SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
147*be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
148*be8c453dSColin LeMahieu                                                const void *Decoder) {
149ff370ed9SColin LeMahieu   unsigned Register = 0;
150ff370ed9SColin LeMahieu   switch (RegNo) {
151ff370ed9SColin LeMahieu   case 0:
152ff370ed9SColin LeMahieu     Register = Hexagon::M0;
153ff370ed9SColin LeMahieu     break;
154ff370ed9SColin LeMahieu   case 1:
155ff370ed9SColin LeMahieu     Register = Hexagon::M1;
156ff370ed9SColin LeMahieu     break;
157ff370ed9SColin LeMahieu   default:
158ff370ed9SColin LeMahieu     return MCDisassembler::Fail;
159ff370ed9SColin LeMahieu   }
160e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
161ff370ed9SColin LeMahieu   return MCDisassembler::Success;
162ff370ed9SColin LeMahieu }
163ff370ed9SColin LeMahieu 
164383c36e3SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
165*be8c453dSColin LeMahieu                                                   uint64_t /*Address*/,
166*be8c453dSColin LeMahieu                                                   const void *Decoder) {
167383c36e3SColin LeMahieu   static const uint16_t DoubleRegDecoderTable[] = {
168383c36e3SColin LeMahieu       Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
169383c36e3SColin LeMahieu       Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
170383c36e3SColin LeMahieu       Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
171*be8c453dSColin LeMahieu       Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
172383c36e3SColin LeMahieu 
173*be8c453dSColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
174383c36e3SColin LeMahieu                               sizeof(DoubleRegDecoderTable)));
175383c36e3SColin LeMahieu }
176383c36e3SColin LeMahieu 
177efa74e02SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
178efa74e02SColin LeMahieu                                                 uint64_t /*Address*/,
179efa74e02SColin LeMahieu                                                 void const *Decoder) {
180efa74e02SColin LeMahieu   if (RegNo > 3)
181efa74e02SColin LeMahieu     return MCDisassembler::Fail;
182efa74e02SColin LeMahieu 
183efa74e02SColin LeMahieu   unsigned Register = PredRegDecoderTable[RegNo];
184e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
185efa74e02SColin LeMahieu   return MCDisassembler::Success;
186efa74e02SColin LeMahieu }
187efa74e02SColin LeMahieu 
18888ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc"
18988ebb9e2SColin LeMahieu 
19088ebb9e2SColin LeMahieu static MCDisassembler *createHexagonDisassembler(Target const &T,
19188ebb9e2SColin LeMahieu                                                  MCSubtargetInfo const &STI,
19288ebb9e2SColin LeMahieu                                                  MCContext &Ctx) {
19388ebb9e2SColin LeMahieu   return new HexagonDisassembler(STI, Ctx);
19488ebb9e2SColin LeMahieu }
19588ebb9e2SColin LeMahieu 
19688ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() {
19788ebb9e2SColin LeMahieu   TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
19888ebb9e2SColin LeMahieu                                          createHexagonDisassembler);
19988ebb9e2SColin LeMahieu }
20088ebb9e2SColin LeMahieu 
20188ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
2027fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
20388ebb9e2SColin LeMahieu                                                  uint64_t Address,
20488ebb9e2SColin LeMahieu                                                  raw_ostream &os,
20588ebb9e2SColin LeMahieu                                                  raw_ostream &cs) const {
20668d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
20768d967d9SColin LeMahieu   bool Complete = false;
20868d967d9SColin LeMahieu   Size = 0;
2094aa6bea7SRafael Espindola 
21068d967d9SColin LeMahieu   *CurrentBundle = &MI;
21168d967d9SColin LeMahieu   MI.setOpcode(Hexagon::BUNDLE);
21268d967d9SColin LeMahieu   MI.addOperand(MCOperand::createImm(0));
213*be8c453dSColin LeMahieu   while (Result == Success && Complete == false) {
21468d967d9SColin LeMahieu     if (Bytes.size() < HEXAGON_INSTR_SIZE)
21568d967d9SColin LeMahieu       return MCDisassembler::Fail;
21668d967d9SColin LeMahieu     MCInst *Inst = new (getContext()) MCInst;
21768d967d9SColin LeMahieu     Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
21868d967d9SColin LeMahieu     MI.addOperand(MCOperand::createInst(Inst));
21968d967d9SColin LeMahieu     Size += HEXAGON_INSTR_SIZE;
22068d967d9SColin LeMahieu     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
22168d967d9SColin LeMahieu   }
22268d967d9SColin LeMahieu   return Result;
22368d967d9SColin LeMahieu }
22468d967d9SColin LeMahieu 
22568d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction(
22668d967d9SColin LeMahieu     MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
22768d967d9SColin LeMahieu     raw_ostream &os, raw_ostream &cs, bool &Complete) const {
22868d967d9SColin LeMahieu   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
22968d967d9SColin LeMahieu 
23068d967d9SColin LeMahieu   uint32_t Instruction =
23188ebb9e2SColin LeMahieu       llvm::support::endian::read<uint32_t, llvm::support::little,
23288ebb9e2SColin LeMahieu                                   llvm::support::unaligned>(Bytes.data());
23388ebb9e2SColin LeMahieu 
23468d967d9SColin LeMahieu   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
23568d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
23668d967d9SColin LeMahieu       HexagonII::INST_PARSE_LOOP_END) {
23768d967d9SColin LeMahieu     if (BundleSize == 0)
23868d967d9SColin LeMahieu       HexagonMCInstrInfo::setInnerLoop(MCB);
23968d967d9SColin LeMahieu     else if (BundleSize == 1)
24068d967d9SColin LeMahieu       HexagonMCInstrInfo::setOuterLoop(MCB);
24168d967d9SColin LeMahieu     else
24268d967d9SColin LeMahieu       return DecodeStatus::Fail;
24368d967d9SColin LeMahieu   }
24468d967d9SColin LeMahieu 
24568d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
24668d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
247*be8c453dSColin LeMahieu       HexagonII::INST_PARSE_DUPLEX) {
248*be8c453dSColin LeMahieu     // Determine the instruction class of each instruction in the duplex.
249*be8c453dSColin LeMahieu     unsigned duplexIClass, IClassLow, IClassHigh;
250*be8c453dSColin LeMahieu 
251*be8c453dSColin LeMahieu     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
252*be8c453dSColin LeMahieu     switch (duplexIClass) {
253*be8c453dSColin LeMahieu     default:
254*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
255*be8c453dSColin LeMahieu     case 0:
256*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
257*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
258*be8c453dSColin LeMahieu       break;
259*be8c453dSColin LeMahieu     case 1:
260*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
261*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
262*be8c453dSColin LeMahieu       break;
263*be8c453dSColin LeMahieu     case 2:
264*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
265*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
266*be8c453dSColin LeMahieu       break;
267*be8c453dSColin LeMahieu     case 3:
268*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_A;
269*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
270*be8c453dSColin LeMahieu       break;
271*be8c453dSColin LeMahieu     case 4:
272*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
273*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
274*be8c453dSColin LeMahieu       break;
275*be8c453dSColin LeMahieu     case 5:
276*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
277*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
278*be8c453dSColin LeMahieu       break;
279*be8c453dSColin LeMahieu     case 6:
280*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
281*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
282*be8c453dSColin LeMahieu       break;
283*be8c453dSColin LeMahieu     case 7:
284*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
285*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
286*be8c453dSColin LeMahieu       break;
287*be8c453dSColin LeMahieu     case 8:
288*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
289*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
290*be8c453dSColin LeMahieu       break;
291*be8c453dSColin LeMahieu     case 9:
292*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
293*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
294*be8c453dSColin LeMahieu       break;
295*be8c453dSColin LeMahieu     case 10:
296*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
297*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
298*be8c453dSColin LeMahieu       break;
299*be8c453dSColin LeMahieu     case 11:
300*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
301*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
302*be8c453dSColin LeMahieu       break;
303*be8c453dSColin LeMahieu     case 12:
304*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
305*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
306*be8c453dSColin LeMahieu       break;
307*be8c453dSColin LeMahieu     case 13:
308*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
309*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
310*be8c453dSColin LeMahieu       break;
311*be8c453dSColin LeMahieu     case 14:
312*be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
313*be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S2;
314*be8c453dSColin LeMahieu       break;
315*be8c453dSColin LeMahieu     }
316*be8c453dSColin LeMahieu 
317*be8c453dSColin LeMahieu     // Set the MCInst to be a duplex instruction. Which one doesn't matter.
318*be8c453dSColin LeMahieu     MI.setOpcode(Hexagon::DuplexIClass0);
319*be8c453dSColin LeMahieu 
320*be8c453dSColin LeMahieu     // Decode each instruction in the duplex.
321*be8c453dSColin LeMahieu     // Create an MCInst for each instruction.
322*be8c453dSColin LeMahieu     unsigned instLow = Instruction & 0x1fff;
323*be8c453dSColin LeMahieu     unsigned instHigh = (Instruction >> 16) & 0x1fff;
324*be8c453dSColin LeMahieu     unsigned opLow;
325*be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
326*be8c453dSColin LeMahieu         MCDisassembler::Success)
327*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
328*be8c453dSColin LeMahieu     unsigned opHigh;
329*be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
330*be8c453dSColin LeMahieu         MCDisassembler::Success)
331*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
332*be8c453dSColin LeMahieu     MCInst *MILow = new (getContext()) MCInst;
333*be8c453dSColin LeMahieu     MILow->setOpcode(opLow);
334*be8c453dSColin LeMahieu     MCInst *MIHigh = new (getContext()) MCInst;
335*be8c453dSColin LeMahieu     MIHigh->setOpcode(opHigh);
336*be8c453dSColin LeMahieu     AddSubinstOperands(MILow, opLow, instLow);
337*be8c453dSColin LeMahieu     AddSubinstOperands(MIHigh, opHigh, instHigh);
338*be8c453dSColin LeMahieu     // see ConvertToSubInst() in
339*be8c453dSColin LeMahieu     // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
340*be8c453dSColin LeMahieu 
341*be8c453dSColin LeMahieu     // Add the duplex instruction MCInsts as operands to the passed in MCInst.
342*be8c453dSColin LeMahieu     MCOperand OPLow = MCOperand::createInst(MILow);
343*be8c453dSColin LeMahieu     MCOperand OPHigh = MCOperand::createInst(MIHigh);
344*be8c453dSColin LeMahieu     MI.addOperand(OPLow);
345*be8c453dSColin LeMahieu     MI.addOperand(OPHigh);
346*be8c453dSColin LeMahieu     Complete = true;
347*be8c453dSColin LeMahieu   } else {
348*be8c453dSColin LeMahieu     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
34968d967d9SColin LeMahieu         HexagonII::INST_PARSE_PACKET_END)
35068d967d9SColin LeMahieu       Complete = true;
35168d967d9SColin LeMahieu     // Calling the auto-generated decoder function.
35268d967d9SColin LeMahieu     Result =
35368d967d9SColin LeMahieu         decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
354*be8c453dSColin LeMahieu   }
35568d967d9SColin LeMahieu 
3565d6f03bdSColin LeMahieu   return Result;
35788ebb9e2SColin LeMahieu }
358*be8c453dSColin LeMahieu 
359*be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
360*be8c453dSColin LeMahieu enum subInstBinaryValues {
361*be8c453dSColin LeMahieu   V4_SA1_addi_BITS = 0x0000,
362*be8c453dSColin LeMahieu   V4_SA1_addi_MASK = 0x1800,
363*be8c453dSColin LeMahieu   V4_SA1_addrx_BITS = 0x1800,
364*be8c453dSColin LeMahieu   V4_SA1_addrx_MASK = 0x1f00,
365*be8c453dSColin LeMahieu   V4_SA1_addsp_BITS = 0x0c00,
366*be8c453dSColin LeMahieu   V4_SA1_addsp_MASK = 0x1c00,
367*be8c453dSColin LeMahieu   V4_SA1_and1_BITS = 0x1200,
368*be8c453dSColin LeMahieu   V4_SA1_and1_MASK = 0x1f00,
369*be8c453dSColin LeMahieu   V4_SA1_clrf_BITS = 0x1a70,
370*be8c453dSColin LeMahieu   V4_SA1_clrf_MASK = 0x1e70,
371*be8c453dSColin LeMahieu   V4_SA1_clrfnew_BITS = 0x1a50,
372*be8c453dSColin LeMahieu   V4_SA1_clrfnew_MASK = 0x1e70,
373*be8c453dSColin LeMahieu   V4_SA1_clrt_BITS = 0x1a60,
374*be8c453dSColin LeMahieu   V4_SA1_clrt_MASK = 0x1e70,
375*be8c453dSColin LeMahieu   V4_SA1_clrtnew_BITS = 0x1a40,
376*be8c453dSColin LeMahieu   V4_SA1_clrtnew_MASK = 0x1e70,
377*be8c453dSColin LeMahieu   V4_SA1_cmpeqi_BITS = 0x1900,
378*be8c453dSColin LeMahieu   V4_SA1_cmpeqi_MASK = 0x1f00,
379*be8c453dSColin LeMahieu   V4_SA1_combine0i_BITS = 0x1c00,
380*be8c453dSColin LeMahieu   V4_SA1_combine0i_MASK = 0x1d18,
381*be8c453dSColin LeMahieu   V4_SA1_combine1i_BITS = 0x1c08,
382*be8c453dSColin LeMahieu   V4_SA1_combine1i_MASK = 0x1d18,
383*be8c453dSColin LeMahieu   V4_SA1_combine2i_BITS = 0x1c10,
384*be8c453dSColin LeMahieu   V4_SA1_combine2i_MASK = 0x1d18,
385*be8c453dSColin LeMahieu   V4_SA1_combine3i_BITS = 0x1c18,
386*be8c453dSColin LeMahieu   V4_SA1_combine3i_MASK = 0x1d18,
387*be8c453dSColin LeMahieu   V4_SA1_combinerz_BITS = 0x1d08,
388*be8c453dSColin LeMahieu   V4_SA1_combinerz_MASK = 0x1d08,
389*be8c453dSColin LeMahieu   V4_SA1_combinezr_BITS = 0x1d00,
390*be8c453dSColin LeMahieu   V4_SA1_combinezr_MASK = 0x1d08,
391*be8c453dSColin LeMahieu   V4_SA1_dec_BITS = 0x1300,
392*be8c453dSColin LeMahieu   V4_SA1_dec_MASK = 0x1f00,
393*be8c453dSColin LeMahieu   V4_SA1_inc_BITS = 0x1100,
394*be8c453dSColin LeMahieu   V4_SA1_inc_MASK = 0x1f00,
395*be8c453dSColin LeMahieu   V4_SA1_seti_BITS = 0x0800,
396*be8c453dSColin LeMahieu   V4_SA1_seti_MASK = 0x1c00,
397*be8c453dSColin LeMahieu   V4_SA1_setin1_BITS = 0x1a00,
398*be8c453dSColin LeMahieu   V4_SA1_setin1_MASK = 0x1e40,
399*be8c453dSColin LeMahieu   V4_SA1_sxtb_BITS = 0x1500,
400*be8c453dSColin LeMahieu   V4_SA1_sxtb_MASK = 0x1f00,
401*be8c453dSColin LeMahieu   V4_SA1_sxth_BITS = 0x1400,
402*be8c453dSColin LeMahieu   V4_SA1_sxth_MASK = 0x1f00,
403*be8c453dSColin LeMahieu   V4_SA1_tfr_BITS = 0x1000,
404*be8c453dSColin LeMahieu   V4_SA1_tfr_MASK = 0x1f00,
405*be8c453dSColin LeMahieu   V4_SA1_zxtb_BITS = 0x1700,
406*be8c453dSColin LeMahieu   V4_SA1_zxtb_MASK = 0x1f00,
407*be8c453dSColin LeMahieu   V4_SA1_zxth_BITS = 0x1600,
408*be8c453dSColin LeMahieu   V4_SA1_zxth_MASK = 0x1f00,
409*be8c453dSColin LeMahieu   V4_SL1_loadri_io_BITS = 0x0000,
410*be8c453dSColin LeMahieu   V4_SL1_loadri_io_MASK = 0x1000,
411*be8c453dSColin LeMahieu   V4_SL1_loadrub_io_BITS = 0x1000,
412*be8c453dSColin LeMahieu   V4_SL1_loadrub_io_MASK = 0x1000,
413*be8c453dSColin LeMahieu   V4_SL2_deallocframe_BITS = 0x1f00,
414*be8c453dSColin LeMahieu   V4_SL2_deallocframe_MASK = 0x1fc0,
415*be8c453dSColin LeMahieu   V4_SL2_jumpr31_BITS = 0x1fc0,
416*be8c453dSColin LeMahieu   V4_SL2_jumpr31_MASK = 0x1fc4,
417*be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_BITS = 0x1fc5,
418*be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_MASK = 0x1fc7,
419*be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
420*be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
421*be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_BITS = 0x1fc4,
422*be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_MASK = 0x1fc7,
423*be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
424*be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
425*be8c453dSColin LeMahieu   V4_SL2_loadrb_io_BITS = 0x1000,
426*be8c453dSColin LeMahieu   V4_SL2_loadrb_io_MASK = 0x1800,
427*be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_BITS = 0x1e00,
428*be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_MASK = 0x1f00,
429*be8c453dSColin LeMahieu   V4_SL2_loadrh_io_BITS = 0x0000,
430*be8c453dSColin LeMahieu   V4_SL2_loadrh_io_MASK = 0x1800,
431*be8c453dSColin LeMahieu   V4_SL2_loadri_sp_BITS = 0x1c00,
432*be8c453dSColin LeMahieu   V4_SL2_loadri_sp_MASK = 0x1e00,
433*be8c453dSColin LeMahieu   V4_SL2_loadruh_io_BITS = 0x0800,
434*be8c453dSColin LeMahieu   V4_SL2_loadruh_io_MASK = 0x1800,
435*be8c453dSColin LeMahieu   V4_SL2_return_BITS = 0x1f40,
436*be8c453dSColin LeMahieu   V4_SL2_return_MASK = 0x1fc4,
437*be8c453dSColin LeMahieu   V4_SL2_return_f_BITS = 0x1f45,
438*be8c453dSColin LeMahieu   V4_SL2_return_f_MASK = 0x1fc7,
439*be8c453dSColin LeMahieu   V4_SL2_return_fnew_BITS = 0x1f47,
440*be8c453dSColin LeMahieu   V4_SL2_return_fnew_MASK = 0x1fc7,
441*be8c453dSColin LeMahieu   V4_SL2_return_t_BITS = 0x1f44,
442*be8c453dSColin LeMahieu   V4_SL2_return_t_MASK = 0x1fc7,
443*be8c453dSColin LeMahieu   V4_SL2_return_tnew_BITS = 0x1f46,
444*be8c453dSColin LeMahieu   V4_SL2_return_tnew_MASK = 0x1fc7,
445*be8c453dSColin LeMahieu   V4_SS1_storeb_io_BITS = 0x1000,
446*be8c453dSColin LeMahieu   V4_SS1_storeb_io_MASK = 0x1000,
447*be8c453dSColin LeMahieu   V4_SS1_storew_io_BITS = 0x0000,
448*be8c453dSColin LeMahieu   V4_SS1_storew_io_MASK = 0x1000,
449*be8c453dSColin LeMahieu   V4_SS2_allocframe_BITS = 0x1c00,
450*be8c453dSColin LeMahieu   V4_SS2_allocframe_MASK = 0x1e00,
451*be8c453dSColin LeMahieu   V4_SS2_storebi0_BITS = 0x1200,
452*be8c453dSColin LeMahieu   V4_SS2_storebi0_MASK = 0x1f00,
453*be8c453dSColin LeMahieu   V4_SS2_storebi1_BITS = 0x1300,
454*be8c453dSColin LeMahieu   V4_SS2_storebi1_MASK = 0x1f00,
455*be8c453dSColin LeMahieu   V4_SS2_stored_sp_BITS = 0x0a00,
456*be8c453dSColin LeMahieu   V4_SS2_stored_sp_MASK = 0x1e00,
457*be8c453dSColin LeMahieu   V4_SS2_storeh_io_BITS = 0x0000,
458*be8c453dSColin LeMahieu   V4_SS2_storeh_io_MASK = 0x1800,
459*be8c453dSColin LeMahieu   V4_SS2_storew_sp_BITS = 0x0800,
460*be8c453dSColin LeMahieu   V4_SS2_storew_sp_MASK = 0x1e00,
461*be8c453dSColin LeMahieu   V4_SS2_storewi0_BITS = 0x1000,
462*be8c453dSColin LeMahieu   V4_SS2_storewi0_MASK = 0x1f00,
463*be8c453dSColin LeMahieu   V4_SS2_storewi1_BITS = 0x1100,
464*be8c453dSColin LeMahieu   V4_SS2_storewi1_MASK = 0x1f00
465*be8c453dSColin LeMahieu };
466*be8c453dSColin LeMahieu 
467*be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
468*be8c453dSColin LeMahieu                                  raw_ostream &os) {
469*be8c453dSColin LeMahieu   switch (IClass) {
470*be8c453dSColin LeMahieu   case HexagonII::HSIG_L1:
471*be8c453dSColin LeMahieu     if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
472*be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadri_io;
473*be8c453dSColin LeMahieu     else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
474*be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadrub_io;
475*be8c453dSColin LeMahieu     else {
476*be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
477*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
478*be8c453dSColin LeMahieu     }
479*be8c453dSColin LeMahieu     break;
480*be8c453dSColin LeMahieu   case HexagonII::HSIG_L2:
481*be8c453dSColin LeMahieu     if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
482*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_deallocframe;
483*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
484*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31;
485*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
486*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_f;
487*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
488*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_fnew;
489*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
490*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_t;
491*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
492*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_tnew;
493*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
494*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrb_io;
495*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
496*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrd_sp;
497*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
498*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrh_io;
499*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
500*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadri_sp;
501*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
502*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadruh_io;
503*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
504*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return;
505*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
506*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_f;
507*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
508*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_fnew;
509*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
510*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_t;
511*be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
512*be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_tnew;
513*be8c453dSColin LeMahieu     else {
514*be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
515*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
516*be8c453dSColin LeMahieu     }
517*be8c453dSColin LeMahieu     break;
518*be8c453dSColin LeMahieu   case HexagonII::HSIG_A:
519*be8c453dSColin LeMahieu     if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
520*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addi;
521*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
522*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addrx;
523*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
524*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addsp;
525*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
526*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_and1;
527*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
528*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrf;
529*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
530*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrfnew;
531*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
532*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrt;
533*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
534*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrtnew;
535*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
536*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_cmpeqi;
537*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
538*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine0i;
539*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
540*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine1i;
541*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
542*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine2i;
543*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
544*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine3i;
545*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
546*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinerz;
547*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
548*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinezr;
549*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
550*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_dec;
551*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
552*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_inc;
553*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
554*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_seti;
555*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
556*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_setin1;
557*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
558*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxtb;
559*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
560*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxth;
561*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
562*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_tfr;
563*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
564*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxtb;
565*be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
566*be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxth;
567*be8c453dSColin LeMahieu     else {
568*be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
569*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
570*be8c453dSColin LeMahieu     }
571*be8c453dSColin LeMahieu     break;
572*be8c453dSColin LeMahieu   case HexagonII::HSIG_S1:
573*be8c453dSColin LeMahieu     if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
574*be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storeb_io;
575*be8c453dSColin LeMahieu     else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
576*be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storew_io;
577*be8c453dSColin LeMahieu     else {
578*be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
579*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
580*be8c453dSColin LeMahieu     }
581*be8c453dSColin LeMahieu     break;
582*be8c453dSColin LeMahieu   case HexagonII::HSIG_S2:
583*be8c453dSColin LeMahieu     if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
584*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_allocframe;
585*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
586*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi0;
587*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
588*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi1;
589*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
590*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_stored_sp;
591*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
592*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storeh_io;
593*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
594*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storew_sp;
595*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
596*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi0;
597*be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
598*be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi1;
599*be8c453dSColin LeMahieu     else {
600*be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
601*be8c453dSColin LeMahieu       return MCDisassembler::Fail;
602*be8c453dSColin LeMahieu     }
603*be8c453dSColin LeMahieu     break;
604*be8c453dSColin LeMahieu   default:
605*be8c453dSColin LeMahieu     os << "<unknown>";
606*be8c453dSColin LeMahieu     return MCDisassembler::Fail;
607*be8c453dSColin LeMahieu   }
608*be8c453dSColin LeMahieu   return MCDisassembler::Success;
609*be8c453dSColin LeMahieu }
610*be8c453dSColin LeMahieu 
611*be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
612*be8c453dSColin LeMahieu   if (encoded_reg < 8)
613*be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg;
614*be8c453dSColin LeMahieu   else if (encoded_reg < 16)
615*be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg + 8;
616*be8c453dSColin LeMahieu   return Hexagon::NoRegister;
617*be8c453dSColin LeMahieu }
618*be8c453dSColin LeMahieu 
619*be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
620*be8c453dSColin LeMahieu   if (encoded_dreg < 4)
621*be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg;
622*be8c453dSColin LeMahieu   else if (encoded_dreg < 8)
623*be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg + 4;
624*be8c453dSColin LeMahieu   return Hexagon::NoRegister;
625*be8c453dSColin LeMahieu }
626*be8c453dSColin LeMahieu 
627*be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) {
628*be8c453dSColin LeMahieu   int64_t operand;
629*be8c453dSColin LeMahieu   MCOperand Op;
630*be8c453dSColin LeMahieu   switch (opcode) {
631*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_deallocframe:
632*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31:
633*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_f:
634*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_fnew:
635*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_t:
636*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_tnew:
637*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return:
638*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_f:
639*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_fnew:
640*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_t:
641*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_tnew:
642*be8c453dSColin LeMahieu     // no operands for these instructions
643*be8c453dSColin LeMahieu     break;
644*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_allocframe:
645*be8c453dSColin LeMahieu     // u 8-4{5_3}
646*be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 3;
647*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
648*be8c453dSColin LeMahieu     MI->addOperand(Op);
649*be8c453dSColin LeMahieu     break;
650*be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadri_io:
651*be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8{4_2}
652*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
653*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
654*be8c453dSColin LeMahieu     MI->addOperand(Op);
655*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
656*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
657*be8c453dSColin LeMahieu     MI->addOperand(Op);
658*be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 6;
659*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
660*be8c453dSColin LeMahieu     MI->addOperand(Op);
661*be8c453dSColin LeMahieu     break;
662*be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadrub_io:
663*be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8
664*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
665*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
666*be8c453dSColin LeMahieu     MI->addOperand(Op);
667*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
668*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
669*be8c453dSColin LeMahieu     MI->addOperand(Op);
670*be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
671*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
672*be8c453dSColin LeMahieu     MI->addOperand(Op);
673*be8c453dSColin LeMahieu     break;
674*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrb_io:
675*be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8
676*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
677*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
678*be8c453dSColin LeMahieu     MI->addOperand(Op);
679*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
680*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
681*be8c453dSColin LeMahieu     MI->addOperand(Op);
682*be8c453dSColin LeMahieu     operand = (inst & 0x700) >> 8;
683*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
684*be8c453dSColin LeMahieu     MI->addOperand(Op);
685*be8c453dSColin LeMahieu     break;
686*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrh_io:
687*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadruh_io:
688*be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8{3_1}
689*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
690*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
691*be8c453dSColin LeMahieu     MI->addOperand(Op);
692*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
693*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
694*be8c453dSColin LeMahieu     MI->addOperand(Op);
695*be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
696*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
697*be8c453dSColin LeMahieu     MI->addOperand(Op);
698*be8c453dSColin LeMahieu     break;
699*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrd_sp:
700*be8c453dSColin LeMahieu     // Rdd 2-0, u 7-3{5_3}
701*be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
702*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
703*be8c453dSColin LeMahieu     MI->addOperand(Op);
704*be8c453dSColin LeMahieu     operand = ((inst & 0x0f8) >> 3) << 3;
705*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
706*be8c453dSColin LeMahieu     MI->addOperand(Op);
707*be8c453dSColin LeMahieu     break;
708*be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadri_sp:
709*be8c453dSColin LeMahieu     // Rd 3-0, u 8-4{5_2}
710*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
711*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
712*be8c453dSColin LeMahieu     MI->addOperand(Op);
713*be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
714*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
715*be8c453dSColin LeMahieu     MI->addOperand(Op);
716*be8c453dSColin LeMahieu     break;
717*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addi:
718*be8c453dSColin LeMahieu     // Rx 3-0 (x2), s7 10-4
719*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
720*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
721*be8c453dSColin LeMahieu     MI->addOperand(Op);
722*be8c453dSColin LeMahieu     MI->addOperand(Op);
723*be8c453dSColin LeMahieu     operand = SignExtend64<7>((inst & 0x7f0) >> 4);
724*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
725*be8c453dSColin LeMahieu     MI->addOperand(Op);
726*be8c453dSColin LeMahieu     break;
727*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addrx:
728*be8c453dSColin LeMahieu     // Rx 3-0 (x2), Rs 7-4
729*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
730*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
731*be8c453dSColin LeMahieu     MI->addOperand(Op);
732*be8c453dSColin LeMahieu     MI->addOperand(Op);
733*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
734*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
735*be8c453dSColin LeMahieu     MI->addOperand(Op);
736*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_and1:
737*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_dec:
738*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_inc:
739*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxtb:
740*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxth:
741*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_tfr:
742*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxtb:
743*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxth:
744*be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4
745*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
746*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
747*be8c453dSColin LeMahieu     MI->addOperand(Op);
748*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
749*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
750*be8c453dSColin LeMahieu     MI->addOperand(Op);
751*be8c453dSColin LeMahieu     break;
752*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addsp:
753*be8c453dSColin LeMahieu     // Rd 3-0, u 9-4{6_2}
754*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
755*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
756*be8c453dSColin LeMahieu     MI->addOperand(Op);
757*be8c453dSColin LeMahieu     operand = ((inst & 0x3f0) >> 4) << 2;
758*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
759*be8c453dSColin LeMahieu     MI->addOperand(Op);
760*be8c453dSColin LeMahieu     break;
761*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_seti:
762*be8c453dSColin LeMahieu     // Rd 3-0, u 9-4
763*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
764*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
765*be8c453dSColin LeMahieu     MI->addOperand(Op);
766*be8c453dSColin LeMahieu     operand = (inst & 0x3f0) >> 4;
767*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
768*be8c453dSColin LeMahieu     MI->addOperand(Op);
769*be8c453dSColin LeMahieu     break;
770*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrf:
771*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrfnew:
772*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrt:
773*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrtnew:
774*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_setin1:
775*be8c453dSColin LeMahieu     // Rd 3-0
776*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
777*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
778*be8c453dSColin LeMahieu     MI->addOperand(Op);
779*be8c453dSColin LeMahieu     break;
780*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_cmpeqi:
781*be8c453dSColin LeMahieu     // Rs 7-4, u 1-0
782*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
783*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
784*be8c453dSColin LeMahieu     MI->addOperand(Op);
785*be8c453dSColin LeMahieu     operand = inst & 0x3;
786*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
787*be8c453dSColin LeMahieu     MI->addOperand(Op);
788*be8c453dSColin LeMahieu     break;
789*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine0i:
790*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine1i:
791*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine2i:
792*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine3i:
793*be8c453dSColin LeMahieu     // Rdd 2-0, u 6-5
794*be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
795*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
796*be8c453dSColin LeMahieu     MI->addOperand(Op);
797*be8c453dSColin LeMahieu     operand = (inst & 0x060) >> 5;
798*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
799*be8c453dSColin LeMahieu     MI->addOperand(Op);
800*be8c453dSColin LeMahieu     break;
801*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinerz:
802*be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinezr:
803*be8c453dSColin LeMahieu     // Rdd 2-0, Rs 7-4
804*be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
805*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
806*be8c453dSColin LeMahieu     MI->addOperand(Op);
807*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
808*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
809*be8c453dSColin LeMahieu     MI->addOperand(Op);
810*be8c453dSColin LeMahieu     break;
811*be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storeb_io:
812*be8c453dSColin LeMahieu     // Rs 7-4, u 11-8, Rt 3-0
813*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
814*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
815*be8c453dSColin LeMahieu     MI->addOperand(Op);
816*be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
817*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
818*be8c453dSColin LeMahieu     MI->addOperand(Op);
819*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
820*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
821*be8c453dSColin LeMahieu     MI->addOperand(Op);
822*be8c453dSColin LeMahieu     break;
823*be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storew_io:
824*be8c453dSColin LeMahieu     // Rs 7-4, u 11-8{4_2}, Rt 3-0
825*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
826*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
827*be8c453dSColin LeMahieu     MI->addOperand(Op);
828*be8c453dSColin LeMahieu     operand = ((inst & 0xf00) >> 8) << 2;
829*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
830*be8c453dSColin LeMahieu     MI->addOperand(Op);
831*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
832*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
833*be8c453dSColin LeMahieu     MI->addOperand(Op);
834*be8c453dSColin LeMahieu     break;
835*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi0:
836*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi1:
837*be8c453dSColin LeMahieu     // Rs 7-4, u 3-0
838*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
839*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
840*be8c453dSColin LeMahieu     MI->addOperand(Op);
841*be8c453dSColin LeMahieu     operand = inst & 0xf;
842*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
843*be8c453dSColin LeMahieu     MI->addOperand(Op);
844*be8c453dSColin LeMahieu     break;
845*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi0:
846*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi1:
847*be8c453dSColin LeMahieu     // Rs 7-4, u 3-0{4_2}
848*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
849*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
850*be8c453dSColin LeMahieu     MI->addOperand(Op);
851*be8c453dSColin LeMahieu     operand = (inst & 0xf) << 2;
852*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
853*be8c453dSColin LeMahieu     MI->addOperand(Op);
854*be8c453dSColin LeMahieu     break;
855*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_stored_sp:
856*be8c453dSColin LeMahieu     // s 8-3{6_3}, Rtt 2-0
857*be8c453dSColin LeMahieu     operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
858*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
859*be8c453dSColin LeMahieu     MI->addOperand(Op);
860*be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
861*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
862*be8c453dSColin LeMahieu     MI->addOperand(Op);
863*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storeh_io:
864*be8c453dSColin LeMahieu     // Rs 7-4, u 10-8{3_1}, Rt 3-0
865*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
866*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
867*be8c453dSColin LeMahieu     MI->addOperand(Op);
868*be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
869*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
870*be8c453dSColin LeMahieu     MI->addOperand(Op);
871*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
872*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
873*be8c453dSColin LeMahieu     MI->addOperand(Op);
874*be8c453dSColin LeMahieu     break;
875*be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storew_sp:
876*be8c453dSColin LeMahieu     // u 8-4{5_2}, Rd 3-0
877*be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
878*be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
879*be8c453dSColin LeMahieu     MI->addOperand(Op);
880*be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
881*be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
882*be8c453dSColin LeMahieu     MI->addOperand(Op);
883*be8c453dSColin LeMahieu     break;
884*be8c453dSColin LeMahieu   default:
885*be8c453dSColin LeMahieu     // don't crash with an invalid subinstruction
886*be8c453dSColin LeMahieu     // llvm_unreachable("Invalid subinstruction in duplex instruction");
887*be8c453dSColin LeMahieu     break;
888*be8c453dSColin LeMahieu   }
889*be8c453dSColin LeMahieu }
890