1//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//
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// This class extends MCInstrInfo to allow Hexagon specific MCInstr queries
10//
11//===----------------------------------------------------------------------===//
12
13#include "MCTargetDesc/HexagonMCInstrInfo.h"
14#include "MCTargetDesc/HexagonBaseInfo.h"
15#include "MCTargetDesc/HexagonMCChecker.h"
16#include "MCTargetDesc/HexagonMCExpr.h"
17#include "MCTargetDesc/HexagonMCShuffler.h"
18#include "MCTargetDesc/HexagonMCTargetDesc.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInst.h"
23#include "llvm/MC/MCInstrInfo.h"
24#include "llvm/MC/MCInstrItineraries.h"
25#include "llvm/MC/MCSubtargetInfo.h"
26#include "llvm/Support/Casting.h"
27#include "llvm/Support/ErrorHandling.h"
28#include <cassert>
29#include <cstdint>
30#include <limits>
31
32using namespace llvm;
33
34bool HexagonMCInstrInfo::PredicateInfo::isPredicated() const {
35  return Register != Hexagon::NoRegister;
36}
37
38Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
39                                        MCInst const &Inst)
40    : MCII(MCII), BundleCurrent(Inst.begin() +
41                                HexagonMCInstrInfo::bundleInstructionsOffset),
42      BundleEnd(Inst.end()), DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
43
44Hexagon::PacketIterator::PacketIterator(MCInstrInfo const &MCII,
45                                        MCInst const &Inst, std::nullptr_t)
46    : MCII(MCII), BundleCurrent(Inst.end()), BundleEnd(Inst.end()),
47      DuplexCurrent(Inst.end()), DuplexEnd(Inst.end()) {}
48
49Hexagon::PacketIterator &Hexagon::PacketIterator::operator++() {
50  if (DuplexCurrent != DuplexEnd) {
51    ++DuplexCurrent;
52    if (DuplexCurrent == DuplexEnd) {
53      DuplexCurrent = BundleEnd;
54      DuplexEnd = BundleEnd;
55      ++BundleCurrent;
56    }
57    return *this;
58  }
59  ++BundleCurrent;
60  if (BundleCurrent != BundleEnd) {
61    MCInst const &Inst = *BundleCurrent->getInst();
62    if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
63      DuplexCurrent = Inst.begin();
64      DuplexEnd = Inst.end();
65    }
66  }
67  return *this;
68}
69
70MCInst const &Hexagon::PacketIterator::operator*() const {
71  if (DuplexCurrent != DuplexEnd)
72    return *DuplexCurrent->getInst();
73  return *BundleCurrent->getInst();
74}
75
76bool Hexagon::PacketIterator::operator==(PacketIterator const &Other) const {
77  return BundleCurrent == Other.BundleCurrent && BundleEnd == Other.BundleEnd &&
78         DuplexCurrent == Other.DuplexCurrent && DuplexEnd == Other.DuplexEnd;
79}
80
81void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
82                                     MCContext &Context) {
83  MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
84}
85
86void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
87                                          MCInstrInfo const &MCII, MCInst &MCB,
88                                          MCInst const &MCI) {
89  assert(HexagonMCInstrInfo::isBundle(MCB));
90  MCOperand const &exOp =
91      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
92
93  // Create the extender.
94  MCInst *XMCI =
95      new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
96  XMCI->setLoc(MCI.getLoc());
97
98  MCB.addOperand(MCOperand::createInst(XMCI));
99}
100
101iterator_range<Hexagon::PacketIterator>
102HexagonMCInstrInfo::bundleInstructions(MCInstrInfo const &MCII,
103                                       MCInst const &MCI) {
104  assert(isBundle(MCI));
105  return make_range(Hexagon::PacketIterator(MCII, MCI),
106                    Hexagon::PacketIterator(MCII, MCI, nullptr));
107}
108
109iterator_range<MCInst::const_iterator>
110HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
111  assert(isBundle(MCI));
112  return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end());
113}
114
115size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
116  if (HexagonMCInstrInfo::isBundle(MCI))
117    return (MCI.size() - bundleInstructionsOffset);
118  else
119    return (1);
120}
121
122bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
123                                            MCSubtargetInfo const &STI,
124                                            MCContext &Context, MCInst &MCB,
125                                            HexagonMCChecker *Check) {
126  // Check the bundle for errors.
127  bool CheckOk = Check ? Check->check(false) : true;
128  if (!CheckOk)
129    return false;
130  // Examine the packet and convert pairs of instructions to compound
131  // instructions when possible.
132  if (!HexagonDisableCompound)
133    HexagonMCInstrInfo::tryCompound(MCII, STI, Context, MCB);
134  HexagonMCShuffle(Context, false, MCII, STI, MCB);
135  // Examine the packet and convert pairs of instructions to duplex
136  // instructions when possible.
137  MCInst InstBundlePreDuplex = MCInst(MCB);
138  if (STI.getFeatureBits() [Hexagon::FeatureDuplex]) {
139    SmallVector<DuplexCandidate, 8> possibleDuplexes;
140    possibleDuplexes =
141        HexagonMCInstrInfo::getDuplexPossibilties(MCII, STI, MCB);
142    HexagonMCShuffle(Context, MCII, STI, MCB, possibleDuplexes);
143  }
144  // Examines packet and pad the packet, if needed, when an
145  // end-loop is in the bundle.
146  HexagonMCInstrInfo::padEndloop(MCB, Context);
147  // If compounding and duplexing didn't reduce the size below
148  // 4 or less we have a packet that is too big.
149  if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE)
150    return false;
151  // Check the bundle for errors.
152  CheckOk = Check ? Check->check(true) : true;
153  if (!CheckOk)
154    return false;
155  HexagonMCShuffle(Context, true, MCII, STI, MCB);
156  return true;
157}
158
159MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
160                                          MCInst const &Inst,
161                                          MCOperand const &MO) {
162  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
163         HexagonMCInstrInfo::isExtended(MCII, Inst));
164
165  MCInst XMI;
166  XMI.setOpcode(Hexagon::A4_ext);
167  if (MO.isImm())
168    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
169  else if (MO.isExpr())
170    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
171  else
172    llvm_unreachable("invalid extendable operand");
173  return XMI;
174}
175
176MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,
177                                         MCInst const &inst0,
178                                         MCInst const &inst1) {
179  assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
180  MCInst *duplexInst = new (Context) MCInst;
181  duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);
182
183  MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
184  MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
185  duplexInst->addOperand(MCOperand::createInst(SubInst0));
186  duplexInst->addOperand(MCOperand::createInst(SubInst1));
187  return duplexInst;
188}
189
190MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
191                                                   size_t Index) {
192  assert(Index <= bundleSize(MCB));
193  if (Index == 0)
194    return nullptr;
195  MCInst const *Inst =
196      MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst();
197  if (isImmext(*Inst))
198    return Inst;
199  return nullptr;
200}
201
202void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context,
203                                        MCInstrInfo const &MCII, MCInst &MCB,
204                                        MCInst const &MCI) {
205  if (isConstExtended(MCII, MCI))
206    addConstExtender(Context, MCII, MCB, MCI);
207}
208
209unsigned HexagonMCInstrInfo::getMemAccessSize(MCInstrInfo const &MCII,
210      MCInst const &MCI) {
211  uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
212  unsigned S = (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;
213  return HexagonII::getMemAccessSizeInBytes(HexagonII::MemAccessSize(S));
214}
215
216unsigned HexagonMCInstrInfo::getAddrMode(MCInstrInfo const &MCII,
217                                         MCInst const &MCI) {
218  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
219  return static_cast<unsigned>((F >> HexagonII::AddrModePos) &
220                               HexagonII::AddrModeMask);
221}
222
223MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
224                                               MCInst const &MCI) {
225  return MCII.get(MCI.getOpcode());
226}
227
228unsigned HexagonMCInstrInfo::getDuplexRegisterNumbering(unsigned Reg) {
229  using namespace Hexagon;
230
231  switch (Reg) {
232  default:
233    llvm_unreachable("unknown duplex register");
234  // Rs       Rss
235  case R0:
236  case D0:
237    return 0;
238  case R1:
239  case D1:
240    return 1;
241  case R2:
242  case D2:
243    return 2;
244  case R3:
245  case D3:
246    return 3;
247  case R4:
248  case D8:
249    return 4;
250  case R5:
251  case D9:
252    return 5;
253  case R6:
254  case D10:
255    return 6;
256  case R7:
257  case D11:
258    return 7;
259  case R16:
260    return 8;
261  case R17:
262    return 9;
263  case R18:
264    return 10;
265  case R19:
266    return 11;
267  case R20:
268    return 12;
269  case R21:
270    return 13;
271  case R22:
272    return 14;
273  case R23:
274    return 15;
275  }
276}
277
278MCExpr const &HexagonMCInstrInfo::getExpr(MCExpr const &Expr) {
279  const auto &HExpr = cast<HexagonMCExpr>(Expr);
280  assert(HExpr.getExpr());
281  return *HExpr.getExpr();
282}
283
284unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,
285                                                   MCInst const &MCI) {
286  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
287  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
288}
289
290MCOperand const &
291HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
292                                         MCInst const &MCI) {
293  unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
294  MCOperand const &MO = MCI.getOperand(O);
295
296  assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
297          HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
298         (MO.isImm() || MO.isExpr()));
299  return (MO);
300}
301
302unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,
303                                                MCInst const &MCI) {
304  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
305  return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask);
306}
307
308unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII,
309                                           MCInst const &MCI) {
310  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
311  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
312}
313
314bool HexagonMCInstrInfo::isExtentSigned(MCInstrInfo const &MCII,
315                                        MCInst const &MCI) {
316  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
317  return (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
318}
319
320/// Return the maximum value of an extendable operand.
321int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,
322                                    MCInst const &MCI) {
323  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
324         HexagonMCInstrInfo::isExtended(MCII, MCI));
325
326  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
327    return (1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1)) - 1;
328  return (1 << HexagonMCInstrInfo::getExtentBits(MCII, MCI)) - 1;
329}
330
331/// Return the minimum value of an extendable operand.
332int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
333                                    MCInst const &MCI) {
334  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
335         HexagonMCInstrInfo::isExtended(MCII, MCI));
336
337  if (HexagonMCInstrInfo::isExtentSigned(MCII, MCI)) // if value is signed
338    return -(1 << (HexagonMCInstrInfo::getExtentBits(MCII, MCI) - 1));
339  return 0;
340}
341
342StringRef HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
343                                      MCInst const &MCI) {
344  return MCII.getName(MCI.getOpcode());
345}
346
347unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,
348                                                 MCInst const &MCI) {
349  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
350  return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask);
351}
352
353MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
354                                                        MCInst const &MCI) {
355  if (HexagonMCInstrInfo::hasTmpDst(MCII, MCI)) {
356    // VTMP doesn't actually exist in the encodings for these 184
357    // 3 instructions so go ahead and create it here.
358    static MCOperand MCO = MCOperand::createReg(Hexagon::VTMP);
359    return (MCO);
360  } else {
361    unsigned O = HexagonMCInstrInfo::getNewValueOp(MCII, MCI);
362    MCOperand const &MCO = MCI.getOperand(O);
363
364    assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
365            HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
366           MCO.isReg());
367    return (MCO);
368  }
369}
370
371/// Return the new value or the newly produced value.
372unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
373                                                  MCInst const &MCI) {
374  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
375  return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
376}
377
378MCOperand const &
379HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
380                                        MCInst const &MCI) {
381  unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
382  MCOperand const &MCO = MCI.getOperand(O);
383
384  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
385          HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
386         MCO.isReg());
387  return (MCO);
388}
389
390/// Return the Hexagon ISA class for the insn.
391unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,
392                                     MCInst const &MCI) {
393  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
394  return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
395}
396
397/// Return the slots this instruction can execute out of
398unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,
399                                      MCSubtargetInfo const &STI,
400                                      MCInst const &MCI) {
401  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
402  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
403  return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
404}
405
406/// Return the slots this instruction consumes in addition to
407/// the slot(s) it can execute out of
408
409unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII,
410                                                   MCSubtargetInfo const &STI,
411                                                   MCInst const &MCI) {
412  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
413  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
414  unsigned Slots = 0;
415
416  // FirstStage are slots that this instruction can execute in.
417  // FirstStage+1 are slots that are also consumed by this instruction.
418  // For example: vmemu can only execute in slot 0 but also consumes slot 1.
419  for (unsigned Stage = II[SchedClass].FirstStage + 1;
420       Stage < II[SchedClass].LastStage; ++Stage) {
421    unsigned Units = (Stage + HexagonStages)->getUnits();
422    if (Units > HexagonGetLastSlot())
423      break;
424    // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8
425    Slots |= Units;
426  }
427
428  // if 0 is returned, then no additional slots are consumed by this inst.
429  return Slots;
430}
431
432bool HexagonMCInstrInfo::hasDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
433  if (!HexagonMCInstrInfo::isBundle(MCI))
434    return false;
435
436  for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
437    if (HexagonMCInstrInfo::isDuplex(MCII, *I.getInst()))
438      return true;
439  }
440
441  return false;
442}
443
444bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
445  return extenderForIndex(MCB, Index) != nullptr;
446}
447
448bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
449  if (!HexagonMCInstrInfo::isBundle(MCI))
450    return false;
451
452  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
453    if (isImmext(*I.getInst()))
454      return true;
455  }
456
457  return false;
458}
459
460/// Return whether the insn produces a value.
461bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
462                                     MCInst const &MCI) {
463  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
464  return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
465}
466
467/// Return whether the insn produces a second value.
468bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
469                                      MCInst const &MCI) {
470  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
471  return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);
472}
473
474MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
475  assert(isBundle(MCB));
476  assert(Index < HEXAGON_PACKET_SIZE);
477  return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
478}
479
480/// Return where the instruction is an accumulator.
481bool HexagonMCInstrInfo::isAccumulator(MCInstrInfo const &MCII,
482                                       MCInst const &MCI) {
483  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
484  return ((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
485}
486
487bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {
488  auto Result = Hexagon::BUNDLE == MCI.getOpcode();
489  assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
490  return Result;
491}
492
493bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
494                                         MCInst const &MCI) {
495  if (HexagonMCInstrInfo::isExtended(MCII, MCI))
496    return true;
497  if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
498    return false;
499  MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);
500  if (isa<HexagonMCExpr>(MO.getExpr()) &&
501      HexagonMCInstrInfo::mustExtend(*MO.getExpr()))
502    return true;
503  // Branch insns are handled as necessary by relaxation.
504  if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
505      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCJ &&
506       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
507      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ &&
508       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
509    return false;
510  // Otherwise loop instructions and other CR insts are handled by relaxation
511  else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
512           (MCI.getOpcode() != Hexagon::C4_addipc))
513    return false;
514
515  assert(!MO.isImm());
516  if (isa<HexagonMCExpr>(MO.getExpr()) &&
517      HexagonMCInstrInfo::mustNotExtend(*MO.getExpr()))
518    return false;
519  int64_t Value;
520  if (!MO.getExpr()->evaluateAsAbsolute(Value))
521    return true;
522  int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
523  int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
524  return (MinValue > Value || Value > MaxValue);
525}
526
527bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
528  return !HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
529         !HexagonMCInstrInfo::isPrefix(MCII, MCI);
530}
531
532bool HexagonMCInstrInfo::isCofMax1(MCInstrInfo const &MCII, MCInst const &MCI) {
533  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
534  return ((F >> HexagonII::CofMax1Pos) & HexagonII::CofMax1Mask);
535}
536
537bool HexagonMCInstrInfo::isCofRelax1(MCInstrInfo const &MCII,
538                                     MCInst const &MCI) {
539  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
540  return ((F >> HexagonII::CofRelax1Pos) & HexagonII::CofRelax1Mask);
541}
542
543bool HexagonMCInstrInfo::isCofRelax2(MCInstrInfo const &MCII,
544                                     MCInst const &MCI) {
545  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
546  return ((F >> HexagonII::CofRelax2Pos) & HexagonII::CofRelax2Mask);
547}
548
549bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
550                                    MCInst const &MCI) {
551  return (getType(MCII, MCI) == HexagonII::TypeCJ);
552}
553
554bool HexagonMCInstrInfo::isCVINew(MCInstrInfo const &MCII, MCInst const &MCI) {
555  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
556  return ((F >> HexagonII::CVINewPos) & HexagonII::CVINewMask);
557}
558
559bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
560  return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
561          (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
562}
563
564bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
565  return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI);
566}
567
568bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
569                                      MCInst const &MCI) {
570  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
571  return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
572}
573
574bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII,
575                                    MCInst const &MCI) {
576  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
577  return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
578}
579
580bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
581  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
582  return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
583}
584
585bool HexagonMCInstrInfo::isHVX(MCInstrInfo const &MCII, MCInst const &MCI) {
586  const uint64_t V = getType(MCII, MCI);
587  return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
588}
589
590bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
591  return MCI.getOpcode() == Hexagon::A4_ext;
592}
593
594bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {
595  assert(isBundle(MCI));
596  int64_t Flags = MCI.getOperand(0).getImm();
597  return (Flags & innerLoopMask) != 0;
598}
599
600bool HexagonMCInstrInfo::isIntReg(unsigned Reg) {
601  return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
602}
603
604bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) {
605  return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
606          (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
607}
608
609/// Return whether the insn expects newly produced value.
610bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII,
611                                    MCInst const &MCI) {
612  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
613  return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
614}
615
616/// Return whether the operand is extendable.
617bool HexagonMCInstrInfo::isOpExtendable(MCInstrInfo const &MCII,
618                                        MCInst const &MCI, unsigned short O) {
619  return (O == HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
620}
621
622bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) {
623  assert(isBundle(MCI));
624  int64_t Flags = MCI.getOperand(0).getImm();
625  return (Flags & outerLoopMask) != 0;
626}
627
628bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,
629                                      MCInst const &MCI) {
630  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
631  return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
632}
633
634bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
635  return HexagonII::TypeEXTENDER == HexagonMCInstrInfo::getType(MCII, MCI);
636}
637
638bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
639                                         MCInst const &MCI) {
640  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
641  return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);
642}
643
644/// Return whether the insn is newly predicated.
645bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
646                                         MCInst const &MCI) {
647  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
648  return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
649}
650
651bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
652                                          MCInst const &MCI) {
653  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
654  return (
655      !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask));
656}
657
658bool HexagonMCInstrInfo::isPredReg(unsigned Reg) {
659  return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0);
660}
661
662/// Return whether the insn can be packaged only with A and X-type insns.
663bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
664  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
665  return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
666}
667
668/// Return whether the insn can be packaged only with an A-type insn in slot #1.
669bool HexagonMCInstrInfo::isRestrictSlot1AOK(MCInstrInfo const &MCII,
670                                            MCInst const &MCI) {
671  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
672  return ((F >> HexagonII::RestrictSlot1AOKPos) &
673          HexagonII::RestrictSlot1AOKMask);
674}
675
676bool HexagonMCInstrInfo::isRestrictNoSlot1Store(MCInstrInfo const &MCII,
677                                                MCInst const &MCI) {
678  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
679  return ((F >> HexagonII::RestrictNoSlot1StorePos) &
680          HexagonII::RestrictNoSlot1StoreMask);
681}
682
683/// Return whether the insn is solo, i.e., cannot be in a packet.
684bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
685  const uint64_t F = MCII.get(MCI.getOpcode()).TSFlags;
686  return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
687}
688
689bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
690  assert(isBundle(MCI));
691  auto Flags = MCI.getOperand(0).getImm();
692  return (Flags & memReorderDisabledMask) != 0;
693}
694
695bool HexagonMCInstrInfo::isSubInstruction(MCInst const &MCI) {
696  switch (MCI.getOpcode()) {
697  default:
698    return false;
699  case Hexagon::SA1_addi:
700  case Hexagon::SA1_addrx:
701  case Hexagon::SA1_addsp:
702  case Hexagon::SA1_and1:
703  case Hexagon::SA1_clrf:
704  case Hexagon::SA1_clrfnew:
705  case Hexagon::SA1_clrt:
706  case Hexagon::SA1_clrtnew:
707  case Hexagon::SA1_cmpeqi:
708  case Hexagon::SA1_combine0i:
709  case Hexagon::SA1_combine1i:
710  case Hexagon::SA1_combine2i:
711  case Hexagon::SA1_combine3i:
712  case Hexagon::SA1_combinerz:
713  case Hexagon::SA1_combinezr:
714  case Hexagon::SA1_dec:
715  case Hexagon::SA1_inc:
716  case Hexagon::SA1_seti:
717  case Hexagon::SA1_setin1:
718  case Hexagon::SA1_sxtb:
719  case Hexagon::SA1_sxth:
720  case Hexagon::SA1_tfr:
721  case Hexagon::SA1_zxtb:
722  case Hexagon::SA1_zxth:
723  case Hexagon::SL1_loadri_io:
724  case Hexagon::SL1_loadrub_io:
725  case Hexagon::SL2_deallocframe:
726  case Hexagon::SL2_jumpr31:
727  case Hexagon::SL2_jumpr31_f:
728  case Hexagon::SL2_jumpr31_fnew:
729  case Hexagon::SL2_jumpr31_t:
730  case Hexagon::SL2_jumpr31_tnew:
731  case Hexagon::SL2_loadrb_io:
732  case Hexagon::SL2_loadrd_sp:
733  case Hexagon::SL2_loadrh_io:
734  case Hexagon::SL2_loadri_sp:
735  case Hexagon::SL2_loadruh_io:
736  case Hexagon::SL2_return:
737  case Hexagon::SL2_return_f:
738  case Hexagon::SL2_return_fnew:
739  case Hexagon::SL2_return_t:
740  case Hexagon::SL2_return_tnew:
741  case Hexagon::SS1_storeb_io:
742  case Hexagon::SS1_storew_io:
743  case Hexagon::SS2_allocframe:
744  case Hexagon::SS2_storebi0:
745  case Hexagon::SS2_storebi1:
746  case Hexagon::SS2_stored_sp:
747  case Hexagon::SS2_storeh_io:
748  case Hexagon::SS2_storew_sp:
749  case Hexagon::SS2_storewi0:
750  case Hexagon::SS2_storewi1:
751    return true;
752  }
753}
754
755bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
756  if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) &&
757      (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST))
758    return true;
759  return false;
760}
761
762int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
763  auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
764                  << 8;
765  if (MCI.size() <= Index)
766    return Sentinal;
767  MCOperand const &MCO = MCI.getOperand(Index);
768  if (!MCO.isExpr())
769    return Sentinal;
770  int64_t Value;
771  if (!MCO.getExpr()->evaluateAsAbsolute(Value))
772    return Sentinal;
773  return Value;
774}
775
776void HexagonMCInstrInfo::setMustExtend(MCExpr const &Expr, bool Val) {
777  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
778  HExpr.setMustExtend(Val);
779}
780
781bool HexagonMCInstrInfo::mustExtend(MCExpr const &Expr) {
782  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
783  return HExpr.mustExtend();
784}
785void HexagonMCInstrInfo::setMustNotExtend(MCExpr const &Expr, bool Val) {
786  HexagonMCExpr &HExpr = const_cast<HexagonMCExpr &>(cast<HexagonMCExpr>(Expr));
787  HExpr.setMustNotExtend(Val);
788}
789bool HexagonMCInstrInfo::mustNotExtend(MCExpr const &Expr) {
790  HexagonMCExpr const &HExpr = cast<HexagonMCExpr>(Expr);
791  return HExpr.mustNotExtend();
792}
793void HexagonMCInstrInfo::setS27_2_reloc(MCExpr const &Expr, bool Val) {
794  HexagonMCExpr &HExpr =
795      const_cast<HexagonMCExpr &>(*cast<HexagonMCExpr>(&Expr));
796  HExpr.setS27_2_reloc(Val);
797}
798bool HexagonMCInstrInfo::s27_2_reloc(MCExpr const &Expr) {
799  HexagonMCExpr const *HExpr = dyn_cast<HexagonMCExpr>(&Expr);
800  if (!HExpr)
801    return false;
802  return HExpr->s27_2_reloc();
803}
804
805void HexagonMCInstrInfo::padEndloop(MCInst &MCB, MCContext &Context) {
806  MCInst Nop;
807  Nop.setOpcode(Hexagon::A2_nop);
808  assert(isBundle(MCB));
809  while ((HexagonMCInstrInfo::isInnerLoop(MCB) &&
810          (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||
811         ((HexagonMCInstrInfo::isOuterLoop(MCB) &&
812           (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))))
813    MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
814}
815
816HexagonMCInstrInfo::PredicateInfo
817HexagonMCInstrInfo::predicateInfo(MCInstrInfo const &MCII, MCInst const &MCI) {
818  if (!isPredicated(MCII, MCI))
819    return {0, 0, false};
820  MCInstrDesc const &Desc = getDesc(MCII, MCI);
821  for (auto I = Desc.getNumDefs(), N = Desc.getNumOperands(); I != N; ++I)
822    if (Desc.OpInfo[I].RegClass == Hexagon::PredRegsRegClassID)
823      return {MCI.getOperand(I).getReg(), I, isPredicatedTrue(MCII, MCI)};
824  return {0, 0, false};
825}
826
827bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,
828                                      MCInst const &MCI) {
829  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
830  return (F >> HexagonII::PrefersSlot3Pos) & HexagonII::PrefersSlot3Mask;
831}
832
833/// return true if instruction has hasTmpDst attribute.
834bool HexagonMCInstrInfo::hasTmpDst(MCInstrInfo const &MCII, MCInst const &MCI) {
835  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
836  return (F >> HexagonII::HasTmpDstPos) & HexagonII::HasTmpDstMask;
837}
838
839void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,
840                                       DuplexCandidate Candidate) {
841  assert(Candidate.packetIndexI < MCB.size());
842  assert(Candidate.packetIndexJ < MCB.size());
843  assert(isBundle(MCB));
844  MCInst *Duplex =
845      deriveDuplex(Context, Candidate.iClass,
846                   *MCB.getOperand(Candidate.packetIndexJ).getInst(),
847                   *MCB.getOperand(Candidate.packetIndexI).getInst());
848  assert(Duplex != nullptr);
849  MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
850  MCB.erase(MCB.begin() + Candidate.packetIndexJ);
851}
852
853void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
854  assert(isBundle(MCI));
855  MCOperand &Operand = MCI.getOperand(0);
856  Operand.setImm(Operand.getImm() | innerLoopMask);
857}
858
859void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
860  assert(isBundle(MCI));
861  MCOperand &Operand = MCI.getOperand(0);
862  Operand.setImm(Operand.getImm() | memReorderDisabledMask);
863  assert(isMemReorderDisabled(MCI));
864}
865
866void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
867  assert(isBundle(MCI));
868  MCOperand &Operand = MCI.getOperand(0);
869  Operand.setImm(Operand.getImm() | outerLoopMask);
870}
871
872unsigned HexagonMCInstrInfo::SubregisterBit(unsigned Consumer,
873                                            unsigned Producer,
874                                            unsigned Producer2) {
875  // If we're a single vector consumer of a double producer, set subreg bit
876  // based on if we're accessing the lower or upper register component
877  if (Producer >= Hexagon::W0 && Producer <= Hexagon::W15)
878    if (Consumer >= Hexagon::V0 && Consumer <= Hexagon::V31)
879      return (Consumer - Hexagon::V0) & 0x1;
880  if (Producer2 != Hexagon::NoRegister)
881    return Consumer == Producer;
882  return 0;
883}
884