1249259Sdim//===- HexagonMCInst.cpp - Hexagon sub-class of MCInst --------------------===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim// This class extends MCInst to allow some Hexagon VLIW annotations.
11249259Sdim//
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdim#include "HexagonInstrInfo.h"
15249259Sdim#include "MCTargetDesc/HexagonBaseInfo.h"
16249259Sdim#include "MCTargetDesc/HexagonMCInst.h"
17249259Sdim#include "MCTargetDesc/HexagonMCTargetDesc.h"
18249259Sdim
19249259Sdimusing namespace llvm;
20249259Sdim
21249259Sdim// Return the slots used by the insn.
22249259Sdimunsigned HexagonMCInst::getUnits(const HexagonTargetMachine* TM) const {
23249259Sdim  const HexagonInstrInfo* QII = TM->getInstrInfo();
24249259Sdim  const InstrItineraryData* II = TM->getInstrItineraryData();
25249259Sdim  const InstrStage*
26249259Sdim    IS = II->beginStage(QII->get(this->getOpcode()).getSchedClass());
27249259Sdim
28249259Sdim  return (IS->getUnits());
29249259Sdim}
30249259Sdim
31249259Sdim// Return the Hexagon ISA class for the insn.
32249259Sdimunsigned HexagonMCInst::getType() const {
33249259Sdim  const uint64_t F = MCID->TSFlags;
34249259Sdim
35249259Sdim  return ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
36249259Sdim}
37249259Sdim
38249259Sdim// Return whether the insn is an actual insn.
39249259Sdimbool HexagonMCInst::isCanon() const {
40249259Sdim  return (!MCID->isPseudo() &&
41249259Sdim          !isPrefix() &&
42249259Sdim          getType() != HexagonII::TypeENDLOOP);
43249259Sdim}
44249259Sdim
45249259Sdim// Return whether the insn is a prefix.
46249259Sdimbool HexagonMCInst::isPrefix() const {
47249259Sdim  return (getType() == HexagonII::TypePREFIX);
48249259Sdim}
49249259Sdim
50249259Sdim// Return whether the insn is solo, i.e., cannot be in a packet.
51249259Sdimbool HexagonMCInst::isSolo() const {
52249259Sdim  const uint64_t F = MCID->TSFlags;
53249259Sdim  return ((F >> HexagonII::SoloPos) & HexagonII::SoloMask);
54249259Sdim}
55249259Sdim
56249259Sdim// Return whether the insn is a new-value consumer.
57249259Sdimbool HexagonMCInst::isNewValue() const {
58249259Sdim  const uint64_t F = MCID->TSFlags;
59249259Sdim  return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
60249259Sdim}
61249259Sdim
62249259Sdim// Return whether the instruction is a legal new-value producer.
63249259Sdimbool HexagonMCInst::hasNewValue() const {
64249259Sdim  const uint64_t F = MCID->TSFlags;
65249259Sdim  return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
66249259Sdim}
67249259Sdim
68249259Sdim// Return the operand that consumes or produces a new value.
69249259Sdimconst MCOperand& HexagonMCInst::getNewValue() const {
70249259Sdim  const uint64_t F = MCID->TSFlags;
71249259Sdim  const unsigned O = (F >> HexagonII::NewValueOpPos) &
72249259Sdim                     HexagonII::NewValueOpMask;
73249259Sdim  const MCOperand& MCO = getOperand(O);
74249259Sdim
75249259Sdim  assert ((isNewValue() || hasNewValue()) && MCO.isReg());
76249259Sdim  return (MCO);
77249259Sdim}
78249259Sdim
79249259Sdim// Return whether the instruction needs to be constant extended.
80249259Sdim// 1) Always return true if the instruction has 'isExtended' flag set.
81249259Sdim//
82249259Sdim// isExtendable:
83249259Sdim// 2) For immediate extended operands, return true only if the value is
84249259Sdim//    out-of-range.
85249259Sdim// 3) For global address, always return true.
86249259Sdim
87249259Sdimbool HexagonMCInst::isConstExtended(void) const {
88249259Sdim  if (isExtended())
89249259Sdim    return true;
90249259Sdim
91249259Sdim  if (!isExtendable())
92249259Sdim    return false;
93249259Sdim
94249259Sdim  short ExtOpNum = getCExtOpNum();
95249259Sdim  int MinValue   = getMinValue();
96249259Sdim  int MaxValue   = getMaxValue();
97249259Sdim  const MCOperand& MO = getOperand(ExtOpNum);
98249259Sdim
99249259Sdim  // We could be using an instruction with an extendable immediate and shoehorn
100249259Sdim  // a global address into it. If it is a global address it will be constant
101249259Sdim  // extended. We do this for COMBINE.
102249259Sdim  // We currently only handle isGlobal() because it is the only kind of
103249259Sdim  // object we are going to end up with here for now.
104249259Sdim  // In the future we probably should add isSymbol(), etc.
105249259Sdim  if (MO.isExpr())
106249259Sdim    return true;
107249259Sdim
108249259Sdim  // If the extendable operand is not 'Immediate' type, the instruction should
109249259Sdim  // have 'isExtended' flag set.
110249259Sdim  assert(MO.isImm() && "Extendable operand must be Immediate type");
111249259Sdim
112249259Sdim  int ImmValue = MO.getImm();
113249259Sdim  return (ImmValue < MinValue || ImmValue > MaxValue);
114249259Sdim}
115249259Sdim
116249259Sdim// Return whether the instruction must be always extended.
117249259Sdimbool HexagonMCInst::isExtended(void) const {
118249259Sdim  const uint64_t F = MCID->TSFlags;
119249259Sdim  return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
120249259Sdim}
121249259Sdim
122249259Sdim// Return true if the instruction may be extended based on the operand value.
123249259Sdimbool HexagonMCInst::isExtendable(void) const {
124249259Sdim  const uint64_t F = MCID->TSFlags;
125249259Sdim  return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
126249259Sdim}
127249259Sdim
128249259Sdim// Return number of bits in the constant extended operand.
129249259Sdimunsigned HexagonMCInst::getBitCount(void) const {
130249259Sdim  const uint64_t F = MCID->TSFlags;
131249259Sdim  return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
132249259Sdim}
133249259Sdim
134249259Sdim// Return constant extended operand number.
135249259Sdimunsigned short HexagonMCInst::getCExtOpNum(void) const {
136249259Sdim  const uint64_t F = MCID->TSFlags;
137249259Sdim  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
138249259Sdim}
139249259Sdim
140249259Sdim// Return whether the operand can be constant extended.
141249259Sdimbool HexagonMCInst::isOperandExtended(const unsigned short OperandNum) const {
142249259Sdim  const uint64_t F = MCID->TSFlags;
143249259Sdim  return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
144249259Sdim          == OperandNum;
145249259Sdim}
146249259Sdim
147249259Sdim// Return the min value that a constant extendable operand can have
148249259Sdim// without being extended.
149249259Sdimint HexagonMCInst::getMinValue(void) const {
150249259Sdim  const uint64_t F = MCID->TSFlags;
151249259Sdim  unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
152249259Sdim                    & HexagonII::ExtentSignedMask;
153249259Sdim  unsigned bits =  (F >> HexagonII::ExtentBitsPos)
154249259Sdim                    & HexagonII::ExtentBitsMask;
155249259Sdim
156249259Sdim  if (isSigned) // if value is signed
157249259Sdim    return -1 << (bits - 1);
158249259Sdim  else
159249259Sdim    return 0;
160249259Sdim}
161249259Sdim
162249259Sdim// Return the max value that a constant extendable operand can have
163249259Sdim// without being extended.
164249259Sdimint HexagonMCInst::getMaxValue(void) const {
165249259Sdim  const uint64_t F = MCID->TSFlags;
166249259Sdim  unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
167249259Sdim                    & HexagonII::ExtentSignedMask;
168249259Sdim  unsigned bits =  (F >> HexagonII::ExtentBitsPos)
169249259Sdim                    & HexagonII::ExtentBitsMask;
170249259Sdim
171249259Sdim  if (isSigned) // if value is signed
172249259Sdim    return ~(-1 << (bits - 1));
173249259Sdim  else
174249259Sdim    return ~(-1 << bits);
175249259Sdim}
176