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,
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 
72*1e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
73*1e9d1d76SColin LeMahieu                                   const void *Decoder);
74*1e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
75*1e9d1d76SColin LeMahieu                                   const void *Decoder);
76*1e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
77*1e9d1d76SColin LeMahieu                                     const void *Decoder);
78*1e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
79*1e9d1d76SColin LeMahieu                                     const void *Decoder);
80*1e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
81*1e9d1d76SColin LeMahieu                                     const void *Decoder);
82*1e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
83*1e9d1d76SColin LeMahieu                                     const void *Decoder);
84*1e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
85*1e9d1d76SColin LeMahieu                                   const void *Decoder);
86*1e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
87*1e9d1d76SColin LeMahieu                                  const void *Decoder);
88*1e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
89*1e9d1d76SColin LeMahieu                                    const void *Decoder);
90*1e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
91*1e9d1d76SColin LeMahieu                                    const void *Decoder);
92*1e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
93*1e9d1d76SColin LeMahieu                                    const void *Decoder);
94*1e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
95*1e9d1d76SColin LeMahieu                                    const void *Decoder);
96*1e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
97*1e9d1d76SColin LeMahieu                                    const void *Decoder);
98*1e9d1d76SColin 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;
23868d967d9SColin LeMahieu   MI.setOpcode(Hexagon::BUNDLE);
23968d967d9SColin LeMahieu   MI.addOperand(MCOperand::createImm(0));
240be8c453dSColin LeMahieu   while (Result == Success && Complete == false) {
24168d967d9SColin LeMahieu     if (Bytes.size() < HEXAGON_INSTR_SIZE)
24268d967d9SColin LeMahieu       return MCDisassembler::Fail;
24368d967d9SColin LeMahieu     MCInst *Inst = new (getContext()) MCInst;
24468d967d9SColin LeMahieu     Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
24568d967d9SColin LeMahieu     MI.addOperand(MCOperand::createInst(Inst));
24668d967d9SColin LeMahieu     Size += HEXAGON_INSTR_SIZE;
24768d967d9SColin LeMahieu     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
24868d967d9SColin LeMahieu   }
24968d967d9SColin LeMahieu   return Result;
25068d967d9SColin LeMahieu }
25168d967d9SColin LeMahieu 
25268d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction(
25368d967d9SColin LeMahieu     MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
25468d967d9SColin LeMahieu     raw_ostream &os, raw_ostream &cs, bool &Complete) const {
25568d967d9SColin LeMahieu   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
25668d967d9SColin LeMahieu 
25768d967d9SColin LeMahieu   uint32_t Instruction =
25888ebb9e2SColin LeMahieu       llvm::support::endian::read<uint32_t, llvm::support::little,
25988ebb9e2SColin LeMahieu                                   llvm::support::unaligned>(Bytes.data());
26088ebb9e2SColin LeMahieu 
26168d967d9SColin LeMahieu   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
26268d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
26368d967d9SColin LeMahieu       HexagonII::INST_PARSE_LOOP_END) {
26468d967d9SColin LeMahieu     if (BundleSize == 0)
26568d967d9SColin LeMahieu       HexagonMCInstrInfo::setInnerLoop(MCB);
26668d967d9SColin LeMahieu     else if (BundleSize == 1)
26768d967d9SColin LeMahieu       HexagonMCInstrInfo::setOuterLoop(MCB);
26868d967d9SColin LeMahieu     else
26968d967d9SColin LeMahieu       return DecodeStatus::Fail;
27068d967d9SColin LeMahieu   }
27168d967d9SColin LeMahieu 
27268d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
27368d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
274be8c453dSColin LeMahieu       HexagonII::INST_PARSE_DUPLEX) {
275be8c453dSColin LeMahieu     // Determine the instruction class of each instruction in the duplex.
276be8c453dSColin LeMahieu     unsigned duplexIClass, IClassLow, IClassHigh;
277be8c453dSColin LeMahieu 
278be8c453dSColin LeMahieu     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
279be8c453dSColin LeMahieu     switch (duplexIClass) {
280be8c453dSColin LeMahieu     default:
281be8c453dSColin LeMahieu       return MCDisassembler::Fail;
282be8c453dSColin LeMahieu     case 0:
283be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
284be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
285be8c453dSColin LeMahieu       break;
286be8c453dSColin LeMahieu     case 1:
287be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
288be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
289be8c453dSColin LeMahieu       break;
290be8c453dSColin LeMahieu     case 2:
291be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
292be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
293be8c453dSColin LeMahieu       break;
294be8c453dSColin LeMahieu     case 3:
295be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_A;
296be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
297be8c453dSColin LeMahieu       break;
298be8c453dSColin LeMahieu     case 4:
299be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
300be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
301be8c453dSColin LeMahieu       break;
302be8c453dSColin LeMahieu     case 5:
303be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
304be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
305be8c453dSColin LeMahieu       break;
306be8c453dSColin LeMahieu     case 6:
307be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
308be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
309be8c453dSColin LeMahieu       break;
310be8c453dSColin LeMahieu     case 7:
311be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
312be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
313be8c453dSColin LeMahieu       break;
314be8c453dSColin LeMahieu     case 8:
315be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
316be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
317be8c453dSColin LeMahieu       break;
318be8c453dSColin LeMahieu     case 9:
319be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
320be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
321be8c453dSColin LeMahieu       break;
322be8c453dSColin LeMahieu     case 10:
323be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
324be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
325be8c453dSColin LeMahieu       break;
326be8c453dSColin LeMahieu     case 11:
327be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
328be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
329be8c453dSColin LeMahieu       break;
330be8c453dSColin LeMahieu     case 12:
331be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
332be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
333be8c453dSColin LeMahieu       break;
334be8c453dSColin LeMahieu     case 13:
335be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
336be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
337be8c453dSColin LeMahieu       break;
338be8c453dSColin LeMahieu     case 14:
339be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
340be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S2;
341be8c453dSColin LeMahieu       break;
342be8c453dSColin LeMahieu     }
343be8c453dSColin LeMahieu 
344be8c453dSColin LeMahieu     // Set the MCInst to be a duplex instruction. Which one doesn't matter.
345be8c453dSColin LeMahieu     MI.setOpcode(Hexagon::DuplexIClass0);
346be8c453dSColin LeMahieu 
347be8c453dSColin LeMahieu     // Decode each instruction in the duplex.
348be8c453dSColin LeMahieu     // Create an MCInst for each instruction.
349be8c453dSColin LeMahieu     unsigned instLow = Instruction & 0x1fff;
350be8c453dSColin LeMahieu     unsigned instHigh = (Instruction >> 16) & 0x1fff;
351be8c453dSColin LeMahieu     unsigned opLow;
352be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
353be8c453dSColin LeMahieu         MCDisassembler::Success)
354be8c453dSColin LeMahieu       return MCDisassembler::Fail;
355be8c453dSColin LeMahieu     unsigned opHigh;
356be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
357be8c453dSColin LeMahieu         MCDisassembler::Success)
358be8c453dSColin LeMahieu       return MCDisassembler::Fail;
359be8c453dSColin LeMahieu     MCInst *MILow = new (getContext()) MCInst;
360be8c453dSColin LeMahieu     MILow->setOpcode(opLow);
361be8c453dSColin LeMahieu     MCInst *MIHigh = new (getContext()) MCInst;
362be8c453dSColin LeMahieu     MIHigh->setOpcode(opHigh);
363be8c453dSColin LeMahieu     AddSubinstOperands(MILow, opLow, instLow);
364be8c453dSColin LeMahieu     AddSubinstOperands(MIHigh, opHigh, instHigh);
365be8c453dSColin LeMahieu     // see ConvertToSubInst() in
366be8c453dSColin LeMahieu     // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
367be8c453dSColin LeMahieu 
368be8c453dSColin LeMahieu     // Add the duplex instruction MCInsts as operands to the passed in MCInst.
369be8c453dSColin LeMahieu     MCOperand OPLow = MCOperand::createInst(MILow);
370be8c453dSColin LeMahieu     MCOperand OPHigh = MCOperand::createInst(MIHigh);
371be8c453dSColin LeMahieu     MI.addOperand(OPLow);
372be8c453dSColin LeMahieu     MI.addOperand(OPHigh);
373be8c453dSColin LeMahieu     Complete = true;
374be8c453dSColin LeMahieu   } else {
375be8c453dSColin LeMahieu     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
37668d967d9SColin LeMahieu         HexagonII::INST_PARSE_PACKET_END)
37768d967d9SColin LeMahieu       Complete = true;
37868d967d9SColin LeMahieu     // Calling the auto-generated decoder function.
37968d967d9SColin LeMahieu     Result =
38068d967d9SColin LeMahieu         decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
381be8c453dSColin LeMahieu   }
38268d967d9SColin LeMahieu 
3835d6f03bdSColin LeMahieu   return Result;
38488ebb9e2SColin LeMahieu }
385be8c453dSColin LeMahieu 
386*1e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
387*1e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
388*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<16>(tmp);
389*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
390*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
391*1e9d1d76SColin LeMahieu }
392*1e9d1d76SColin LeMahieu 
393*1e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
394*1e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
395*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
396*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
397*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
398*1e9d1d76SColin LeMahieu }
399*1e9d1d76SColin LeMahieu 
400*1e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
401*1e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
402*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<11>(tmp);
403*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
404*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
405*1e9d1d76SColin LeMahieu }
406*1e9d1d76SColin LeMahieu 
407*1e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
408*1e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
409*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<12>(tmp);
410*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
411*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
412*1e9d1d76SColin LeMahieu }
413*1e9d1d76SColin LeMahieu 
414*1e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
415*1e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
416*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<13>(tmp);
417*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
418*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
419*1e9d1d76SColin LeMahieu }
420*1e9d1d76SColin LeMahieu 
421*1e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
422*1e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
423*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<14>(tmp);
424*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
425*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
426*1e9d1d76SColin LeMahieu }
427*1e9d1d76SColin LeMahieu 
428*1e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
429*1e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
430*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<10>(tmp);
431*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
432*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
433*1e9d1d76SColin LeMahieu }
434*1e9d1d76SColin LeMahieu 
435*1e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/,
436*1e9d1d76SColin LeMahieu                                  const void *Decoder) {
437*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<8>(tmp);
438*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
439*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
440*1e9d1d76SColin LeMahieu }
441*1e9d1d76SColin LeMahieu 
442*1e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
443*1e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
444*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
445*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
446*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
447*1e9d1d76SColin LeMahieu }
448*1e9d1d76SColin LeMahieu 
449*1e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
450*1e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
451*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<4>(tmp);
452*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
453*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
454*1e9d1d76SColin LeMahieu }
455*1e9d1d76SColin LeMahieu 
456*1e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
457*1e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
458*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<5>(tmp);
459*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
460*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
461*1e9d1d76SColin LeMahieu }
462*1e9d1d76SColin LeMahieu 
463*1e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
464*1e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
465*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<6>(tmp);
466*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
467*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
468*1e9d1d76SColin LeMahieu }
469*1e9d1d76SColin LeMahieu 
470*1e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
471*1e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
472*1e9d1d76SColin LeMahieu   uint64_t imm = SignExtend64<7>(tmp);
473*1e9d1d76SColin LeMahieu   MI.addOperand(MCOperand::createImm(imm));
474*1e9d1d76SColin LeMahieu   return MCDisassembler::Success;
475*1e9d1d76SColin LeMahieu }
476*1e9d1d76SColin LeMahieu 
477be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
478be8c453dSColin LeMahieu enum subInstBinaryValues {
479be8c453dSColin LeMahieu   V4_SA1_addi_BITS = 0x0000,
480be8c453dSColin LeMahieu   V4_SA1_addi_MASK = 0x1800,
481be8c453dSColin LeMahieu   V4_SA1_addrx_BITS = 0x1800,
482be8c453dSColin LeMahieu   V4_SA1_addrx_MASK = 0x1f00,
483be8c453dSColin LeMahieu   V4_SA1_addsp_BITS = 0x0c00,
484be8c453dSColin LeMahieu   V4_SA1_addsp_MASK = 0x1c00,
485be8c453dSColin LeMahieu   V4_SA1_and1_BITS = 0x1200,
486be8c453dSColin LeMahieu   V4_SA1_and1_MASK = 0x1f00,
487be8c453dSColin LeMahieu   V4_SA1_clrf_BITS = 0x1a70,
488be8c453dSColin LeMahieu   V4_SA1_clrf_MASK = 0x1e70,
489be8c453dSColin LeMahieu   V4_SA1_clrfnew_BITS = 0x1a50,
490be8c453dSColin LeMahieu   V4_SA1_clrfnew_MASK = 0x1e70,
491be8c453dSColin LeMahieu   V4_SA1_clrt_BITS = 0x1a60,
492be8c453dSColin LeMahieu   V4_SA1_clrt_MASK = 0x1e70,
493be8c453dSColin LeMahieu   V4_SA1_clrtnew_BITS = 0x1a40,
494be8c453dSColin LeMahieu   V4_SA1_clrtnew_MASK = 0x1e70,
495be8c453dSColin LeMahieu   V4_SA1_cmpeqi_BITS = 0x1900,
496be8c453dSColin LeMahieu   V4_SA1_cmpeqi_MASK = 0x1f00,
497be8c453dSColin LeMahieu   V4_SA1_combine0i_BITS = 0x1c00,
498be8c453dSColin LeMahieu   V4_SA1_combine0i_MASK = 0x1d18,
499be8c453dSColin LeMahieu   V4_SA1_combine1i_BITS = 0x1c08,
500be8c453dSColin LeMahieu   V4_SA1_combine1i_MASK = 0x1d18,
501be8c453dSColin LeMahieu   V4_SA1_combine2i_BITS = 0x1c10,
502be8c453dSColin LeMahieu   V4_SA1_combine2i_MASK = 0x1d18,
503be8c453dSColin LeMahieu   V4_SA1_combine3i_BITS = 0x1c18,
504be8c453dSColin LeMahieu   V4_SA1_combine3i_MASK = 0x1d18,
505be8c453dSColin LeMahieu   V4_SA1_combinerz_BITS = 0x1d08,
506be8c453dSColin LeMahieu   V4_SA1_combinerz_MASK = 0x1d08,
507be8c453dSColin LeMahieu   V4_SA1_combinezr_BITS = 0x1d00,
508be8c453dSColin LeMahieu   V4_SA1_combinezr_MASK = 0x1d08,
509be8c453dSColin LeMahieu   V4_SA1_dec_BITS = 0x1300,
510be8c453dSColin LeMahieu   V4_SA1_dec_MASK = 0x1f00,
511be8c453dSColin LeMahieu   V4_SA1_inc_BITS = 0x1100,
512be8c453dSColin LeMahieu   V4_SA1_inc_MASK = 0x1f00,
513be8c453dSColin LeMahieu   V4_SA1_seti_BITS = 0x0800,
514be8c453dSColin LeMahieu   V4_SA1_seti_MASK = 0x1c00,
515be8c453dSColin LeMahieu   V4_SA1_setin1_BITS = 0x1a00,
516be8c453dSColin LeMahieu   V4_SA1_setin1_MASK = 0x1e40,
517be8c453dSColin LeMahieu   V4_SA1_sxtb_BITS = 0x1500,
518be8c453dSColin LeMahieu   V4_SA1_sxtb_MASK = 0x1f00,
519be8c453dSColin LeMahieu   V4_SA1_sxth_BITS = 0x1400,
520be8c453dSColin LeMahieu   V4_SA1_sxth_MASK = 0x1f00,
521be8c453dSColin LeMahieu   V4_SA1_tfr_BITS = 0x1000,
522be8c453dSColin LeMahieu   V4_SA1_tfr_MASK = 0x1f00,
523be8c453dSColin LeMahieu   V4_SA1_zxtb_BITS = 0x1700,
524be8c453dSColin LeMahieu   V4_SA1_zxtb_MASK = 0x1f00,
525be8c453dSColin LeMahieu   V4_SA1_zxth_BITS = 0x1600,
526be8c453dSColin LeMahieu   V4_SA1_zxth_MASK = 0x1f00,
527be8c453dSColin LeMahieu   V4_SL1_loadri_io_BITS = 0x0000,
528be8c453dSColin LeMahieu   V4_SL1_loadri_io_MASK = 0x1000,
529be8c453dSColin LeMahieu   V4_SL1_loadrub_io_BITS = 0x1000,
530be8c453dSColin LeMahieu   V4_SL1_loadrub_io_MASK = 0x1000,
531be8c453dSColin LeMahieu   V4_SL2_deallocframe_BITS = 0x1f00,
532be8c453dSColin LeMahieu   V4_SL2_deallocframe_MASK = 0x1fc0,
533be8c453dSColin LeMahieu   V4_SL2_jumpr31_BITS = 0x1fc0,
534be8c453dSColin LeMahieu   V4_SL2_jumpr31_MASK = 0x1fc4,
535be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_BITS = 0x1fc5,
536be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_MASK = 0x1fc7,
537be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
538be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
539be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_BITS = 0x1fc4,
540be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_MASK = 0x1fc7,
541be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
542be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
543be8c453dSColin LeMahieu   V4_SL2_loadrb_io_BITS = 0x1000,
544be8c453dSColin LeMahieu   V4_SL2_loadrb_io_MASK = 0x1800,
545be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_BITS = 0x1e00,
546be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_MASK = 0x1f00,
547be8c453dSColin LeMahieu   V4_SL2_loadrh_io_BITS = 0x0000,
548be8c453dSColin LeMahieu   V4_SL2_loadrh_io_MASK = 0x1800,
549be8c453dSColin LeMahieu   V4_SL2_loadri_sp_BITS = 0x1c00,
550be8c453dSColin LeMahieu   V4_SL2_loadri_sp_MASK = 0x1e00,
551be8c453dSColin LeMahieu   V4_SL2_loadruh_io_BITS = 0x0800,
552be8c453dSColin LeMahieu   V4_SL2_loadruh_io_MASK = 0x1800,
553be8c453dSColin LeMahieu   V4_SL2_return_BITS = 0x1f40,
554be8c453dSColin LeMahieu   V4_SL2_return_MASK = 0x1fc4,
555be8c453dSColin LeMahieu   V4_SL2_return_f_BITS = 0x1f45,
556be8c453dSColin LeMahieu   V4_SL2_return_f_MASK = 0x1fc7,
557be8c453dSColin LeMahieu   V4_SL2_return_fnew_BITS = 0x1f47,
558be8c453dSColin LeMahieu   V4_SL2_return_fnew_MASK = 0x1fc7,
559be8c453dSColin LeMahieu   V4_SL2_return_t_BITS = 0x1f44,
560be8c453dSColin LeMahieu   V4_SL2_return_t_MASK = 0x1fc7,
561be8c453dSColin LeMahieu   V4_SL2_return_tnew_BITS = 0x1f46,
562be8c453dSColin LeMahieu   V4_SL2_return_tnew_MASK = 0x1fc7,
563be8c453dSColin LeMahieu   V4_SS1_storeb_io_BITS = 0x1000,
564be8c453dSColin LeMahieu   V4_SS1_storeb_io_MASK = 0x1000,
565be8c453dSColin LeMahieu   V4_SS1_storew_io_BITS = 0x0000,
566be8c453dSColin LeMahieu   V4_SS1_storew_io_MASK = 0x1000,
567be8c453dSColin LeMahieu   V4_SS2_allocframe_BITS = 0x1c00,
568be8c453dSColin LeMahieu   V4_SS2_allocframe_MASK = 0x1e00,
569be8c453dSColin LeMahieu   V4_SS2_storebi0_BITS = 0x1200,
570be8c453dSColin LeMahieu   V4_SS2_storebi0_MASK = 0x1f00,
571be8c453dSColin LeMahieu   V4_SS2_storebi1_BITS = 0x1300,
572be8c453dSColin LeMahieu   V4_SS2_storebi1_MASK = 0x1f00,
573be8c453dSColin LeMahieu   V4_SS2_stored_sp_BITS = 0x0a00,
574be8c453dSColin LeMahieu   V4_SS2_stored_sp_MASK = 0x1e00,
575be8c453dSColin LeMahieu   V4_SS2_storeh_io_BITS = 0x0000,
576be8c453dSColin LeMahieu   V4_SS2_storeh_io_MASK = 0x1800,
577be8c453dSColin LeMahieu   V4_SS2_storew_sp_BITS = 0x0800,
578be8c453dSColin LeMahieu   V4_SS2_storew_sp_MASK = 0x1e00,
579be8c453dSColin LeMahieu   V4_SS2_storewi0_BITS = 0x1000,
580be8c453dSColin LeMahieu   V4_SS2_storewi0_MASK = 0x1f00,
581be8c453dSColin LeMahieu   V4_SS2_storewi1_BITS = 0x1100,
582be8c453dSColin LeMahieu   V4_SS2_storewi1_MASK = 0x1f00
583be8c453dSColin LeMahieu };
584be8c453dSColin LeMahieu 
585be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
586be8c453dSColin LeMahieu                                  raw_ostream &os) {
587be8c453dSColin LeMahieu   switch (IClass) {
588be8c453dSColin LeMahieu   case HexagonII::HSIG_L1:
589be8c453dSColin LeMahieu     if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
590be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadri_io;
591be8c453dSColin LeMahieu     else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
592be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadrub_io;
593be8c453dSColin LeMahieu     else {
594be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
595be8c453dSColin LeMahieu       return MCDisassembler::Fail;
596be8c453dSColin LeMahieu     }
597be8c453dSColin LeMahieu     break;
598be8c453dSColin LeMahieu   case HexagonII::HSIG_L2:
599be8c453dSColin LeMahieu     if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
600be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_deallocframe;
601be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
602be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31;
603be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
604be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_f;
605be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
606be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_fnew;
607be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
608be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_t;
609be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
610be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_tnew;
611be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
612be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrb_io;
613be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
614be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrd_sp;
615be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
616be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrh_io;
617be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
618be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadri_sp;
619be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
620be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadruh_io;
621be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
622be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return;
623be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
624be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_f;
625be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
626be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_fnew;
627be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
628be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_t;
629be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
630be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_tnew;
631be8c453dSColin LeMahieu     else {
632be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
633be8c453dSColin LeMahieu       return MCDisassembler::Fail;
634be8c453dSColin LeMahieu     }
635be8c453dSColin LeMahieu     break;
636be8c453dSColin LeMahieu   case HexagonII::HSIG_A:
637be8c453dSColin LeMahieu     if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
638be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addi;
639be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
640be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addrx;
641be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
642be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addsp;
643be8c453dSColin LeMahieu     else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
644be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_and1;
645be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
646be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrf;
647be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
648be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrfnew;
649be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
650be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrt;
651be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
652be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrtnew;
653be8c453dSColin LeMahieu     else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
654be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_cmpeqi;
655be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
656be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine0i;
657be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
658be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine1i;
659be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
660be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine2i;
661be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
662be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine3i;
663be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
664be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinerz;
665be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
666be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinezr;
667be8c453dSColin LeMahieu     else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
668be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_dec;
669be8c453dSColin LeMahieu     else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
670be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_inc;
671be8c453dSColin LeMahieu     else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
672be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_seti;
673be8c453dSColin LeMahieu     else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
674be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_setin1;
675be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
676be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxtb;
677be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
678be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxth;
679be8c453dSColin LeMahieu     else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
680be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_tfr;
681be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
682be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxtb;
683be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
684be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxth;
685be8c453dSColin LeMahieu     else {
686be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
687be8c453dSColin LeMahieu       return MCDisassembler::Fail;
688be8c453dSColin LeMahieu     }
689be8c453dSColin LeMahieu     break;
690be8c453dSColin LeMahieu   case HexagonII::HSIG_S1:
691be8c453dSColin LeMahieu     if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
692be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storeb_io;
693be8c453dSColin LeMahieu     else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
694be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storew_io;
695be8c453dSColin LeMahieu     else {
696be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
697be8c453dSColin LeMahieu       return MCDisassembler::Fail;
698be8c453dSColin LeMahieu     }
699be8c453dSColin LeMahieu     break;
700be8c453dSColin LeMahieu   case HexagonII::HSIG_S2:
701be8c453dSColin LeMahieu     if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
702be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_allocframe;
703be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
704be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi0;
705be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
706be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi1;
707be8c453dSColin LeMahieu     else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
708be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_stored_sp;
709be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
710be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storeh_io;
711be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
712be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storew_sp;
713be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
714be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi0;
715be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
716be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi1;
717be8c453dSColin LeMahieu     else {
718be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
719be8c453dSColin LeMahieu       return MCDisassembler::Fail;
720be8c453dSColin LeMahieu     }
721be8c453dSColin LeMahieu     break;
722be8c453dSColin LeMahieu   default:
723be8c453dSColin LeMahieu     os << "<unknown>";
724be8c453dSColin LeMahieu     return MCDisassembler::Fail;
725be8c453dSColin LeMahieu   }
726be8c453dSColin LeMahieu   return MCDisassembler::Success;
727be8c453dSColin LeMahieu }
728be8c453dSColin LeMahieu 
729be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
730be8c453dSColin LeMahieu   if (encoded_reg < 8)
731be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg;
732be8c453dSColin LeMahieu   else if (encoded_reg < 16)
733be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg + 8;
734be8c453dSColin LeMahieu   return Hexagon::NoRegister;
735be8c453dSColin LeMahieu }
736be8c453dSColin LeMahieu 
737be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
738be8c453dSColin LeMahieu   if (encoded_dreg < 4)
739be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg;
740be8c453dSColin LeMahieu   else if (encoded_dreg < 8)
741be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg + 4;
742be8c453dSColin LeMahieu   return Hexagon::NoRegister;
743be8c453dSColin LeMahieu }
744be8c453dSColin LeMahieu 
745be8c453dSColin LeMahieu static void AddSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) {
746be8c453dSColin LeMahieu   int64_t operand;
747be8c453dSColin LeMahieu   MCOperand Op;
748be8c453dSColin LeMahieu   switch (opcode) {
749be8c453dSColin LeMahieu   case Hexagon::V4_SL2_deallocframe:
750be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31:
751be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_f:
752be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_fnew:
753be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_t:
754be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_tnew:
755be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return:
756be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_f:
757be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_fnew:
758be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_t:
759be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_tnew:
760be8c453dSColin LeMahieu     // no operands for these instructions
761be8c453dSColin LeMahieu     break;
762be8c453dSColin LeMahieu   case Hexagon::V4_SS2_allocframe:
763be8c453dSColin LeMahieu     // u 8-4{5_3}
764be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 3;
765be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
766be8c453dSColin LeMahieu     MI->addOperand(Op);
767be8c453dSColin LeMahieu     break;
768be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadri_io:
769be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8{4_2}
770be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
771be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
772be8c453dSColin LeMahieu     MI->addOperand(Op);
773be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
774be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
775be8c453dSColin LeMahieu     MI->addOperand(Op);
776be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 6;
777be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
778be8c453dSColin LeMahieu     MI->addOperand(Op);
779be8c453dSColin LeMahieu     break;
780be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadrub_io:
781be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8
782be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
783be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
784be8c453dSColin LeMahieu     MI->addOperand(Op);
785be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
786be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
787be8c453dSColin LeMahieu     MI->addOperand(Op);
788be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
789be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
790be8c453dSColin LeMahieu     MI->addOperand(Op);
791be8c453dSColin LeMahieu     break;
792be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrb_io:
793be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8
794be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
795be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
796be8c453dSColin LeMahieu     MI->addOperand(Op);
797be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
798be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
799be8c453dSColin LeMahieu     MI->addOperand(Op);
800be8c453dSColin LeMahieu     operand = (inst & 0x700) >> 8;
801be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
802be8c453dSColin LeMahieu     MI->addOperand(Op);
803be8c453dSColin LeMahieu     break;
804be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrh_io:
805be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadruh_io:
806be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8{3_1}
807be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
808be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
809be8c453dSColin LeMahieu     MI->addOperand(Op);
810be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
811be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
812be8c453dSColin LeMahieu     MI->addOperand(Op);
813be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
814be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
815be8c453dSColin LeMahieu     MI->addOperand(Op);
816be8c453dSColin LeMahieu     break;
817be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrd_sp:
818be8c453dSColin LeMahieu     // Rdd 2-0, u 7-3{5_3}
819be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
820be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
821be8c453dSColin LeMahieu     MI->addOperand(Op);
822be8c453dSColin LeMahieu     operand = ((inst & 0x0f8) >> 3) << 3;
823be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
824be8c453dSColin LeMahieu     MI->addOperand(Op);
825be8c453dSColin LeMahieu     break;
826be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadri_sp:
827be8c453dSColin LeMahieu     // Rd 3-0, u 8-4{5_2}
828be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
829be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
830be8c453dSColin LeMahieu     MI->addOperand(Op);
831be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
832be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
833be8c453dSColin LeMahieu     MI->addOperand(Op);
834be8c453dSColin LeMahieu     break;
835be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addi:
836be8c453dSColin LeMahieu     // Rx 3-0 (x2), s7 10-4
837be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
838be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
839be8c453dSColin LeMahieu     MI->addOperand(Op);
840be8c453dSColin LeMahieu     MI->addOperand(Op);
841be8c453dSColin LeMahieu     operand = SignExtend64<7>((inst & 0x7f0) >> 4);
842be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
843be8c453dSColin LeMahieu     MI->addOperand(Op);
844be8c453dSColin LeMahieu     break;
845be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addrx:
846be8c453dSColin LeMahieu     // Rx 3-0 (x2), Rs 7-4
847be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
848be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
849be8c453dSColin LeMahieu     MI->addOperand(Op);
850be8c453dSColin LeMahieu     MI->addOperand(Op);
851be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
852be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
853be8c453dSColin LeMahieu     MI->addOperand(Op);
854be8c453dSColin LeMahieu   case Hexagon::V4_SA1_and1:
855be8c453dSColin LeMahieu   case Hexagon::V4_SA1_dec:
856be8c453dSColin LeMahieu   case Hexagon::V4_SA1_inc:
857be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxtb:
858be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxth:
859be8c453dSColin LeMahieu   case Hexagon::V4_SA1_tfr:
860be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxtb:
861be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxth:
862be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4
863be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
864be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
865be8c453dSColin LeMahieu     MI->addOperand(Op);
866be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
867be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
868be8c453dSColin LeMahieu     MI->addOperand(Op);
869be8c453dSColin LeMahieu     break;
870be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addsp:
871be8c453dSColin LeMahieu     // Rd 3-0, u 9-4{6_2}
872be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
873be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
874be8c453dSColin LeMahieu     MI->addOperand(Op);
875be8c453dSColin LeMahieu     operand = ((inst & 0x3f0) >> 4) << 2;
876be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
877be8c453dSColin LeMahieu     MI->addOperand(Op);
878be8c453dSColin LeMahieu     break;
879be8c453dSColin LeMahieu   case Hexagon::V4_SA1_seti:
880be8c453dSColin LeMahieu     // Rd 3-0, u 9-4
881be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
882be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
883be8c453dSColin LeMahieu     MI->addOperand(Op);
884be8c453dSColin LeMahieu     operand = (inst & 0x3f0) >> 4;
885be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
886be8c453dSColin LeMahieu     MI->addOperand(Op);
887be8c453dSColin LeMahieu     break;
888be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrf:
889be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrfnew:
890be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrt:
891be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrtnew:
892be8c453dSColin LeMahieu   case Hexagon::V4_SA1_setin1:
893be8c453dSColin LeMahieu     // Rd 3-0
894be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
895be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
896be8c453dSColin LeMahieu     MI->addOperand(Op);
897be8c453dSColin LeMahieu     break;
898be8c453dSColin LeMahieu   case Hexagon::V4_SA1_cmpeqi:
899be8c453dSColin LeMahieu     // Rs 7-4, u 1-0
900be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
901be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
902be8c453dSColin LeMahieu     MI->addOperand(Op);
903be8c453dSColin LeMahieu     operand = inst & 0x3;
904be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
905be8c453dSColin LeMahieu     MI->addOperand(Op);
906be8c453dSColin LeMahieu     break;
907be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine0i:
908be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine1i:
909be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine2i:
910be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine3i:
911be8c453dSColin LeMahieu     // Rdd 2-0, u 6-5
912be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
913be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
914be8c453dSColin LeMahieu     MI->addOperand(Op);
915be8c453dSColin LeMahieu     operand = (inst & 0x060) >> 5;
916be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
917be8c453dSColin LeMahieu     MI->addOperand(Op);
918be8c453dSColin LeMahieu     break;
919be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinerz:
920be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinezr:
921be8c453dSColin LeMahieu     // Rdd 2-0, Rs 7-4
922be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
923be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
924be8c453dSColin LeMahieu     MI->addOperand(Op);
925be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
926be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
927be8c453dSColin LeMahieu     MI->addOperand(Op);
928be8c453dSColin LeMahieu     break;
929be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storeb_io:
930be8c453dSColin LeMahieu     // Rs 7-4, u 11-8, Rt 3-0
931be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
932be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
933be8c453dSColin LeMahieu     MI->addOperand(Op);
934be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
935be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
936be8c453dSColin LeMahieu     MI->addOperand(Op);
937be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
938be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
939be8c453dSColin LeMahieu     MI->addOperand(Op);
940be8c453dSColin LeMahieu     break;
941be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storew_io:
942be8c453dSColin LeMahieu     // Rs 7-4, u 11-8{4_2}, Rt 3-0
943be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
944be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
945be8c453dSColin LeMahieu     MI->addOperand(Op);
946be8c453dSColin LeMahieu     operand = ((inst & 0xf00) >> 8) << 2;
947be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
948be8c453dSColin LeMahieu     MI->addOperand(Op);
949be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
950be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
951be8c453dSColin LeMahieu     MI->addOperand(Op);
952be8c453dSColin LeMahieu     break;
953be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi0:
954be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi1:
955be8c453dSColin LeMahieu     // Rs 7-4, u 3-0
956be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
957be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
958be8c453dSColin LeMahieu     MI->addOperand(Op);
959be8c453dSColin LeMahieu     operand = inst & 0xf;
960be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
961be8c453dSColin LeMahieu     MI->addOperand(Op);
962be8c453dSColin LeMahieu     break;
963be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi0:
964be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi1:
965be8c453dSColin LeMahieu     // Rs 7-4, u 3-0{4_2}
966be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
967be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
968be8c453dSColin LeMahieu     MI->addOperand(Op);
969be8c453dSColin LeMahieu     operand = (inst & 0xf) << 2;
970be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
971be8c453dSColin LeMahieu     MI->addOperand(Op);
972be8c453dSColin LeMahieu     break;
973be8c453dSColin LeMahieu   case Hexagon::V4_SS2_stored_sp:
974be8c453dSColin LeMahieu     // s 8-3{6_3}, Rtt 2-0
975be8c453dSColin LeMahieu     operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
976be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
977be8c453dSColin LeMahieu     MI->addOperand(Op);
978be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
979be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
980be8c453dSColin LeMahieu     MI->addOperand(Op);
981be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storeh_io:
982be8c453dSColin LeMahieu     // Rs 7-4, u 10-8{3_1}, Rt 3-0
983be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
984be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
985be8c453dSColin LeMahieu     MI->addOperand(Op);
986be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
987be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
988be8c453dSColin LeMahieu     MI->addOperand(Op);
989be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
990be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
991be8c453dSColin LeMahieu     MI->addOperand(Op);
992be8c453dSColin LeMahieu     break;
993be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storew_sp:
994be8c453dSColin LeMahieu     // u 8-4{5_2}, Rd 3-0
995be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
996be8c453dSColin LeMahieu     Op = MCOperand::createImm(operand);
997be8c453dSColin LeMahieu     MI->addOperand(Op);
998be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
999be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1000be8c453dSColin LeMahieu     MI->addOperand(Op);
1001be8c453dSColin LeMahieu     break;
1002be8c453dSColin LeMahieu   default:
1003be8c453dSColin LeMahieu     // don't crash with an invalid subinstruction
1004be8c453dSColin LeMahieu     // llvm_unreachable("Invalid subinstruction in duplex instruction");
1005be8c453dSColin LeMahieu     break;
1006be8c453dSColin LeMahieu   }
1007be8c453dSColin LeMahieu }
1008