1//===- HexagonDisassembler.cpp - Disassembler for Hexagon ISA -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#define DEBUG_TYPE "hexagon-disassembler"
10
11#include "MCTargetDesc/HexagonBaseInfo.h"
12#include "MCTargetDesc/HexagonMCChecker.h"
13#include "MCTargetDesc/HexagonMCInstrInfo.h"
14#include "MCTargetDesc/HexagonMCTargetDesc.h"
15#include "TargetInfo/HexagonTargetInfo.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCDisassembler/MCDisassembler.h"
20#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCFixedLenDisassembler.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCRegisterInfo.h"
25#include "llvm/MC/MCSubtargetInfo.h"
26#include "llvm/Support/Endian.h"
27#include "llvm/Support/MathExtras.h"
28#include "llvm/Support/TargetRegistry.h"
29#include "llvm/Support/raw_ostream.h"
30#include <cassert>
31#include <cstddef>
32#include <cstdint>
33#include <memory>
34
35using namespace llvm;
36using namespace Hexagon;
37
38using DecodeStatus = MCDisassembler::DecodeStatus;
39
40namespace {
41
42/// Hexagon disassembler for all Hexagon platforms.
43class HexagonDisassembler : public MCDisassembler {
44public:
45  std::unique_ptr<MCInstrInfo const> const MCII;
46  std::unique_ptr<MCInst *> CurrentBundle;
47  mutable MCInst const *CurrentExtender;
48
49  HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
50                      MCInstrInfo const *MCII)
51      : MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *),
52        CurrentExtender(nullptr) {}
53
54  DecodeStatus getSingleInstruction(MCInst &Instr, MCInst &MCB,
55                                    ArrayRef<uint8_t> Bytes, uint64_t Address,
56                                    raw_ostream &CStream, bool &Complete) const;
57  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
58                              ArrayRef<uint8_t> Bytes, uint64_t Address,
59                              raw_ostream &CStream) const override;
60  void remapInstruction(MCInst &Instr) const;
61};
62
63static uint64_t fullValue(HexagonDisassembler const &Disassembler, MCInst &MI,
64                          int64_t Value) {
65  MCInstrInfo MCII = *Disassembler.MCII;
66  if (!Disassembler.CurrentExtender ||
67      MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
68    return Value;
69  unsigned Alignment = HexagonMCInstrInfo::getExtentAlignment(MCII, MI);
70  uint32_t Lower6 = static_cast<uint32_t>(Value >> Alignment) & 0x3f;
71  int64_t Bits;
72  bool Success =
73      Disassembler.CurrentExtender->getOperand(0).getExpr()->evaluateAsAbsolute(
74          Bits);
75  assert(Success);
76  (void)Success;
77  uint64_t Upper26 = static_cast<uint64_t>(Bits);
78  uint64_t Operand = Upper26 | Lower6;
79  return Operand;
80}
81static HexagonDisassembler const &disassembler(void const *Decoder) {
82  return *static_cast<HexagonDisassembler const *>(Decoder);
83}
84template <size_t T>
85static void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
86  HexagonDisassembler const &Disassembler = disassembler(Decoder);
87  int64_t FullValue = fullValue(Disassembler, MI, SignExtend64<T>(tmp));
88  int64_t Extended = SignExtend64<32>(FullValue);
89  HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
90}
91}
92
93// Forward declare these because the auto-generated code will reference them.
94// Definitions are further down.
95
96static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
97                                               uint64_t Address,
98                                               const void *Decoder);
99static DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst,
100                                                      unsigned RegNo,
101                                                      uint64_t Address,
102                                                      const void *Decoder);
103static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
104                                                   uint64_t Address,
105                                                   const void *Decoder);
106static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
107                                             uint64_t Address,
108                                             const void *Decoder);
109static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
110                                                  uint64_t Address,
111                                                  const void *Decoder);
112static DecodeStatus
113DecodeGeneralDoubleLow8RegsRegisterClass(MCInst &Inst, unsigned RegNo,
114                                         uint64_t Address, const void *Decoder);
115static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
116                                             uint64_t Address,
117                                             const void *Decoder);
118static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst,
119                                              unsigned RegNo,
120                                              uint64_t Address,
121                                              const void *Decoder);
122static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
123                                                uint64_t Address,
124                                                const void *Decoder);
125static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
126                                             uint64_t Address,
127                                             const void *Decoder);
128static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
129                                               uint64_t Address,
130                                               const void *Decoder);
131static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
132                                                 uint64_t Address,
133                                                 const void *Decoder);
134static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
135                                               uint64_t Address,
136                                               const void *Decoder);
137static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
138                                                 uint64_t Address,
139                                                 const void *Decoder);
140static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
141                                                   uint64_t Address,
142                                                   const void *Decoder);
143
144static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
145                                       uint64_t Address, const void *Decoder);
146static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
147                                    uint64_t /*Address*/, const void *Decoder);
148static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
149                                    const void *Decoder);
150#include "HexagonDepDecoders.inc"
151#include "HexagonGenDisassemblerTables.inc"
152
153static MCDisassembler *createHexagonDisassembler(const Target &T,
154                                                 const MCSubtargetInfo &STI,
155                                                 MCContext &Ctx) {
156  return new HexagonDisassembler(STI, Ctx, T.createMCInstrInfo());
157}
158
159extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonDisassembler() {
160  TargetRegistry::RegisterMCDisassembler(getTheHexagonTarget(),
161                                         createHexagonDisassembler);
162}
163
164DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
165                                                 ArrayRef<uint8_t> Bytes,
166                                                 uint64_t Address,
167                                                 raw_ostream &cs) const {
168  DecodeStatus Result = DecodeStatus::Success;
169  bool Complete = false;
170  Size = 0;
171
172  *CurrentBundle = &MI;
173  MI.setOpcode(Hexagon::BUNDLE);
174  MI.addOperand(MCOperand::createImm(0));
175  while (Result == Success && !Complete) {
176    if (Bytes.size() < HEXAGON_INSTR_SIZE)
177      return MCDisassembler::Fail;
178    MCInst *Inst = new (getContext()) MCInst;
179    Result = getSingleInstruction(*Inst, MI, Bytes, Address, cs, Complete);
180    MI.addOperand(MCOperand::createInst(Inst));
181    Size += HEXAGON_INSTR_SIZE;
182    Bytes = Bytes.slice(HEXAGON_INSTR_SIZE);
183  }
184  if (Result == MCDisassembler::Fail)
185    return Result;
186  if (Size > HEXAGON_MAX_PACKET_SIZE)
187    return MCDisassembler::Fail;
188  HexagonMCChecker Checker(getContext(), *MCII, STI, MI,
189                           *getContext().getRegisterInfo(), false);
190  if (!Checker.check())
191    return MCDisassembler::Fail;
192  remapInstruction(MI);
193  return MCDisassembler::Success;
194}
195
196void HexagonDisassembler::remapInstruction(MCInst &Instr) const {
197  for (auto I: HexagonMCInstrInfo::bundleInstructions(Instr)) {
198    auto &MI = const_cast<MCInst &>(*I.getInst());
199    switch (MI.getOpcode()) {
200    case Hexagon::S2_allocframe:
201      if (MI.getOperand(0).getReg() == Hexagon::R29) {
202        MI.setOpcode(Hexagon::S6_allocframe_to_raw);
203        MI.erase(MI.begin () + 1);
204        MI.erase(MI.begin ());
205      }
206      break;
207    case Hexagon::L2_deallocframe:
208      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
209          MI.getOperand(1).getReg() == Hexagon::R30) {
210        MI.setOpcode(L6_deallocframe_map_to_raw);
211        MI.erase(MI.begin () + 1);
212        MI.erase(MI.begin ());
213      }
214      break;
215    case Hexagon::L4_return:
216      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
217          MI.getOperand(1).getReg() == Hexagon::R30) {
218        MI.setOpcode(L6_return_map_to_raw);
219        MI.erase(MI.begin () + 1);
220        MI.erase(MI.begin ());
221      }
222      break;
223    case Hexagon::L4_return_t:
224      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
225          MI.getOperand(2).getReg() == Hexagon::R30) {
226        MI.setOpcode(L4_return_map_to_raw_t);
227        MI.erase(MI.begin () + 2);
228        MI.erase(MI.begin ());
229      }
230      break;
231    case Hexagon::L4_return_f:
232      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
233          MI.getOperand(2).getReg() == Hexagon::R30) {
234        MI.setOpcode(L4_return_map_to_raw_f);
235        MI.erase(MI.begin () + 2);
236        MI.erase(MI.begin ());
237      }
238      break;
239    case Hexagon::L4_return_tnew_pt:
240      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
241          MI.getOperand(2).getReg() == Hexagon::R30) {
242        MI.setOpcode(L4_return_map_to_raw_tnew_pt);
243        MI.erase(MI.begin () + 2);
244        MI.erase(MI.begin ());
245      }
246      break;
247    case Hexagon::L4_return_fnew_pt:
248      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
249          MI.getOperand(2).getReg() == Hexagon::R30) {
250        MI.setOpcode(L4_return_map_to_raw_fnew_pt);
251        MI.erase(MI.begin () + 2);
252        MI.erase(MI.begin ());
253      }
254      break;
255    case Hexagon::L4_return_tnew_pnt:
256      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
257          MI.getOperand(2).getReg() == Hexagon::R30) {
258        MI.setOpcode(L4_return_map_to_raw_tnew_pnt);
259        MI.erase(MI.begin () + 2);
260        MI.erase(MI.begin ());
261      }
262      break;
263    case Hexagon::L4_return_fnew_pnt:
264      if (MI.getOperand(0).getReg() == Hexagon::D15 &&
265          MI.getOperand(2).getReg() == Hexagon::R30) {
266        MI.setOpcode(L4_return_map_to_raw_fnew_pnt);
267        MI.erase(MI.begin () + 2);
268        MI.erase(MI.begin ());
269      }
270      break;
271    }
272  }
273}
274
275static void adjustDuplex(MCInst &MI, MCContext &Context) {
276  switch (MI.getOpcode()) {
277  case Hexagon::SA1_setin1:
278    MI.insert(MI.begin() + 1,
279              MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
280    break;
281  case Hexagon::SA1_dec:
282    MI.insert(MI.begin() + 2,
283              MCOperand::createExpr(MCConstantExpr::create(-1, Context)));
284    break;
285  default:
286    break;
287  }
288}
289
290DecodeStatus HexagonDisassembler::getSingleInstruction(MCInst &MI, MCInst &MCB,
291                                                       ArrayRef<uint8_t> Bytes,
292                                                       uint64_t Address,
293                                                       raw_ostream &cs,
294                                                       bool &Complete) const {
295  assert(Bytes.size() >= HEXAGON_INSTR_SIZE);
296
297  uint32_t Instruction = support::endian::read32le(Bytes.data());
298
299  auto BundleSize = HexagonMCInstrInfo::bundleSize(MCB);
300  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
301      HexagonII::INST_PARSE_LOOP_END) {
302    if (BundleSize == 0)
303      HexagonMCInstrInfo::setInnerLoop(MCB);
304    else if (BundleSize == 1)
305      HexagonMCInstrInfo::setOuterLoop(MCB);
306    else
307      return DecodeStatus::Fail;
308  }
309
310  CurrentExtender = HexagonMCInstrInfo::extenderForIndex(
311      MCB, HexagonMCInstrInfo::bundleSize(MCB));
312
313  DecodeStatus Result = DecodeStatus::Fail;
314  if ((Instruction & HexagonII::INST_PARSE_MASK) ==
315      HexagonII::INST_PARSE_DUPLEX) {
316    unsigned duplexIClass;
317    uint8_t const *DecodeLow, *DecodeHigh;
318    duplexIClass = ((Instruction >> 28) & 0xe) | ((Instruction >> 13) & 0x1);
319    switch (duplexIClass) {
320    default:
321      return MCDisassembler::Fail;
322    case 0:
323      DecodeLow = DecoderTableSUBINSN_L132;
324      DecodeHigh = DecoderTableSUBINSN_L132;
325      break;
326    case 1:
327      DecodeLow = DecoderTableSUBINSN_L232;
328      DecodeHigh = DecoderTableSUBINSN_L132;
329      break;
330    case 2:
331      DecodeLow = DecoderTableSUBINSN_L232;
332      DecodeHigh = DecoderTableSUBINSN_L232;
333      break;
334    case 3:
335      DecodeLow = DecoderTableSUBINSN_A32;
336      DecodeHigh = DecoderTableSUBINSN_A32;
337      break;
338    case 4:
339      DecodeLow = DecoderTableSUBINSN_L132;
340      DecodeHigh = DecoderTableSUBINSN_A32;
341      break;
342    case 5:
343      DecodeLow = DecoderTableSUBINSN_L232;
344      DecodeHigh = DecoderTableSUBINSN_A32;
345      break;
346    case 6:
347      DecodeLow = DecoderTableSUBINSN_S132;
348      DecodeHigh = DecoderTableSUBINSN_A32;
349      break;
350    case 7:
351      DecodeLow = DecoderTableSUBINSN_S232;
352      DecodeHigh = DecoderTableSUBINSN_A32;
353      break;
354    case 8:
355      DecodeLow = DecoderTableSUBINSN_S132;
356      DecodeHigh = DecoderTableSUBINSN_L132;
357      break;
358    case 9:
359      DecodeLow = DecoderTableSUBINSN_S132;
360      DecodeHigh = DecoderTableSUBINSN_L232;
361      break;
362    case 10:
363      DecodeLow = DecoderTableSUBINSN_S132;
364      DecodeHigh = DecoderTableSUBINSN_S132;
365      break;
366    case 11:
367      DecodeLow = DecoderTableSUBINSN_S232;
368      DecodeHigh = DecoderTableSUBINSN_S132;
369      break;
370    case 12:
371      DecodeLow = DecoderTableSUBINSN_S232;
372      DecodeHigh = DecoderTableSUBINSN_L132;
373      break;
374    case 13:
375      DecodeLow = DecoderTableSUBINSN_S232;
376      DecodeHigh = DecoderTableSUBINSN_L232;
377      break;
378    case 14:
379      DecodeLow = DecoderTableSUBINSN_S232;
380      DecodeHigh = DecoderTableSUBINSN_S232;
381      break;
382    }
383    MI.setOpcode(Hexagon::DuplexIClass0 + duplexIClass);
384    MCInst *MILow = new (getContext()) MCInst;
385    MCInst *MIHigh = new (getContext()) MCInst;
386    auto TmpExtender = CurrentExtender;
387    CurrentExtender =
388        nullptr; // constant extenders in duplex must always be in slot 1
389    Result = decodeInstruction(DecodeLow, *MILow, Instruction & 0x1fff, Address,
390                               this, STI);
391    CurrentExtender = TmpExtender;
392    if (Result != DecodeStatus::Success)
393      return DecodeStatus::Fail;
394    adjustDuplex(*MILow, getContext());
395    Result = decodeInstruction(
396        DecodeHigh, *MIHigh, (Instruction >> 16) & 0x1fff, Address, this, STI);
397    if (Result != DecodeStatus::Success)
398      return DecodeStatus::Fail;
399    adjustDuplex(*MIHigh, getContext());
400    MCOperand OPLow = MCOperand::createInst(MILow);
401    MCOperand OPHigh = MCOperand::createInst(MIHigh);
402    MI.addOperand(OPLow);
403    MI.addOperand(OPHigh);
404    Complete = true;
405  } else {
406    if ((Instruction & HexagonII::INST_PARSE_MASK) ==
407        HexagonII::INST_PARSE_PACKET_END)
408      Complete = true;
409
410    if (CurrentExtender != nullptr)
411      Result = decodeInstruction(DecoderTableMustExtend32, MI, Instruction,
412                                 Address, this, STI);
413
414    if (Result != MCDisassembler::Success)
415      Result = decodeInstruction(DecoderTable32, MI, Instruction, Address, this,
416                                 STI);
417
418    if (Result != MCDisassembler::Success &&
419        STI.getFeatureBits()[Hexagon::ExtensionHVX])
420      Result = decodeInstruction(DecoderTableEXT_mmvec32, MI, Instruction,
421                                 Address, this, STI);
422
423  }
424
425  switch (MI.getOpcode()) {
426  case Hexagon::J4_cmpeqn1_f_jumpnv_nt:
427  case Hexagon::J4_cmpeqn1_f_jumpnv_t:
428  case Hexagon::J4_cmpeqn1_fp0_jump_nt:
429  case Hexagon::J4_cmpeqn1_fp0_jump_t:
430  case Hexagon::J4_cmpeqn1_fp1_jump_nt:
431  case Hexagon::J4_cmpeqn1_fp1_jump_t:
432  case Hexagon::J4_cmpeqn1_t_jumpnv_nt:
433  case Hexagon::J4_cmpeqn1_t_jumpnv_t:
434  case Hexagon::J4_cmpeqn1_tp0_jump_nt:
435  case Hexagon::J4_cmpeqn1_tp0_jump_t:
436  case Hexagon::J4_cmpeqn1_tp1_jump_nt:
437  case Hexagon::J4_cmpeqn1_tp1_jump_t:
438  case Hexagon::J4_cmpgtn1_f_jumpnv_nt:
439  case Hexagon::J4_cmpgtn1_f_jumpnv_t:
440  case Hexagon::J4_cmpgtn1_fp0_jump_nt:
441  case Hexagon::J4_cmpgtn1_fp0_jump_t:
442  case Hexagon::J4_cmpgtn1_fp1_jump_nt:
443  case Hexagon::J4_cmpgtn1_fp1_jump_t:
444  case Hexagon::J4_cmpgtn1_t_jumpnv_nt:
445  case Hexagon::J4_cmpgtn1_t_jumpnv_t:
446  case Hexagon::J4_cmpgtn1_tp0_jump_nt:
447  case Hexagon::J4_cmpgtn1_tp0_jump_t:
448  case Hexagon::J4_cmpgtn1_tp1_jump_nt:
449  case Hexagon::J4_cmpgtn1_tp1_jump_t:
450    MI.insert(MI.begin() + 1,
451              MCOperand::createExpr(MCConstantExpr::create(-1, getContext())));
452    break;
453  default:
454    break;
455  }
456
457  if (HexagonMCInstrInfo::isNewValue(*MCII, MI)) {
458    unsigned OpIndex = HexagonMCInstrInfo::getNewValueOp(*MCII, MI);
459    MCOperand &MCO = MI.getOperand(OpIndex);
460    assert(MCO.isReg() && "New value consumers must be registers");
461    unsigned Register =
462        getContext().getRegisterInfo()->getEncodingValue(MCO.getReg());
463    if ((Register & 0x6) == 0)
464      // HexagonPRM 10.11 Bit 1-2 == 0 is reserved
465      return MCDisassembler::Fail;
466    unsigned Lookback = (Register & 0x6) >> 1;
467    unsigned Offset = 1;
468    bool Vector = HexagonMCInstrInfo::isVector(*MCII, MI);
469    bool PrevVector = false;
470    auto Instructions = HexagonMCInstrInfo::bundleInstructions(**CurrentBundle);
471    auto i = Instructions.end() - 1;
472    for (auto n = Instructions.begin() - 1;; --i, ++Offset) {
473      if (i == n)
474        // Couldn't find producer
475        return MCDisassembler::Fail;
476      bool CurrentVector = HexagonMCInstrInfo::isVector(*MCII, *i->getInst());
477      if (Vector && !CurrentVector)
478        // Skip scalars when calculating distances for vectors
479        ++Lookback;
480      if (HexagonMCInstrInfo::isImmext(*i->getInst()) && (Vector == PrevVector))
481        ++Lookback;
482      PrevVector = CurrentVector;
483      if (Offset == Lookback)
484        break;
485    }
486    auto const &Inst = *i->getInst();
487    bool SubregBit = (Register & 0x1) != 0;
488    if (HexagonMCInstrInfo::hasNewValue2(*MCII, Inst)) {
489      // If subreg bit is set we're selecting the second produced newvalue
490      unsigned Producer = SubregBit ?
491          HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg() :
492          HexagonMCInstrInfo::getNewValueOperand2(*MCII, Inst).getReg();
493      assert(Producer != Hexagon::NoRegister);
494      MCO.setReg(Producer);
495    } else if (HexagonMCInstrInfo::hasNewValue(*MCII, Inst)) {
496      unsigned Producer =
497          HexagonMCInstrInfo::getNewValueOperand(*MCII, Inst).getReg();
498      if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
499        Producer = ((Producer - Hexagon::W0) << 1) + SubregBit + Hexagon::V0;
500      else if (SubregBit)
501        // Hexagon PRM 10.11 New-value operands
502        // Nt[0] is reserved and should always be encoded as zero.
503        return MCDisassembler::Fail;
504      assert(Producer != Hexagon::NoRegister);
505      MCO.setReg(Producer);
506    } else
507      return MCDisassembler::Fail;
508  }
509
510  if (CurrentExtender != nullptr) {
511    MCInst const &Inst = HexagonMCInstrInfo::isDuplex(*MCII, MI)
512                             ? *MI.getOperand(1).getInst()
513                             : MI;
514    if (!HexagonMCInstrInfo::isExtendable(*MCII, Inst) &&
515        !HexagonMCInstrInfo::isExtended(*MCII, Inst))
516      return MCDisassembler::Fail;
517  }
518  return Result;
519}
520
521static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
522                                        ArrayRef<MCPhysReg> Table) {
523  if (RegNo < Table.size()) {
524    Inst.addOperand(MCOperand::createReg(Table[RegNo]));
525    return MCDisassembler::Success;
526  }
527
528  return MCDisassembler::Fail;
529}
530
531static DecodeStatus DecodeIntRegsLow8RegisterClass(MCInst &Inst, unsigned RegNo,
532                                                   uint64_t Address,
533                                                   const void *Decoder) {
534  return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);
535}
536
537static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,
538                                               uint64_t Address,
539                                               const void *Decoder) {
540  static const MCPhysReg IntRegDecoderTable[] = {
541      Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,  Hexagon::R4,
542      Hexagon::R5,  Hexagon::R6,  Hexagon::R7,  Hexagon::R8,  Hexagon::R9,
543      Hexagon::R10, Hexagon::R11, Hexagon::R12, Hexagon::R13, Hexagon::R14,
544      Hexagon::R15, Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
545      Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23, Hexagon::R24,
546      Hexagon::R25, Hexagon::R26, Hexagon::R27, Hexagon::R28, Hexagon::R29,
547      Hexagon::R30, Hexagon::R31};
548
549  return DecodeRegisterClass(Inst, RegNo, IntRegDecoderTable);
550}
551
552static DecodeStatus DecodeGeneralSubRegsRegisterClass(MCInst &Inst,
553                                                      unsigned RegNo,
554                                                      uint64_t Address,
555                                                      const void *Decoder) {
556  static const MCPhysReg GeneralSubRegDecoderTable[] = {
557      Hexagon::R0,  Hexagon::R1,  Hexagon::R2,  Hexagon::R3,
558      Hexagon::R4,  Hexagon::R5,  Hexagon::R6,  Hexagon::R7,
559      Hexagon::R16, Hexagon::R17, Hexagon::R18, Hexagon::R19,
560      Hexagon::R20, Hexagon::R21, Hexagon::R22, Hexagon::R23,
561  };
562
563  return DecodeRegisterClass(Inst, RegNo, GeneralSubRegDecoderTable);
564}
565
566static DecodeStatus DecodeHvxVRRegisterClass(MCInst &Inst, unsigned RegNo,
567                                             uint64_t /*Address*/,
568                                             const void *Decoder) {
569  static const MCPhysReg HvxVRDecoderTable[] = {
570      Hexagon::V0,  Hexagon::V1,  Hexagon::V2,  Hexagon::V3,  Hexagon::V4,
571      Hexagon::V5,  Hexagon::V6,  Hexagon::V7,  Hexagon::V8,  Hexagon::V9,
572      Hexagon::V10, Hexagon::V11, Hexagon::V12, Hexagon::V13, Hexagon::V14,
573      Hexagon::V15, Hexagon::V16, Hexagon::V17, Hexagon::V18, Hexagon::V19,
574      Hexagon::V20, Hexagon::V21, Hexagon::V22, Hexagon::V23, Hexagon::V24,
575      Hexagon::V25, Hexagon::V26, Hexagon::V27, Hexagon::V28, Hexagon::V29,
576      Hexagon::V30, Hexagon::V31};
577
578  return DecodeRegisterClass(Inst, RegNo, HvxVRDecoderTable);
579}
580
581static DecodeStatus DecodeDoubleRegsRegisterClass(MCInst &Inst, unsigned RegNo,
582                                                  uint64_t /*Address*/,
583                                                  const void *Decoder) {
584  static const MCPhysReg DoubleRegDecoderTable[] = {
585      Hexagon::D0,  Hexagon::D1,  Hexagon::D2,  Hexagon::D3,
586      Hexagon::D4,  Hexagon::D5,  Hexagon::D6,  Hexagon::D7,
587      Hexagon::D8,  Hexagon::D9,  Hexagon::D10, Hexagon::D11,
588      Hexagon::D12, Hexagon::D13, Hexagon::D14, Hexagon::D15};
589
590  return DecodeRegisterClass(Inst, RegNo >> 1, DoubleRegDecoderTable);
591}
592
593static DecodeStatus DecodeGeneralDoubleLow8RegsRegisterClass(
594    MCInst &Inst, unsigned RegNo, uint64_t /*Address*/, const void *Decoder) {
595  static const MCPhysReg GeneralDoubleLow8RegDecoderTable[] = {
596      Hexagon::D0, Hexagon::D1, Hexagon::D2,  Hexagon::D3,
597      Hexagon::D8, Hexagon::D9, Hexagon::D10, Hexagon::D11};
598
599  return DecodeRegisterClass(Inst, RegNo, GeneralDoubleLow8RegDecoderTable);
600}
601
602static DecodeStatus DecodeHvxWRRegisterClass(MCInst &Inst, unsigned RegNo,
603                                             uint64_t /*Address*/,
604                                             const void *Decoder) {
605  static const MCPhysReg HvxWRDecoderTable[] = {
606      Hexagon::W0,  Hexagon::W1,  Hexagon::W2,  Hexagon::W3,
607      Hexagon::W4,  Hexagon::W5,  Hexagon::W6,  Hexagon::W7,
608      Hexagon::W8,  Hexagon::W9,  Hexagon::W10, Hexagon::W11,
609      Hexagon::W12, Hexagon::W13, Hexagon::W14, Hexagon::W15};
610
611  return (DecodeRegisterClass(Inst, RegNo >> 1, HvxWRDecoderTable));
612}
613
614LLVM_ATTRIBUTE_UNUSED  // Suppress warning temporarily.
615static DecodeStatus DecodeHvxVQRRegisterClass(MCInst &Inst,
616                                              unsigned RegNo,
617                                              uint64_t /*Address*/,
618                                              const void *Decoder) {
619  static const MCPhysReg HvxVQRDecoderTable[] = {
620      Hexagon::VQ0,  Hexagon::VQ1,  Hexagon::VQ2,  Hexagon::VQ3,
621      Hexagon::VQ4,  Hexagon::VQ5,  Hexagon::VQ6,  Hexagon::VQ7};
622
623  return DecodeRegisterClass(Inst, RegNo >> 2, HvxVQRDecoderTable);
624}
625
626static DecodeStatus DecodePredRegsRegisterClass(MCInst &Inst, unsigned RegNo,
627                                                uint64_t /*Address*/,
628                                                const void *Decoder) {
629  static const MCPhysReg PredRegDecoderTable[] = {Hexagon::P0, Hexagon::P1,
630                                                  Hexagon::P2, Hexagon::P3};
631
632  return DecodeRegisterClass(Inst, RegNo, PredRegDecoderTable);
633}
634
635static DecodeStatus DecodeHvxQRRegisterClass(MCInst &Inst, unsigned RegNo,
636                                             uint64_t /*Address*/,
637                                             const void *Decoder) {
638  static const MCPhysReg HvxQRDecoderTable[] = {Hexagon::Q0, Hexagon::Q1,
639                                                Hexagon::Q2, Hexagon::Q3};
640
641  return DecodeRegisterClass(Inst, RegNo, HvxQRDecoderTable);
642}
643
644static DecodeStatus DecodeCtrRegsRegisterClass(MCInst &Inst, unsigned RegNo,
645                                               uint64_t /*Address*/,
646                                               const void *Decoder) {
647  using namespace Hexagon;
648
649  static const MCPhysReg CtrlRegDecoderTable[] = {
650    /*  0 */  SA0,        LC0,        SA1,        LC1,
651    /*  4 */  P3_0,       C5,         M0,         M1,
652    /*  8 */  USR,        PC,         UGP,        GP,
653    /* 12 */  CS0,        CS1,        UPCYCLELO,  UPCYCLEHI,
654    /* 16 */  FRAMELIMIT, FRAMEKEY,   PKTCOUNTLO, PKTCOUNTHI,
655    /* 20 */  0,          0,          0,          0,
656    /* 24 */  0,          0,          0,          0,
657    /* 28 */  0,          0,          UTIMERLO,   UTIMERHI
658  };
659
660  if (RegNo >= array_lengthof(CtrlRegDecoderTable))
661    return MCDisassembler::Fail;
662
663  static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
664  if (CtrlRegDecoderTable[RegNo] == NoRegister)
665    return MCDisassembler::Fail;
666
667  unsigned Register = CtrlRegDecoderTable[RegNo];
668  Inst.addOperand(MCOperand::createReg(Register));
669  return MCDisassembler::Success;
670}
671
672static DecodeStatus DecodeCtrRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
673                                                 uint64_t /*Address*/,
674                                                 const void *Decoder) {
675  using namespace Hexagon;
676
677  static const MCPhysReg CtrlReg64DecoderTable[] = {
678    /*  0 */  C1_0,       0,          C3_2,       0,
679    /*  4 */  C5_4,       0,          C7_6,       0,
680    /*  8 */  C9_8,       0,          C11_10,     0,
681    /* 12 */  CS,         0,          UPCYCLE,    0,
682    /* 16 */  C17_16,     0,          PKTCOUNT,   0,
683    /* 20 */  0,          0,          0,          0,
684    /* 24 */  0,          0,          0,          0,
685    /* 28 */  0,          0,          UTIMER,     0
686  };
687
688  if (RegNo >= array_lengthof(CtrlReg64DecoderTable))
689    return MCDisassembler::Fail;
690
691  static_assert(NoRegister == 0, "Expecting NoRegister to be 0");
692  if (CtrlReg64DecoderTable[RegNo] == NoRegister)
693    return MCDisassembler::Fail;
694
695  unsigned Register = CtrlReg64DecoderTable[RegNo];
696  Inst.addOperand(MCOperand::createReg(Register));
697  return MCDisassembler::Success;
698}
699
700static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
701                                               uint64_t /*Address*/,
702                                               const void *Decoder) {
703  unsigned Register = 0;
704  switch (RegNo) {
705  case 0:
706    Register = Hexagon::M0;
707    break;
708  case 1:
709    Register = Hexagon::M1;
710    break;
711  default:
712    return MCDisassembler::Fail;
713  }
714  Inst.addOperand(MCOperand::createReg(Register));
715  return MCDisassembler::Success;
716}
717
718static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
719                                       uint64_t /*Address*/,
720                                       const void *Decoder) {
721  HexagonDisassembler const &Disassembler = disassembler(Decoder);
722  int64_t FullValue = fullValue(Disassembler, MI, tmp);
723  assert(FullValue >= 0 && "Negative in unsigned decoder");
724  HexagonMCInstrInfo::addConstant(MI, FullValue, Disassembler.getContext());
725  return MCDisassembler::Success;
726}
727
728static DecodeStatus s32_0ImmDecoder(MCInst &MI, unsigned tmp,
729                                    uint64_t /*Address*/, const void *Decoder) {
730  HexagonDisassembler const &Disassembler = disassembler(Decoder);
731  unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
732  tmp = SignExtend64(tmp, Bits);
733  signedDecoder<32>(MI, tmp, Decoder);
734  return MCDisassembler::Success;
735}
736
737// custom decoder for various jump/call immediates
738static DecodeStatus brtargetDecoder(MCInst &MI, unsigned tmp, uint64_t Address,
739                                    const void *Decoder) {
740  HexagonDisassembler const &Disassembler = disassembler(Decoder);
741  unsigned Bits = HexagonMCInstrInfo::getExtentBits(*Disassembler.MCII, MI);
742  // r13_2 is not extendable, so if there are no extent bits, it's r13_2
743  if (Bits == 0)
744    Bits = 15;
745  uint64_t FullValue = fullValue(Disassembler, MI, SignExtend64(tmp, Bits));
746  uint32_t Extended = FullValue + Address;
747  if (!Disassembler.tryAddingSymbolicOperand(MI, Extended, Address, true, 0, 4))
748    HexagonMCInstrInfo::addConstant(MI, Extended, Disassembler.getContext());
749  return MCDisassembler::Success;
750}
751
752static DecodeStatus DecodeGuestRegsRegisterClass(MCInst &Inst, unsigned RegNo,
753                                                 uint64_t /*Address*/,
754                                                 const void *Decoder) {
755  using namespace Hexagon;
756
757  static const MCPhysReg GuestRegDecoderTable[] = {
758    /*  0 */ GELR,      GSR,        GOSP,       G3,
759    /*  4 */ G4,        G5,         G6,         G7,
760    /*  8 */ G8,        G9,         G10,        G11,
761    /* 12 */ G12,       G13,        G14,        G15,
762    /* 16 */ GPMUCNT4,  GPMUCNT5,   GPMUCNT6,   GPMUCNT7,
763    /* 20 */ G20,       G21,        G22,        G23,
764    /* 24 */ GPCYCLELO, GPCYCLEHI,  GPMUCNT0,   GPMUCNT1,
765    /* 28 */ GPMUCNT2,  GPMUCNT3,   G30,        G31
766  };
767
768  if (RegNo >= array_lengthof(GuestRegDecoderTable))
769    return MCDisassembler::Fail;
770  if (GuestRegDecoderTable[RegNo] == Hexagon::NoRegister)
771    return MCDisassembler::Fail;
772
773  unsigned Register = GuestRegDecoderTable[RegNo];
774  Inst.addOperand(MCOperand::createReg(Register));
775  return MCDisassembler::Success;
776}
777
778static DecodeStatus DecodeGuestRegs64RegisterClass(MCInst &Inst, unsigned RegNo,
779                                                   uint64_t /*Address*/,
780                                                   const void *Decoder) {
781  using namespace Hexagon;
782
783  static const MCPhysReg GuestReg64DecoderTable[] = {
784    /*  0 */ G1_0,      0,          G3_2,       0,
785    /*  4 */ G5_4,      0,          G7_6,       0,
786    /*  8 */ G9_8,      0,          G11_10,     0,
787    /* 12 */ G13_12,    0,          G15_14,     0,
788    /* 16 */ G17_16,    0,          G19_18,     0,
789    /* 20 */ G21_20,    0,          G23_22,     0,
790    /* 24 */ G25_24,    0,          G27_26,     0,
791    /* 28 */ G29_28,    0,          G31_30,     0
792  };
793
794  if (RegNo >= array_lengthof(GuestReg64DecoderTable))
795    return MCDisassembler::Fail;
796  if (GuestReg64DecoderTable[RegNo] == Hexagon::NoRegister)
797    return MCDisassembler::Fail;
798
799  unsigned Register = GuestReg64DecoderTable[RegNo];
800  Inst.addOperand(MCOperand::createReg(Register));
801  return MCDisassembler::Success;
802}
803