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 
10*7cd08927SColin LeMahieu #define DEBUG_TYPE "hexagon-disassembler"
11*7cd08927SColin LeMahieu 
1268d967d9SColin LeMahieu #include "Hexagon.h"
1388ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonBaseInfo.h"
14*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCChecker.h"
1588ebb9e2SColin LeMahieu #include "MCTargetDesc/HexagonMCTargetDesc.h"
16*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonMCInstrInfo.h"
17*7cd08927SColin LeMahieu #include "MCTargetDesc/HexagonInstPrinter.h"
18*7cd08927SColin LeMahieu #include "llvm/ADT/StringExtras.h"
1988ebb9e2SColin LeMahieu #include "llvm/MC/MCDisassembler.h"
20*7cd08927SColin LeMahieu #include "llvm/MC/MCContext.h"
2188ebb9e2SColin LeMahieu #include "llvm/MC/MCExpr.h"
2288ebb9e2SColin LeMahieu #include "llvm/MC/MCFixedLenDisassembler.h"
2388ebb9e2SColin LeMahieu #include "llvm/MC/MCInst.h"
2488ebb9e2SColin LeMahieu #include "llvm/MC/MCInstrDesc.h"
25*7cd08927SColin LeMahieu #include "llvm/MC/MCInstrInfo.h"
2688ebb9e2SColin LeMahieu #include "llvm/MC/MCSubtargetInfo.h"
2788ebb9e2SColin LeMahieu #include "llvm/Support/Debug.h"
2888ebb9e2SColin LeMahieu #include "llvm/Support/ErrorHandling.h"
2988ebb9e2SColin LeMahieu #include "llvm/Support/LEB128.h"
30*7cd08927SColin LeMahieu #include "llvm/Support/MemoryObject.h"
31d9903888SChandler Carruth #include "llvm/Support/raw_ostream.h"
32*7cd08927SColin LeMahieu #include "llvm/Support/TargetRegistry.h"
33d9903888SChandler Carruth #include <vector>
3488ebb9e2SColin LeMahieu 
3588ebb9e2SColin LeMahieu using namespace llvm;
3668d967d9SColin LeMahieu using namespace Hexagon;
3788ebb9e2SColin LeMahieu 
38*7cd08927SColin LeMahieu typedef MCDisassembler::DecodeStatus DecodeStatus;
3988ebb9e2SColin LeMahieu 
4088ebb9e2SColin LeMahieu namespace {
4188ebb9e2SColin LeMahieu /// \brief Hexagon disassembler for all Hexagon platforms.
4288ebb9e2SColin LeMahieu class HexagonDisassembler : public MCDisassembler {
4388ebb9e2SColin LeMahieu public:
44*7cd08927SColin LeMahieu   std::unique_ptr<MCInstrInfo const> const MCII;
4568d967d9SColin LeMahieu   std::unique_ptr<MCInst *> CurrentBundle;
46*7cd08927SColin LeMahieu   HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
47*7cd08927SColin LeMahieu                       MCInstrInfo const *MCII)
48*7cd08927SColin LeMahieu       : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *) {}
4988ebb9e2SColin LeMahieu 
5068d967d9SColin LeMahieu   DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
5168d967d9SColin LeMahieu                                     ArrayRef<uint8_t> Bytes, uint64_t Address,
5268d967d9SColin LeMahieu                                     raw_ostream &VStream, raw_ostream &CStream,
5368d967d9SColin LeMahieu                                     bool &Complete) const;
544aa6bea7SRafael Espindola   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
557fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
564aa6bea7SRafael Espindola                               raw_ostream &VStream,
574aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
58*7cd08927SColin LeMahieu 
59*7cd08927SColin LeMahieu   void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const;
60*7cd08927SColin LeMahieu   void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) const;
6188ebb9e2SColin LeMahieu };
62f00654e3SAlexander Kornienko }
6388ebb9e2SColin LeMahieu 
64*7cd08927SColin LeMahieu // Forward declare these because the auto-generated code will reference them.
65*7cd08927SColin LeMahieu // Definitions are further down.
66*7cd08927SColin LeMahieu 
67*7cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
68be8c453dSColin LeMahieu                                                uint64_t Address,
69be8c453dSColin LeMahieu                                                const void *Decoder);
707c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
717c958713SColin LeMahieu                                                    uint64_t Address,
727c958713SColin LeMahieu                                                    const void *Decoder);
737c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
747c958713SColin LeMahieu                                                   uint64_t Address,
757c958713SColin LeMahieu                                                   const void *Decoder);
76*7cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
77*7cd08927SColin LeMahieu                                                   uint64_t Address,
78*7cd08927SColin LeMahieu                                                   const void *Decoder);
797c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
807c958713SColin LeMahieu                                                   uint64_t Address,
817c958713SColin LeMahieu                                                   const void *Decoder);
82*7cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
83*7cd08927SColin LeMahieu                                                 uint64_t Address,
84*7cd08927SColin LeMahieu                                                 const void *Decoder);
857c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
867c958713SColin LeMahieu                                                    uint64_t Address,
877c958713SColin LeMahieu                                                    const void *Decoder);
88f3db884eSColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
89be8c453dSColin LeMahieu                                                uint64_t Address,
90be8c453dSColin LeMahieu                                                const void *Decoder);
91*7cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
92*7cd08927SColin LeMahieu                                                uint64_t Address,
93*7cd08927SColin LeMahieu                                                const void *Decoder);
94404d5b24SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
95be8c453dSColin LeMahieu                                                  uint64_t Address,
96*7cd08927SColin LeMahieu                                                  const void *Decoder);
97*7cd08927SColin LeMahieu 
98*7cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn);
99*7cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
100be8c453dSColin LeMahieu                                  void const *Decoder);
101be8c453dSColin LeMahieu 
102be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
103be8c453dSColin LeMahieu                                  raw_ostream &os);
104f3db884eSColin LeMahieu 
105*7cd08927SColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg);
106*7cd08927SColin LeMahieu 
107*7cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
108*7cd08927SColin LeMahieu                                        uint64_t Address, const void *Decoder);
1091e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1101e9d1d76SColin LeMahieu                                   const void *Decoder);
1111e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1121e9d1d76SColin LeMahieu                                   const void *Decoder);
1131e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1141e9d1d76SColin LeMahieu                                     const void *Decoder);
1151e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1161e9d1d76SColin LeMahieu                                     const void *Decoder);
1171e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1181e9d1d76SColin LeMahieu                                     const void *Decoder);
1191e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1201e9d1d76SColin LeMahieu                                     const void *Decoder);
1211e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1221e9d1d76SColin LeMahieu                                   const void *Decoder);
1231e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1241e9d1d76SColin LeMahieu                                  const void *Decoder);
1251e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1261e9d1d76SColin LeMahieu                                    const void *Decoder);
1271e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1281e9d1d76SColin LeMahieu                                    const void *Decoder);
1291e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1301e9d1d76SColin LeMahieu                                    const void *Decoder);
1311e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1321e9d1d76SColin LeMahieu                                    const void *Decoder);
1331e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1341e9d1d76SColin LeMahieu                                    const void *Decoder);
1357c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1367c958713SColin LeMahieu                                    const void *Decoder);
1377c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
1387c958713SColin LeMahieu                                    const void *Decoder);
139*7cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
140*7cd08927SColin LeMahieu                                     const void *Decoder);
141efa74e02SColin LeMahieu 
14288ebb9e2SColin LeMahieu #include "HexagonGenDisassemblerTables.inc"
14388ebb9e2SColin LeMahieu 
144*7cd08927SColin LeMahieu static MCDisassembler *createHexagonDisassembler(const Target &T,
145*7cd08927SColin LeMahieu                                                  const MCSubtargetInfo &STI,
14688ebb9e2SColin LeMahieu                                                  MCContext &Ctx) {
147*7cd08927SColin LeMahieu   return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
14888ebb9e2SColin LeMahieu }
14988ebb9e2SColin LeMahieu 
15088ebb9e2SColin LeMahieu extern "C" void LLVMInitializeHexagonDisassembler() {
15188ebb9e2SColin LeMahieu   TargetRegistry::RegisterMCDisassembler(TheHexagonTarget,
15288ebb9e2SColin LeMahieu                                          createHexagonDisassembler);
15388ebb9e2SColin LeMahieu }
15488ebb9e2SColin LeMahieu 
15588ebb9e2SColin LeMahieu DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
1567fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
15788ebb9e2SColin LeMahieu                                                  uint64_t Address,
15888ebb9e2SColin LeMahieu                                                  raw_ostream &os,
15988ebb9e2SColin LeMahieu                                                  raw_ostream &cs) const {
16068d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
16168d967d9SColin LeMahieu   bool Complete = false;
16268d967d9SColin LeMahieu   Size = 0;
1634aa6bea7SRafael Espindola 
16468d967d9SColin LeMahieu   *CurrentBundle = &MI;
16568d967d9SColin LeMahieu   MI.setOpcode(Hexagon::BUNDLE);
16668d967d9SColin LeMahieu   MI.addOperand(MCOperand::createImm(0));
167be8c453dSColin LeMahieu   while (Result == Success && Complete == false) {
16868d967d9SColin LeMahieu     if (Bytes.size() < HEXAGON_INSTR_SIZE)
16968d967d9SColin LeMahieu       return MCDisassembler::Fail;
17068d967d9SColin LeMahieu     MCInst *Inst = new (getContext()) MCInst;
17168d967d9SColin LeMahieu     Result = getSingleInstruction(*Inst, MI, Bytes, Address, os, cs, Complete);
17268d967d9SColin LeMahieu     MI.addOperand(MCOperand::createInst(Inst));
17368d967d9SColin LeMahieu     Size += HEXAGON_INSTR_SIZE;
17468d967d9SColin LeMahieu     Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
17568d967d9SColin LeMahieu   }
176*7cd08927SColin LeMahieu   if(Result == MCDisassembler::Fail)
17768d967d9SColin LeMahieu     return Result;
178*7cd08927SColin LeMahieu   HexagonMCChecker Checker (*MCII, STI, MI, MI, *getContext().getRegisterInfo());
179*7cd08927SColin LeMahieu   if(!Checker.check())
180*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
181*7cd08927SColin LeMahieu   return MCDisassembler::Success;
182*7cd08927SColin LeMahieu }
183*7cd08927SColin LeMahieu 
184*7cd08927SColin LeMahieu namespace {
185*7cd08927SColin LeMahieu HexagonDisassembler const &disassembler(void const *Decoder) {
186*7cd08927SColin LeMahieu   return *static_cast<HexagonDisassembler const *>(Decoder);
187*7cd08927SColin LeMahieu }
188*7cd08927SColin LeMahieu MCContext &contextFromDecoder(void const *Decoder) {
189*7cd08927SColin LeMahieu   return disassembler(Decoder).getContext();
190*7cd08927SColin LeMahieu }
19168d967d9SColin LeMahieu }
19268d967d9SColin LeMahieu 
19368d967d9SColin LeMahieu DecodeStatus HexagonDisassembler::getSingleInstruction(
19468d967d9SColin LeMahieu     MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
19568d967d9SColin LeMahieu     raw_ostream &os, raw_ostream &cs, bool &Complete) const {
19668d967d9SColin LeMahieu   assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
19768d967d9SColin LeMahieu 
19868d967d9SColin LeMahieu   uint32_t Instruction =
199*7cd08927SColin LeMahieu       (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
20088ebb9e2SColin LeMahieu 
20168d967d9SColin LeMahieu   auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
20268d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
20368d967d9SColin LeMahieu       HexagonII::INST_PARSE_LOOP_END) {
20468d967d9SColin LeMahieu     if (BundleSize == 0)
20568d967d9SColin LeMahieu       HexagonMCInstrInfo::setInnerLoop(MCB);
20668d967d9SColin LeMahieu     else if (BundleSize == 1)
20768d967d9SColin LeMahieu       HexagonMCInstrInfo::setOuterLoop(MCB);
20868d967d9SColin LeMahieu     else
20968d967d9SColin LeMahieu       return DecodeStatus::Fail;
21068d967d9SColin LeMahieu   }
21168d967d9SColin LeMahieu 
21268d967d9SColin LeMahieu   DecodeStatus Result = DecodeStatus::Success;
21368d967d9SColin LeMahieu   if ((Instruction & HexagonII::INST_PARSE_MASK) ==
214be8c453dSColin LeMahieu       HexagonII::INST_PARSE_DUPLEX) {
215be8c453dSColin LeMahieu     // Determine the instruction class of each instruction in the duplex.
216be8c453dSColin LeMahieu     unsigned duplexIClass, IClassLow, IClassHigh;
217be8c453dSColin LeMahieu 
218be8c453dSColin LeMahieu     duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
219be8c453dSColin LeMahieu     switch (duplexIClass) {
220be8c453dSColin LeMahieu     default:
221be8c453dSColin LeMahieu       return MCDisassembler::Fail;
222be8c453dSColin LeMahieu     case 0:
223be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
224be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
225be8c453dSColin LeMahieu       break;
226be8c453dSColin LeMahieu     case 1:
227be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
228be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
229be8c453dSColin LeMahieu       break;
230be8c453dSColin LeMahieu     case 2:
231be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
232be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
233be8c453dSColin LeMahieu       break;
234be8c453dSColin LeMahieu     case 3:
235be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_A;
236be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
237be8c453dSColin LeMahieu       break;
238be8c453dSColin LeMahieu     case 4:
239be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L1;
240be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
241be8c453dSColin LeMahieu       break;
242be8c453dSColin LeMahieu     case 5:
243be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_L2;
244be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
245be8c453dSColin LeMahieu       break;
246be8c453dSColin LeMahieu     case 6:
247be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
248be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
249be8c453dSColin LeMahieu       break;
250be8c453dSColin LeMahieu     case 7:
251be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
252be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_A;
253be8c453dSColin LeMahieu       break;
254be8c453dSColin LeMahieu     case 8:
255be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
256be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
257be8c453dSColin LeMahieu       break;
258be8c453dSColin LeMahieu     case 9:
259be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
260be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
261be8c453dSColin LeMahieu       break;
262be8c453dSColin LeMahieu     case 10:
263be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S1;
264be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
265be8c453dSColin LeMahieu       break;
266be8c453dSColin LeMahieu     case 11:
267be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
268be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S1;
269be8c453dSColin LeMahieu       break;
270be8c453dSColin LeMahieu     case 12:
271be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
272be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L1;
273be8c453dSColin LeMahieu       break;
274be8c453dSColin LeMahieu     case 13:
275be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
276be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_L2;
277be8c453dSColin LeMahieu       break;
278be8c453dSColin LeMahieu     case 14:
279be8c453dSColin LeMahieu       IClassLow = HexagonII::HSIG_S2;
280be8c453dSColin LeMahieu       IClassHigh = HexagonII::HSIG_S2;
281be8c453dSColin LeMahieu       break;
282be8c453dSColin LeMahieu     }
283be8c453dSColin LeMahieu 
284be8c453dSColin LeMahieu     // Set the MCInst to be a duplex instruction. Which one doesn't matter.
285be8c453dSColin LeMahieu     MI.setOpcode(Hexagon::DuplexIClass0);
286be8c453dSColin LeMahieu 
287be8c453dSColin LeMahieu     // Decode each instruction in the duplex.
288be8c453dSColin LeMahieu     // Create an MCInst for each instruction.
289be8c453dSColin LeMahieu     unsigned instLow = Instruction & 0x1fff;
290be8c453dSColin LeMahieu     unsigned instHigh = (Instruction >> 16) & 0x1fff;
291be8c453dSColin LeMahieu     unsigned opLow;
292be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassLow, instLow, opLow, os) !=
293be8c453dSColin LeMahieu         MCDisassembler::Success)
294be8c453dSColin LeMahieu       return MCDisassembler::Fail;
295be8c453dSColin LeMahieu     unsigned opHigh;
296be8c453dSColin LeMahieu     if (GetSubinstOpcode(IClassHigh, instHigh, opHigh, os) !=
297be8c453dSColin LeMahieu         MCDisassembler::Success)
298be8c453dSColin LeMahieu       return MCDisassembler::Fail;
299be8c453dSColin LeMahieu     MCInst *MILow = new (getContext()) MCInst;
300be8c453dSColin LeMahieu     MILow->setOpcode(opLow);
301be8c453dSColin LeMahieu     MCInst *MIHigh = new (getContext()) MCInst;
302be8c453dSColin LeMahieu     MIHigh->setOpcode(opHigh);
303*7cd08927SColin LeMahieu     addSubinstOperands(MILow, opLow, instLow);
304*7cd08927SColin LeMahieu     addSubinstOperands(MIHigh, opHigh, instHigh);
305be8c453dSColin LeMahieu     // see ConvertToSubInst() in
306be8c453dSColin LeMahieu     // lib/Target/Hexagon/MCTargetDesc/HexagonMCDuplexInfo.cpp
307be8c453dSColin LeMahieu 
308be8c453dSColin LeMahieu     // Add the duplex instruction MCInsts as operands to the passed in MCInst.
309be8c453dSColin LeMahieu     MCOperand OPLow = MCOperand::createInst(MILow);
310be8c453dSColin LeMahieu     MCOperand OPHigh = MCOperand::createInst(MIHigh);
311be8c453dSColin LeMahieu     MI.addOperand(OPLow);
312be8c453dSColin LeMahieu     MI.addOperand(OPHigh);
313be8c453dSColin LeMahieu     Complete = true;
314be8c453dSColin LeMahieu   } else {
315be8c453dSColin LeMahieu     if ((Instruction & HexagonII::INST_PARSE_MASK) ==
31668d967d9SColin LeMahieu         HexagonII::INST_PARSE_PACKET_END)
31768d967d9SColin LeMahieu       Complete = true;
31868d967d9SColin LeMahieu     // Calling the auto-generated decoder function.
31968d967d9SColin LeMahieu     Result =
32068d967d9SColin LeMahieu         decodeInstruction(DecoderTable32, MI, Instruction, Address, this, STI);
321*7cd08927SColin LeMahieu 
322*7cd08927SColin LeMahieu     // If a, "standard" insn isn't found check special cases.
323*7cd08927SColin LeMahieu     if (MCDisassembler::Success != Result ||
324*7cd08927SColin LeMahieu         MI.getOpcode() == Hexagon::A4_ext) {
325*7cd08927SColin LeMahieu       Result = decodeImmext(MI, Instruction, this);
326*7cd08927SColin LeMahieu       if (MCDisassembler::Success != Result) {
327*7cd08927SColin LeMahieu         Result = decodeSpecial(MI, Instruction);
328*7cd08927SColin LeMahieu       }
329*7cd08927SColin LeMahieu     } else {
330*7cd08927SColin LeMahieu       // If the instruction is a compound instruction, register values will
331*7cd08927SColin LeMahieu       // follow the duplex model, so the register values in the MCInst are
332*7cd08927SColin LeMahieu       // incorrect. If the instruction is a compound, loop through the
333*7cd08927SColin LeMahieu       // operands and change registers appropriately.
334*7cd08927SColin LeMahieu       if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) ==
335*7cd08927SColin LeMahieu           HexagonII::TypeCOMPOUND) {
336*7cd08927SColin LeMahieu         for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last; ++i) {
337*7cd08927SColin LeMahieu           if (i->isReg()) {
338*7cd08927SColin LeMahieu             unsigned reg = i->getReg() - Hexagon::R0;
339*7cd08927SColin LeMahieu             i->setReg(getRegFromSubinstEncoding(reg));
340*7cd08927SColin LeMahieu           }
341*7cd08927SColin LeMahieu         }
342*7cd08927SColin LeMahieu       }
343*7cd08927SColin LeMahieu     }
344be8c453dSColin LeMahieu   }
34568d967d9SColin LeMahieu 
346*7cd08927SColin LeMahieu   if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
347*7cd08927SColin LeMahieu     unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
348*7cd08927SColin LeMahieu     MCOperand &MCO = MI.getOperand(OpIndex);
349*7cd08927SColin LeMahieu     assert(MCO.isReg() && "New value consumers must be registers");
350*7cd08927SColin LeMahieu     unsigned Register =
351*7cd08927SColin LeMahieu         getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
352*7cd08927SColin LeMahieu     if ((Register & 0x6) == 0)
353*7cd08927SColin LeMahieu       // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
354*7cd08927SColin LeMahieu       return MCDisassembler::Fail;
355*7cd08927SColin LeMahieu     unsigned Lookback = (Register & 0x6) >> 1;
356*7cd08927SColin LeMahieu     unsigned Offset = 1;
357*7cd08927SColin LeMahieu     bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
358*7cd08927SColin LeMahieu     auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
359*7cd08927SColin LeMahieu     auto i = Instructions.end() - 1;
360*7cd08927SColin LeMahieu     for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
361*7cd08927SColin LeMahieu       if (i == n)
362*7cd08927SColin LeMahieu         // Couldn't find producer
363*7cd08927SColin LeMahieu         return MCDisassembler::Fail;
364*7cd08927SColin LeMahieu       if (Vector && !HexagonMCInstrInfo::isVector(*MCII, *i->getInst()))
365*7cd08927SColin LeMahieu         // Skip scalars when calculating distances for vectors
366*7cd08927SColin LeMahieu         ++Lookback;
367*7cd08927SColin LeMahieu       if (HexagonMCInstrInfo::isImmext(*i->getInst()))
368*7cd08927SColin LeMahieu         ++Lookback;
369*7cd08927SColin LeMahieu       if (Offset == Lookback)
370*7cd08927SColin LeMahieu         break;
371*7cd08927SColin LeMahieu     }
372*7cd08927SColin LeMahieu     auto const &Inst = *i->getInst();
373*7cd08927SColin LeMahieu     bool SubregBit = (Register & 0x1) != 0;
374*7cd08927SColin LeMahieu     if (SubregBit && HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
375*7cd08927SColin LeMahieu       // If subreg bit is set we're selecting the second produced newvalue
376*7cd08927SColin LeMahieu       unsigned Producer =
377*7cd08927SColin LeMahieu           HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
378*7cd08927SColin LeMahieu       assert(Producer != Hexagon::NoRegister);
379*7cd08927SColin LeMahieu       MCO.setReg(Producer);
380*7cd08927SColin LeMahieu     } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
381*7cd08927SColin LeMahieu       unsigned Producer =
382*7cd08927SColin LeMahieu           HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
383*7cd08927SColin LeMahieu       if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
384*7cd08927SColin LeMahieu         Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0;
385*7cd08927SColin LeMahieu       else if (SubregBit)
386*7cd08927SColin LeMahieu         // Subreg bit should not be set for non-doublevector newvalue producers
387*7cd08927SColin LeMahieu         return MCDisassembler::Fail;
388*7cd08927SColin LeMahieu       assert(Producer != Hexagon::NoRegister);
389*7cd08927SColin LeMahieu       MCO.setReg(Producer);
390*7cd08927SColin LeMahieu     } else
391*7cd08927SColin LeMahieu       return MCDisassembler::Fail;
392*7cd08927SColin LeMahieu   }
393*7cd08927SColin LeMahieu 
394*7cd08927SColin LeMahieu   adjustExtendedInstructions(MI, MCB);
395*7cd08927SColin LeMahieu   MCInst const *Extender =
396*7cd08927SColin LeMahieu     HexagonMCInstrInfo::extenderForIndex(MCB,
397*7cd08927SColin LeMahieu                                          HexagonMCInstrInfo::bundleSize(MCB));
398*7cd08927SColin LeMahieu   if(Extender != nullptr) {
399*7cd08927SColin LeMahieu     MCInst const & Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI) ?
400*7cd08927SColin LeMahieu                           *MI.getOperand(1).getInst() : MI;
401*7cd08927SColin LeMahieu     if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
402*7cd08927SColin LeMahieu         !HexagonMCInstrInfo::isExtended(*MCII, Inst))
403*7cd08927SColin LeMahieu       return MCDisassembler::Fail;
404*7cd08927SColin LeMahieu   }
4055d6f03bdSColin LeMahieu   return Result;
40688ebb9e2SColin LeMahieu }
407*7cd08927SColin LeMahieu 
408*7cd08927SColin LeMahieu void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI,
409*7cd08927SColin LeMahieu                                                      MCInst const &MCB) const {
410*7cd08927SColin LeMahieu   if (!HexagonMCInstrInfo::hasExtenderForIndex(
411*7cd08927SColin LeMahieu           MCB, HexagonMCInstrInfo::bundleSize(MCB))) {
412*7cd08927SColin LeMahieu     unsigned opcode;
413*7cd08927SColin LeMahieu     // This code is used by the disassembler to disambiguate between GP
414*7cd08927SColin LeMahieu     // relative and absolute addressing instructions since they both have
415*7cd08927SColin LeMahieu     // same encoding bits. However, an absolute addressing instruction must
416*7cd08927SColin LeMahieu     // follow an immediate extender. Disassembler alwaus select absolute
417*7cd08927SColin LeMahieu     // addressing instructions first and uses this code to change them into
418*7cd08927SColin LeMahieu     // GP relative instruction in the absence of the corresponding immediate
419*7cd08927SColin LeMahieu     // extender.
420*7cd08927SColin LeMahieu     switch (MCI.getOpcode()) {
421*7cd08927SColin LeMahieu     case Hexagon::S2_storerbabs:
422*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerbgp;
423*7cd08927SColin LeMahieu       break;
424*7cd08927SColin LeMahieu     case Hexagon::S2_storerhabs:
425*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerhgp;
426*7cd08927SColin LeMahieu       break;
427*7cd08927SColin LeMahieu     case Hexagon::S2_storerfabs:
428*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerfgp;
429*7cd08927SColin LeMahieu       break;
430*7cd08927SColin LeMahieu     case Hexagon::S2_storeriabs:
431*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerigp;
432*7cd08927SColin LeMahieu       break;
433*7cd08927SColin LeMahieu     case Hexagon::S2_storerbnewabs:
434*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerbnewgp;
435*7cd08927SColin LeMahieu       break;
436*7cd08927SColin LeMahieu     case Hexagon::S2_storerhnewabs:
437*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerhnewgp;
438*7cd08927SColin LeMahieu       break;
439*7cd08927SColin LeMahieu     case Hexagon::S2_storerinewabs:
440*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerinewgp;
441*7cd08927SColin LeMahieu       break;
442*7cd08927SColin LeMahieu     case Hexagon::S2_storerdabs:
443*7cd08927SColin LeMahieu       opcode = Hexagon::S2_storerdgp;
444*7cd08927SColin LeMahieu       break;
445*7cd08927SColin LeMahieu     case Hexagon::L4_loadrb_abs:
446*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadrbgp;
447*7cd08927SColin LeMahieu       break;
448*7cd08927SColin LeMahieu     case Hexagon::L4_loadrub_abs:
449*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadrubgp;
450*7cd08927SColin LeMahieu       break;
451*7cd08927SColin LeMahieu     case Hexagon::L4_loadrh_abs:
452*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadrhgp;
453*7cd08927SColin LeMahieu       break;
454*7cd08927SColin LeMahieu     case Hexagon::L4_loadruh_abs:
455*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadruhgp;
456*7cd08927SColin LeMahieu       break;
457*7cd08927SColin LeMahieu     case Hexagon::L4_loadri_abs:
458*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadrigp;
459*7cd08927SColin LeMahieu       break;
460*7cd08927SColin LeMahieu     case Hexagon::L4_loadrd_abs:
461*7cd08927SColin LeMahieu       opcode = Hexagon::L2_loadrdgp;
462*7cd08927SColin LeMahieu       break;
463*7cd08927SColin LeMahieu     default:
464*7cd08927SColin LeMahieu       opcode = MCI.getOpcode();
465*7cd08927SColin LeMahieu     }
466*7cd08927SColin LeMahieu     MCI.setOpcode(opcode);
467*7cd08927SColin LeMahieu   }
468*7cd08927SColin LeMahieu }
469*7cd08927SColin LeMahieu 
470*7cd08927SColin LeMahieu namespace llvm {
471*7cd08927SColin LeMahieu extern const MCInstrDesc HexagonInsts[];
472*7cd08927SColin LeMahieu }
473*7cd08927SColin LeMahieu 
474*7cd08927SColin LeMahieu static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
475*7cd08927SColin LeMahieu                                         const uint16_t Table[], size_t Size) {
476*7cd08927SColin LeMahieu   if (RegNo < Size) {
477*7cd08927SColin LeMahieu     Inst.addOperand(MCOperand::createReg(Table[RegNo]));
478*7cd08927SColin LeMahieu     return MCDisassembler::Success;
479*7cd08927SColin LeMahieu   } else
480*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
481*7cd08927SColin LeMahieu }
482*7cd08927SColin LeMahieu 
4837c958713SColin LeMahieu static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
4847c958713SColin LeMahieu                                                    uint64_t Address,
4857c958713SColin LeMahieu                                                    const void *Decoder) {
4867c958713SColin LeMahieu   return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
4877c958713SColin LeMahieu }
4887c958713SColin LeMahieu 
489*7cd08927SColin LeMahieu static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
490*7cd08927SColin LeMahieu                                                uint64_t Address,
491*7cd08927SColin LeMahieu                                                const void *Decoder) {
492*7cd08927SColin LeMahieu   static const uint16_t IntRegDecoderTable[] = {
493*7cd08927SColin LeMahieu       Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
494*7cd08927SColin LeMahieu       Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
495*7cd08927SColin LeMahieu       Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
496*7cd08927SColin LeMahieu       Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
497*7cd08927SColin LeMahieu       Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
498*7cd08927SColin LeMahieu       Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
499*7cd08927SColin LeMahieu       Hexagon::R30, Hexagon::R31};
500*7cd08927SColin LeMahieu 
501*7cd08927SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable,
502*7cd08927SColin LeMahieu                               sizeof(IntRegDecoderTable)));
503*7cd08927SColin LeMahieu }
5047c958713SColin LeMahieu 
5057c958713SColin LeMahieu static DecodeStatus DecodeVectorRegsRegisterClass(MCInst &Inst, unsigned RegNo,
5067c958713SColin LeMahieu                                                   uint64_t /*Address*/,
5077c958713SColin LeMahieu                                                   const void *Decoder) {
5087c958713SColin LeMahieu   static const uint16_t VecRegDecoderTable[] = {
5097c958713SColin LeMahieu       Hexagon::V0,  Hexagon::V1,  Hexagon::V2,  Hexagon::V3,  Hexagon::V4,
5107c958713SColin LeMahieu       Hexagon::V5,  Hexagon::V6,  Hexagon::V7,  Hexagon::V8,  Hexagon::V9,
5117c958713SColin LeMahieu       Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
5127c958713SColin LeMahieu       Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
5137c958713SColin LeMahieu       Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
5147c958713SColin LeMahieu       Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
5157c958713SColin LeMahieu       Hexagon::V30, Hexagon::V31};
5167c958713SColin LeMahieu 
5177c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, VecRegDecoderTable,
5187c958713SColin LeMahieu                               sizeof(VecRegDecoderTable)));
5197c958713SColin LeMahieu }
5207c958713SColin LeMahieu 
521*7cd08927SColin LeMahieu static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
522*7cd08927SColin LeMahieu                                                   uint64_t /*Address*/,
523*7cd08927SColin LeMahieu                                                   const void *Decoder) {
524*7cd08927SColin LeMahieu   static const uint16_t DoubleRegDecoderTable[] = {
525*7cd08927SColin LeMahieu       Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
526*7cd08927SColin LeMahieu       Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
527*7cd08927SColin LeMahieu       Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
528*7cd08927SColin LeMahieu       Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
529*7cd08927SColin LeMahieu 
530*7cd08927SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable,
531*7cd08927SColin LeMahieu                               sizeof(DoubleRegDecoderTable)));
532*7cd08927SColin LeMahieu }
533*7cd08927SColin LeMahieu 
5347c958713SColin LeMahieu static DecodeStatus DecodeVecDblRegsRegisterClass(MCInst &Inst, unsigned RegNo,
5357c958713SColin LeMahieu                                                   uint64_t /*Address*/,
5367c958713SColin LeMahieu                                                   const void *Decoder) {
5377c958713SColin LeMahieu   static const uint16_t VecDblRegDecoderTable[] = {
5387c958713SColin LeMahieu       Hexagon::W0,  Hexagon::W1,  Hexagon::W2,  Hexagon::W3,
5397c958713SColin LeMahieu       Hexagon::W4,  Hexagon::W5,  Hexagon::W6,  Hexagon::W7,
5407c958713SColin LeMahieu       Hexagon::W8,  Hexagon::W9,  Hexagon::W10, Hexagon::W11,
5417c958713SColin LeMahieu       Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
5427c958713SColin LeMahieu 
5437c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo >> 1, VecDblRegDecoderTable,
5447c958713SColin LeMahieu                               sizeof(VecDblRegDecoderTable)));
5457c958713SColin LeMahieu }
5467c958713SColin LeMahieu 
547*7cd08927SColin LeMahieu static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
548*7cd08927SColin LeMahieu                                                 uint64_t /*Address*/,
549*7cd08927SColin LeMahieu                                                 const void *Decoder) {
550*7cd08927SColin LeMahieu   static const uint16_t PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
551*7cd08927SColin LeMahieu                                                  Hexagon::P2, Hexagon::P3};
552*7cd08927SColin LeMahieu 
553*7cd08927SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable,
554*7cd08927SColin LeMahieu                               sizeof(PredRegDecoderTable)));
555*7cd08927SColin LeMahieu }
556*7cd08927SColin LeMahieu 
5577c958713SColin LeMahieu static DecodeStatus DecodeVecPredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
5587c958713SColin LeMahieu                                                    uint64_t /*Address*/,
5597c958713SColin LeMahieu                                                    const void *Decoder) {
5607c958713SColin LeMahieu   static const uint16_t VecPredRegDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
5617c958713SColin LeMahieu                                                     Hexagon::Q2, Hexagon::Q3};
5627c958713SColin LeMahieu 
5637c958713SColin LeMahieu   return (DecodeRegisterClass(Inst, RegNo, VecPredRegDecoderTable,
5647c958713SColin LeMahieu                               sizeof(VecPredRegDecoderTable)));
5657c958713SColin LeMahieu }
566be8c453dSColin LeMahieu 
567*7cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
568*7cd08927SColin LeMahieu                                                uint64_t /*Address*/,
569*7cd08927SColin LeMahieu                                                const void *Decoder) {
570*7cd08927SColin LeMahieu   static const uint16_t CtrlRegDecoderTable[] = {
571*7cd08927SColin LeMahieu     Hexagon::SA0, Hexagon::LC0, Hexagon::SA1, Hexagon::LC1,
572*7cd08927SColin LeMahieu     Hexagon::P3_0, Hexagon::C5, Hexagon::C6, Hexagon::C7,
573*7cd08927SColin LeMahieu     Hexagon::USR, Hexagon::PC, Hexagon::UGP, Hexagon::GP,
574*7cd08927SColin LeMahieu     Hexagon::CS0, Hexagon::CS1, Hexagon::UPCL, Hexagon::UPC
575*7cd08927SColin LeMahieu   };
576*7cd08927SColin LeMahieu 
577*7cd08927SColin LeMahieu   if (RegNo >= sizeof(CtrlRegDecoderTable) / sizeof(CtrlRegDecoderTable[0]))
578*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
579*7cd08927SColin LeMahieu 
580*7cd08927SColin LeMahieu   if (CtrlRegDecoderTable[RegNo] == Hexagon::NoRegister)
581*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
582*7cd08927SColin LeMahieu 
583*7cd08927SColin LeMahieu   unsigned Register = CtrlRegDecoderTable[RegNo];
584*7cd08927SColin LeMahieu   Inst.addOperand(MCOperand::createReg(Register));
585*7cd08927SColin LeMahieu   return MCDisassembler::Success;
586*7cd08927SColin LeMahieu }
587*7cd08927SColin LeMahieu 
588*7cd08927SColin LeMahieu static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
589*7cd08927SColin LeMahieu                                                  uint64_t /*Address*/,
590*7cd08927SColin LeMahieu                                                  const void *Decoder) {
591*7cd08927SColin LeMahieu   static const uint16_t CtrlReg64DecoderTable[] = {
592*7cd08927SColin LeMahieu       Hexagon::C1_0,   Hexagon::NoRegister,
593*7cd08927SColin LeMahieu       Hexagon::C3_2,   Hexagon::NoRegister,
594*7cd08927SColin LeMahieu       Hexagon::C7_6,   Hexagon::NoRegister,
595*7cd08927SColin LeMahieu       Hexagon::C9_8,   Hexagon::NoRegister,
596*7cd08927SColin LeMahieu       Hexagon::C11_10, Hexagon::NoRegister,
597*7cd08927SColin LeMahieu       Hexagon::CS,     Hexagon::NoRegister,
598*7cd08927SColin LeMahieu       Hexagon::UPC,    Hexagon::NoRegister
599*7cd08927SColin LeMahieu   };
600*7cd08927SColin LeMahieu 
601*7cd08927SColin LeMahieu   if (RegNo >= sizeof(CtrlReg64DecoderTable) / sizeof(CtrlReg64DecoderTable[0]))
602*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
603*7cd08927SColin LeMahieu 
604*7cd08927SColin LeMahieu   if (CtrlReg64DecoderTable[RegNo] == Hexagon::NoRegister)
605*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
606*7cd08927SColin LeMahieu 
607*7cd08927SColin LeMahieu   unsigned Register = CtrlReg64DecoderTable[RegNo];
608*7cd08927SColin LeMahieu   Inst.addOperand(MCOperand::createReg(Register));
609*7cd08927SColin LeMahieu   return MCDisassembler::Success;
610*7cd08927SColin LeMahieu }
611*7cd08927SColin LeMahieu 
612*7cd08927SColin LeMahieu static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
613*7cd08927SColin LeMahieu                                                uint64_t /*Address*/,
614*7cd08927SColin LeMahieu                                                const void *Decoder) {
615*7cd08927SColin LeMahieu   unsigned Register = 0;
616*7cd08927SColin LeMahieu   switch (RegNo) {
617*7cd08927SColin LeMahieu   case 0:
618*7cd08927SColin LeMahieu     Register = Hexagon::M0;
619*7cd08927SColin LeMahieu     break;
620*7cd08927SColin LeMahieu   case 1:
621*7cd08927SColin LeMahieu     Register = Hexagon::M1;
622*7cd08927SColin LeMahieu     break;
623*7cd08927SColin LeMahieu   default:
624*7cd08927SColin LeMahieu     return MCDisassembler::Fail;
625*7cd08927SColin LeMahieu   }
626*7cd08927SColin LeMahieu   Inst.addOperand(MCOperand::createReg(Register));
627*7cd08927SColin LeMahieu   return MCDisassembler::Success;
628*7cd08927SColin LeMahieu }
629*7cd08927SColin LeMahieu 
630*7cd08927SColin LeMahieu namespace {
631*7cd08927SColin LeMahieu uint32_t fullValue(MCInstrInfo const &MCII,
632*7cd08927SColin LeMahieu                   MCInst &MCB,
633*7cd08927SColin LeMahieu                   MCInst &MI,
634*7cd08927SColin LeMahieu                   int64_t Value) {
635*7cd08927SColin LeMahieu   MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex(
636*7cd08927SColin LeMahieu     MCB, HexagonMCInstrInfo::bundleSize(MCB));
637*7cd08927SColin LeMahieu   if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
638*7cd08927SColin LeMahieu     return Value;
639*7cd08927SColin LeMahieu   unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
640*7cd08927SColin LeMahieu   uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
641*7cd08927SColin LeMahieu   int64_t Bits;
642*7cd08927SColin LeMahieu   bool Success = Extender->getOperand(0).getExpr()->evaluateAsAbsolute(Bits);
643*7cd08927SColin LeMahieu   assert(Success);(void)Success;
644*7cd08927SColin LeMahieu   uint32_t Upper26 = static_cast<uint32_t>(Bits);
645*7cd08927SColin LeMahieu   uint32_t Operand = Upper26 | Lower6;
646*7cd08927SColin LeMahieu   return Operand;
647*7cd08927SColin LeMahieu }
648*7cd08927SColin LeMahieu template <size_t T>
649*7cd08927SColin LeMahieu void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
650*7cd08927SColin LeMahieu   HexagonDisassembler const &Disassembler = disassembler(Decoder);
651*7cd08927SColin LeMahieu   int64_t FullValue = fullValue(*Disassembler.MCII,
652*7cd08927SColin LeMahieu                                 **Disassembler.CurrentBundle,
653*7cd08927SColin LeMahieu                                 MI, SignExtend64<T>(tmp));
654*7cd08927SColin LeMahieu   int64_t Extended = SignExtend64<32>(FullValue);
655*7cd08927SColin LeMahieu   HexagonMCInstrInfo::addConstant(MI, Extended,
656*7cd08927SColin LeMahieu                                   Disassembler.getContext());
657*7cd08927SColin LeMahieu }
658*7cd08927SColin LeMahieu }
659*7cd08927SColin LeMahieu 
660*7cd08927SColin LeMahieu static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
661*7cd08927SColin LeMahieu                                        uint64_t /*Address*/,
662*7cd08927SColin LeMahieu                                        const void *Decoder) {
663*7cd08927SColin LeMahieu   HexagonDisassembler const &Disassembler = disassembler(Decoder);
664*7cd08927SColin LeMahieu   int64_t FullValue = fullValue(*Disassembler.MCII,
665*7cd08927SColin LeMahieu                                 **Disassembler.CurrentBundle,
666*7cd08927SColin LeMahieu                                 MI, tmp);
667*7cd08927SColin LeMahieu   assert(FullValue >= 0 && "Negative in unsigned decoder");
668*7cd08927SColin LeMahieu   HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
669*7cd08927SColin LeMahieu   return MCDisassembler::Success;
670*7cd08927SColin LeMahieu }
671*7cd08927SColin LeMahieu 
6721e9d1d76SColin LeMahieu static DecodeStatus s16ImmDecoder(MCInst &MI, unsigned tmp,
6731e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
674*7cd08927SColin LeMahieu   signedDecoder<16>(MI, tmp, Decoder);
6751e9d1d76SColin LeMahieu   return MCDisassembler::Success;
6761e9d1d76SColin LeMahieu }
6771e9d1d76SColin LeMahieu 
6781e9d1d76SColin LeMahieu static DecodeStatus s12ImmDecoder(MCInst &MI, unsigned tmp,
6791e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
680*7cd08927SColin LeMahieu   signedDecoder<12>(MI, tmp, Decoder);
6811e9d1d76SColin LeMahieu   return MCDisassembler::Success;
6821e9d1d76SColin LeMahieu }
6831e9d1d76SColin LeMahieu 
6841e9d1d76SColin LeMahieu static DecodeStatus s11_0ImmDecoder(MCInst &MI, unsigned tmp,
6851e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
686*7cd08927SColin LeMahieu   signedDecoder<11>(MI, tmp, Decoder);
6871e9d1d76SColin LeMahieu   return MCDisassembler::Success;
6881e9d1d76SColin LeMahieu }
6891e9d1d76SColin LeMahieu 
6901e9d1d76SColin LeMahieu static DecodeStatus s11_1ImmDecoder(MCInst &MI, unsigned tmp,
6911e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
692*7cd08927SColin LeMahieu   HexagonMCInstrInfo::addConstant(MI, SignExtend64<12>(tmp), contextFromDecoder(Decoder));
6931e9d1d76SColin LeMahieu   return MCDisassembler::Success;
6941e9d1d76SColin LeMahieu }
6951e9d1d76SColin LeMahieu 
6961e9d1d76SColin LeMahieu static DecodeStatus s11_2ImmDecoder(MCInst &MI, unsigned tmp,
6971e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
698*7cd08927SColin LeMahieu   signedDecoder<13>(MI, tmp, Decoder);
6991e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7001e9d1d76SColin LeMahieu }
7011e9d1d76SColin LeMahieu 
7021e9d1d76SColin LeMahieu static DecodeStatus s11_3ImmDecoder(MCInst &MI, unsigned tmp,
7031e9d1d76SColin LeMahieu                                     uint64_t /*Address*/, const void *Decoder) {
704*7cd08927SColin LeMahieu   signedDecoder<14>(MI, tmp, Decoder);
7051e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7061e9d1d76SColin LeMahieu }
7071e9d1d76SColin LeMahieu 
7081e9d1d76SColin LeMahieu static DecodeStatus s10ImmDecoder(MCInst &MI, unsigned tmp,
7091e9d1d76SColin LeMahieu                                   uint64_t /*Address*/, const void *Decoder) {
710*7cd08927SColin LeMahieu   signedDecoder<10>(MI, tmp, Decoder);
7111e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7121e9d1d76SColin LeMahieu }
7131e9d1d76SColin LeMahieu 
7141e9d1d76SColin LeMahieu static DecodeStatus s8ImmDecoder(MCInst &MI, unsigned tmp, uint64_t /*Address*/,
7151e9d1d76SColin LeMahieu                                  const void *Decoder) {
716*7cd08927SColin LeMahieu   signedDecoder<8>(MI, tmp, Decoder);
7171e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7181e9d1d76SColin LeMahieu }
7191e9d1d76SColin LeMahieu 
7201e9d1d76SColin LeMahieu static DecodeStatus s6_0ImmDecoder(MCInst &MI, unsigned tmp,
7211e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
722*7cd08927SColin LeMahieu   signedDecoder<6>(MI, tmp, Decoder);
7231e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7241e9d1d76SColin LeMahieu }
7251e9d1d76SColin LeMahieu 
7261e9d1d76SColin LeMahieu static DecodeStatus s4_0ImmDecoder(MCInst &MI, unsigned tmp,
7271e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
728*7cd08927SColin LeMahieu   signedDecoder<4>(MI, tmp, Decoder);
7291e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7301e9d1d76SColin LeMahieu }
7311e9d1d76SColin LeMahieu 
7321e9d1d76SColin LeMahieu static DecodeStatus s4_1ImmDecoder(MCInst &MI, unsigned tmp,
7331e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
734*7cd08927SColin LeMahieu   signedDecoder<5>(MI, tmp, Decoder);
7351e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7361e9d1d76SColin LeMahieu }
7371e9d1d76SColin LeMahieu 
7381e9d1d76SColin LeMahieu static DecodeStatus s4_2ImmDecoder(MCInst &MI, unsigned tmp,
7391e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
740*7cd08927SColin LeMahieu   signedDecoder<6>(MI, tmp, Decoder);
7411e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7421e9d1d76SColin LeMahieu }
7431e9d1d76SColin LeMahieu 
7441e9d1d76SColin LeMahieu static DecodeStatus s4_3ImmDecoder(MCInst &MI, unsigned tmp,
7451e9d1d76SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
746*7cd08927SColin LeMahieu   signedDecoder<7>(MI, tmp, Decoder);
7471e9d1d76SColin LeMahieu   return MCDisassembler::Success;
7481e9d1d76SColin LeMahieu }
7491e9d1d76SColin LeMahieu 
7507c958713SColin LeMahieu static DecodeStatus s4_6ImmDecoder(MCInst &MI, unsigned tmp,
7517c958713SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
752*7cd08927SColin LeMahieu   signedDecoder<10>(MI, tmp, Decoder);
7537c958713SColin LeMahieu   return MCDisassembler::Success;
7547c958713SColin LeMahieu }
7557c958713SColin LeMahieu 
7567c958713SColin LeMahieu static DecodeStatus s3_6ImmDecoder(MCInst &MI, unsigned tmp,
7577c958713SColin LeMahieu                                    uint64_t /*Address*/, const void *Decoder) {
758*7cd08927SColin LeMahieu   signedDecoder<19>(MI, tmp, Decoder);
7597c958713SColin LeMahieu   return MCDisassembler::Success;
7607c958713SColin LeMahieu }
7617c958713SColin LeMahieu 
762*7cd08927SColin LeMahieu // custom decoder for various jump/call immediates
763*7cd08927SColin LeMahieu static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
764*7cd08927SColin LeMahieu                                     const void *Decoder) {
765*7cd08927SColin LeMahieu   HexagonDisassembler const &Disassembler = disassembler(Decoder);
766*7cd08927SColin LeMahieu   unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
767*7cd08927SColin LeMahieu   // r13_2 is not extendable, so if there are no extent bits, it's r13_2
768*7cd08927SColin LeMahieu   if (Bits == 0)
769*7cd08927SColin LeMahieu     Bits = 15;
770*7cd08927SColin LeMahieu   uint32_t FullValue = fullValue(*Disassembler.MCII,
771*7cd08927SColin LeMahieu                                 **Disassembler.CurrentBundle,
772*7cd08927SColin LeMahieu                                 MI, SignExtend64(tmp, Bits));
773*7cd08927SColin LeMahieu   int64_t Extended = SignExtend64<32>(FullValue) + Address;
774*7cd08927SColin LeMahieu   if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true,
775*7cd08927SColin LeMahieu                                               0, 4))
776*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
777*7cd08927SColin LeMahieu   return MCDisassembler::Success;
778*7cd08927SColin LeMahieu }
779*7cd08927SColin LeMahieu 
780*7cd08927SColin LeMahieu // Addressing mode dependent load store opcode map.
781*7cd08927SColin LeMahieu //   - If an insn is preceded by an extender the address is absolute.
782*7cd08927SColin LeMahieu //      - memw(##symbol) = r0
783*7cd08927SColin LeMahieu //   - If an insn is not preceded by an extender the address is GP relative.
784*7cd08927SColin LeMahieu //      - memw(gp + #symbol) = r0
785*7cd08927SColin LeMahieu // Please note that the instructions must be ordered in the descending order
786*7cd08927SColin LeMahieu // of their opcode.
787*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_ST
788*7cd08927SColin LeMahieu static unsigned int StoreConditionalOpcodeData[][2] = {
789*7cd08927SColin LeMahieu     {S4_pstorerdfnew_abs, 0xafc02084},
790*7cd08927SColin LeMahieu     {S4_pstorerdtnew_abs, 0xafc02080},
791*7cd08927SColin LeMahieu     {S4_pstorerdf_abs, 0xafc00084},
792*7cd08927SColin LeMahieu     {S4_pstorerdt_abs, 0xafc00080},
793*7cd08927SColin LeMahieu     {S4_pstorerinewfnew_abs, 0xafa03084},
794*7cd08927SColin LeMahieu     {S4_pstorerinewtnew_abs, 0xafa03080},
795*7cd08927SColin LeMahieu     {S4_pstorerhnewfnew_abs, 0xafa02884},
796*7cd08927SColin LeMahieu     {S4_pstorerhnewtnew_abs, 0xafa02880},
797*7cd08927SColin LeMahieu     {S4_pstorerbnewfnew_abs, 0xafa02084},
798*7cd08927SColin LeMahieu     {S4_pstorerbnewtnew_abs, 0xafa02080},
799*7cd08927SColin LeMahieu     {S4_pstorerinewf_abs, 0xafa01084},
800*7cd08927SColin LeMahieu     {S4_pstorerinewt_abs, 0xafa01080},
801*7cd08927SColin LeMahieu     {S4_pstorerhnewf_abs, 0xafa00884},
802*7cd08927SColin LeMahieu     {S4_pstorerhnewt_abs, 0xafa00880},
803*7cd08927SColin LeMahieu     {S4_pstorerbnewf_abs, 0xafa00084},
804*7cd08927SColin LeMahieu     {S4_pstorerbnewt_abs, 0xafa00080},
805*7cd08927SColin LeMahieu     {S4_pstorerifnew_abs, 0xaf802084},
806*7cd08927SColin LeMahieu     {S4_pstoreritnew_abs, 0xaf802080},
807*7cd08927SColin LeMahieu     {S4_pstorerif_abs, 0xaf800084},
808*7cd08927SColin LeMahieu     {S4_pstorerit_abs, 0xaf800080},
809*7cd08927SColin LeMahieu     {S4_pstorerhfnew_abs, 0xaf402084},
810*7cd08927SColin LeMahieu     {S4_pstorerhtnew_abs, 0xaf402080},
811*7cd08927SColin LeMahieu     {S4_pstorerhf_abs, 0xaf400084},
812*7cd08927SColin LeMahieu     {S4_pstorerht_abs, 0xaf400080},
813*7cd08927SColin LeMahieu     {S4_pstorerbfnew_abs, 0xaf002084},
814*7cd08927SColin LeMahieu     {S4_pstorerbtnew_abs, 0xaf002080},
815*7cd08927SColin LeMahieu     {S4_pstorerbf_abs, 0xaf000084},
816*7cd08927SColin LeMahieu     {S4_pstorerbt_abs, 0xaf000080}};
817*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD
818*7cd08927SColin LeMahieu 
819*7cd08927SColin LeMahieu // HexagonII::INST_ICLASS_LD_ST_2
820*7cd08927SColin LeMahieu static unsigned int LoadStoreOpcodeData[][2] = {{L4_loadrd_abs, 0x49c00000},
821*7cd08927SColin LeMahieu                                                 {L4_loadri_abs, 0x49800000},
822*7cd08927SColin LeMahieu                                                 {L4_loadruh_abs, 0x49600000},
823*7cd08927SColin LeMahieu                                                 {L4_loadrh_abs, 0x49400000},
824*7cd08927SColin LeMahieu                                                 {L4_loadrub_abs, 0x49200000},
825*7cd08927SColin LeMahieu                                                 {L4_loadrb_abs, 0x49000000},
826*7cd08927SColin LeMahieu                                                 {S2_storerdabs, 0x48c00000},
827*7cd08927SColin LeMahieu                                                 {S2_storerinewabs, 0x48a01000},
828*7cd08927SColin LeMahieu                                                 {S2_storerhnewabs, 0x48a00800},
829*7cd08927SColin LeMahieu                                                 {S2_storerbnewabs, 0x48a00000},
830*7cd08927SColin LeMahieu                                                 {S2_storeriabs, 0x48800000},
831*7cd08927SColin LeMahieu                                                 {S2_storerfabs, 0x48600000},
832*7cd08927SColin LeMahieu                                                 {S2_storerhabs, 0x48400000},
833*7cd08927SColin LeMahieu                                                 {S2_storerbabs, 0x48000000}};
834*7cd08927SColin LeMahieu static int NumCondS =
835*7cd08927SColin LeMahieu     sizeof(StoreConditionalOpcodeData) / sizeof(StoreConditionalOpcodeData[0]);
836*7cd08927SColin LeMahieu static int NumLS = sizeof(LoadStoreOpcodeData) / sizeof(LoadStoreOpcodeData[0]);
837*7cd08927SColin LeMahieu 
838*7cd08927SColin LeMahieu static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
839*7cd08927SColin LeMahieu 
840*7cd08927SColin LeMahieu   unsigned MachineOpcode = 0;
841*7cd08927SColin LeMahieu   unsigned LLVMOpcode = 0;
842*7cd08927SColin LeMahieu   int i;
843*7cd08927SColin LeMahieu 
844*7cd08927SColin LeMahieu   if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_ST) {
845*7cd08927SColin LeMahieu     for (i = 0; i < NumCondS; ++i) {
846*7cd08927SColin LeMahieu       if ((insn & StoreConditionalOpcodeData[i][1]) ==
847*7cd08927SColin LeMahieu           StoreConditionalOpcodeData[i][1]) {
848*7cd08927SColin LeMahieu         MachineOpcode = StoreConditionalOpcodeData[i][1];
849*7cd08927SColin LeMahieu         LLVMOpcode = StoreConditionalOpcodeData[i][0];
850*7cd08927SColin LeMahieu         break;
851*7cd08927SColin LeMahieu       }
852*7cd08927SColin LeMahieu     }
853*7cd08927SColin LeMahieu   }
854*7cd08927SColin LeMahieu   if ((insn & HexagonII::INST_ICLASS_MASK) == HexagonII::INST_ICLASS_LD_ST_2) {
855*7cd08927SColin LeMahieu     for (i = 0; i < NumLS; ++i) {
856*7cd08927SColin LeMahieu       if ((insn & LoadStoreOpcodeData[i][1]) == LoadStoreOpcodeData[i][1]) {
857*7cd08927SColin LeMahieu         MachineOpcode = LoadStoreOpcodeData[i][1];
858*7cd08927SColin LeMahieu         LLVMOpcode = LoadStoreOpcodeData[i][0];
859*7cd08927SColin LeMahieu         break;
860*7cd08927SColin LeMahieu       }
861*7cd08927SColin LeMahieu     }
862*7cd08927SColin LeMahieu   }
863*7cd08927SColin LeMahieu 
864*7cd08927SColin LeMahieu   if (MachineOpcode) {
865*7cd08927SColin LeMahieu     unsigned Value = 0;
866*7cd08927SColin LeMahieu     unsigned shift = 0;
867*7cd08927SColin LeMahieu     MI.setOpcode(LLVMOpcode);
868*7cd08927SColin LeMahieu     // Remove the parse bits from the insn.
869*7cd08927SColin LeMahieu     insn &= ~HexagonII::INST_PARSE_MASK;
870*7cd08927SColin LeMahieu 
871*7cd08927SColin LeMahieu     switch (LLVMOpcode) {
872*7cd08927SColin LeMahieu     default:
873*7cd08927SColin LeMahieu       return MCDisassembler::Fail;
874*7cd08927SColin LeMahieu       break;
875*7cd08927SColin LeMahieu 
876*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerdf_abs:
877*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerdt_abs:
878*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerdfnew_abs:
879*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerdtnew_abs: {
880*7cd08927SColin LeMahieu       // op: Pv
881*7cd08927SColin LeMahieu       Value = insn & UINT64_C(3);
882*7cd08927SColin LeMahieu       DecodePredRegsRegisterClass(MI, Value, 0, 0);
883*7cd08927SColin LeMahieu       // op: u6
884*7cd08927SColin LeMahieu       Value = (insn >> 12) & UINT64_C(48);
885*7cd08927SColin LeMahieu       Value |= (insn >> 3) & UINT64_C(15);
886*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value));
887*7cd08927SColin LeMahieu       // op: Rtt
888*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(31);
889*7cd08927SColin LeMahieu       DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
890*7cd08927SColin LeMahieu       break;
891*7cd08927SColin LeMahieu     }
892*7cd08927SColin LeMahieu 
893*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbnewf_abs:
894*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbnewt_abs:
895*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbnewfnew_abs:
896*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbnewtnew_abs:
897*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhnewf_abs:
898*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhnewt_abs:
899*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhnewfnew_abs:
900*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhnewtnew_abs:
901*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerinewf_abs:
902*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerinewt_abs:
903*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerinewfnew_abs:
904*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerinewtnew_abs: {
905*7cd08927SColin LeMahieu       // op: Pv
906*7cd08927SColin LeMahieu       Value = insn & UINT64_C(3);
907*7cd08927SColin LeMahieu       DecodePredRegsRegisterClass(MI, Value, 0, 0);
908*7cd08927SColin LeMahieu       // op: u6
909*7cd08927SColin LeMahieu       Value = (insn >> 12) & UINT64_C(48);
910*7cd08927SColin LeMahieu       Value |= (insn >> 3) & UINT64_C(15);
911*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value));
912*7cd08927SColin LeMahieu       // op: Nt
913*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(7);
914*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
915*7cd08927SColin LeMahieu       break;
916*7cd08927SColin LeMahieu     }
917*7cd08927SColin LeMahieu 
918*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbf_abs:
919*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbt_abs:
920*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbfnew_abs:
921*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerbtnew_abs:
922*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhf_abs:
923*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerht_abs:
924*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhfnew_abs:
925*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerhtnew_abs:
926*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerif_abs:
927*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerit_abs:
928*7cd08927SColin LeMahieu     case Hexagon::S4_pstorerifnew_abs:
929*7cd08927SColin LeMahieu     case Hexagon::S4_pstoreritnew_abs: {
930*7cd08927SColin LeMahieu       // op: Pv
931*7cd08927SColin LeMahieu       Value = insn & UINT64_C(3);
932*7cd08927SColin LeMahieu       DecodePredRegsRegisterClass(MI, Value, 0, 0);
933*7cd08927SColin LeMahieu       // op: u6
934*7cd08927SColin LeMahieu       Value = (insn >> 12) & UINT64_C(48);
935*7cd08927SColin LeMahieu       Value |= (insn >> 3) & UINT64_C(15);
936*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value));
937*7cd08927SColin LeMahieu       // op: Rt
938*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(31);
939*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
940*7cd08927SColin LeMahieu       break;
941*7cd08927SColin LeMahieu     }
942*7cd08927SColin LeMahieu 
943*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrdf_abs:
944*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrdt_abs:
945*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrdfnew_abs:
946*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrdtnew_abs: {
947*7cd08927SColin LeMahieu       // op: Rdd
948*7cd08927SColin LeMahieu       Value = insn & UINT64_C(31);
949*7cd08927SColin LeMahieu       DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
950*7cd08927SColin LeMahieu       // op: Pt
951*7cd08927SColin LeMahieu       Value = ((insn >> 9) & UINT64_C(3));
952*7cd08927SColin LeMahieu       DecodePredRegsRegisterClass(MI, Value, 0, 0);
953*7cd08927SColin LeMahieu       // op: u6
954*7cd08927SColin LeMahieu       Value = ((insn >> 15) & UINT64_C(62));
955*7cd08927SColin LeMahieu       Value |= ((insn >> 8) & UINT64_C(1));
956*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value));
957*7cd08927SColin LeMahieu       break;
958*7cd08927SColin LeMahieu     }
959*7cd08927SColin LeMahieu 
960*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrbf_abs:
961*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrbt_abs:
962*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrbfnew_abs:
963*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrbtnew_abs:
964*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrhf_abs:
965*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrht_abs:
966*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrhfnew_abs:
967*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrhtnew_abs:
968*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrubf_abs:
969*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrubt_abs:
970*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrubfnew_abs:
971*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrubtnew_abs:
972*7cd08927SColin LeMahieu     case Hexagon::L4_ploadruhf_abs:
973*7cd08927SColin LeMahieu     case Hexagon::L4_ploadruht_abs:
974*7cd08927SColin LeMahieu     case Hexagon::L4_ploadruhfnew_abs:
975*7cd08927SColin LeMahieu     case Hexagon::L4_ploadruhtnew_abs:
976*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrif_abs:
977*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrit_abs:
978*7cd08927SColin LeMahieu     case Hexagon::L4_ploadrifnew_abs:
979*7cd08927SColin LeMahieu     case Hexagon::L4_ploadritnew_abs:
980*7cd08927SColin LeMahieu       // op: Rd
981*7cd08927SColin LeMahieu       Value = insn & UINT64_C(31);
982*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
983*7cd08927SColin LeMahieu       // op: Pt
984*7cd08927SColin LeMahieu       Value = (insn >> 9) & UINT64_C(3);
985*7cd08927SColin LeMahieu       DecodePredRegsRegisterClass(MI, Value, 0, 0);
986*7cd08927SColin LeMahieu       // op: u6
987*7cd08927SColin LeMahieu       Value = (insn >> 15) & UINT64_C(62);
988*7cd08927SColin LeMahieu       Value |= (insn >> 8) & UINT64_C(1);
989*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value));
990*7cd08927SColin LeMahieu       break;
991*7cd08927SColin LeMahieu 
992*7cd08927SColin LeMahieu     // op: g16_2
993*7cd08927SColin LeMahieu     case (Hexagon::L4_loadri_abs):
994*7cd08927SColin LeMahieu       ++shift;
995*7cd08927SColin LeMahieu     // op: g16_1
996*7cd08927SColin LeMahieu     case Hexagon::L4_loadrh_abs:
997*7cd08927SColin LeMahieu     case Hexagon::L4_loadruh_abs:
998*7cd08927SColin LeMahieu       ++shift;
999*7cd08927SColin LeMahieu     // op: g16_0
1000*7cd08927SColin LeMahieu     case Hexagon::L4_loadrb_abs:
1001*7cd08927SColin LeMahieu     case Hexagon::L4_loadrub_abs: {
1002*7cd08927SColin LeMahieu       // op: Rd
1003*7cd08927SColin LeMahieu       Value |= insn & UINT64_C(31);
1004*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
1005*7cd08927SColin LeMahieu       Value = (insn >> 11) & UINT64_C(49152);
1006*7cd08927SColin LeMahieu       Value |= (insn >> 7) & UINT64_C(15872);
1007*7cd08927SColin LeMahieu       Value |= (insn >> 5) & UINT64_C(511);
1008*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value << shift));
1009*7cd08927SColin LeMahieu       break;
1010*7cd08927SColin LeMahieu     }
1011*7cd08927SColin LeMahieu 
1012*7cd08927SColin LeMahieu     case Hexagon::L4_loadrd_abs: {
1013*7cd08927SColin LeMahieu       Value = insn & UINT64_C(31);
1014*7cd08927SColin LeMahieu       DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
1015*7cd08927SColin LeMahieu       Value = (insn >> 11) & UINT64_C(49152);
1016*7cd08927SColin LeMahieu       Value |= (insn >> 7) & UINT64_C(15872);
1017*7cd08927SColin LeMahieu       Value |= (insn >> 5) & UINT64_C(511);
1018*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value << 3));
1019*7cd08927SColin LeMahieu       break;
1020*7cd08927SColin LeMahieu     }
1021*7cd08927SColin LeMahieu 
1022*7cd08927SColin LeMahieu     case Hexagon::S2_storerdabs: {
1023*7cd08927SColin LeMahieu       // op: g16_3
1024*7cd08927SColin LeMahieu       Value = (insn >> 11) & UINT64_C(49152);
1025*7cd08927SColin LeMahieu       Value |= (insn >> 7) & UINT64_C(15872);
1026*7cd08927SColin LeMahieu       Value |= (insn >> 5) & UINT64_C(256);
1027*7cd08927SColin LeMahieu       Value |= insn & UINT64_C(255);
1028*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value << 3));
1029*7cd08927SColin LeMahieu       // op: Rtt
1030*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(31);
1031*7cd08927SColin LeMahieu       DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
1032*7cd08927SColin LeMahieu       break;
1033*7cd08927SColin LeMahieu     }
1034*7cd08927SColin LeMahieu 
1035*7cd08927SColin LeMahieu     // op: g16_2
1036*7cd08927SColin LeMahieu     case Hexagon::S2_storerinewabs:
1037*7cd08927SColin LeMahieu       ++shift;
1038*7cd08927SColin LeMahieu     // op: g16_1
1039*7cd08927SColin LeMahieu     case Hexagon::S2_storerhnewabs:
1040*7cd08927SColin LeMahieu       ++shift;
1041*7cd08927SColin LeMahieu     // op: g16_0
1042*7cd08927SColin LeMahieu     case Hexagon::S2_storerbnewabs: {
1043*7cd08927SColin LeMahieu       Value = (insn >> 11) & UINT64_C(49152);
1044*7cd08927SColin LeMahieu       Value |= (insn >> 7) & UINT64_C(15872);
1045*7cd08927SColin LeMahieu       Value |= (insn >> 5) & UINT64_C(256);
1046*7cd08927SColin LeMahieu       Value |= insn & UINT64_C(255);
1047*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value << shift));
1048*7cd08927SColin LeMahieu       // op: Nt
1049*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(7);
1050*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
1051*7cd08927SColin LeMahieu       break;
1052*7cd08927SColin LeMahieu     }
1053*7cd08927SColin LeMahieu 
1054*7cd08927SColin LeMahieu     // op: g16_2
1055*7cd08927SColin LeMahieu     case Hexagon::S2_storeriabs:
1056*7cd08927SColin LeMahieu       ++shift;
1057*7cd08927SColin LeMahieu     // op: g16_1
1058*7cd08927SColin LeMahieu     case Hexagon::S2_storerhabs:
1059*7cd08927SColin LeMahieu     case Hexagon::S2_storerfabs:
1060*7cd08927SColin LeMahieu       ++shift;
1061*7cd08927SColin LeMahieu     // op: g16_0
1062*7cd08927SColin LeMahieu     case Hexagon::S2_storerbabs: {
1063*7cd08927SColin LeMahieu       Value = (insn >> 11) & UINT64_C(49152);
1064*7cd08927SColin LeMahieu       Value |= (insn >> 7) & UINT64_C(15872);
1065*7cd08927SColin LeMahieu       Value |= (insn >> 5) & UINT64_C(256);
1066*7cd08927SColin LeMahieu       Value |= insn & UINT64_C(255);
1067*7cd08927SColin LeMahieu       MI.addOperand(MCOperand::createImm(Value << shift));
1068*7cd08927SColin LeMahieu       // op: Rt
1069*7cd08927SColin LeMahieu       Value = (insn >> 8) & UINT64_C(31);
1070*7cd08927SColin LeMahieu       DecodeIntRegsRegisterClass(MI, Value, 0, 0);
1071*7cd08927SColin LeMahieu       break;
1072*7cd08927SColin LeMahieu     }
1073*7cd08927SColin LeMahieu     }
1074*7cd08927SColin LeMahieu     return MCDisassembler::Success;
1075*7cd08927SColin LeMahieu   }
1076*7cd08927SColin LeMahieu   return MCDisassembler::Fail;
1077*7cd08927SColin LeMahieu }
1078*7cd08927SColin LeMahieu 
1079*7cd08927SColin LeMahieu static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
1080*7cd08927SColin LeMahieu                                  void const *Decoder) {
1081*7cd08927SColin LeMahieu 
1082*7cd08927SColin LeMahieu   // Instruction Class for a constant a extender: bits 31:28 = 0x0000
1083*7cd08927SColin LeMahieu   if ((~insn & 0xf0000000) == 0xf0000000) {
1084*7cd08927SColin LeMahieu     unsigned Value;
1085*7cd08927SColin LeMahieu     // 27:16 High 12 bits of 26-bit extender.
1086*7cd08927SColin LeMahieu     Value = (insn & 0x0fff0000) << 4;
1087*7cd08927SColin LeMahieu     // 13:0 Low 14 bits of 26-bit extender.
1088*7cd08927SColin LeMahieu     Value |= ((insn & 0x3fff) << 6);
1089*7cd08927SColin LeMahieu     MI.setOpcode(Hexagon::A4_ext);
1090*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(MI, Value, contextFromDecoder(Decoder));
1091*7cd08927SColin LeMahieu     return MCDisassembler::Success;
1092*7cd08927SColin LeMahieu   }
1093*7cd08927SColin LeMahieu   return MCDisassembler::Fail;
1094*7cd08927SColin LeMahieu }
1095*7cd08927SColin LeMahieu 
1096be8c453dSColin LeMahieu // These values are from HexagonGenMCCodeEmitter.inc and HexagonIsetDx.td
1097be8c453dSColin LeMahieu enum subInstBinaryValues {
1098be8c453dSColin LeMahieu   V4_SA1_addi_BITS = 0x0000,
1099be8c453dSColin LeMahieu   V4_SA1_addi_MASK = 0x1800,
1100be8c453dSColin LeMahieu   V4_SA1_addrx_BITS = 0x1800,
1101be8c453dSColin LeMahieu   V4_SA1_addrx_MASK = 0x1f00,
1102be8c453dSColin LeMahieu   V4_SA1_addsp_BITS = 0x0c00,
1103be8c453dSColin LeMahieu   V4_SA1_addsp_MASK = 0x1c00,
1104be8c453dSColin LeMahieu   V4_SA1_and1_BITS = 0x1200,
1105be8c453dSColin LeMahieu   V4_SA1_and1_MASK = 0x1f00,
1106be8c453dSColin LeMahieu   V4_SA1_clrf_BITS = 0x1a70,
1107be8c453dSColin LeMahieu   V4_SA1_clrf_MASK = 0x1e70,
1108be8c453dSColin LeMahieu   V4_SA1_clrfnew_BITS = 0x1a50,
1109be8c453dSColin LeMahieu   V4_SA1_clrfnew_MASK = 0x1e70,
1110be8c453dSColin LeMahieu   V4_SA1_clrt_BITS = 0x1a60,
1111be8c453dSColin LeMahieu   V4_SA1_clrt_MASK = 0x1e70,
1112be8c453dSColin LeMahieu   V4_SA1_clrtnew_BITS = 0x1a40,
1113be8c453dSColin LeMahieu   V4_SA1_clrtnew_MASK = 0x1e70,
1114be8c453dSColin LeMahieu   V4_SA1_cmpeqi_BITS = 0x1900,
1115be8c453dSColin LeMahieu   V4_SA1_cmpeqi_MASK = 0x1f00,
1116be8c453dSColin LeMahieu   V4_SA1_combine0i_BITS = 0x1c00,
1117be8c453dSColin LeMahieu   V4_SA1_combine0i_MASK = 0x1d18,
1118be8c453dSColin LeMahieu   V4_SA1_combine1i_BITS = 0x1c08,
1119be8c453dSColin LeMahieu   V4_SA1_combine1i_MASK = 0x1d18,
1120be8c453dSColin LeMahieu   V4_SA1_combine2i_BITS = 0x1c10,
1121be8c453dSColin LeMahieu   V4_SA1_combine2i_MASK = 0x1d18,
1122be8c453dSColin LeMahieu   V4_SA1_combine3i_BITS = 0x1c18,
1123be8c453dSColin LeMahieu   V4_SA1_combine3i_MASK = 0x1d18,
1124be8c453dSColin LeMahieu   V4_SA1_combinerz_BITS = 0x1d08,
1125be8c453dSColin LeMahieu   V4_SA1_combinerz_MASK = 0x1d08,
1126be8c453dSColin LeMahieu   V4_SA1_combinezr_BITS = 0x1d00,
1127be8c453dSColin LeMahieu   V4_SA1_combinezr_MASK = 0x1d08,
1128be8c453dSColin LeMahieu   V4_SA1_dec_BITS = 0x1300,
1129be8c453dSColin LeMahieu   V4_SA1_dec_MASK = 0x1f00,
1130be8c453dSColin LeMahieu   V4_SA1_inc_BITS = 0x1100,
1131be8c453dSColin LeMahieu   V4_SA1_inc_MASK = 0x1f00,
1132be8c453dSColin LeMahieu   V4_SA1_seti_BITS = 0x0800,
1133be8c453dSColin LeMahieu   V4_SA1_seti_MASK = 0x1c00,
1134be8c453dSColin LeMahieu   V4_SA1_setin1_BITS = 0x1a00,
1135be8c453dSColin LeMahieu   V4_SA1_setin1_MASK = 0x1e40,
1136be8c453dSColin LeMahieu   V4_SA1_sxtb_BITS = 0x1500,
1137be8c453dSColin LeMahieu   V4_SA1_sxtb_MASK = 0x1f00,
1138be8c453dSColin LeMahieu   V4_SA1_sxth_BITS = 0x1400,
1139be8c453dSColin LeMahieu   V4_SA1_sxth_MASK = 0x1f00,
1140be8c453dSColin LeMahieu   V4_SA1_tfr_BITS = 0x1000,
1141be8c453dSColin LeMahieu   V4_SA1_tfr_MASK = 0x1f00,
1142be8c453dSColin LeMahieu   V4_SA1_zxtb_BITS = 0x1700,
1143be8c453dSColin LeMahieu   V4_SA1_zxtb_MASK = 0x1f00,
1144be8c453dSColin LeMahieu   V4_SA1_zxth_BITS = 0x1600,
1145be8c453dSColin LeMahieu   V4_SA1_zxth_MASK = 0x1f00,
1146be8c453dSColin LeMahieu   V4_SL1_loadri_io_BITS = 0x0000,
1147be8c453dSColin LeMahieu   V4_SL1_loadri_io_MASK = 0x1000,
1148be8c453dSColin LeMahieu   V4_SL1_loadrub_io_BITS = 0x1000,
1149be8c453dSColin LeMahieu   V4_SL1_loadrub_io_MASK = 0x1000,
1150be8c453dSColin LeMahieu   V4_SL2_deallocframe_BITS = 0x1f00,
1151be8c453dSColin LeMahieu   V4_SL2_deallocframe_MASK = 0x1fc0,
1152be8c453dSColin LeMahieu   V4_SL2_jumpr31_BITS = 0x1fc0,
1153be8c453dSColin LeMahieu   V4_SL2_jumpr31_MASK = 0x1fc4,
1154be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_BITS = 0x1fc5,
1155be8c453dSColin LeMahieu   V4_SL2_jumpr31_f_MASK = 0x1fc7,
1156be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_BITS = 0x1fc7,
1157be8c453dSColin LeMahieu   V4_SL2_jumpr31_fnew_MASK = 0x1fc7,
1158be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_BITS = 0x1fc4,
1159be8c453dSColin LeMahieu   V4_SL2_jumpr31_t_MASK = 0x1fc7,
1160be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_BITS = 0x1fc6,
1161be8c453dSColin LeMahieu   V4_SL2_jumpr31_tnew_MASK = 0x1fc7,
1162be8c453dSColin LeMahieu   V4_SL2_loadrb_io_BITS = 0x1000,
1163be8c453dSColin LeMahieu   V4_SL2_loadrb_io_MASK = 0x1800,
1164be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_BITS = 0x1e00,
1165be8c453dSColin LeMahieu   V4_SL2_loadrd_sp_MASK = 0x1f00,
1166be8c453dSColin LeMahieu   V4_SL2_loadrh_io_BITS = 0x0000,
1167be8c453dSColin LeMahieu   V4_SL2_loadrh_io_MASK = 0x1800,
1168be8c453dSColin LeMahieu   V4_SL2_loadri_sp_BITS = 0x1c00,
1169be8c453dSColin LeMahieu   V4_SL2_loadri_sp_MASK = 0x1e00,
1170be8c453dSColin LeMahieu   V4_SL2_loadruh_io_BITS = 0x0800,
1171be8c453dSColin LeMahieu   V4_SL2_loadruh_io_MASK = 0x1800,
1172be8c453dSColin LeMahieu   V4_SL2_return_BITS = 0x1f40,
1173be8c453dSColin LeMahieu   V4_SL2_return_MASK = 0x1fc4,
1174be8c453dSColin LeMahieu   V4_SL2_return_f_BITS = 0x1f45,
1175be8c453dSColin LeMahieu   V4_SL2_return_f_MASK = 0x1fc7,
1176be8c453dSColin LeMahieu   V4_SL2_return_fnew_BITS = 0x1f47,
1177be8c453dSColin LeMahieu   V4_SL2_return_fnew_MASK = 0x1fc7,
1178be8c453dSColin LeMahieu   V4_SL2_return_t_BITS = 0x1f44,
1179be8c453dSColin LeMahieu   V4_SL2_return_t_MASK = 0x1fc7,
1180be8c453dSColin LeMahieu   V4_SL2_return_tnew_BITS = 0x1f46,
1181be8c453dSColin LeMahieu   V4_SL2_return_tnew_MASK = 0x1fc7,
1182be8c453dSColin LeMahieu   V4_SS1_storeb_io_BITS = 0x1000,
1183be8c453dSColin LeMahieu   V4_SS1_storeb_io_MASK = 0x1000,
1184be8c453dSColin LeMahieu   V4_SS1_storew_io_BITS = 0x0000,
1185be8c453dSColin LeMahieu   V4_SS1_storew_io_MASK = 0x1000,
1186be8c453dSColin LeMahieu   V4_SS2_allocframe_BITS = 0x1c00,
1187be8c453dSColin LeMahieu   V4_SS2_allocframe_MASK = 0x1e00,
1188be8c453dSColin LeMahieu   V4_SS2_storebi0_BITS = 0x1200,
1189be8c453dSColin LeMahieu   V4_SS2_storebi0_MASK = 0x1f00,
1190be8c453dSColin LeMahieu   V4_SS2_storebi1_BITS = 0x1300,
1191be8c453dSColin LeMahieu   V4_SS2_storebi1_MASK = 0x1f00,
1192be8c453dSColin LeMahieu   V4_SS2_stored_sp_BITS = 0x0a00,
1193be8c453dSColin LeMahieu   V4_SS2_stored_sp_MASK = 0x1e00,
1194be8c453dSColin LeMahieu   V4_SS2_storeh_io_BITS = 0x0000,
1195be8c453dSColin LeMahieu   V4_SS2_storeh_io_MASK = 0x1800,
1196be8c453dSColin LeMahieu   V4_SS2_storew_sp_BITS = 0x0800,
1197be8c453dSColin LeMahieu   V4_SS2_storew_sp_MASK = 0x1e00,
1198be8c453dSColin LeMahieu   V4_SS2_storewi0_BITS = 0x1000,
1199be8c453dSColin LeMahieu   V4_SS2_storewi0_MASK = 0x1f00,
1200be8c453dSColin LeMahieu   V4_SS2_storewi1_BITS = 0x1100,
1201be8c453dSColin LeMahieu   V4_SS2_storewi1_MASK = 0x1f00
1202be8c453dSColin LeMahieu };
1203be8c453dSColin LeMahieu 
1204be8c453dSColin LeMahieu static unsigned GetSubinstOpcode(unsigned IClass, unsigned inst, unsigned &op,
1205be8c453dSColin LeMahieu                                  raw_ostream &os) {
1206be8c453dSColin LeMahieu   switch (IClass) {
1207be8c453dSColin LeMahieu   case HexagonII::HSIG_L1:
1208be8c453dSColin LeMahieu     if ((inst & V4_SL1_loadri_io_MASK) == V4_SL1_loadri_io_BITS)
1209be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadri_io;
1210be8c453dSColin LeMahieu     else if ((inst & V4_SL1_loadrub_io_MASK) == V4_SL1_loadrub_io_BITS)
1211be8c453dSColin LeMahieu       op = Hexagon::V4_SL1_loadrub_io;
1212be8c453dSColin LeMahieu     else {
1213be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
1214be8c453dSColin LeMahieu       return MCDisassembler::Fail;
1215be8c453dSColin LeMahieu     }
1216be8c453dSColin LeMahieu     break;
1217be8c453dSColin LeMahieu   case HexagonII::HSIG_L2:
1218be8c453dSColin LeMahieu     if ((inst & V4_SL2_deallocframe_MASK) == V4_SL2_deallocframe_BITS)
1219be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_deallocframe;
1220be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_MASK) == V4_SL2_jumpr31_BITS)
1221be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31;
1222be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_f_MASK) == V4_SL2_jumpr31_f_BITS)
1223be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_f;
1224be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_fnew_MASK) == V4_SL2_jumpr31_fnew_BITS)
1225be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_fnew;
1226be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_t_MASK) == V4_SL2_jumpr31_t_BITS)
1227be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_t;
1228be8c453dSColin LeMahieu     else if ((inst & V4_SL2_jumpr31_tnew_MASK) == V4_SL2_jumpr31_tnew_BITS)
1229be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_jumpr31_tnew;
1230be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrb_io_MASK) == V4_SL2_loadrb_io_BITS)
1231be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrb_io;
1232be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrd_sp_MASK) == V4_SL2_loadrd_sp_BITS)
1233be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrd_sp;
1234be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadrh_io_MASK) == V4_SL2_loadrh_io_BITS)
1235be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadrh_io;
1236be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadri_sp_MASK) == V4_SL2_loadri_sp_BITS)
1237be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadri_sp;
1238be8c453dSColin LeMahieu     else if ((inst & V4_SL2_loadruh_io_MASK) == V4_SL2_loadruh_io_BITS)
1239be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_loadruh_io;
1240be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_MASK) == V4_SL2_return_BITS)
1241be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return;
1242be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_f_MASK) == V4_SL2_return_f_BITS)
1243be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_f;
1244be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_fnew_MASK) == V4_SL2_return_fnew_BITS)
1245be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_fnew;
1246be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_t_MASK) == V4_SL2_return_t_BITS)
1247be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_t;
1248be8c453dSColin LeMahieu     else if ((inst & V4_SL2_return_tnew_MASK) == V4_SL2_return_tnew_BITS)
1249be8c453dSColin LeMahieu       op = Hexagon::V4_SL2_return_tnew;
1250be8c453dSColin LeMahieu     else {
1251be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
1252be8c453dSColin LeMahieu       return MCDisassembler::Fail;
1253be8c453dSColin LeMahieu     }
1254be8c453dSColin LeMahieu     break;
1255be8c453dSColin LeMahieu   case HexagonII::HSIG_A:
1256be8c453dSColin LeMahieu     if ((inst & V4_SA1_addi_MASK) == V4_SA1_addi_BITS)
1257be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addi;
1258be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addrx_MASK) == V4_SA1_addrx_BITS)
1259be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addrx;
1260be8c453dSColin LeMahieu     else if ((inst & V4_SA1_addsp_MASK) == V4_SA1_addsp_BITS)
1261be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_addsp;
1262be8c453dSColin LeMahieu     else if ((inst & V4_SA1_and1_MASK) == V4_SA1_and1_BITS)
1263be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_and1;
1264be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrf_MASK) == V4_SA1_clrf_BITS)
1265be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrf;
1266be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrfnew_MASK) == V4_SA1_clrfnew_BITS)
1267be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrfnew;
1268be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrt_MASK) == V4_SA1_clrt_BITS)
1269be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrt;
1270be8c453dSColin LeMahieu     else if ((inst & V4_SA1_clrtnew_MASK) == V4_SA1_clrtnew_BITS)
1271be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_clrtnew;
1272be8c453dSColin LeMahieu     else if ((inst & V4_SA1_cmpeqi_MASK) == V4_SA1_cmpeqi_BITS)
1273be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_cmpeqi;
1274be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine0i_MASK) == V4_SA1_combine0i_BITS)
1275be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine0i;
1276be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine1i_MASK) == V4_SA1_combine1i_BITS)
1277be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine1i;
1278be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine2i_MASK) == V4_SA1_combine2i_BITS)
1279be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine2i;
1280be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combine3i_MASK) == V4_SA1_combine3i_BITS)
1281be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combine3i;
1282be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinerz_MASK) == V4_SA1_combinerz_BITS)
1283be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinerz;
1284be8c453dSColin LeMahieu     else if ((inst & V4_SA1_combinezr_MASK) == V4_SA1_combinezr_BITS)
1285be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_combinezr;
1286be8c453dSColin LeMahieu     else if ((inst & V4_SA1_dec_MASK) == V4_SA1_dec_BITS)
1287be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_dec;
1288be8c453dSColin LeMahieu     else if ((inst & V4_SA1_inc_MASK) == V4_SA1_inc_BITS)
1289be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_inc;
1290be8c453dSColin LeMahieu     else if ((inst & V4_SA1_seti_MASK) == V4_SA1_seti_BITS)
1291be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_seti;
1292be8c453dSColin LeMahieu     else if ((inst & V4_SA1_setin1_MASK) == V4_SA1_setin1_BITS)
1293be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_setin1;
1294be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxtb_MASK) == V4_SA1_sxtb_BITS)
1295be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxtb;
1296be8c453dSColin LeMahieu     else if ((inst & V4_SA1_sxth_MASK) == V4_SA1_sxth_BITS)
1297be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_sxth;
1298be8c453dSColin LeMahieu     else if ((inst & V4_SA1_tfr_MASK) == V4_SA1_tfr_BITS)
1299be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_tfr;
1300be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxtb_MASK) == V4_SA1_zxtb_BITS)
1301be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxtb;
1302be8c453dSColin LeMahieu     else if ((inst & V4_SA1_zxth_MASK) == V4_SA1_zxth_BITS)
1303be8c453dSColin LeMahieu       op = Hexagon::V4_SA1_zxth;
1304be8c453dSColin LeMahieu     else {
1305be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
1306be8c453dSColin LeMahieu       return MCDisassembler::Fail;
1307be8c453dSColin LeMahieu     }
1308be8c453dSColin LeMahieu     break;
1309be8c453dSColin LeMahieu   case HexagonII::HSIG_S1:
1310be8c453dSColin LeMahieu     if ((inst & V4_SS1_storeb_io_MASK) == V4_SS1_storeb_io_BITS)
1311be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storeb_io;
1312be8c453dSColin LeMahieu     else if ((inst & V4_SS1_storew_io_MASK) == V4_SS1_storew_io_BITS)
1313be8c453dSColin LeMahieu       op = Hexagon::V4_SS1_storew_io;
1314be8c453dSColin LeMahieu     else {
1315be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
1316be8c453dSColin LeMahieu       return MCDisassembler::Fail;
1317be8c453dSColin LeMahieu     }
1318be8c453dSColin LeMahieu     break;
1319be8c453dSColin LeMahieu   case HexagonII::HSIG_S2:
1320be8c453dSColin LeMahieu     if ((inst & V4_SS2_allocframe_MASK) == V4_SS2_allocframe_BITS)
1321be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_allocframe;
1322be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi0_MASK) == V4_SS2_storebi0_BITS)
1323be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi0;
1324be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storebi1_MASK) == V4_SS2_storebi1_BITS)
1325be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storebi1;
1326be8c453dSColin LeMahieu     else if ((inst & V4_SS2_stored_sp_MASK) == V4_SS2_stored_sp_BITS)
1327be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_stored_sp;
1328be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storeh_io_MASK) == V4_SS2_storeh_io_BITS)
1329be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storeh_io;
1330be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storew_sp_MASK) == V4_SS2_storew_sp_BITS)
1331be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storew_sp;
1332be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi0_MASK) == V4_SS2_storewi0_BITS)
1333be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi0;
1334be8c453dSColin LeMahieu     else if ((inst & V4_SS2_storewi1_MASK) == V4_SS2_storewi1_BITS)
1335be8c453dSColin LeMahieu       op = Hexagon::V4_SS2_storewi1;
1336be8c453dSColin LeMahieu     else {
1337be8c453dSColin LeMahieu       os << "<unknown subinstruction>";
1338be8c453dSColin LeMahieu       return MCDisassembler::Fail;
1339be8c453dSColin LeMahieu     }
1340be8c453dSColin LeMahieu     break;
1341be8c453dSColin LeMahieu   default:
1342be8c453dSColin LeMahieu     os << "<unknown>";
1343be8c453dSColin LeMahieu     return MCDisassembler::Fail;
1344be8c453dSColin LeMahieu   }
1345be8c453dSColin LeMahieu   return MCDisassembler::Success;
1346be8c453dSColin LeMahieu }
1347be8c453dSColin LeMahieu 
1348be8c453dSColin LeMahieu static unsigned getRegFromSubinstEncoding(unsigned encoded_reg) {
1349be8c453dSColin LeMahieu   if (encoded_reg < 8)
1350be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg;
1351be8c453dSColin LeMahieu   else if (encoded_reg < 16)
1352be8c453dSColin LeMahieu     return Hexagon::R0 + encoded_reg + 8;
1353*7cd08927SColin LeMahieu 
1354*7cd08927SColin LeMahieu   // patently false value
1355be8c453dSColin LeMahieu   return Hexagon::NoRegister;
1356be8c453dSColin LeMahieu }
1357be8c453dSColin LeMahieu 
1358be8c453dSColin LeMahieu static unsigned getDRegFromSubinstEncoding(unsigned encoded_dreg) {
1359be8c453dSColin LeMahieu   if (encoded_dreg < 4)
1360be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg;
1361be8c453dSColin LeMahieu   else if (encoded_dreg < 8)
1362be8c453dSColin LeMahieu     return Hexagon::D0 + encoded_dreg + 4;
1363*7cd08927SColin LeMahieu 
1364*7cd08927SColin LeMahieu   // patently false value
1365be8c453dSColin LeMahieu   return Hexagon::NoRegister;
1366be8c453dSColin LeMahieu }
1367be8c453dSColin LeMahieu 
1368*7cd08927SColin LeMahieu void HexagonDisassembler::addSubinstOperands(MCInst *MI, unsigned opcode,
1369*7cd08927SColin LeMahieu                                              unsigned inst) const {
1370be8c453dSColin LeMahieu   int64_t operand;
1371be8c453dSColin LeMahieu   MCOperand Op;
1372be8c453dSColin LeMahieu   switch (opcode) {
1373be8c453dSColin LeMahieu   case Hexagon::V4_SL2_deallocframe:
1374be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31:
1375be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_f:
1376be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_fnew:
1377be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_t:
1378be8c453dSColin LeMahieu   case Hexagon::V4_SL2_jumpr31_tnew:
1379be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return:
1380be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_f:
1381be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_fnew:
1382be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_t:
1383be8c453dSColin LeMahieu   case Hexagon::V4_SL2_return_tnew:
1384be8c453dSColin LeMahieu     // no operands for these instructions
1385be8c453dSColin LeMahieu     break;
1386be8c453dSColin LeMahieu   case Hexagon::V4_SS2_allocframe:
1387be8c453dSColin LeMahieu     // u 8-4{5_3}
1388be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 3;
1389*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1390be8c453dSColin LeMahieu     break;
1391be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadri_io:
1392be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8{4_2}
1393be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1394be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1395be8c453dSColin LeMahieu     MI->addOperand(Op);
1396be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1397be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1398be8c453dSColin LeMahieu     MI->addOperand(Op);
1399be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 6;
1400*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1401be8c453dSColin LeMahieu     break;
1402be8c453dSColin LeMahieu   case Hexagon::V4_SL1_loadrub_io:
1403be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 11-8
1404be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1405be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1406be8c453dSColin LeMahieu     MI->addOperand(Op);
1407be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1408be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1409be8c453dSColin LeMahieu     MI->addOperand(Op);
1410be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
1411*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1412be8c453dSColin LeMahieu     break;
1413be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrb_io:
1414be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8
1415be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1416be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1417be8c453dSColin LeMahieu     MI->addOperand(Op);
1418be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1419be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1420be8c453dSColin LeMahieu     MI->addOperand(Op);
1421be8c453dSColin LeMahieu     operand = (inst & 0x700) >> 8;
1422*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1423be8c453dSColin LeMahieu     break;
1424be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrh_io:
1425be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadruh_io:
1426be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4, u 10-8{3_1}
1427be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1428be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1429be8c453dSColin LeMahieu     MI->addOperand(Op);
1430be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1431be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1432be8c453dSColin LeMahieu     MI->addOperand(Op);
1433be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
1434*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1435be8c453dSColin LeMahieu     break;
1436be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadrd_sp:
1437be8c453dSColin LeMahieu     // Rdd 2-0, u 7-3{5_3}
1438be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
1439be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1440be8c453dSColin LeMahieu     MI->addOperand(Op);
1441be8c453dSColin LeMahieu     operand = ((inst & 0x0f8) >> 3) << 3;
1442*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1443be8c453dSColin LeMahieu     break;
1444be8c453dSColin LeMahieu   case Hexagon::V4_SL2_loadri_sp:
1445be8c453dSColin LeMahieu     // Rd 3-0, u 8-4{5_2}
1446be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1447be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1448be8c453dSColin LeMahieu     MI->addOperand(Op);
1449be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
1450*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1451be8c453dSColin LeMahieu     break;
1452be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addi:
1453be8c453dSColin LeMahieu     // Rx 3-0 (x2), s7 10-4
1454be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1455be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1456be8c453dSColin LeMahieu     MI->addOperand(Op);
1457be8c453dSColin LeMahieu     MI->addOperand(Op);
1458be8c453dSColin LeMahieu     operand = SignExtend64<7>((inst & 0x7f0) >> 4);
1459*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1460be8c453dSColin LeMahieu     break;
1461be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addrx:
1462be8c453dSColin LeMahieu     // Rx 3-0 (x2), Rs 7-4
1463be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1464be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1465be8c453dSColin LeMahieu     MI->addOperand(Op);
1466be8c453dSColin LeMahieu     MI->addOperand(Op);
1467be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1468be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1469be8c453dSColin LeMahieu     MI->addOperand(Op);
1470be8c453dSColin LeMahieu   case Hexagon::V4_SA1_and1:
1471be8c453dSColin LeMahieu   case Hexagon::V4_SA1_dec:
1472be8c453dSColin LeMahieu   case Hexagon::V4_SA1_inc:
1473be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxtb:
1474be8c453dSColin LeMahieu   case Hexagon::V4_SA1_sxth:
1475be8c453dSColin LeMahieu   case Hexagon::V4_SA1_tfr:
1476be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxtb:
1477be8c453dSColin LeMahieu   case Hexagon::V4_SA1_zxth:
1478be8c453dSColin LeMahieu     // Rd 3-0, Rs 7-4
1479be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1480be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1481be8c453dSColin LeMahieu     MI->addOperand(Op);
1482be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1483be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1484be8c453dSColin LeMahieu     MI->addOperand(Op);
1485be8c453dSColin LeMahieu     break;
1486be8c453dSColin LeMahieu   case Hexagon::V4_SA1_addsp:
1487be8c453dSColin LeMahieu     // Rd 3-0, u 9-4{6_2}
1488be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1489be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1490be8c453dSColin LeMahieu     MI->addOperand(Op);
1491be8c453dSColin LeMahieu     operand = ((inst & 0x3f0) >> 4) << 2;
1492*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1493be8c453dSColin LeMahieu     break;
1494be8c453dSColin LeMahieu   case Hexagon::V4_SA1_seti:
1495be8c453dSColin LeMahieu     // Rd 3-0, u 9-4
1496be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1497be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1498be8c453dSColin LeMahieu     MI->addOperand(Op);
1499be8c453dSColin LeMahieu     operand = (inst & 0x3f0) >> 4;
1500*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1501be8c453dSColin LeMahieu     break;
1502be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrf:
1503be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrfnew:
1504be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrt:
1505be8c453dSColin LeMahieu   case Hexagon::V4_SA1_clrtnew:
1506be8c453dSColin LeMahieu   case Hexagon::V4_SA1_setin1:
1507be8c453dSColin LeMahieu     // Rd 3-0
1508be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1509be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1510be8c453dSColin LeMahieu     MI->addOperand(Op);
1511be8c453dSColin LeMahieu     break;
1512be8c453dSColin LeMahieu   case Hexagon::V4_SA1_cmpeqi:
1513be8c453dSColin LeMahieu     // Rs 7-4, u 1-0
1514be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1515be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1516be8c453dSColin LeMahieu     MI->addOperand(Op);
1517be8c453dSColin LeMahieu     operand = inst & 0x3;
1518*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1519be8c453dSColin LeMahieu     break;
1520be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine0i:
1521be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine1i:
1522be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine2i:
1523be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combine3i:
1524be8c453dSColin LeMahieu     // Rdd 2-0, u 6-5
1525be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
1526be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1527be8c453dSColin LeMahieu     MI->addOperand(Op);
1528be8c453dSColin LeMahieu     operand = (inst & 0x060) >> 5;
1529*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1530be8c453dSColin LeMahieu     break;
1531be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinerz:
1532be8c453dSColin LeMahieu   case Hexagon::V4_SA1_combinezr:
1533be8c453dSColin LeMahieu     // Rdd 2-0, Rs 7-4
1534be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
1535be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1536be8c453dSColin LeMahieu     MI->addOperand(Op);
1537be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1538be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1539be8c453dSColin LeMahieu     MI->addOperand(Op);
1540be8c453dSColin LeMahieu     break;
1541be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storeb_io:
1542be8c453dSColin LeMahieu     // Rs 7-4, u 11-8, Rt 3-0
1543be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1544be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1545be8c453dSColin LeMahieu     MI->addOperand(Op);
1546be8c453dSColin LeMahieu     operand = (inst & 0xf00) >> 8;
1547*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1548be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1549be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1550be8c453dSColin LeMahieu     MI->addOperand(Op);
1551be8c453dSColin LeMahieu     break;
1552be8c453dSColin LeMahieu   case Hexagon::V4_SS1_storew_io:
1553be8c453dSColin LeMahieu     // Rs 7-4, u 11-8{4_2}, Rt 3-0
1554be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1555be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1556be8c453dSColin LeMahieu     MI->addOperand(Op);
1557be8c453dSColin LeMahieu     operand = ((inst & 0xf00) >> 8) << 2;
1558*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1559be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1560be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1561be8c453dSColin LeMahieu     MI->addOperand(Op);
1562be8c453dSColin LeMahieu     break;
1563be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi0:
1564be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storebi1:
1565be8c453dSColin LeMahieu     // Rs 7-4, u 3-0
1566be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1567be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1568be8c453dSColin LeMahieu     MI->addOperand(Op);
1569be8c453dSColin LeMahieu     operand = inst & 0xf;
1570*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1571be8c453dSColin LeMahieu     break;
1572be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi0:
1573be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storewi1:
1574be8c453dSColin LeMahieu     // Rs 7-4, u 3-0{4_2}
1575be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1576be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1577be8c453dSColin LeMahieu     MI->addOperand(Op);
1578be8c453dSColin LeMahieu     operand = (inst & 0xf) << 2;
1579*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1580be8c453dSColin LeMahieu     break;
1581be8c453dSColin LeMahieu   case Hexagon::V4_SS2_stored_sp:
1582be8c453dSColin LeMahieu     // s 8-3{6_3}, Rtt 2-0
1583be8c453dSColin LeMahieu     operand = SignExtend64<9>(((inst & 0x1f8) >> 3) << 3);
1584*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1585be8c453dSColin LeMahieu     operand = getDRegFromSubinstEncoding(inst & 0x7);
1586be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1587be8c453dSColin LeMahieu     MI->addOperand(Op);
1588160f73e3SColin LeMahieu     break;
1589be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storeh_io:
1590be8c453dSColin LeMahieu     // Rs 7-4, u 10-8{3_1}, Rt 3-0
1591be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding((inst & 0xf0) >> 4);
1592be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1593be8c453dSColin LeMahieu     MI->addOperand(Op);
1594be8c453dSColin LeMahieu     operand = ((inst & 0x700) >> 8) << 1;
1595*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1596be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1597be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1598be8c453dSColin LeMahieu     MI->addOperand(Op);
1599be8c453dSColin LeMahieu     break;
1600be8c453dSColin LeMahieu   case Hexagon::V4_SS2_storew_sp:
1601be8c453dSColin LeMahieu     // u 8-4{5_2}, Rd 3-0
1602be8c453dSColin LeMahieu     operand = ((inst & 0x1f0) >> 4) << 2;
1603*7cd08927SColin LeMahieu     HexagonMCInstrInfo::addConstant(*MI, operand, getContext());
1604be8c453dSColin LeMahieu     operand = getRegFromSubinstEncoding(inst & 0xf);
1605be8c453dSColin LeMahieu     Op = MCOperand::createReg(operand);
1606be8c453dSColin LeMahieu     MI->addOperand(Op);
1607be8c453dSColin LeMahieu     break;
1608be8c453dSColin LeMahieu   default:
1609be8c453dSColin LeMahieu     // don't crash with an invalid subinstruction
1610be8c453dSColin LeMahieu     // llvm_unreachable("Invalid subinstruction in duplex instruction");
1611be8c453dSColin LeMahieu     break;
1612be8c453dSColin LeMahieu   }
1613be8c453dSColin LeMahieu }
1614