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