X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetInstrInfo.cpp;h=d52ecb32cf752e98faa30aa34aa4aa286fb503ac;hb=91b60c14872883e8dbad73c55ec141ae9f7d4537;hp=ca26718708e1fa08ddb4e418b767de637ba13d17;hpb=93fa70598c88fe14ebe4b3752daab4ea265233e1;p=oota-llvm.git diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index ca26718708e..d52ecb32cf7 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -1,56 +1,174 @@ -//===-- TargetMachine.cpp - General Target Information ---------------------==// +//===-- TargetInstrInfo.cpp - Target Instruction Information --------------===// // -// This file describes the general parts of a Target machine. -// This file also implements MachineInstrInfo and MachineCacheInfo. +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the TargetInstrInfo class. // //===----------------------------------------------------------------------===// -#include "llvm/Target/MachineInstrInfo.h" -#include "llvm/Constant.h" -#include "llvm/DerivedTypes.h" - -//--------------------------------------------------------------------------- -// class MachineInstructionInfo -// Interface to description of machine instructions -//--------------------------------------------------------------------------- - - -MachineInstrInfo::MachineInstrInfo(const TargetMachine& tgt, - const MachineInstrDescriptor* Desc, - unsigned DescSize, - unsigned NumRealOpCodes) - : target(tgt), desc(Desc), descSize(DescSize), numRealOpCodes(NumRealOpCodes) { - // FIXME: TargetInstrDescriptors should not be global - assert(TargetInstrDescriptors == NULL && desc != NULL); - TargetInstrDescriptors = desc; // initialize global variable -} - -MachineInstrInfo::~MachineInstrInfo() { - TargetInstrDescriptors = NULL; // reset global variable -} - - -bool MachineInstrInfo::constantFitsInImmedField(MachineOpCode opCode, - int64_t intValue) const { - // First, check if opCode has an immed field. - bool isSignExtended; - uint64_t maxImmedValue = maxImmedConstant(opCode, isSignExtended); - if (maxImmedValue != 0) - { - // NEED TO HANDLE UNSIGNED VALUES SINCE THEY MAY BECOME MUCH - // SMALLER AFTER CASTING TO SIGN-EXTENDED int, short, or char. - // See CreateUIntSetInstruction in SparcInstrInfo.cpp. - - // Now check if the constant fits - if (intValue <= (int64_t) maxImmedValue && - intValue >= -((int64_t) maxImmedValue+1)) - return true; - } - - return false; +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCInstrItineraries.h" +#include "llvm/Support/ErrorHandling.h" +#include +using namespace llvm; + +//===----------------------------------------------------------------------===// +// TargetInstrInfo +//===----------------------------------------------------------------------===// + +TargetInstrInfo::~TargetInstrInfo() { +} + +const TargetRegisterClass* +TargetInstrInfo::getRegClass(const MCInstrDesc &MCID, unsigned OpNum, + const TargetRegisterInfo *TRI) const { + if (OpNum >= MCID.getNumOperands()) + return 0; + + short RegClass = MCID.OpInfo[OpNum].RegClass; + if (MCID.OpInfo[OpNum].isLookupPtrRegClass()) + return TRI->getPointerRegClass(RegClass); + + // Instructions like INSERT_SUBREG do not have fixed register classes. + if (RegClass < 0) + return 0; + + // Otherwise just look it up normally. + return TRI->getRegClass(RegClass); +} + +unsigned +TargetInstrInfo::getNumMicroOps(const InstrItineraryData *ItinData, + const MachineInstr *MI) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + unsigned Class = MI->getDesc().getSchedClass(); + unsigned UOps = ItinData->Itineraries[Class].NumMicroOps; + if (UOps) + return UOps; + + // The # of u-ops is dynamically determined. The specific target should + // override this function to return the right number. + return 1; +} + +int +TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, unsigned DefIdx, + const MachineInstr *UseMI, unsigned UseIdx) const { + if (!ItinData || ItinData->isEmpty()) + return -1; + + unsigned DefClass = DefMI->getDesc().getSchedClass(); + unsigned UseClass = UseMI->getDesc().getSchedClass(); + return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); +} + +int +TargetInstrInfo::getOperandLatency(const InstrItineraryData *ItinData, + SDNode *DefNode, unsigned DefIdx, + SDNode *UseNode, unsigned UseIdx) const { + if (!ItinData || ItinData->isEmpty()) + return -1; + + if (!DefNode->isMachineOpcode()) + return -1; + + unsigned DefClass = get(DefNode->getMachineOpcode()).getSchedClass(); + if (!UseNode->isMachineOpcode()) + return ItinData->getOperandCycle(DefClass, DefIdx); + unsigned UseClass = get(UseNode->getMachineOpcode()).getSchedClass(); + return ItinData->getOperandLatency(DefClass, DefIdx, UseClass, UseIdx); +} + +int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, + const MachineInstr *MI, + unsigned *PredCost) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + return ItinData->getStageLatency(MI->getDesc().getSchedClass()); +} + +int TargetInstrInfo::getInstrLatency(const InstrItineraryData *ItinData, + SDNode *N) const { + if (!ItinData || ItinData->isEmpty()) + return 1; + + if (!N->isMachineOpcode()) + return 1; + + return ItinData->getStageLatency(get(N->getMachineOpcode()).getSchedClass()); +} + +bool TargetInstrInfo::hasLowDefLatency(const InstrItineraryData *ItinData, + const MachineInstr *DefMI, + unsigned DefIdx) const { + if (!ItinData || ItinData->isEmpty()) + return false; + + unsigned DefClass = DefMI->getDesc().getSchedClass(); + int DefCycle = ItinData->getOperandCycle(DefClass, DefIdx); + return (DefCycle != -1 && DefCycle <= 1); } -bool MachineInstrInfo::ConstantTypeMustBeLoaded(const Constant* CV) const { - assert(CV->getType()->isPrimitiveType() || isa(CV->getType())); - return !(CV->getType()->isIntegral() || isa(CV->getType())); +/// insertNoop - Insert a noop into the instruction stream at the specified +/// point. +void TargetInstrInfo::insertNoop(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI) const { + llvm_unreachable("Target didn't implement insertNoop!"); +} + + +bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { + const MCInstrDesc &MCID = MI->getDesc(); + if (!MCID.isTerminator()) return false; + + // Conditional branch is a special case. + if (MCID.isBranch() && !MCID.isBarrier()) + return true; + if (!MCID.isPredicable()) + return true; + return !isPredicated(MI); +} + + +/// Measure the specified inline asm to determine an approximation of its +/// length. +/// Comments (which run till the next SeparatorString or newline) do not +/// count as an instruction. +/// Any other non-whitespace text is considered an instruction, with +/// multiple instructions separated by SeparatorString or newlines. +/// Variable-length instructions are not handled here; this function +/// may be overloaded in the target code to do that. +unsigned TargetInstrInfo::getInlineAsmLength(const char *Str, + const MCAsmInfo &MAI) const { + + + // Count the number of instructions in the asm. + bool atInsnStart = true; + unsigned Length = 0; + for (; *Str; ++Str) { + if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(), + strlen(MAI.getSeparatorString())) == 0) + atInsnStart = true; + if (atInsnStart && !std::isspace(*Str)) { + Length += MAI.getMaxInstLength(); + atInsnStart = false; + } + if (atInsnStart && strncmp(Str, MAI.getCommentString(), + strlen(MAI.getCommentString())) == 0) + atInsnStart = false; + } + + return Length; }