1//===- HexagonMCInstrInfo.cpp - Hexagon sub-class of MCInst ---------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class extends MCInstrInfo to allow Hexagon specific MCInstr queries
11//
12//===----------------------------------------------------------------------===//
13
14#include "HexagonMCInstrInfo.h"
15
16#include "Hexagon.h"
17#include "HexagonBaseInfo.h"
18#include "HexagonMCChecker.h"
19
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCInstrInfo.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24
25namespace llvm {
26void HexagonMCInstrInfo::addConstant(MCInst &MI, uint64_t Value,
27                                     MCContext &Context) {
28  MI.addOperand(MCOperand::createExpr(MCConstantExpr::create(Value, Context)));
29}
30
31void HexagonMCInstrInfo::addConstExtender(MCContext &Context,
32                                          MCInstrInfo const &MCII, MCInst &MCB,
33                                          MCInst const &MCI) {
34  assert(HexagonMCInstrInfo::isBundle(MCB));
35  MCOperand const &exOp =
36      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
37
38  // Create the extender.
39  MCInst *XMCI =
40      new (Context) MCInst(HexagonMCInstrInfo::deriveExtender(MCII, MCI, exOp));
41
42  MCB.addOperand(MCOperand::createInst(XMCI));
43}
44
45iterator_range<MCInst::const_iterator>
46HexagonMCInstrInfo::bundleInstructions(MCInst const &MCI) {
47  assert(isBundle(MCI));
48  return make_range(MCI.begin() + bundleInstructionsOffset, MCI.end());
49}
50
51size_t HexagonMCInstrInfo::bundleSize(MCInst const &MCI) {
52  if (HexagonMCInstrInfo::isBundle(MCI))
53    return (MCI.size() - bundleInstructionsOffset);
54  else
55    return (1);
56}
57
58bool HexagonMCInstrInfo::canonicalizePacket(MCInstrInfo const &MCII,
59                                            MCSubtargetInfo const &STI,
60                                            MCContext &Context, MCInst &MCB,
61                                            HexagonMCChecker *Check) {
62  // Examine the packet and convert pairs of instructions to compound
63  // instructions when possible.
64  if (!HexagonDisableCompound)
65    HexagonMCInstrInfo::tryCompound(MCII, Context, MCB);
66  // Check the bundle for errors.
67  bool CheckOk = Check ? Check->check() : true;
68  if (!CheckOk)
69    return false;
70  HexagonMCShuffle(MCII, STI, MCB);
71  // Examine the packet and convert pairs of instructions to duplex
72  // instructions when possible.
73  MCInst InstBundlePreDuplex = MCInst(MCB);
74  if (!HexagonDisableDuplex) {
75    SmallVector<DuplexCandidate, 8> possibleDuplexes;
76    possibleDuplexes = HexagonMCInstrInfo::getDuplexPossibilties(MCII, MCB);
77    HexagonMCShuffle(MCII, STI, Context, MCB, possibleDuplexes);
78  }
79  // Examines packet and pad the packet, if needed, when an
80  // end-loop is in the bundle.
81  HexagonMCInstrInfo::padEndloop(Context, MCB);
82  // If compounding and duplexing didn't reduce the size below
83  // 4 or less we have a packet that is too big.
84  if (HexagonMCInstrInfo::bundleSize(MCB) > HEXAGON_PACKET_SIZE)
85    return false;
86  HexagonMCShuffle(MCII, STI, MCB);
87  return true;
88}
89
90void HexagonMCInstrInfo::clampExtended(MCInstrInfo const &MCII,
91                                       MCContext &Context, MCInst &MCI) {
92  assert(HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
93         HexagonMCInstrInfo::isExtended(MCII, MCI));
94  MCOperand &exOp =
95      MCI.getOperand(HexagonMCInstrInfo::getExtendableOp(MCII, MCI));
96  // If the extended value is a constant, then use it for the extended and
97  // for the extender instructions, masking off the lower 6 bits and
98  // including the assumed bits.
99  int64_t Value;
100  if (exOp.getExpr()->evaluateAsAbsolute(Value)) {
101    unsigned Shift = HexagonMCInstrInfo::getExtentAlignment(MCII, MCI);
102    exOp.setExpr(MCConstantExpr::create((Value & 0x3f) << Shift, Context));
103  }
104}
105
106MCInst HexagonMCInstrInfo::createBundle() {
107  MCInst Result;
108  Result.setOpcode(Hexagon::BUNDLE);
109  Result.addOperand(MCOperand::createImm(0));
110  return Result;
111}
112
113MCInst *HexagonMCInstrInfo::deriveDuplex(MCContext &Context, unsigned iClass,
114                                         MCInst const &inst0,
115                                         MCInst const &inst1) {
116  assert((iClass <= 0xf) && "iClass must have range of 0 to 0xf");
117  MCInst *duplexInst = new (Context) MCInst;
118  duplexInst->setOpcode(Hexagon::DuplexIClass0 + iClass);
119
120  MCInst *SubInst0 = new (Context) MCInst(deriveSubInst(inst0));
121  MCInst *SubInst1 = new (Context) MCInst(deriveSubInst(inst1));
122  duplexInst->addOperand(MCOperand::createInst(SubInst0));
123  duplexInst->addOperand(MCOperand::createInst(SubInst1));
124  return duplexInst;
125}
126
127MCInst HexagonMCInstrInfo::deriveExtender(MCInstrInfo const &MCII,
128                                          MCInst const &Inst,
129                                          MCOperand const &MO) {
130  assert(HexagonMCInstrInfo::isExtendable(MCII, Inst) ||
131         HexagonMCInstrInfo::isExtended(MCII, Inst));
132
133  MCInstrDesc const &Desc = HexagonMCInstrInfo::getDesc(MCII, Inst);
134  MCInst XMI;
135  XMI.setOpcode((Desc.isBranch() || Desc.isCall() ||
136                 HexagonMCInstrInfo::getType(MCII, Inst) == HexagonII::TypeCR)
137                    ? Hexagon::A4_ext_b
138                    : Hexagon::A4_ext);
139  if (MO.isImm())
140    XMI.addOperand(MCOperand::createImm(MO.getImm() & (~0x3f)));
141  else if (MO.isExpr())
142    XMI.addOperand(MCOperand::createExpr(MO.getExpr()));
143  else
144    llvm_unreachable("invalid extendable operand");
145  return XMI;
146}
147
148MCInst const *HexagonMCInstrInfo::extenderForIndex(MCInst const &MCB,
149                                                   size_t Index) {
150  assert(Index <= bundleSize(MCB));
151  if (Index == 0)
152    return nullptr;
153  MCInst const *Inst =
154      MCB.getOperand(Index + bundleInstructionsOffset - 1).getInst();
155  if (isImmext(*Inst))
156    return Inst;
157  return nullptr;
158}
159
160void HexagonMCInstrInfo::extendIfNeeded(MCContext &Context,
161                                        MCInstrInfo const &MCII, MCInst &MCB,
162                                        MCInst const &MCI, bool MustExtend) {
163  if (isConstExtended(MCII, MCI) || MustExtend)
164    addConstExtender(Context, MCII, MCB, MCI);
165}
166
167HexagonII::MemAccessSize
168HexagonMCInstrInfo::getAccessSize(MCInstrInfo const &MCII, MCInst const &MCI) {
169  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
170
171  return (HexagonII::MemAccessSize((F >> HexagonII::MemAccessSizePos) &
172                                   HexagonII::MemAccesSizeMask));
173}
174
175unsigned HexagonMCInstrInfo::getBitCount(MCInstrInfo const &MCII,
176                                         MCInst const &MCI) {
177  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
178  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
179}
180
181// Return constant extended operand number.
182unsigned short HexagonMCInstrInfo::getCExtOpNum(MCInstrInfo const &MCII,
183                                                MCInst const &MCI) {
184  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
185  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
186}
187
188MCInstrDesc const &HexagonMCInstrInfo::getDesc(MCInstrInfo const &MCII,
189                                               MCInst const &MCI) {
190  return (MCII.get(MCI.getOpcode()));
191}
192
193unsigned short HexagonMCInstrInfo::getExtendableOp(MCInstrInfo const &MCII,
194                                                   MCInst const &MCI) {
195  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
196  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
197}
198
199MCOperand const &
200HexagonMCInstrInfo::getExtendableOperand(MCInstrInfo const &MCII,
201                                         MCInst const &MCI) {
202  unsigned O = HexagonMCInstrInfo::getExtendableOp(MCII, MCI);
203  MCOperand const &MO = MCI.getOperand(O);
204
205  assert((HexagonMCInstrInfo::isExtendable(MCII, MCI) ||
206          HexagonMCInstrInfo::isExtended(MCII, MCI)) &&
207         (MO.isImm() || MO.isExpr()));
208  return (MO);
209}
210
211unsigned HexagonMCInstrInfo::getExtentAlignment(MCInstrInfo const &MCII,
212                                                MCInst const &MCI) {
213  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
214  return ((F >> HexagonII::ExtentAlignPos) & HexagonII::ExtentAlignMask);
215}
216
217unsigned HexagonMCInstrInfo::getExtentBits(MCInstrInfo const &MCII,
218                                           MCInst const &MCI) {
219  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
220  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
221}
222
223// Return the max value that a constant extendable operand can have
224// without being extended.
225int HexagonMCInstrInfo::getMaxValue(MCInstrInfo const &MCII,
226                                    MCInst const &MCI) {
227  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
228  unsigned isSigned =
229      (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
230  unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
231
232  if (isSigned) // if value is signed
233    return ~(-1U << (bits - 1));
234  else
235    return ~(-1U << bits);
236}
237
238// Return the min value that a constant extendable operand can have
239// without being extended.
240int HexagonMCInstrInfo::getMinValue(MCInstrInfo const &MCII,
241                                    MCInst const &MCI) {
242  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
243  unsigned isSigned =
244      (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
245  unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
246
247  if (isSigned) // if value is signed
248    return -1U << (bits - 1);
249  else
250    return 0;
251}
252
253char const *HexagonMCInstrInfo::getName(MCInstrInfo const &MCII,
254                                        MCInst const &MCI) {
255  return MCII.getName(MCI.getOpcode());
256}
257
258unsigned short HexagonMCInstrInfo::getNewValueOp(MCInstrInfo const &MCII,
259                                                 MCInst const &MCI) {
260  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
261  return ((F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask);
262}
263
264MCOperand const &HexagonMCInstrInfo::getNewValueOperand(MCInstrInfo const &MCII,
265                                                        MCInst const &MCI) {
266  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
267  unsigned const O =
268      (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask;
269  MCOperand const &MCO = MCI.getOperand(O);
270
271  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
272          HexagonMCInstrInfo::hasNewValue(MCII, MCI)) &&
273         MCO.isReg());
274  return (MCO);
275}
276
277/// Return the new value or the newly produced value.
278unsigned short HexagonMCInstrInfo::getNewValueOp2(MCInstrInfo const &MCII,
279                                                  MCInst const &MCI) {
280  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
281  return ((F >> HexagonII::NewValueOpPos2) & HexagonII::NewValueOpMask2);
282}
283
284MCOperand const &
285HexagonMCInstrInfo::getNewValueOperand2(MCInstrInfo const &MCII,
286                                        MCInst const &MCI) {
287  unsigned O = HexagonMCInstrInfo::getNewValueOp2(MCII, MCI);
288  MCOperand const &MCO = MCI.getOperand(O);
289
290  assert((HexagonMCInstrInfo::isNewValue(MCII, MCI) ||
291          HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) &&
292         MCO.isReg());
293  return (MCO);
294}
295
296int HexagonMCInstrInfo::getSubTarget(MCInstrInfo const &MCII,
297                                     MCInst const &MCI) {
298  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
299
300  HexagonII::SubTarget Target = static_cast<HexagonII::SubTarget>(
301      (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask);
302
303  switch (Target) {
304  default:
305    return Hexagon::ArchV4;
306  case HexagonII::HasV5SubT:
307    return Hexagon::ArchV5;
308  }
309}
310
311// Return the Hexagon ISA class for the insn.
312unsigned HexagonMCInstrInfo::getType(MCInstrInfo const &MCII,
313                                     MCInst const &MCI) {
314  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
315
316  return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
317}
318
319unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII,
320                                      MCSubtargetInfo const &STI,
321                                      MCInst const &MCI) {
322
323  const InstrItinerary *II = STI.getSchedModel().InstrItineraries;
324  int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
325  return ((II[SchedClass].FirstStage + HexagonStages)->getUnits());
326}
327
328bool HexagonMCInstrInfo::hasImmExt(MCInst const &MCI) {
329  if (!HexagonMCInstrInfo::isBundle(MCI))
330    return false;
331
332  for (const auto &I : HexagonMCInstrInfo::bundleInstructions(MCI)) {
333    auto MI = I.getInst();
334    if (isImmext(*MI))
335      return true;
336  }
337
338  return false;
339}
340
341bool HexagonMCInstrInfo::hasExtenderForIndex(MCInst const &MCB, size_t Index) {
342  return extenderForIndex(MCB, Index) != nullptr;
343}
344
345// Return whether the instruction is a legal new-value producer.
346bool HexagonMCInstrInfo::hasNewValue(MCInstrInfo const &MCII,
347                                     MCInst const &MCI) {
348  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
349  return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
350}
351
352/// Return whether the insn produces a second value.
353bool HexagonMCInstrInfo::hasNewValue2(MCInstrInfo const &MCII,
354                                      MCInst const &MCI) {
355  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
356  return ((F >> HexagonII::hasNewValuePos2) & HexagonII::hasNewValueMask2);
357}
358
359MCInst const &HexagonMCInstrInfo::instruction(MCInst const &MCB, size_t Index) {
360  assert(isBundle(MCB));
361  assert(Index < HEXAGON_PACKET_SIZE);
362  return *MCB.getOperand(bundleInstructionsOffset + Index).getInst();
363}
364
365bool HexagonMCInstrInfo::isBundle(MCInst const &MCI) {
366  auto Result = Hexagon::BUNDLE == MCI.getOpcode();
367  assert(!Result || (MCI.size() > 0 && MCI.getOperand(0).isImm()));
368  return Result;
369}
370
371// Return whether the insn is an actual insn.
372bool HexagonMCInstrInfo::isCanon(MCInstrInfo const &MCII, MCInst const &MCI) {
373  return (!HexagonMCInstrInfo::getDesc(MCII, MCI).isPseudo() &&
374          !HexagonMCInstrInfo::isPrefix(MCII, MCI) &&
375          HexagonMCInstrInfo::getType(MCII, MCI) != HexagonII::TypeENDLOOP);
376}
377
378bool HexagonMCInstrInfo::isCompound(MCInstrInfo const &MCII,
379                                    MCInst const &MCI) {
380  return (getType(MCII, MCI) == HexagonII::TypeCOMPOUND);
381}
382
383bool HexagonMCInstrInfo::isDblRegForSubInst(unsigned Reg) {
384  return ((Reg >= Hexagon::D0 && Reg <= Hexagon::D3) ||
385          (Reg >= Hexagon::D8 && Reg <= Hexagon::D11));
386}
387
388bool HexagonMCInstrInfo::isDuplex(MCInstrInfo const &MCII, MCInst const &MCI) {
389  return HexagonII::TypeDUPLEX == HexagonMCInstrInfo::getType(MCII, MCI);
390}
391
392// Return whether the instruction needs to be constant extended.
393// 1) Always return true if the instruction has 'isExtended' flag set.
394//
395// isExtendable:
396// 2) For immediate extended operands, return true only if the value is
397//    out-of-range.
398// 3) For global address, always return true.
399
400bool HexagonMCInstrInfo::isConstExtended(MCInstrInfo const &MCII,
401                                         MCInst const &MCI) {
402  if (HexagonMCInstrInfo::isExtended(MCII, MCI))
403    return true;
404  // Branch insns are handled as necessary by relaxation.
405  if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeJ) ||
406      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCOMPOUND &&
407       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()) ||
408      (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV &&
409       HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch()))
410    return false;
411  // Otherwise loop instructions and other CR insts are handled by relaxation
412  else if ((HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR) &&
413           (MCI.getOpcode() != Hexagon::C4_addipc))
414    return false;
415  else if (!HexagonMCInstrInfo::isExtendable(MCII, MCI))
416    return false;
417
418  MCOperand const &MO = HexagonMCInstrInfo::getExtendableOperand(MCII, MCI);
419
420  // We could be using an instruction with an extendable immediate and shoehorn
421  // a global address into it. If it is a global address it will be constant
422  // extended. We do this for COMBINE.
423  // We currently only handle isGlobal() because it is the only kind of
424  // object we are going to end up with here for now.
425  // In the future we probably should add isSymbol(), etc.
426  assert(!MO.isImm());
427  int64_t Value;
428  if (!MO.getExpr()->evaluateAsAbsolute(Value))
429    return true;
430  int MinValue = HexagonMCInstrInfo::getMinValue(MCII, MCI);
431  int MaxValue = HexagonMCInstrInfo::getMaxValue(MCII, MCI);
432  return (MinValue > Value || Value > MaxValue);
433}
434
435bool HexagonMCInstrInfo::isExtendable(MCInstrInfo const &MCII,
436                                      MCInst const &MCI) {
437  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
438  return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
439}
440
441bool HexagonMCInstrInfo::isExtended(MCInstrInfo const &MCII,
442                                    MCInst const &MCI) {
443  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
444  return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
445}
446
447bool HexagonMCInstrInfo::isFloat(MCInstrInfo const &MCII, MCInst const &MCI) {
448  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
449  return ((F >> HexagonII::FPPos) & HexagonII::FPMask);
450}
451
452bool HexagonMCInstrInfo::isImmext(MCInst const &MCI) {
453  auto Op = MCI.getOpcode();
454  return (Op == Hexagon::A4_ext_b || Op == Hexagon::A4_ext_c ||
455          Op == Hexagon::A4_ext_g || Op == Hexagon::A4_ext);
456}
457
458bool HexagonMCInstrInfo::isInnerLoop(MCInst const &MCI) {
459  assert(isBundle(MCI));
460  int64_t Flags = MCI.getOperand(0).getImm();
461  return (Flags & innerLoopMask) != 0;
462}
463
464bool HexagonMCInstrInfo::isIntReg(unsigned Reg) {
465  return (Reg >= Hexagon::R0 && Reg <= Hexagon::R31);
466}
467
468bool HexagonMCInstrInfo::isIntRegForSubInst(unsigned Reg) {
469  return ((Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
470          (Reg >= Hexagon::R16 && Reg <= Hexagon::R23));
471}
472
473// Return whether the insn is a new-value consumer.
474bool HexagonMCInstrInfo::isNewValue(MCInstrInfo const &MCII,
475                                    MCInst const &MCI) {
476  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
477  return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
478}
479
480// Return whether the operand can be constant extended.
481bool HexagonMCInstrInfo::isOperandExtended(MCInstrInfo const &MCII,
482                                           MCInst const &MCI,
483                                           unsigned short OperandNum) {
484  uint64_t const F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
485  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) ==
486         OperandNum;
487}
488
489bool HexagonMCInstrInfo::isOuterLoop(MCInst const &MCI) {
490  assert(isBundle(MCI));
491  int64_t Flags = MCI.getOperand(0).getImm();
492  return (Flags & outerLoopMask) != 0;
493}
494
495bool HexagonMCInstrInfo::isPredicated(MCInstrInfo const &MCII,
496                                      MCInst const &MCI) {
497  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
498  return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
499}
500
501bool HexagonMCInstrInfo::isPredicateLate(MCInstrInfo const &MCII,
502                                         MCInst const &MCI) {
503  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
504  return (F >> HexagonII::PredicateLatePos & HexagonII::PredicateLateMask);
505}
506
507/// Return whether the insn is newly predicated.
508bool HexagonMCInstrInfo::isPredicatedNew(MCInstrInfo const &MCII,
509                                         MCInst const &MCI) {
510  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
511  return ((F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask);
512}
513
514bool HexagonMCInstrInfo::isPredicatedTrue(MCInstrInfo const &MCII,
515                                          MCInst const &MCI) {
516  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
517  return (
518      !((F >> HexagonII::PredicatedFalsePos) & HexagonII::PredicatedFalseMask));
519}
520
521bool HexagonMCInstrInfo::isPredReg(unsigned Reg) {
522  return (Reg >= Hexagon::P0 && Reg <= Hexagon::P3_0);
523}
524
525bool HexagonMCInstrInfo::isPrefix(MCInstrInfo const &MCII, MCInst const &MCI) {
526  return (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypePREFIX);
527}
528
529bool HexagonMCInstrInfo::isSolo(MCInstrInfo const &MCII, MCInst const &MCI) {
530  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
531  return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
532}
533
534bool HexagonMCInstrInfo::isMemReorderDisabled(MCInst const &MCI) {
535  assert(isBundle(MCI));
536  auto Flags = MCI.getOperand(0).getImm();
537  return (Flags & memReorderDisabledMask) != 0;
538}
539
540bool HexagonMCInstrInfo::isMemStoreReorderEnabled(MCInst const &MCI) {
541  assert(isBundle(MCI));
542  auto Flags = MCI.getOperand(0).getImm();
543  return (Flags & memStoreReorderEnabledMask) != 0;
544}
545
546bool HexagonMCInstrInfo::isSoloAX(MCInstrInfo const &MCII, MCInst const &MCI) {
547  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
548  return ((F >> HexagonII::SoloAXPos) & HexagonII::SoloAXMask);
549}
550
551bool HexagonMCInstrInfo::isSoloAin1(MCInstrInfo const &MCII,
552                                    MCInst const &MCI) {
553  const uint64_t F = HexagonMCInstrInfo::getDesc(MCII, MCI).TSFlags;
554  return ((F >> HexagonII::SoloAin1Pos) & HexagonII::SoloAin1Mask);
555}
556
557bool HexagonMCInstrInfo::isVector(MCInstrInfo const &MCII, MCInst const &MCI) {
558  if ((getType(MCII, MCI) <= HexagonII::TypeCVI_LAST) &&
559      (getType(MCII, MCI) >= HexagonII::TypeCVI_FIRST))
560    return true;
561  return false;
562}
563
564int64_t HexagonMCInstrInfo::minConstant(MCInst const &MCI, size_t Index) {
565  auto Sentinal = static_cast<int64_t>(std::numeric_limits<uint32_t>::max())
566                  << 8;
567  if (MCI.size() <= Index)
568    return Sentinal;
569  MCOperand const &MCO = MCI.getOperand(Index);
570  if (!MCO.isExpr())
571    return Sentinal;
572  int64_t Value;
573  if (!MCO.getExpr()->evaluateAsAbsolute(Value))
574    return Sentinal;
575  return Value;
576}
577
578void HexagonMCInstrInfo::padEndloop(MCContext &Context, MCInst &MCB) {
579  MCInst Nop;
580  Nop.setOpcode(Hexagon::A2_nop);
581  assert(isBundle(MCB));
582  while ((HexagonMCInstrInfo::isInnerLoop(MCB) &&
583          (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_INNER_SIZE)) ||
584         ((HexagonMCInstrInfo::isOuterLoop(MCB) &&
585           (HexagonMCInstrInfo::bundleSize(MCB) < HEXAGON_PACKET_OUTER_SIZE))))
586    MCB.addOperand(MCOperand::createInst(new (Context) MCInst(Nop)));
587}
588
589bool HexagonMCInstrInfo::prefersSlot3(MCInstrInfo const &MCII,
590                                      MCInst const &MCI) {
591  if (HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCR)
592    return false;
593
594  unsigned SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass();
595  switch (SchedClass) {
596  case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123:
597  case Hexagon::Sched::ALU64_tc_2_SLOT23:
598  case Hexagon::Sched::ALU64_tc_3x_SLOT23:
599  case Hexagon::Sched::M_tc_2_SLOT23:
600  case Hexagon::Sched::M_tc_3x_SLOT23:
601  case Hexagon::Sched::S_2op_tc_2_SLOT23:
602  case Hexagon::Sched::S_3op_tc_2_SLOT23:
603  case Hexagon::Sched::S_3op_tc_3x_SLOT23:
604    return true;
605  }
606  return false;
607}
608
609void HexagonMCInstrInfo::replaceDuplex(MCContext &Context, MCInst &MCB,
610                                       DuplexCandidate Candidate) {
611  assert(Candidate.packetIndexI < MCB.size());
612  assert(Candidate.packetIndexJ < MCB.size());
613  assert(isBundle(MCB));
614  MCInst *Duplex =
615      deriveDuplex(Context, Candidate.iClass,
616                   *MCB.getOperand(Candidate.packetIndexJ).getInst(),
617                   *MCB.getOperand(Candidate.packetIndexI).getInst());
618  assert(Duplex != nullptr);
619  MCB.getOperand(Candidate.packetIndexI).setInst(Duplex);
620  MCB.erase(MCB.begin() + Candidate.packetIndexJ);
621}
622
623void HexagonMCInstrInfo::setInnerLoop(MCInst &MCI) {
624  assert(isBundle(MCI));
625  MCOperand &Operand = MCI.getOperand(0);
626  Operand.setImm(Operand.getImm() | innerLoopMask);
627}
628
629void HexagonMCInstrInfo::setMemReorderDisabled(MCInst &MCI) {
630  assert(isBundle(MCI));
631  MCOperand &Operand = MCI.getOperand(0);
632  Operand.setImm(Operand.getImm() | memReorderDisabledMask);
633  assert(isMemReorderDisabled(MCI));
634}
635
636void HexagonMCInstrInfo::setMemStoreReorderEnabled(MCInst &MCI) {
637  assert(isBundle(MCI));
638  MCOperand &Operand = MCI.getOperand(0);
639  Operand.setImm(Operand.getImm() | memStoreReorderEnabledMask);
640  assert(isMemStoreReorderEnabled(MCI));
641}
642
643void HexagonMCInstrInfo::setOuterLoop(MCInst &MCI) {
644  assert(isBundle(MCI));
645  MCOperand &Operand = MCI.getOperand(0);
646  Operand.setImm(Operand.getImm() | outerLoopMask);
647}
648}
649