0f7a337ba613bc863f36d283e60ce5f2cd991460
[oota-llvm.git] / lib / Target / Hexagon / MCTargetDesc / HexagonMCInst.cpp
1 //===- HexagonMCInst.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 MCInst to allow some Hexagon VLIW annotations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "HexagonInstrInfo.h"
15 #include "HexagonTargetMachine.h"
16 #include "MCTargetDesc/HexagonBaseInfo.h"
17 #include "MCTargetDesc/HexagonMCInst.h"
18 #include "MCTargetDesc/HexagonMCTargetDesc.h"
19 #include "llvm/Support/TargetRegistry.h"
20
21 using namespace llvm;
22
23 HexagonMCInst::HexagonMCInst(unsigned op)
24     : packetBegin(false), packetEnd(false),
25       MCID(llvm::TheHexagonTarget.createMCInstrInfo()->get(op)) {
26   assert(MCID.getSize() == 4 && "All instructions should be 32bit");
27   setOpcode(op);
28 }
29
30 bool HexagonMCInst::isPacketBegin() const { return packetBegin; }
31 bool HexagonMCInst::isPacketEnd() const { return packetEnd; }
32 void HexagonMCInst::setPacketEnd(bool Y) { packetEnd = Y; }
33 void HexagonMCInst::setPacketBegin(bool Y) { packetBegin = Y; }
34
35 unsigned HexagonMCInst::getUnits(HexagonTargetMachine const &TM) const {
36   const HexagonInstrInfo *QII = TM.getSubtargetImpl()->getInstrInfo();
37   const InstrItineraryData *II = TM.getSubtargetImpl()->getInstrItineraryData();
38   const InstrStage *IS =
39       II->beginStage(QII->get(this->getOpcode()).getSchedClass());
40
41   return (IS->getUnits());
42 }
43
44 bool HexagonMCInst::isNewValue() const {
45   const uint64_t F = MCID.TSFlags;
46   return ((F >> HexagonII::NewValuePos) & HexagonII::NewValueMask);
47 }
48
49 bool HexagonMCInst::hasNewValue() const {
50   const uint64_t F = MCID.TSFlags;
51   return ((F >> HexagonII::hasNewValuePos) & HexagonII::hasNewValueMask);
52 }
53
54 MCOperand const &HexagonMCInst::getNewValue() const {
55   const uint64_t F = MCID.TSFlags;
56   const unsigned O =
57       (F >> HexagonII::NewValueOpPos) & HexagonII::NewValueOpMask;
58   const MCOperand &MCO = getOperand(O);
59
60   assert((isNewValue() || hasNewValue()) && MCO.isReg());
61   return (MCO);
62 }
63
64 // Return whether the instruction needs to be constant extended.
65 // 1) Always return true if the instruction has 'isExtended' flag set.
66 //
67 // isExtendable:
68 // 2) For immediate extended operands, return true only if the value is
69 //    out-of-range.
70 // 3) For global address, always return true.
71 bool HexagonMCInst::isConstExtended(void) const {
72   if (isExtended())
73     return true;
74
75   if (!isExtendable())
76     return false;
77
78   short ExtOpNum = getCExtOpNum();
79   int MinValue = getMinValue();
80   int MaxValue = getMaxValue();
81   const MCOperand &MO = getOperand(ExtOpNum);
82
83   // We could be using an instruction with an extendable immediate and shoehorn
84   // a global address into it. If it is a global address it will be constant
85   // extended. We do this for COMBINE.
86   // We currently only handle isGlobal() because it is the only kind of
87   // object we are going to end up with here for now.
88   // In the future we probably should add isSymbol(), etc.
89   if (MO.isExpr())
90     return true;
91
92   // If the extendable operand is not 'Immediate' type, the instruction should
93   // have 'isExtended' flag set.
94   assert(MO.isImm() && "Extendable operand must be Immediate type");
95
96   int ImmValue = MO.getImm();
97   return (ImmValue < MinValue || ImmValue > MaxValue);
98 }
99
100 bool HexagonMCInst::isExtended(void) const {
101   const uint64_t F = MCID.TSFlags;
102   return (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
103 }
104
105 bool HexagonMCInst::isExtendable(void) const {
106   const uint64_t F = MCID.TSFlags;
107   return (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
108 }
109
110 unsigned HexagonMCInst::getBitCount(void) const {
111   const uint64_t F = MCID.TSFlags;
112   return ((F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask);
113 }
114
115 unsigned short HexagonMCInst::getCExtOpNum(void) const {
116   const uint64_t F = MCID.TSFlags;
117   return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask);
118 }
119
120 bool HexagonMCInst::isOperandExtended(const unsigned short OperandNum) const {
121   const uint64_t F = MCID.TSFlags;
122   return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask) ==
123          OperandNum;
124 }
125
126 int HexagonMCInst::getMinValue(void) const {
127   const uint64_t F = MCID.TSFlags;
128   unsigned isSigned =
129       (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
130   unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
131
132   if (isSigned)
133     return -1U << (bits - 1);
134   else
135     return 0;
136 }
137
138 int HexagonMCInst::getMaxValue(void) const {
139   const uint64_t F = MCID.TSFlags;
140   unsigned isSigned =
141       (F >> HexagonII::ExtentSignedPos) & HexagonII::ExtentSignedMask;
142   unsigned bits = (F >> HexagonII::ExtentBitsPos) & HexagonII::ExtentBitsMask;
143
144   if (isSigned)
145     return ~(-1U << (bits - 1));
146   else
147     return ~(-1U << bits);
148 }