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);
61f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
62be8c453dSColin LeMahieu                                                uint64_t Address,
63be8c453dSColin LeMahieu                                                const void *Decoder);
64404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
65be8c453dSColin LeMahieu                                                  uint64_t Address,
66be8c453dSColin LeMahieu                                                  void const *Decoder);
67be8c453dSColin LeMahieu 
68be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
69be8c453dSColin LeMahieu                                  raw_ostream &os);
70be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst);
71f3db884eSColin LeMahieu 
721e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
731e9d1d76SColin LeMahieu                                   const void *Decoder);
741e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
751e9d1d76SColin LeMahieu                                   const void *Decoder);
761e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
771e9d1d76SColin LeMahieu                                     const void *Decoder);
781e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
791e9d1d76SColin LeMahieu                                     const void *Decoder);
801e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
811e9d1d76SColin LeMahieu                                     const void *Decoder);
821e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
831e9d1d76SColin LeMahieu                                     const void *Decoder);
841e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
851e9d1d76SColin LeMahieu                                   const void *Decoder);
861e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
871e9d1d76SColin LeMahieu                                  const void *Decoder);
881e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
891e9d1d76SColin LeMahieu                                    const void *Decoder);
901e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
911e9d1d76SColin LeMahieu                                    const void *Decoder);
921e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
931e9d1d76SColin LeMahieu                                    const void *Decoder);
941e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
951e9d1d76SColin LeMahieu                                    const void *Decoder);
961e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
971e9d1d76SColin LeMahieu                                    const void *Decoder);
981e9d1d76SColin LeMahieu 
99efa74e02SColin LeMahieu static const uint16_t IntRegDecoderTable[] = {
100efa74e02SColin LeMahieu     Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
101efa74e02SColin LeMahieu     Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
102efa74e02SColin LeMahieu     Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
103efa74e02SColin LeMahieu     Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
104efa74e02SColin LeMahieu     Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
105efa74e02SColin LeMahieu     Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
106efa74e02SColin LeMahieu     Hexagon::R30, Hexagon::R31};
107efa74e02SColin LeMahieu 
108efa74e02SColin LeMahieu static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
109efa74e02SColin LeMahieu                                                Hexagon::P2, Hexagon::P3};
110efa74e02SColin LeMahieu 
111383c36e3SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
112383c36e3SColin LeMahieu                                         const uint16_t Table[], size_t Size) {
113383c36e3SColin LeMahieu   if (RegNo < Size) {
114e9119e41SJim Grosbach     Inst.addOperand(MCOperand::createReg(Table[RegNo]));
115383c36e3SColin LeMahieu     return MCDisassembler::Success;
116be8c453dSColin LeMahieu   } else
117383c36e3SColin LeMahieu     return MCDisassembler::Fail;
118383c36e3SColin LeMahieu }
119383c36e3SColin LeMahieu 
120efa74e02SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
121efa74e02SColin LeMahieu                                                uint64_t /*Address*/,
122efa74e02SColin LeMahieu                                                void const *Decoder) {
123efa74e02SColin LeMahieu   if (RegNo > 31)
124efa74e02SColin LeMahieu     return MCDisassembler::Fail;
125efa74e02SColin LeMahieu 
126efa74e02SColin LeMahieu   unsigned Register = IntRegDecoderTable[RegNo];
127e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
128efa74e02SColin LeMahieu   return MCDisassembler::Success;
129efa74e02SColin LeMahieu }
130efa74e02SColin LeMahieu 
131f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
132be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
133be8c453dSColin LeMahieu                                                const void *Decoder) {
134f3db884eSColin LeMahieu   static const uint16_t CtrlRegDecoderTable[] = {
135f3db884eSColin LeMahieu       Hexagon::SA0,  Hexagon::LC0,        Hexagon::SA1,  Hexagon::LC1,
136f3db884eSColin LeMahieu       Hexagon::P3_0, Hexagon::NoRegister, Hexagon::C6,   Hexagon::C7,
137f3db884eSColin LeMahieu       Hexagon::USR,  Hexagon::PC,         Hexagon::UGP,  Hexagon::GP,
138be8c453dSColin LeMahieu       Hexagon::CS0,  Hexagon::CS1,        Hexagon::UPCL, Hexagon::UPCH};
139f3db884eSColin LeMahieu 
140f3db884eSColin LeMahieu   if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
141f3db884eSColin LeMahieu     return MCDisassembler::Fail;
142f3db884eSColin LeMahieu 
143f3db884eSColin LeMahieu   if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
144f3db884eSColin LeMahieu     return MCDisassembler::Fail;
145f3db884eSColin LeMahieu 
146f3db884eSColin LeMahieu   unsigned Register = CtrlRegDecoderTable[RegNo];
147e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
148f3db884eSColin LeMahieu   return MCDisassembler::Success;
149f3db884eSColin LeMahieu }
150f3db884eSColin LeMahieu 
151404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
152be8c453dSColin LeMahieu                                                  uint64_t /*Address*/,
153be8c453dSColin LeMahieu                                                  void const *Decoder) {
154404d5b24SColin LeMahieu   static const uint16_t CtrlReg64DecoderTable[] = {
155be8c453dSColin LeMahieu       Hexagon::C1_0,       Hexagon::NoRegister, Hexagon::C3_2,
156be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::NoRegister, Hexagon::NoRegister,
157be8c453dSColin LeMahieu       Hexagon::C7_6,       Hexagon::NoRegister, Hexagon::C9_8,
158be8c453dSColin LeMahieu       Hexagon::NoRegister, Hexagon::C11_10,     Hexagon::NoRegister,
159be8c453dSColin LeMahieu       Hexagon::CS,         Hexagon::NoRegister, Hexagon::UPC,
160be8c453dSColin LeMahieu       Hexagon::NoRegister};
161404d5b24SColin LeMahieu 
162404d5b24SColin LeMahieu   if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0]))
163404d5b24SColin LeMahieu     return MCDisassembler::Fail;
164404d5b24SColin LeMahieu 
165404d5b24SColin LeMahieu   if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
166404d5b24SColin LeMahieu     return MCDisassembler::Fail;
167404d5b24SColin LeMahieu 
168404d5b24SColin LeMahieu   unsigned Register = CtrlReg64DecoderTable[RegNo];
169e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
170404d5b24SColin LeMahieu   return MCDisassembler::Success;
171404d5b24SColin LeMahieu }
172404d5b24SColin LeMahieu 
173ff370ed9SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
174be8c453dSColin LeMahieu                                                uint64_t /*Address*/,
175be8c453dSColin LeMahieu                                                const void *Decoder) {
176ff370ed9SColin LeMahieu   unsigned Register = 0;
177ff370ed9SColin LeMahieu   switch (RegNo) {
178ff370ed9SColin LeMahieu   case 0:
179ff370ed9SColin LeMahieu     Register = Hexagon::M0;
180ff370ed9SColin LeMahieu     break;
181ff370ed9SColin LeMahieu   case 1:
182ff370ed9SColin LeMahieu     Register = Hexagon::M1;
183ff370ed9SColin LeMahieu     break;
184ff370ed9SColin LeMahieu   default:
185ff370ed9SColin LeMahieu     return MCDisassembler::Fail;
186ff370ed9SColin LeMahieu   }
187e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
188ff370ed9SColin LeMahieu   return MCDisassembler::Success;
189ff370ed9SColin LeMahieu }
190ff370ed9SColin LeMahieu 
191383c36e3SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
192be8c453dSColin LeMahieu                                                   uint64_t /*Address*/,
193be8c453dSColin LeMahieu                                                   const void *Decoder) {
194383c36e3SColin LeMahieu   static const uint16_t DoubleRegDecoderTable[] = {
195383c36e3SColin LeMahieu       Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
196383c36e3SColin LeMahieu       Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
197383c36e3SColin LeMahieu       Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
198be8c453dSColin LeMahieu       Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
199383c36e3SColin LeMahieu 
200be8c453dSColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
201383c36e3SColin LeMahieu                               sizeof(DoubleRegDecoderTable)));
202383c36e3SColin LeMahieu }
203383c36e3SColin LeMahieu 
204efa74e02SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
205efa74e02SColin LeMahieu                                                 uint64_t /*Address*/,
206efa74e02SColin LeMahieu                                                 void const *Decoder) {
207efa74e02SColin LeMahieu   if (RegNo > 3)
208efa74e02SColin LeMahieu     return MCDisassembler::Fail;
209efa74e02SColin LeMahieu 
210efa74e02SColin LeMahieu   unsigned Register = PredRegDecoderTable[RegNo];
211e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Register));
212efa74e02SColin LeMahieu   return MCDisassembler::Success;
213efa74e02SColin LeMahieu }
214efa74e02SColin LeMahieu 
21588ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc"
21688ebb9e2SColin LeMahieu 
21788ebb9e2SColin LeMahieu static MCDisassembler *createHexagonDisassembler(Target const &T,
21888ebb9e2SColin LeMahieu                                                  MCSubtargetInfo const &STI,
21988ebb9e2SColin LeMahieu                                                  MCContext &Ctx) {
22088ebb9e2SColin LeMahieu   return new HexagonDisassembler(STI, Ctx);
22188ebb9e2SColin LeMahieu }
22288ebb9e2SColin LeMahieu 
22388ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() {
22488ebb9e2SColin LeMahieu   TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
22588ebb9e2SColin LeMahieu                                          createHexagonDisassembler);
22688ebb9e2SColin LeMahieu }
22788ebb9e2SColin LeMahieu 
22888ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
2297fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
23088ebb9e2SColin LeMahieu                                                  uint64_t Address,
23188ebb9e2SColin LeMahieu                                                  raw_ostream &os,
23288ebb9e2SColin LeMahieu                                                  raw_ostream &cs) const {
23368d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
23468d967d9SColin LeMahieu   bool Complete = false;
23568d967d9SColin LeMahieu   Size = 0;
2364aa6bea7SRafael Espindola 
23768d967d9SColin LeMahieu   *CurrentBundle = &MI;
238*f97999dcSCameron Esfahani   MI.clear();
23968d967d9SColin LeMahieu   MI.setOpcode(Hexagon::BUNDLE);
24068d967d9SColin LeMahieu   MI.addOperand(MCOperand::createImm(0));
241be8c453dSColin LeMahieu   while (Result == Success && Complete == false) {
24268d967d9SColin LeMahieu     if (Bytes.size() < HEXAGON_INSTR_SIZE)
24368d967d9SColin LeMahieu       return MCDisassembler::Fail;
24468d967d9SColin LeMahieu     MCInst *Inst = new (getContext()) MCInst;
24568d967d9SColin LeMahieu     Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
24668d967d9SColin LeMahieu     MI.addOperand(MCOperand::createInst(Inst));
24768d967d9SColin LeMahieu     Size += HEXAGON_INSTR_SIZE;
24868d967d9SColin LeMahieu     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
24968d967d9SColin LeMahieu   }
25068d967d9SColin LeMahieu   return Result;
25168d967d9SColin LeMahieu }
25268d967d9SColin LeMahieu 
25368d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction(
25468d967d9SColin LeMahieu     MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
25568d967d9SColin LeMahieu     raw_ostream &os, raw_ostream &cs, bool &Complete) const {
25668d967d9SColin LeMahieu   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
25768d967d9SColin LeMahieu 
25868d967d9SColin LeMahieu   uint32_t Instruction =
25988ebb9e2SColin LeMahieu       llvm::support::endian::read<uint32_t, llvm::support::little,
26088ebb9e2SColin LeMahieu                                   llvm::support::unaligned>(Bytes.data());
26188ebb9e2SColin LeMahieu 
26268d967d9SColin LeMahieu   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
26368d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
26468d967d9SColin LeMahieu       HexagonII::INST_PARSE_LOOP_END) {
26568d967d9SColin LeMahieu     if (BundleSize == 0)
26668d967d9SColin LeMahieu       HexagonMCInstrInfo::setInnerLoop(MCB);
26768d967d9SColin LeMahieu     else if (BundleSize == 1)
26868d967d9SColin LeMahieu       HexagonMCInstrInfo::setOuterLoop(MCB);
26968d967d9SColin LeMahieu     else
27068d967d9SColin LeMahieu       return DecodeStatus::Fail;
27168d967d9SColin LeMahieu   }
27268d967d9SColin LeMahieu 
27368d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
27468d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
275be8c453dSColin LeMahieu       HexagonII::INST_PARSE_DUPLEX) {
276be8c453dSColin LeMahieu     // Determine the instruction class of each instruction in the duplex.
277be8c453dSColin LeMahieu     unsigned duplexIClass, IClassLow, IClassHigh;
278be8c453dSColin LeMahieu 
279be8c453dSColin LeMahieu     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
280be8c453dSColin LeMahieu     switch (duplexIClass) {
281be8c453dSColin LeMahieu     default:
282be8c453dSColin LeMahieu       return MCDisassembler::Fail;
283be8c453dSColin LeMahieu     case 0:
284be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
285be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
286be8c453dSColin LeMahieu       break;
287be8c453dSColin LeMahieu     case 1:
288be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
289be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
290be8c453dSColin LeMahieu       break;
291be8c453dSColin LeMahieu     case 2:
292be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
293be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
294be8c453dSColin LeMahieu       break;
295be8c453dSColin LeMahieu     case 3:
296be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_A;
297be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
298be8c453dSColin LeMahieu       break;
299be8c453dSColin LeMahieu     case 4:
300be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
301be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
302be8c453dSColin LeMahieu       break;
303be8c453dSColin LeMahieu     case 5:
304be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
305be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
306be8c453dSColin LeMahieu       break;
307be8c453dSColin LeMahieu     case 6:
308be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
309be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
310be8c453dSColin LeMahieu       break;
311be8c453dSColin LeMahieu     case 7:
312be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
313be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
314be8c453dSColin LeMahieu       break;
315be8c453dSColin LeMahieu     case 8:
316be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
317be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
318be8c453dSColin LeMahieu       break;
319be8c453dSColin LeMahieu     case 9:
320be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
321be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
322be8c453dSColin LeMahieu       break;
323be8c453dSColin LeMahieu     case 10:
324be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
325be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
326be8c453dSColin LeMahieu       break;
327be8c453dSColin LeMahieu     case 11:
328be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
329be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
330be8c453dSColin LeMahieu       break;
331be8c453dSColin LeMahieu     case 12:
332be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
333be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
334be8c453dSColin LeMahieu       break;
335be8c453dSColin LeMahieu     case 13:
336be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
337be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
338be8c453dSColin LeMahieu       break;
339be8c453dSColin LeMahieu     case 14:
340be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
341be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S2;
342be8c453dSColin LeMahieu       break;
343be8c453dSColin LeMahieu     }
344be8c453dSColin LeMahieu 
345be8c453dSColin LeMahieu     // Set the MCInst to be a duplex instruction. Which one doesn't matter.
346be8c453dSColin LeMahieu     MI.setOpcode(Hexagon::DuplexIClass0);
347be8c453dSColin LeMahieu 
348be8c453dSColin LeMahieu     // Decode each instruction in the duplex.
349be8c453dSColin LeMahieu     // Create an MCInst for each instruction.
350be8c453dSColin LeMahieu     unsigned instLow = Instruction & 0x1fff;
351be8c453dSColin LeMahieu     unsigned instHigh = (Instruction >> 16) & 0x1fff;
352be8c453dSColin LeMahieu     unsigned opLow;
353be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
354be8c453dSColin LeMahieu         MCDisassembler::Success)
355be8c453dSColin LeMahieu       return MCDisassembler::Fail;
356be8c453dSColin LeMahieu     unsigned opHigh;
357be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
358be8c453dSColin LeMahieu         MCDisassembler::Success)
359be8c453dSColin LeMahieu       return MCDisassembler::Fail;
360be8c453dSColin LeMahieu     MCInst *MILow = new (getContext()) MCInst;
361be8c453dSColin LeMahieu     MILow->setOpcode(opLow);
362be8c453dSColin LeMahieu     MCInst *MIHigh = new (getContext()) MCInst;
363be8c453dSColin LeMahieu     MIHigh->setOpcode(opHigh);
364be8c453dSColin LeMahieu     AddSubinstOperands(MILow, opLow, instLow);
365be8c453dSColin LeMahieu     AddSubinstOperands(MIHigh, opHigh, instHigh);
366be8c453dSColin LeMahieu     // see ConvertToSubInst() in
367be8c453dSColin LeMahieu     // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
368be8c453dSColin LeMahieu 
369be8c453dSColin LeMahieu     // Add the duplex instruction MCInsts as operands to the passed in MCInst.
370be8c453dSColin LeMahieu     MCOperand OPLow = MCOperand::createInst(MILow);
371be8c453dSColin LeMahieu     MCOperand OPHigh = MCOperand::createInst(MIHigh);
372be8c453dSColin LeMahieu     MI.addOperand(OPLow);
373be8c453dSColin LeMahieu     MI.addOperand(OPHigh);
374be8c453dSColin LeMahieu     Complete = true;
375be8c453dSColin LeMahieu   } else {
376be8c453dSColin LeMahieu     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
37768d967d9SColin LeMahieu         HexagonII::INST_PARSE_PACKET_END)
37868d967d9SColin LeMahieu       Complete = true;
37968d967d9SColin LeMahieu     // Calling the auto-generated decoder function.
38068d967d9SColin LeMahieu     Result =
38168d967d9SColin LeMahieu         decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
382be8c453dSColin LeMahieu   }
38368d967d9SColin LeMahieu 
3845d6f03bdSColin LeMahieu   return Result;
38588ebb9e2SColin LeMahieu }
386be8c453dSColin LeMahieu 
3871e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
3881e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
3891e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<16>(tmp);
3901e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
3911e9d1d76SColin LeMahieu   return MCDisassembler::Success;
3921e9d1d76SColin LeMahieu }
3931e9d1d76SColin LeMahieu 
3941e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
3951e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
3961e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
3971e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
3981e9d1d76SColin LeMahieu   return MCDisassembler::Success;
3991e9d1d76SColin LeMahieu }
4001e9d1d76SColin LeMahieu 
4011e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
4021e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4031e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<11>(tmp);
4041e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4051e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4061e9d1d76SColin LeMahieu }
4071e9d1d76SColin LeMahieu 
4081e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
4091e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4101e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
4111e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4121e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4131e9d1d76SColin LeMahieu }
4141e9d1d76SColin LeMahieu 
4151e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
4161e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4171e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<13>(tmp);
4181e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4191e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4201e9d1d76SColin LeMahieu }
4211e9d1d76SColin LeMahieu 
4221e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
4231e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
4241e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<14>(tmp);
4251e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4261e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4271e9d1d76SColin LeMahieu }
4281e9d1d76SColin LeMahieu 
4291e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
4301e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
4311e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<10>(tmp);
4321e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4331e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4341e9d1d76SColin LeMahieu }
4351e9d1d76SColin LeMahieu 
4361e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/,
4371e9d1d76SColin LeMahieu                                  const void *Decoder) {
4381e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<8>(tmp);
4391e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4401e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4411e9d1d76SColin LeMahieu }
4421e9d1d76SColin LeMahieu 
4431e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
4441e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
4451e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
4461e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4471e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4481e9d1d76SColin LeMahieu }
4491e9d1d76SColin LeMahieu 
4501e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
4511e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
4521e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<4>(tmp);
4531e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4541e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4551e9d1d76SColin LeMahieu }
4561e9d1d76SColin LeMahieu 
4571e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
4581e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
4591e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<5>(tmp);
4601e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4611e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4621e9d1d76SColin LeMahieu }
4631e9d1d76SColin LeMahieu 
4641e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
4651e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
4661e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
4671e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4681e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4691e9d1d76SColin LeMahieu }
4701e9d1d76SColin LeMahieu 
4711e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
4721e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
4731e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<7>(tmp);
4741e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
4751e9d1d76SColin LeMahieu   return MCDisassembler::Success;
4761e9d1d76SColin LeMahieu }
4771e9d1d76SColin LeMahieu 
478be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
479be8c453dSColin LeMahieu enum subInstBinaryValues {
480be8c453dSColin LeMahieu   V4_SA1_addi_BITS = 0x0000,
481be8c453dSColin LeMahieu   V4_SA1_addi_MASK = 0x1800,
482be8c453dSColin LeMahieu   V4_SA1_addrx_BITS = 0x1800,
483be8c453dSColin LeMahieu   V4_SA1_addrx_MASK = 0x1f00,
484be8c453dSColin LeMahieu   V4_SA1_addsp_BITS = 0x0c00,
485be8c453dSColin LeMahieu   V4_SA1_addsp_MASK = 0x1c00,
486be8c453dSColin LeMahieu   V4_SA1_and1_BITS = 0x1200,
487be8c453dSColin LeMahieu   V4_SA1_and1_MASK = 0x1f00,
488be8c453dSColin LeMahieu   V4_SA1_clrf_BITS = 0x1a70,
489be8c453dSColin LeMahieu   V4_SA1_clrf_MASK = 0x1e70,
490be8c453dSColin LeMahieu   V4_SA1_clrfnew_BITS = 0x1a50,
491be8c453dSColin LeMahieu   V4_SA1_clrfnew_MASK = 0x1e70,
492be8c453dSColin LeMahieu   V4_SA1_clrt_BITS = 0x1a60,
493be8c453dSColin LeMahieu   V4_SA1_clrt_MASK = 0x1e70,
494be8c453dSColin LeMahieu   V4_SA1_clrtnew_BITS = 0x1a40,
495be8c453dSColin LeMahieu   V4_SA1_clrtnew_MASK = 0x1e70,
496be8c453dSColin LeMahieu   V4_SA1_cmpeqi_BITS = 0x1900,
497be8c453dSColin LeMahieu   V4_SA1_cmpeqi_MASK = 0x1f00,
498be8c453dSColin LeMahieu   V4_SA1_combine0i_BITS = 0x1c00,
499be8c453dSColin LeMahieu   V4_SA1_combine0i_MASK = 0x1d18,
500be8c453dSColin LeMahieu   V4_SA1_combine1i_BITS = 0x1c08,
501be8c453dSColin LeMahieu   V4_SA1_combine1i_MASK = 0x1d18,
502be8c453dSColin LeMahieu   V4_SA1_combine2i_BITS = 0x1c10,
503be8c453dSColin LeMahieu   V4_SA1_combine2i_MASK = 0x1d18,
504be8c453dSColin LeMahieu   V4_SA1_combine3i_BITS = 0x1c18,
505be8c453dSColin LeMahieu   V4_SA1_combine3i_MASK = 0x1d18,
506be8c453dSColin LeMahieu   V4_SA1_combinerz_BITS = 0x1d08,
507be8c453dSColin LeMahieu   V4_SA1_combinerz_MASK = 0x1d08,
508be8c453dSColin LeMahieu   V4_SA1_combinezr_BITS = 0x1d00,
509be8c453dSColin LeMahieu   V4_SA1_combinezr_MASK = 0x1d08,
510be8c453dSColin LeMahieu   V4_SA1_dec_BITS = 0x1300,
511be8c453dSColin LeMahieu   V4_SA1_dec_MASK = 0x1f00,
512be8c453dSColin LeMahieu   V4_SA1_inc_BITS = 0x1100,
513be8c453dSColin LeMahieu   V4_SA1_inc_MASK = 0x1f00,
514be8c453dSColin LeMahieu   V4_SA1_seti_BITS = 0x0800,
515be8c453dSColin LeMahieu   V4_SA1_seti_MASK = 0x1c00,
516be8c453dSColin LeMahieu   V4_SA1_setin1_BITS = 0x1a00,
517be8c453dSColin LeMahieu   V4_SA1_setin1_MASK = 0x1e40,
518be8c453dSColin LeMahieu   V4_SA1_sxtb_BITS = 0x1500,
519be8c453dSColin LeMahieu   V4_SA1_sxtb_MASK = 0x1f00,
520be8c453dSColin LeMahieu   V4_SA1_sxth_BITS = 0x1400,
521be8c453dSColin LeMahieu   V4_SA1_sxth_MASK = 0x1f00,
522be8c453dSColin LeMahieu   V4_SA1_tfr_BITS = 0x1000,
523be8c453dSColin LeMahieu   V4_SA1_tfr_MASK = 0x1f00,
524be8c453dSColin LeMahieu   V4_SA1_zxtb_BITS = 0x1700,
525be8c453dSColin LeMahieu   V4_SA1_zxtb_MASK = 0x1f00,
526be8c453dSColin LeMahieu   V4_SA1_zxth_BITS = 0x1600,
527be8c453dSColin LeMahieu   V4_SA1_zxth_MASK = 0x1f00,
528be8c453dSColin LeMahieu   V4_SL1_loadri_io_BITS = 0x0000,
529be8c453dSColin LeMahieu   V4_SL1_loadri_io_MASK = 0x1000,
530be8c453dSColin LeMahieu   V4_SL1_loadrub_io_BITS = 0x1000,
531be8c453dSColin LeMahieu   V4_SL1_loadrub_io_MASK = 0x1000,
532be8c453dSColin LeMahieu   V4_SL2_deallocframe_BITS = 0x1f00,
533be8c453dSColin LeMahieu   V4_SL2_deallocframe_MASK = 0x1fc0,
534be8c453dSColin LeMahieu   V4_SL2_jumpr31_BITS = 0x1fc0,
535be8c453dSColin LeMahieu   V4_SL2_jumpr31_MASK = 0x1fc4,
536be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_BITS = 0x1fc5,
537be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_MASK = 0x1fc7,
538be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
539be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
540be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_BITS = 0x1fc4,
541be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_MASK = 0x1fc7,
542be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
543be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
544be8c453dSColin LeMahieu   V4_SL2_loadrb_io_BITS = 0x1000,
545be8c453dSColin LeMahieu   V4_SL2_loadrb_io_MASK = 0x1800,
546be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_BITS = 0x1e00,
547be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_MASK = 0x1f00,
548be8c453dSColin LeMahieu   V4_SL2_loadrh_io_BITS = 0x0000,
549be8c453dSColin LeMahieu   V4_SL2_loadrh_io_MASK = 0x1800,
550be8c453dSColin LeMahieu   V4_SL2_loadri_sp_BITS = 0x1c00,
551be8c453dSColin LeMahieu   V4_SL2_loadri_sp_MASK = 0x1e00,
552be8c453dSColin LeMahieu   V4_SL2_loadruh_io_BITS = 0x0800,
553be8c453dSColin LeMahieu   V4_SL2_loadruh_io_MASK = 0x1800,
554be8c453dSColin LeMahieu   V4_SL2_return_BITS = 0x1f40,
555be8c453dSColin LeMahieu   V4_SL2_return_MASK = 0x1fc4,
556be8c453dSColin LeMahieu   V4_SL2_return_f_BITS = 0x1f45,
557be8c453dSColin LeMahieu   V4_SL2_return_f_MASK = 0x1fc7,
558be8c453dSColin LeMahieu   V4_SL2_return_fnew_BITS = 0x1f47,
559be8c453dSColin LeMahieu   V4_SL2_return_fnew_MASK = 0x1fc7,
560be8c453dSColin LeMahieu   V4_SL2_return_t_BITS = 0x1f44,
561be8c453dSColin LeMahieu   V4_SL2_return_t_MASK = 0x1fc7,
562be8c453dSColin LeMahieu   V4_SL2_return_tnew_BITS = 0x1f46,
563be8c453dSColin LeMahieu   V4_SL2_return_tnew_MASK = 0x1fc7,
564be8c453dSColin LeMahieu   V4_SS1_storeb_io_BITS = 0x1000,
565be8c453dSColin LeMahieu   V4_SS1_storeb_io_MASK = 0x1000,
566be8c453dSColin LeMahieu   V4_SS1_storew_io_BITS = 0x0000,
567be8c453dSColin LeMahieu   V4_SS1_storew_io_MASK = 0x1000,
568be8c453dSColin LeMahieu   V4_SS2_allocframe_BITS = 0x1c00,
569be8c453dSColin LeMahieu   V4_SS2_allocframe_MASK = 0x1e00,
570be8c453dSColin LeMahieu   V4_SS2_storebi0_BITS = 0x1200,
571be8c453dSColin LeMahieu   V4_SS2_storebi0_MASK = 0x1f00,
572be8c453dSColin LeMahieu   V4_SS2_storebi1_BITS = 0x1300,
573be8c453dSColin LeMahieu   V4_SS2_storebi1_MASK = 0x1f00,
574be8c453dSColin LeMahieu   V4_SS2_stored_sp_BITS = 0x0a00,
575be8c453dSColin LeMahieu   V4_SS2_stored_sp_MASK = 0x1e00,
576be8c453dSColin LeMahieu   V4_SS2_storeh_io_BITS = 0x0000,
577be8c453dSColin LeMahieu   V4_SS2_storeh_io_MASK = 0x1800,
578be8c453dSColin LeMahieu   V4_SS2_storew_sp_BITS = 0x0800,
579be8c453dSColin LeMahieu   V4_SS2_storew_sp_MASK = 0x1e00,
580be8c453dSColin LeMahieu   V4_SS2_storewi0_BITS = 0x1000,
581be8c453dSColin LeMahieu   V4_SS2_storewi0_MASK = 0x1f00,
582be8c453dSColin LeMahieu   V4_SS2_storewi1_BITS = 0x1100,
583be8c453dSColin LeMahieu   V4_SS2_storewi1_MASK = 0x1f00
584be8c453dSColin LeMahieu };
585be8c453dSColin LeMahieu 
586be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
587be8c453dSColin LeMahieu                                  raw_ostream &os) {
588be8c453dSColin LeMahieu   switch (IClass) {
589be8c453dSColin LeMahieu   case HexagonII::HSIG_L1:
590be8c453dSColin LeMahieu     if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
591be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadri_io;
592be8c453dSColin LeMahieu     else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
593be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadrub_io;
594be8c453dSColin LeMahieu     else {
595be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
596be8c453dSColin LeMahieu       return MCDisassembler::Fail;
597be8c453dSColin LeMahieu     }
598be8c453dSColin LeMahieu     break;
599be8c453dSColin LeMahieu   case HexagonII::HSIG_L2:
600be8c453dSColin LeMahieu     if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
601be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_deallocframe;
602be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
603be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31;
604be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
605be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_f;
606be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
607be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_fnew;
608be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
609be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_t;
610be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
611be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_tnew;
612be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
613be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrb_io;
614be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
615be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrd_sp;
616be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
617be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrh_io;
618be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
619be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadri_sp;
620be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
621be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadruh_io;
622be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
623be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return;
624be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
625be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_f;
626be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
627be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_fnew;
628be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
629be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_t;
630be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
631be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_tnew;
632be8c453dSColin LeMahieu     else {
633be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
634be8c453dSColin LeMahieu       return MCDisassembler::Fail;
635be8c453dSColin LeMahieu     }
636be8c453dSColin LeMahieu     break;
637be8c453dSColin LeMahieu   case HexagonII::HSIG_A:
638be8c453dSColin LeMahieu     if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
639be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addi;
640be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
641be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addrx;
642be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
643be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addsp;
644be8c453dSColin LeMahieu     else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
645be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_and1;
646be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
647be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrf;
648be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
649be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrfnew;
650be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
651be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrt;
652be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
653be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrtnew;
654be8c453dSColin LeMahieu     else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
655be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_cmpeqi;
656be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
657be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine0i;
658be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
659be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine1i;
660be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
661be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine2i;
662be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
663be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine3i;
664be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
665be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinerz;
666be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
667be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinezr;
668be8c453dSColin LeMahieu     else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
669be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_dec;
670be8c453dSColin LeMahieu     else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
671be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_inc;
672be8c453dSColin LeMahieu     else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
673be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_seti;
674be8c453dSColin LeMahieu     else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
675be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_setin1;
676be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
677be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxtb;
678be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
679be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxth;
680be8c453dSColin LeMahieu     else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
681be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_tfr;
682be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
683be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxtb;
684be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
685be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxth;
686be8c453dSColin LeMahieu     else {
687be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
688be8c453dSColin LeMahieu       return MCDisassembler::Fail;
689be8c453dSColin LeMahieu     }
690be8c453dSColin LeMahieu     break;
691be8c453dSColin LeMahieu   case HexagonII::HSIG_S1:
692be8c453dSColin LeMahieu     if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
693be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storeb_io;
694be8c453dSColin LeMahieu     else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
695be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storew_io;
696be8c453dSColin LeMahieu     else {
697be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
698be8c453dSColin LeMahieu       return MCDisassembler::Fail;
699be8c453dSColin LeMahieu     }
700be8c453dSColin LeMahieu     break;
701be8c453dSColin LeMahieu   case HexagonII::HSIG_S2:
702be8c453dSColin LeMahieu     if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
703be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_allocframe;
704be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
705be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi0;
706be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
707be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi1;
708be8c453dSColin LeMahieu     else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
709be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_stored_sp;
710be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
711be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storeh_io;
712be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
713be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storew_sp;
714be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
715be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi0;
716be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
717be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi1;
718be8c453dSColin LeMahieu     else {
719be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
720be8c453dSColin LeMahieu       return MCDisassembler::Fail;
721be8c453dSColin LeMahieu     }
722be8c453dSColin LeMahieu     break;
723be8c453dSColin LeMahieu   default:
724be8c453dSColin LeMahieu     os << "<unknown>";
725be8c453dSColin LeMahieu     return MCDisassembler::Fail;
726be8c453dSColin LeMahieu   }
727be8c453dSColin LeMahieu   return MCDisassembler::Success;
728be8c453dSColin LeMahieu }
729be8c453dSColin LeMahieu 
730be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
731be8c453dSColin LeMahieu   if (encoded_reg < 8)
732be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg;
733be8c453dSColin LeMahieu   else if (encoded_reg < 16)
734be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg + 8;
735be8c453dSColin LeMahieu   return Hexagon::NoRegister;
736be8c453dSColin LeMahieu }
737be8c453dSColin LeMahieu 
738be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
739be8c453dSColin LeMahieu   if (encoded_dreg < 4)
740be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg;
741be8c453dSColin LeMahieu   else if (encoded_dreg < 8)
742be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg + 4;
743be8c453dSColin LeMahieu   return Hexagon::NoRegister;
744be8c453dSColin LeMahieu }
745be8c453dSColin LeMahieu 
746be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) {
747be8c453dSColin LeMahieu   int64_t operand;
748be8c453dSColin LeMahieu   MCOperand Op;
749be8c453dSColin LeMahieu   switch (opcode) {
750be8c453dSColin LeMahieu   case Hexagon::V4_SL2_deallocframe:
751be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31:
752be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_f:
753be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_fnew:
754be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_t:
755be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_tnew:
756be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return:
757be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_f:
758be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_fnew:
759be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_t:
760be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_tnew:
761be8c453dSColin LeMahieu     // no operands for these instructions
762be8c453dSColin LeMahieu     break;
763be8c453dSColin LeMahieu   case Hexagon::V4_SS2_allocframe:
764be8c453dSColin LeMahieu     // u 8-4{5_3}
765be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 3;
766be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
767be8c453dSColin LeMahieu     MI->addOperand(Op);
768be8c453dSColin LeMahieu     break;
769be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadri_io:
770be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8{4_2}
771be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
772be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
773be8c453dSColin LeMahieu     MI->addOperand(Op);
774be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
775be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
776be8c453dSColin LeMahieu     MI->addOperand(Op);
777be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 6;
778be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
779be8c453dSColin LeMahieu     MI->addOperand(Op);
780be8c453dSColin LeMahieu     break;
781be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadrub_io:
782be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8
783be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
784be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
785be8c453dSColin LeMahieu     MI->addOperand(Op);
786be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
787be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
788be8c453dSColin LeMahieu     MI->addOperand(Op);
789be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
790be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
791be8c453dSColin LeMahieu     MI->addOperand(Op);
792be8c453dSColin LeMahieu     break;
793be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrb_io:
794be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8
795be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
796be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
797be8c453dSColin LeMahieu     MI->addOperand(Op);
798be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
799be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
800be8c453dSColin LeMahieu     MI->addOperand(Op);
801be8c453dSColin LeMahieu     operand = (inst & 0x700) >> 8;
802be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
803be8c453dSColin LeMahieu     MI->addOperand(Op);
804be8c453dSColin LeMahieu     break;
805be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrh_io:
806be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadruh_io:
807be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8{3_1}
808be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
809be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
810be8c453dSColin LeMahieu     MI->addOperand(Op);
811be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
812be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
813be8c453dSColin LeMahieu     MI->addOperand(Op);
814be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
815be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
816be8c453dSColin LeMahieu     MI->addOperand(Op);
817be8c453dSColin LeMahieu     break;
818be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrd_sp:
819be8c453dSColin LeMahieu     // Rdd 2-0, u 7-3{5_3}
820be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
821be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
822be8c453dSColin LeMahieu     MI->addOperand(Op);
823be8c453dSColin LeMahieu     operand = ((inst & 0x0f8) >> 3) << 3;
824be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
825be8c453dSColin LeMahieu     MI->addOperand(Op);
826be8c453dSColin LeMahieu     break;
827be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadri_sp:
828be8c453dSColin LeMahieu     // Rd 3-0, u 8-4{5_2}
829be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
830be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
831be8c453dSColin LeMahieu     MI->addOperand(Op);
832be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
833be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
834be8c453dSColin LeMahieu     MI->addOperand(Op);
835be8c453dSColin LeMahieu     break;
836be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addi:
837be8c453dSColin LeMahieu     // Rx 3-0 (x2), s7 10-4
838be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
839be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
840be8c453dSColin LeMahieu     MI->addOperand(Op);
841be8c453dSColin LeMahieu     MI->addOperand(Op);
842be8c453dSColin LeMahieu     operand = SignExtend64<7>((inst & 0x7f0) >> 4);
843be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
844be8c453dSColin LeMahieu     MI->addOperand(Op);
845be8c453dSColin LeMahieu     break;
846be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addrx:
847be8c453dSColin LeMahieu     // Rx 3-0 (x2), Rs 7-4
848be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
849be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
850be8c453dSColin LeMahieu     MI->addOperand(Op);
851be8c453dSColin LeMahieu     MI->addOperand(Op);
852be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
853be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
854be8c453dSColin LeMahieu     MI->addOperand(Op);
855be8c453dSColin LeMahieu   case Hexagon::V4_SA1_and1:
856be8c453dSColin LeMahieu   case Hexagon::V4_SA1_dec:
857be8c453dSColin LeMahieu   case Hexagon::V4_SA1_inc:
858be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxtb:
859be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxth:
860be8c453dSColin LeMahieu   case Hexagon::V4_SA1_tfr:
861be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxtb:
862be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxth:
863be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4
864be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
865be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
866be8c453dSColin LeMahieu     MI->addOperand(Op);
867be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
868be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
869be8c453dSColin LeMahieu     MI->addOperand(Op);
870be8c453dSColin LeMahieu     break;
871be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addsp:
872be8c453dSColin LeMahieu     // Rd 3-0, u 9-4{6_2}
873be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
874be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
875be8c453dSColin LeMahieu     MI->addOperand(Op);
876be8c453dSColin LeMahieu     operand = ((inst & 0x3f0) >> 4) << 2;
877be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
878be8c453dSColin LeMahieu     MI->addOperand(Op);
879be8c453dSColin LeMahieu     break;
880be8c453dSColin LeMahieu   case Hexagon::V4_SA1_seti:
881be8c453dSColin LeMahieu     // Rd 3-0, u 9-4
882be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
883be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
884be8c453dSColin LeMahieu     MI->addOperand(Op);
885be8c453dSColin LeMahieu     operand = (inst & 0x3f0) >> 4;
886be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
887be8c453dSColin LeMahieu     MI->addOperand(Op);
888be8c453dSColin LeMahieu     break;
889be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrf:
890be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrfnew:
891be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrt:
892be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrtnew:
893be8c453dSColin LeMahieu   case Hexagon::V4_SA1_setin1:
894be8c453dSColin LeMahieu     // Rd 3-0
895be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
896be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
897be8c453dSColin LeMahieu     MI->addOperand(Op);
898be8c453dSColin LeMahieu     break;
899be8c453dSColin LeMahieu   case Hexagon::V4_SA1_cmpeqi:
900be8c453dSColin LeMahieu     // Rs 7-4, u 1-0
901be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
902be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
903be8c453dSColin LeMahieu     MI->addOperand(Op);
904be8c453dSColin LeMahieu     operand = inst & 0x3;
905be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
906be8c453dSColin LeMahieu     MI->addOperand(Op);
907be8c453dSColin LeMahieu     break;
908be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine0i:
909be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine1i:
910be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine2i:
911be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine3i:
912be8c453dSColin LeMahieu     // Rdd 2-0, u 6-5
913be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
914be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
915be8c453dSColin LeMahieu     MI->addOperand(Op);
916be8c453dSColin LeMahieu     operand = (inst & 0x060) >> 5;
917be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
918be8c453dSColin LeMahieu     MI->addOperand(Op);
919be8c453dSColin LeMahieu     break;
920be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinerz:
921be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinezr:
922be8c453dSColin LeMahieu     // Rdd 2-0, Rs 7-4
923be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
924be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
925be8c453dSColin LeMahieu     MI->addOperand(Op);
926be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
927be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
928be8c453dSColin LeMahieu     MI->addOperand(Op);
929be8c453dSColin LeMahieu     break;
930be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storeb_io:
931be8c453dSColin LeMahieu     // Rs 7-4, u 11-8, Rt 3-0
932be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
933be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
934be8c453dSColin LeMahieu     MI->addOperand(Op);
935be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
936be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
937be8c453dSColin LeMahieu     MI->addOperand(Op);
938be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
939be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
940be8c453dSColin LeMahieu     MI->addOperand(Op);
941be8c453dSColin LeMahieu     break;
942be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storew_io:
943be8c453dSColin LeMahieu     // Rs 7-4, u 11-8{4_2}, Rt 3-0
944be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
945be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
946be8c453dSColin LeMahieu     MI->addOperand(Op);
947be8c453dSColin LeMahieu     operand = ((inst & 0xf00) >> 8) << 2;
948be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
949be8c453dSColin LeMahieu     MI->addOperand(Op);
950be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
951be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
952be8c453dSColin LeMahieu     MI->addOperand(Op);
953be8c453dSColin LeMahieu     break;
954be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi0:
955be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi1:
956be8c453dSColin LeMahieu     // Rs 7-4, u 3-0
957be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
958be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
959be8c453dSColin LeMahieu     MI->addOperand(Op);
960be8c453dSColin LeMahieu     operand = inst & 0xf;
961be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
962be8c453dSColin LeMahieu     MI->addOperand(Op);
963be8c453dSColin LeMahieu     break;
964be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi0:
965be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi1:
966be8c453dSColin LeMahieu     // Rs 7-4, u 3-0{4_2}
967be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
968be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
969be8c453dSColin LeMahieu     MI->addOperand(Op);
970be8c453dSColin LeMahieu     operand = (inst & 0xf) << 2;
971be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
972be8c453dSColin LeMahieu     MI->addOperand(Op);
973be8c453dSColin LeMahieu     break;
974be8c453dSColin LeMahieu   case Hexagon::V4_SS2_stored_sp:
975be8c453dSColin LeMahieu     // s 8-3{6_3}, Rtt 2-0
976be8c453dSColin LeMahieu     operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
977be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
978be8c453dSColin LeMahieu     MI->addOperand(Op);
979be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
980be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
981be8c453dSColin LeMahieu     MI->addOperand(Op);
982be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storeh_io:
983be8c453dSColin LeMahieu     // Rs 7-4, u 10-8{3_1}, Rt 3-0
984be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
985be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
986be8c453dSColin LeMahieu     MI->addOperand(Op);
987be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
988be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
989be8c453dSColin LeMahieu     MI->addOperand(Op);
990be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
991be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
992be8c453dSColin LeMahieu     MI->addOperand(Op);
993be8c453dSColin LeMahieu     break;
994be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storew_sp:
995be8c453dSColin LeMahieu     // u 8-4{5_2}, Rd 3-0
996be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
997be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
998be8c453dSColin LeMahieu     MI->addOperand(Op);
999be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1000be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1001be8c453dSColin LeMahieu     MI->addOperand(Op);
1002be8c453dSColin LeMahieu     break;
1003be8c453dSColin LeMahieu   default:
1004be8c453dSColin LeMahieu     // don't crash with an invalid subinstruction
1005be8c453dSColin LeMahieu     // llvm_unreachable("Invalid subinstruction in duplex instruction");
1006be8c453dSColin LeMahieu     break;
1007be8c453dSColin LeMahieu   }
1008be8c453dSColin LeMahieu }
1009