1327952Sdim//===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===//
2277323Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6277323Sdim//
7277323Sdim//===----------------------------------------------------------------------===//
8277323Sdim
9296417Sdim#define DEBUG_TYPE "hexagon-disassembler"
10296417Sdim
11277323Sdim#include "MCTargetDesc/HexagonBaseInfo.h"
12296417Sdim#include "MCTargetDesc/HexagonMCChecker.h"
13321369Sdim#include "MCTargetDesc/HexagonMCInstrInfo.h"
14296417Sdim#include "MCTargetDesc/HexagonMCTargetDesc.h"
15353358Sdim#include "TargetInfo/HexagonTargetInfo.h"
16314564Sdim#include "llvm/ADT/ArrayRef.h"
17314564Sdim#include "llvm/ADT/STLExtras.h"
18321369Sdim#include "llvm/MC/MCContext.h"
19309124Sdim#include "llvm/MC/MCDisassembler/MCDisassembler.h"
20277323Sdim#include "llvm/MC/MCExpr.h"
21277323Sdim#include "llvm/MC/MCFixedLenDisassembler.h"
22277323Sdim#include "llvm/MC/MCInst.h"
23296417Sdim#include "llvm/MC/MCInstrInfo.h"
24314564Sdim#include "llvm/MC/MCRegisterInfo.h"
25277323Sdim#include "llvm/MC/MCSubtargetInfo.h"
26327952Sdim#include "llvm/Support/Endian.h"
27314564Sdim#include "llvm/Support/MathExtras.h"
28321369Sdim#include "llvm/Support/TargetRegistry.h"
29296417Sdim#include "llvm/Support/raw_ostream.h"
30314564Sdim#include <cassert>
31314564Sdim#include <cstddef>
32314564Sdim#include <cstdint>
33314564Sdim#include <memory>
34277323Sdim
35277323Sdimusing namespace llvm;
36288943Sdimusing namespace Hexagon;
37277323Sdim
38327952Sdimusing DecodeStatus = MCDisassembler::DecodeStatus;
39277323Sdim
40277323Sdimnamespace {
41314564Sdim
42341825Sdim/// Hexagon disassembler for all Hexagon platforms.
43277323Sdimclass HexagonDisassembler : public MCDisassembler {
44277323Sdimpublic:
45296417Sdim  std::unique_ptr<MCInstrInfo const> const MCII;
46288943Sdim  std::unique_ptr<MCInst *> CurrentBundle;
47327952Sdim  mutable MCInst const *CurrentExtender;
48314564Sdim
49296417Sdim  HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
50296417Sdim                      MCInstrInfo const *MCII)
51327952Sdim      : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *),
52327952Sdim        CurrentExtender(nullptr) {}
53277323Sdim
54288943Sdim  DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
55288943Sdim                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
56360784Sdim                                    raw_ostream &CStream, bool &Complete) const;
57277323Sdim  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
58277323Sdim                              ArrayRef<uint8_t> Bytes, uint64_t Address,
59277323Sdim                              raw_ostream &CStream) const override;
60327952Sdim  void remapInstruction(MCInst &Instr) const;
61277323Sdim};
62277323Sdim
63327952Sdimstatic uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI,
64327952Sdim                          int64_t Value) {
65327952Sdim  MCInstrInfo MCII = *Disassembler.MCII;
66327952Sdim  if (!Disassembler.CurrentExtender ||
67327952Sdim      MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
68327952Sdim    return Value;
69327952Sdim  unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
70327952Sdim  uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
71327952Sdim  int64_t Bits;
72327952Sdim  bool Success =
73327952Sdim      Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute(
74327952Sdim          Bits);
75327952Sdim  assert(Success);
76327952Sdim  (void)Success;
77327952Sdim  uint64_t Upper26 = static_cast<uint64_t>(Bits);
78327952Sdim  uint64_t Operand = Upper26 | Lower6;
79327952Sdim  return Operand;
80321369Sdim}
81327952Sdimstatic HexagonDisassembler const &disassembler(void const *Decoder) {
82327952Sdim  return *static_cast<HexagonDisassembler const *>(Decoder);
83327952Sdim}
84327952Sdimtemplate <size_t T>
85327952Sdimstatic void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
86327952Sdim  HexagonDisassembler const &Disassembler = disassembler(Decoder);
87327952Sdim  int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp));
88327952Sdim  int64_t Extended = SignExtend64<32>(FullValue);
89327952Sdim  HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
90327952Sdim}
91327952Sdim}
92314564Sdim
93296417Sdim// Forward declare these because the auto-generated code will reference them.
94296417Sdim// Definitions are further down.
95296417Sdim
96296417Sdimstatic DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
97288943Sdim                                               uint64_t Address,
98288943Sdim                                               const void *Decoder);
99321369Sdimstatic DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst,
100321369Sdim                                                      unsigned RegNo,
101321369Sdim                                                      uint64_t Address,
102321369Sdim                                                      const void *Decoder);
103296417Sdimstatic DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
104296417Sdim                                                   uint64_t Address,
105296417Sdim                                                   const void *Decoder);
106327952Sdimstatic DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
107327952Sdim                                             uint64_t Address,
108327952Sdim                                             const void *Decoder);
109296417Sdimstatic DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
110296417Sdim                                                  uint64_t Address,
111296417Sdim                                                  const void *Decoder);
112321369Sdimstatic DecodeStatus
113321369SdimDecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
114321369Sdim                                         uint64_t Address, const void *Decoder);
115327952Sdimstatic DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
116327952Sdim                                             uint64_t Address,
117327952Sdim                                             const void *Decoder);
118344779Sdimstatic DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst,
119344779Sdim                                              unsigned RegNo,
120344779Sdim                                              uint64_t Address,
121344779Sdim                                              const void *Decoder);
122296417Sdimstatic DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
123296417Sdim                                                uint64_t Address,
124296417Sdim                                                const void *Decoder);
125327952Sdimstatic DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
126327952Sdim                                             uint64_t Address,
127327952Sdim                                             const void *Decoder);
128277323Sdimstatic DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
129288943Sdim                                               uint64_t Address,
130288943Sdim                                               const void *Decoder);
131341825Sdimstatic DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
132341825Sdim                                                 uint64_t Address,
133341825Sdim                                                 const void *Decoder);
134296417Sdimstatic DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
135296417Sdim                                               uint64_t Address,
136296417Sdim                                               const void *Decoder);
137288943Sdimstatic DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
138288943Sdim                                                 uint64_t Address,
139296417Sdim                                                 const void *Decoder);
140341825Sdimstatic DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
141341825Sdim                                                   uint64_t Address,
142341825Sdim                                                   const void *Decoder);
143277323Sdim
144296417Sdimstatic DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
145296417Sdim                                       uint64_t Address, const void *Decoder);
146321369Sdimstatic DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
147321369Sdim                                    uint64_t /*Address*/, const void *Decoder);
148296417Sdimstatic DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
149296417Sdim                                    const void *Decoder);
150353358Sdim#include "HexagonDepDecoders.inc"
151277323Sdim#include "HexagonGenDisassemblerTables.inc"
152277323Sdim
153296417Sdimstatic MCDisassembler *createHexagonDisassembler(const Target &T,
154296417Sdim                                                 const MCSubtargetInfo &STI,
155277323Sdim                                                 MCContext &Ctx) {
156296417Sdim  return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
157277323Sdim}
158277323Sdim
159360784Sdimextern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonDisassembler() {
160314564Sdim  TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
161277323Sdim                                         createHexagonDisassembler);
162277323Sdim}
163277323Sdim
164277323SdimDecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
165277323Sdim                                                 ArrayRef<uint8_t> Bytes,
166277323Sdim                                                 uint64_t Address,
167277323Sdim                                                 raw_ostream &cs) const {
168288943Sdim  DecodeStatus Result = DecodeStatus::Success;
169288943Sdim  bool Complete = false;
170288943Sdim  Size = 0;
171277323Sdim
172288943Sdim  *CurrentBundle = &MI;
173327952Sdim  MI.setOpcode(Hexagon::BUNDLE);
174327952Sdim  MI.addOperand(MCOperand::createImm(0));
175314564Sdim  while (Result == Success && !Complete) {
176288943Sdim    if (Bytes.size() < HEXAGON_INSTR_SIZE)
177288943Sdim      return MCDisassembler::Fail;
178288943Sdim    MCInst *Inst = new (getContext()) MCInst;
179360784Sdim    Result = getSingleInstruction(*Inst, MI, Bytes, Address, cs, Complete);
180288943Sdim    MI.addOperand(MCOperand::createInst(Inst));
181288943Sdim    Size += HEXAGON_INSTR_SIZE;
182288943Sdim    Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
183288943Sdim  }
184321369Sdim  if (Result == MCDisassembler::Fail)
185296417Sdim    return Result;
186321369Sdim  if (Size > HEXAGON_MAX_PACKET_SIZE)
187296417Sdim    return MCDisassembler::Fail;
188321369Sdim  HexagonMCChecker Checker(getContext(), *MCII, STI, MI,
189321369Sdim                           *getContext().getRegisterInfo(), false);
190321369Sdim  if (!Checker.check())
191321369Sdim    return MCDisassembler::Fail;
192327952Sdim  remapInstruction(MI);
193296417Sdim  return MCDisassembler::Success;
194288943Sdim}
195288943Sdim
196327952Sdimvoid HexagonDisassembler::remapInstruction(MCInst &Instr) const {
197327952Sdim  for (auto I: HexagonMCInstrInfo::bundleInstructions(Instr)) {
198327952Sdim    auto &MI = const_cast<MCInst &>(*I.getInst());
199327952Sdim    switch (MI.getOpcode()) {
200327952Sdim    case Hexagon::S2_allocframe:
201327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::R29) {
202327952Sdim        MI.setOpcode(Hexagon::S6_allocframe_to_raw);
203327952Sdim        MI.erase(MI.begin () + 1);
204327952Sdim        MI.erase(MI.begin ());
205327952Sdim      }
206327952Sdim      break;
207327952Sdim    case Hexagon::L2_deallocframe:
208327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
209327952Sdim          MI.getOperand(1).getReg() == Hexagon::R30) {
210327952Sdim        MI.setOpcode(L6_deallocframe_map_to_raw);
211327952Sdim        MI.erase(MI.begin () + 1);
212327952Sdim        MI.erase(MI.begin ());
213327952Sdim      }
214327952Sdim      break;
215327952Sdim    case Hexagon::L4_return:
216327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
217327952Sdim          MI.getOperand(1).getReg() == Hexagon::R30) {
218327952Sdim        MI.setOpcode(L6_return_map_to_raw);
219327952Sdim        MI.erase(MI.begin () + 1);
220327952Sdim        MI.erase(MI.begin ());
221327952Sdim      }
222327952Sdim      break;
223327952Sdim    case Hexagon::L4_return_t:
224327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
225327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
226327952Sdim        MI.setOpcode(L4_return_map_to_raw_t);
227327952Sdim        MI.erase(MI.begin () + 2);
228327952Sdim        MI.erase(MI.begin ());
229327952Sdim      }
230327952Sdim      break;
231327952Sdim    case Hexagon::L4_return_f:
232327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
233327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
234327952Sdim        MI.setOpcode(L4_return_map_to_raw_f);
235327952Sdim        MI.erase(MI.begin () + 2);
236327952Sdim        MI.erase(MI.begin ());
237327952Sdim      }
238327952Sdim      break;
239327952Sdim    case Hexagon::L4_return_tnew_pt:
240327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
241327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
242327952Sdim        MI.setOpcode(L4_return_map_to_raw_tnew_pt);
243327952Sdim        MI.erase(MI.begin () + 2);
244327952Sdim        MI.erase(MI.begin ());
245327952Sdim      }
246327952Sdim      break;
247327952Sdim    case Hexagon::L4_return_fnew_pt:
248327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
249327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
250327952Sdim        MI.setOpcode(L4_return_map_to_raw_fnew_pt);
251327952Sdim        MI.erase(MI.begin () + 2);
252327952Sdim        MI.erase(MI.begin ());
253327952Sdim      }
254327952Sdim      break;
255327952Sdim    case Hexagon::L4_return_tnew_pnt:
256327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
257327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
258327952Sdim        MI.setOpcode(L4_return_map_to_raw_tnew_pnt);
259327952Sdim        MI.erase(MI.begin () + 2);
260327952Sdim        MI.erase(MI.begin ());
261327952Sdim      }
262327952Sdim      break;
263327952Sdim    case Hexagon::L4_return_fnew_pnt:
264327952Sdim      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
265327952Sdim          MI.getOperand(2).getReg() == Hexagon::R30) {
266327952Sdim        MI.setOpcode(L4_return_map_to_raw_fnew_pnt);
267327952Sdim        MI.erase(MI.begin () + 2);
268327952Sdim        MI.erase(MI.begin ());
269327952Sdim      }
270327952Sdim      break;
271327952Sdim    }
272327952Sdim  }
273327952Sdim}
274327952Sdim
275327952Sdimstatic void adjustDuplex(MCInst &MI, MCContext &Context) {
276321369Sdim  switch (MI.getOpcode()) {
277321369Sdim  case Hexagon::SA1_setin1:
278321369Sdim    MI.insert(MI.begin() + 1,
279321369Sdim              MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
280321369Sdim    break;
281321369Sdim  case Hexagon::SA1_dec:
282321369Sdim    MI.insert(MI.begin() + 2,
283321369Sdim              MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
284321369Sdim    break;
285321369Sdim  default:
286321369Sdim    break;
287321369Sdim  }
288296417Sdim}
289296417Sdim
290360784SdimDecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
291360784Sdim                                                       ArrayRef<uint8_t> Bytes,
292360784Sdim                                                       uint64_t Address,
293360784Sdim                                                       raw_ostream &cs,
294360784Sdim                                                       bool &Complete) const {
295288943Sdim  assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
296288943Sdim
297321369Sdim  uint32_t Instruction = support::endian::read32le(Bytes.data());
298277323Sdim
299288943Sdim  auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
300288943Sdim  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
301288943Sdim      HexagonII::INST_PARSE_LOOP_END) {
302288943Sdim    if (BundleSize == 0)
303288943Sdim      HexagonMCInstrInfo::setInnerLoop(MCB);
304288943Sdim    else if (BundleSize == 1)
305288943Sdim      HexagonMCInstrInfo::setOuterLoop(MCB);
306288943Sdim    else
307288943Sdim      return DecodeStatus::Fail;
308288943Sdim  }
309288943Sdim
310327952Sdim  CurrentExtender = HexagonMCInstrInfo::extenderForIndex(
311321369Sdim      MCB, HexagonMCInstrInfo::bundleSize(MCB));
312321369Sdim
313321369Sdim  DecodeStatus Result = DecodeStatus::Fail;
314288943Sdim  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
315288943Sdim      HexagonII::INST_PARSE_DUPLEX) {
316321369Sdim    unsigned duplexIClass;
317321369Sdim    uint8_t const *DecodeLow, *DecodeHigh;
318288943Sdim    duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
319288943Sdim    switch (duplexIClass) {
320288943Sdim    default:
321288943Sdim      return MCDisassembler::Fail;
322288943Sdim    case 0:
323321369Sdim      DecodeLow = DecoderTableSUBINSN_L132;
324321369Sdim      DecodeHigh = DecoderTableSUBINSN_L132;
325288943Sdim      break;
326288943Sdim    case 1:
327321369Sdim      DecodeLow = DecoderTableSUBINSN_L232;
328321369Sdim      DecodeHigh = DecoderTableSUBINSN_L132;
329288943Sdim      break;
330288943Sdim    case 2:
331321369Sdim      DecodeLow = DecoderTableSUBINSN_L232;
332321369Sdim      DecodeHigh = DecoderTableSUBINSN_L232;
333288943Sdim      break;
334288943Sdim    case 3:
335321369Sdim      DecodeLow = DecoderTableSUBINSN_A32;
336321369Sdim      DecodeHigh = DecoderTableSUBINSN_A32;
337288943Sdim      break;
338288943Sdim    case 4:
339321369Sdim      DecodeLow = DecoderTableSUBINSN_L132;
340321369Sdim      DecodeHigh = DecoderTableSUBINSN_A32;
341288943Sdim      break;
342288943Sdim    case 5:
343321369Sdim      DecodeLow = DecoderTableSUBINSN_L232;
344321369Sdim      DecodeHigh = DecoderTableSUBINSN_A32;
345288943Sdim      break;
346288943Sdim    case 6:
347321369Sdim      DecodeLow = DecoderTableSUBINSN_S132;
348321369Sdim      DecodeHigh = DecoderTableSUBINSN_A32;
349288943Sdim      break;
350288943Sdim    case 7:
351321369Sdim      DecodeLow = DecoderTableSUBINSN_S232;
352321369Sdim      DecodeHigh = DecoderTableSUBINSN_A32;
353288943Sdim      break;
354288943Sdim    case 8:
355321369Sdim      DecodeLow = DecoderTableSUBINSN_S132;
356321369Sdim      DecodeHigh = DecoderTableSUBINSN_L132;
357288943Sdim      break;
358288943Sdim    case 9:
359321369Sdim      DecodeLow = DecoderTableSUBINSN_S132;
360321369Sdim      DecodeHigh = DecoderTableSUBINSN_L232;
361288943Sdim      break;
362288943Sdim    case 10:
363321369Sdim      DecodeLow = DecoderTableSUBINSN_S132;
364321369Sdim      DecodeHigh = DecoderTableSUBINSN_S132;
365288943Sdim      break;
366288943Sdim    case 11:
367321369Sdim      DecodeLow = DecoderTableSUBINSN_S232;
368321369Sdim      DecodeHigh = DecoderTableSUBINSN_S132;
369288943Sdim      break;
370288943Sdim    case 12:
371321369Sdim      DecodeLow = DecoderTableSUBINSN_S232;
372321369Sdim      DecodeHigh = DecoderTableSUBINSN_L132;
373288943Sdim      break;
374288943Sdim    case 13:
375321369Sdim      DecodeLow = DecoderTableSUBINSN_S232;
376321369Sdim      DecodeHigh = DecoderTableSUBINSN_L232;
377288943Sdim      break;
378288943Sdim    case 14:
379321369Sdim      DecodeLow = DecoderTableSUBINSN_S232;
380321369Sdim      DecodeHigh = DecoderTableSUBINSN_S232;
381288943Sdim      break;
382288943Sdim    }
383321369Sdim    MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass);
384288943Sdim    MCInst *MILow = new (getContext()) MCInst;
385288943Sdim    MCInst *MIHigh = new (getContext()) MCInst;
386327952Sdim    auto TmpExtender = CurrentExtender;
387327952Sdim    CurrentExtender =
388327952Sdim        nullptr; // constant extenders in duplex must always be in slot 1
389321369Sdim    Result = decodeInstruction(DecodeLow, *MILow, Instruction & 0x1fff, Address,
390321369Sdim                               this, STI);
391327952Sdim    CurrentExtender = TmpExtender;
392321369Sdim    if (Result != DecodeStatus::Success)
393321369Sdim      return DecodeStatus::Fail;
394321369Sdim    adjustDuplex(*MILow, getContext());
395321369Sdim    Result = decodeInstruction(
396321369Sdim        DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff, Address, this, STI);
397321369Sdim    if (Result != DecodeStatus::Success)
398321369Sdim      return DecodeStatus::Fail;
399321369Sdim    adjustDuplex(*MIHigh, getContext());
400288943Sdim    MCOperand OPLow = MCOperand::createInst(MILow);
401288943Sdim    MCOperand OPHigh = MCOperand::createInst(MIHigh);
402288943Sdim    MI.addOperand(OPLow);
403288943Sdim    MI.addOperand(OPHigh);
404288943Sdim    Complete = true;
405288943Sdim  } else {
406288943Sdim    if ((Instruction & HexagonII::INST_PARSE_MASK) ==
407288943Sdim        HexagonII::INST_PARSE_PACKET_END)
408288943Sdim      Complete = true;
409296417Sdim
410327952Sdim    if (CurrentExtender != nullptr)
411321369Sdim      Result = decodeInstruction(DecoderTableMustExtend32, MI, Instruction,
412321369Sdim                                 Address, this, STI);
413321369Sdim
414321369Sdim    if (Result != MCDisassembler::Success)
415321369Sdim      Result = decodeInstruction(DecoderTable32, MI, Instruction, Address, this,
416321369Sdim                                 STI);
417321369Sdim
418321369Sdim    if (Result != MCDisassembler::Success &&
419321369Sdim        STI.getFeatureBits()[Hexagon::ExtensionHVX])
420321369Sdim      Result = decodeInstruction(DecoderTableEXT_mmvec32, MI, Instruction,
421321369Sdim                                 Address, this, STI);
422321369Sdim
423288943Sdim  }
424288943Sdim
425321369Sdim  switch (MI.getOpcode()) {
426314564Sdim  case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
427314564Sdim  case Hexagon::J4_cmpeqn1_f_jumpnv_t:
428314564Sdim  case Hexagon::J4_cmpeqn1_fp0_jump_nt:
429314564Sdim  case Hexagon::J4_cmpeqn1_fp0_jump_t:
430314564Sdim  case Hexagon::J4_cmpeqn1_fp1_jump_nt:
431314564Sdim  case Hexagon::J4_cmpeqn1_fp1_jump_t:
432314564Sdim  case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
433314564Sdim  case Hexagon::J4_cmpeqn1_t_jumpnv_t:
434314564Sdim  case Hexagon::J4_cmpeqn1_tp0_jump_nt:
435314564Sdim  case Hexagon::J4_cmpeqn1_tp0_jump_t:
436314564Sdim  case Hexagon::J4_cmpeqn1_tp1_jump_nt:
437314564Sdim  case Hexagon::J4_cmpeqn1_tp1_jump_t:
438314564Sdim  case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
439314564Sdim  case Hexagon::J4_cmpgtn1_f_jumpnv_t:
440314564Sdim  case Hexagon::J4_cmpgtn1_fp0_jump_nt:
441314564Sdim  case Hexagon::J4_cmpgtn1_fp0_jump_t:
442314564Sdim  case Hexagon::J4_cmpgtn1_fp1_jump_nt:
443314564Sdim  case Hexagon::J4_cmpgtn1_fp1_jump_t:
444314564Sdim  case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
445314564Sdim  case Hexagon::J4_cmpgtn1_t_jumpnv_t:
446314564Sdim  case Hexagon::J4_cmpgtn1_tp0_jump_nt:
447314564Sdim  case Hexagon::J4_cmpgtn1_tp0_jump_t:
448314564Sdim  case Hexagon::J4_cmpgtn1_tp1_jump_nt:
449314564Sdim  case Hexagon::J4_cmpgtn1_tp1_jump_t:
450321369Sdim    MI.insert(MI.begin() + 1,
451321369Sdim              MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
452314564Sdim    break;
453314564Sdim  default:
454314564Sdim    break;
455314564Sdim  }
456314564Sdim
457296417Sdim  if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
458296417Sdim    unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
459296417Sdim    MCOperand &MCO = MI.getOperand(OpIndex);
460296417Sdim    assert(MCO.isReg() && "New value consumers must be registers");
461296417Sdim    unsigned Register =
462296417Sdim        getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
463296417Sdim    if ((Register & 0x6) == 0)
464296417Sdim      // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
465296417Sdim      return MCDisassembler::Fail;
466296417Sdim    unsigned Lookback = (Register & 0x6) >> 1;
467296417Sdim    unsigned Offset = 1;
468296417Sdim    bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
469327952Sdim    bool PrevVector = false;
470296417Sdim    auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
471296417Sdim    auto i = Instructions.end() - 1;
472296417Sdim    for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
473296417Sdim      if (i == n)
474296417Sdim        // Couldn't find producer
475296417Sdim        return MCDisassembler::Fail;
476327952Sdim      bool CurrentVector = HexagonMCInstrInfo::isVector(*MCII, *i->getInst());
477327952Sdim      if (Vector && !CurrentVector)
478296417Sdim        // Skip scalars when calculating distances for vectors
479296417Sdim        ++Lookback;
480327952Sdim      if (HexagonMCInstrInfo::isImmext(*i->getInst()) && (Vector == PrevVector))
481296417Sdim        ++Lookback;
482327952Sdim      PrevVector = CurrentVector;
483296417Sdim      if (Offset == Lookback)
484296417Sdim        break;
485296417Sdim    }
486296417Sdim    auto const &Inst = *i->getInst();
487296417Sdim    bool SubregBit = (Register & 0x1) != 0;
488327952Sdim    if (HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
489296417Sdim      // If subreg bit is set we're selecting the second produced newvalue
490327952Sdim      unsigned Producer = SubregBit ?
491327952Sdim          HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg() :
492296417Sdim          HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
493296417Sdim      assert(Producer != Hexagon::NoRegister);
494296417Sdim      MCO.setReg(Producer);
495296417Sdim    } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
496296417Sdim      unsigned Producer =
497296417Sdim          HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
498296417Sdim      if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
499296417Sdim        Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0;
500296417Sdim      else if (SubregBit)
501309124Sdim        // Hexagon PRM 10.11 New-value operands
502309124Sdim        // Nt[0] is reserved and should always be encoded as zero.
503296417Sdim        return MCDisassembler::Fail;
504296417Sdim      assert(Producer != Hexagon::NoRegister);
505296417Sdim      MCO.setReg(Producer);
506296417Sdim    } else
507296417Sdim      return MCDisassembler::Fail;
508296417Sdim  }
509296417Sdim
510327952Sdim  if (CurrentExtender != nullptr) {
511321369Sdim    MCInst const &Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI)
512321369Sdim                             ? *MI.getOperand(1).getInst()
513321369Sdim                             : MI;
514296417Sdim    if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
515296417Sdim        !HexagonMCInstrInfo::isExtended(*MCII, Inst))
516296417Sdim      return MCDisassembler::Fail;
517296417Sdim  }
518277323Sdim  return Result;
519277323Sdim}
520288943Sdim
521296417Sdimstatic DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
522296417Sdim                                        ArrayRef<MCPhysReg> Table) {
523296417Sdim  if (RegNo < Table.size()) {
524296417Sdim    Inst.addOperand(MCOperand::createReg(Table[RegNo]));
525296417Sdim    return MCDisassembler::Success;
526296417Sdim  }
527296417Sdim
528296417Sdim  return MCDisassembler::Fail;
529296417Sdim}
530296417Sdim
531296417Sdimstatic DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
532296417Sdim                                                   uint64_t Address,
533296417Sdim                                                   const void *Decoder) {
534296417Sdim  return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
535296417Sdim}
536296417Sdim
537296417Sdimstatic DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
538296417Sdim                                               uint64_t Address,
539296417Sdim                                               const void *Decoder) {
540296417Sdim  static const MCPhysReg IntRegDecoderTable[] = {
541296417Sdim      Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
542296417Sdim      Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
543296417Sdim      Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
544296417Sdim      Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
545296417Sdim      Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
546296417Sdim      Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
547296417Sdim      Hexagon::R30, Hexagon::R31};
548296417Sdim
549296417Sdim  return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable);
550296417Sdim}
551296417Sdim
552321369Sdimstatic DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst,
553321369Sdim                                                      unsigned RegNo,
554321369Sdim                                                      uint64_t Address,
555321369Sdim                                                      const void *Decoder) {
556321369Sdim  static const MCPhysReg GeneralSubRegDecoderTable[] = {
557321369Sdim      Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,
558321369Sdim      Hexagon::R4,  Hexagon::R5,  Hexagon::R6,  Hexagon::R7,
559321369Sdim      Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
560321369Sdim      Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
561321369Sdim  };
562321369Sdim
563321369Sdim  return DecodeRegisterClass(Inst, RegNo, GeneralSubRegDecoderTable);
564321369Sdim}
565321369Sdim
566327952Sdimstatic DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
567327952Sdim                                             uint64_t /*Address*/,
568327952Sdim                                             const void *Decoder) {
569327952Sdim  static const MCPhysReg HvxVRDecoderTable[] = {
570296417Sdim      Hexagon::V0,  Hexagon::V1,  Hexagon::V2,  Hexagon::V3,  Hexagon::V4,
571296417Sdim      Hexagon::V5,  Hexagon::V6,  Hexagon::V7,  Hexagon::V8,  Hexagon::V9,
572296417Sdim      Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
573296417Sdim      Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
574296417Sdim      Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
575296417Sdim      Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
576296417Sdim      Hexagon::V30, Hexagon::V31};
577296417Sdim
578327952Sdim  return DecodeRegisterClass(Inst, RegNo, HvxVRDecoderTable);
579296417Sdim}
580296417Sdim
581296417Sdimstatic DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
582296417Sdim                                                  uint64_t /*Address*/,
583296417Sdim                                                  const void *Decoder) {
584296417Sdim  static const MCPhysReg DoubleRegDecoderTable[] = {
585296417Sdim      Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
586296417Sdim      Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
587296417Sdim      Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
588296417Sdim      Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
589296417Sdim
590296417Sdim  return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable);
591296417Sdim}
592296417Sdim
593321369Sdimstatic DecodeStatus DecodeGeneralDoubleLow8RegsRegisterClass(
594321369Sdim    MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, const void *Decoder) {
595321369Sdim  static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = {
596321369Sdim      Hexagon::D0, Hexagon::D1, Hexagon::D2,  Hexagon::D3,
597321369Sdim      Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11};
598321369Sdim
599321369Sdim  return DecodeRegisterClass(Inst, RegNo, GeneralDoubleLow8RegDecoderTable);
600321369Sdim}
601321369Sdim
602327952Sdimstatic DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
603327952Sdim                                             uint64_t /*Address*/,
604327952Sdim                                             const void *Decoder) {
605327952Sdim  static const MCPhysReg HvxWRDecoderTable[] = {
606296417Sdim      Hexagon::W0,  Hexagon::W1,  Hexagon::W2,  Hexagon::W3,
607296417Sdim      Hexagon::W4,  Hexagon::W5,  Hexagon::W6,  Hexagon::W7,
608296417Sdim      Hexagon::W8,  Hexagon::W9,  Hexagon::W10, Hexagon::W11,
609296417Sdim      Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
610296417Sdim
611327952Sdim  return (DecodeRegisterClass(Inst, RegNo >> 1, HvxWRDecoderTable));
612296417Sdim}
613296417Sdim
614344779SdimLLVM_ATTRIBUTE_UNUSED  // Suppress warning temporarily.
615344779Sdimstatic DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst,
616344779Sdim                                              unsigned RegNo,
617344779Sdim                                              uint64_t /*Address*/,
618344779Sdim                                              const void *Decoder) {
619344779Sdim  static const MCPhysReg HvxVQRDecoderTable[] = {
620344779Sdim      Hexagon::VQ0,  Hexagon::VQ1,  Hexagon::VQ2,  Hexagon::VQ3,
621344779Sdim      Hexagon::VQ4,  Hexagon::VQ5,  Hexagon::VQ6,  Hexagon::VQ7};
622344779Sdim
623344779Sdim  return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable);
624344779Sdim}
625344779Sdim
626296417Sdimstatic DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
627296417Sdim                                                uint64_t /*Address*/,
628296417Sdim                                                const void *Decoder) {
629296417Sdim  static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
630296417Sdim                                                  Hexagon::P2, Hexagon::P3};
631296417Sdim
632296417Sdim  return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable);
633296417Sdim}
634296417Sdim
635327952Sdimstatic DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
636327952Sdim                                             uint64_t /*Address*/,
637327952Sdim                                             const void *Decoder) {
638327952Sdim  static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
639327952Sdim                                                Hexagon::Q2, Hexagon::Q3};
640296417Sdim
641327952Sdim  return DecodeRegisterClass(Inst, RegNo, HvxQRDecoderTable);
642296417Sdim}
643296417Sdim
644296417Sdimstatic DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
645296417Sdim                                               uint64_t /*Address*/,
646296417Sdim                                               const void *Decoder) {
647321369Sdim  using namespace Hexagon;
648327952Sdim
649296417Sdim  static const MCPhysReg CtrlRegDecoderTable[] = {
650321369Sdim    /*  0 */  SA0,        LC0,        SA1,        LC1,
651321369Sdim    /*  4 */  P3_0,       C5,         M0,         M1,
652321369Sdim    /*  8 */  USR,        PC,         UGP,        GP,
653321369Sdim    /* 12 */  CS0,        CS1,        UPCYCLELO,  UPCYCLEHI,
654321369Sdim    /* 16 */  FRAMELIMIT, FRAMEKEY,   PKTCOUNTLO, PKTCOUNTHI,
655321369Sdim    /* 20 */  0,          0,          0,          0,
656321369Sdim    /* 24 */  0,          0,          0,          0,
657321369Sdim    /* 28 */  0,          0,          UTIMERLO,   UTIMERHI
658296417Sdim  };
659296417Sdim
660296417Sdim  if (RegNo >= array_lengthof(CtrlRegDecoderTable))
661296417Sdim    return MCDisassembler::Fail;
662296417Sdim
663321369Sdim  static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
664321369Sdim  if (CtrlRegDecoderTable[RegNo] == NoRegister)
665296417Sdim    return MCDisassembler::Fail;
666296417Sdim
667296417Sdim  unsigned Register = CtrlRegDecoderTable[RegNo];
668296417Sdim  Inst.addOperand(MCOperand::createReg(Register));
669296417Sdim  return MCDisassembler::Success;
670296417Sdim}
671296417Sdim
672296417Sdimstatic DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
673296417Sdim                                                 uint64_t /*Address*/,
674296417Sdim                                                 const void *Decoder) {
675321369Sdim  using namespace Hexagon;
676327952Sdim
677296417Sdim  static const MCPhysReg CtrlReg64DecoderTable[] = {
678321369Sdim    /*  0 */  C1_0,       0,          C3_2,       0,
679321369Sdim    /*  4 */  C5_4,       0,          C7_6,       0,
680321369Sdim    /*  8 */  C9_8,       0,          C11_10,     0,
681321369Sdim    /* 12 */  CS,         0,          UPCYCLE,    0,
682321369Sdim    /* 16 */  C17_16,     0,          PKTCOUNT,   0,
683321369Sdim    /* 20 */  0,          0,          0,          0,
684321369Sdim    /* 24 */  0,          0,          0,          0,
685321369Sdim    /* 28 */  0,          0,          UTIMER,     0
686296417Sdim  };
687296417Sdim
688296417Sdim  if (RegNo >= array_lengthof(CtrlReg64DecoderTable))
689296417Sdim    return MCDisassembler::Fail;
690296417Sdim
691321369Sdim  static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
692321369Sdim  if (CtrlReg64DecoderTable[RegNo] == NoRegister)
693296417Sdim    return MCDisassembler::Fail;
694296417Sdim
695296417Sdim  unsigned Register = CtrlReg64DecoderTable[RegNo];
696296417Sdim  Inst.addOperand(MCOperand::createReg(Register));
697296417Sdim  return MCDisassembler::Success;
698296417Sdim}
699296417Sdim
700296417Sdimstatic DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
701296417Sdim                                               uint64_t /*Address*/,
702296417Sdim                                               const void *Decoder) {
703296417Sdim  unsigned Register = 0;
704296417Sdim  switch (RegNo) {
705296417Sdim  case 0:
706296417Sdim    Register = Hexagon::M0;
707296417Sdim    break;
708296417Sdim  case 1:
709296417Sdim    Register = Hexagon::M1;
710296417Sdim    break;
711296417Sdim  default:
712296417Sdim    return MCDisassembler::Fail;
713296417Sdim  }
714296417Sdim  Inst.addOperand(MCOperand::createReg(Register));
715296417Sdim  return MCDisassembler::Success;
716296417Sdim}
717296417Sdim
718296417Sdimstatic DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
719296417Sdim                                       uint64_t /*Address*/,
720296417Sdim                                       const void *Decoder) {
721296417Sdim  HexagonDisassembler const &Disassembler = disassembler(Decoder);
722327952Sdim  int64_t FullValue = fullValue(Disassembler, MI, tmp);
723296417Sdim  assert(FullValue >= 0 && "Negative in unsigned decoder");
724296417Sdim  HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
725296417Sdim  return MCDisassembler::Success;
726296417Sdim}
727296417Sdim
728321369Sdimstatic DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
729288943Sdim                                    uint64_t /*Address*/, const void *Decoder) {
730321369Sdim  HexagonDisassembler const &Disassembler = disassembler(Decoder);
731321369Sdim  unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
732321369Sdim  tmp = SignExtend64(tmp, Bits);
733321369Sdim  signedDecoder<32>(MI, tmp, Decoder);
734288943Sdim  return MCDisassembler::Success;
735288943Sdim}
736288943Sdim
737296417Sdim// custom decoder for various jump/call immediates
738296417Sdimstatic DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
739296417Sdim                                    const void *Decoder) {
740296417Sdim  HexagonDisassembler const &Disassembler = disassembler(Decoder);
741296417Sdim  unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
742296417Sdim  // r13_2 is not extendable, so if there are no extent bits, it's r13_2
743296417Sdim  if (Bits == 0)
744296417Sdim    Bits = 15;
745327952Sdim  uint64_t FullValue = fullValue(Disassembler, MI, SignExtend64(tmp, Bits));
746327952Sdim  uint32_t Extended = FullValue + Address;
747321369Sdim  if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 0, 4))
748296417Sdim    HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
749296417Sdim  return MCDisassembler::Success;
750296417Sdim}
751341825Sdim
752341825Sdimstatic DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
753341825Sdim                                                 uint64_t /*Address*/,
754341825Sdim                                                 const void *Decoder) {
755341825Sdim  using namespace Hexagon;
756341825Sdim
757341825Sdim  static const MCPhysReg GuestRegDecoderTable[] = {
758341825Sdim    /*  0 */ GELR,      GSR,        GOSP,       G3,
759341825Sdim    /*  4 */ G4,        G5,         G6,         G7,
760341825Sdim    /*  8 */ G8,        G9,         G10,        G11,
761341825Sdim    /* 12 */ G12,       G13,        G14,        G15,
762341825Sdim    /* 16 */ GPMUCNT4,  GPMUCNT5,   GPMUCNT6,   GPMUCNT7,
763341825Sdim    /* 20 */ G20,       G21,        G22,        G23,
764341825Sdim    /* 24 */ GPCYCLELO, GPCYCLEHI,  GPMUCNT0,   GPMUCNT1,
765341825Sdim    /* 28 */ GPMUCNT2,  GPMUCNT3,   G30,        G31
766341825Sdim  };
767341825Sdim
768341825Sdim  if (RegNo >= array_lengthof(GuestRegDecoderTable))
769341825Sdim    return MCDisassembler::Fail;
770341825Sdim  if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister)
771341825Sdim    return MCDisassembler::Fail;
772341825Sdim
773341825Sdim  unsigned Register = GuestRegDecoderTable[RegNo];
774341825Sdim  Inst.addOperand(MCOperand::createReg(Register));
775341825Sdim  return MCDisassembler::Success;
776341825Sdim}
777341825Sdim
778341825Sdimstatic DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
779341825Sdim                                                   uint64_t /*Address*/,
780341825Sdim                                                   const void *Decoder) {
781341825Sdim  using namespace Hexagon;
782341825Sdim
783341825Sdim  static const MCPhysReg GuestReg64DecoderTable[] = {
784341825Sdim    /*  0 */ G1_0,      0,          G3_2,       0,
785341825Sdim    /*  4 */ G5_4,      0,          G7_6,       0,
786341825Sdim    /*  8 */ G9_8,      0,          G11_10,     0,
787341825Sdim    /* 12 */ G13_12,    0,          G15_14,     0,
788341825Sdim    /* 16 */ G17_16,    0,          G19_18,     0,
789341825Sdim    /* 20 */ G21_20,    0,          G23_22,     0,
790341825Sdim    /* 24 */ G25_24,    0,          G27_26,     0,
791341825Sdim    /* 28 */ G29_28,    0,          G31_30,     0
792341825Sdim  };
793341825Sdim
794341825Sdim  if (RegNo >= array_lengthof(GuestReg64DecoderTable))
795341825Sdim    return MCDisassembler::Fail;
796341825Sdim  if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister)
797341825Sdim    return MCDisassembler::Fail;
798341825Sdim
799341825Sdim  unsigned Register = GuestReg64DecoderTable[RegNo];
800341825Sdim  Inst.addOperand(MCOperand::createReg(Register));
801341825Sdim  return MCDisassembler::Success;
802341825Sdim}
803