X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FTargetInstrInfo.cpp;h=c099a7eaefe7ec6b67187f6259d24a8e577c9a37;hb=cf246b7f0b9e23fab53572dbd814b361ace49d08;hp=81759098ed85f6cb6da040ba78f86e1249e97d04;hpb=981b5bd7080db6dbbac6931863d8a2e6d1fc5a0c;p=oota-llvm.git diff --git a/lib/Target/TargetInstrInfo.cpp b/lib/Target/TargetInstrInfo.cpp index 81759098ed8..c099a7eaefe 100644 --- a/lib/Target/TargetInstrInfo.cpp +++ b/lib/Target/TargetInstrInfo.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,53 +12,88 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Constant.h" -#include "llvm/DerivedTypes.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; -namespace llvm { - // External object describing the machine instructions Initialized only when - // the TargetMachine class is created and reset when that class is destroyed. - // - // FIXME: UGLY SPARCV9 HACK! - const TargetInstrDescriptor* TargetInstrDescriptors = 0; +//===----------------------------------------------------------------------===// +// TargetOperandInfo +//===----------------------------------------------------------------------===// + +/// getRegClass - Get the register class for the operand, handling resolution +/// of "symbolic" pointer register classes etc. If this is not a register +/// operand, this returns null. +const TargetRegisterClass * +TargetOperandInfo::getRegClass(const TargetRegisterInfo *TRI) const { + if (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); } -TargetInstrInfo::TargetInstrInfo(const TargetInstrDescriptor* Desc, +//===----------------------------------------------------------------------===// +// TargetInstrInfo +//===----------------------------------------------------------------------===// + +TargetInstrInfo::TargetInstrInfo(const TargetInstrDesc* Desc, unsigned numOpcodes) - : desc(Desc), NumOpcodes(numOpcodes) { - // FIXME: TargetInstrDescriptors should not be global - assert(TargetInstrDescriptors == NULL && desc != NULL - && "TargetMachine data structure corrupt; maybe you tried to create another TargetMachine? (only one may exist in a program)"); - TargetInstrDescriptors = desc; // initialize global variable + : Descriptors(Desc), NumOpcodes(numOpcodes) { } TargetInstrInfo::~TargetInstrInfo() { - TargetInstrDescriptors = NULL; // reset global variable } -int -TargetInstrInfo::getTiedToSrcOperand(MachineOpCode Opc, unsigned OpNum) const { - for (unsigned i = 0, e = getNumOperands(Opc); i != e; ++i) { - if (i == OpNum) - continue; - int ti = getOperandConstraint(Opc, i, TIED_TO); - if (ti == (int)OpNum) - return i; - } - return -1; +/// 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!"); } -// commuteInstruction - The default implementation of this method just exchanges -// operand 1 and 2. -MachineInstr *TargetInstrInfo::commuteInstruction(MachineInstr *MI) const { - assert(MI->getOperand(1).isRegister() && MI->getOperand(2).isRegister() && - "This only knows how to commute register operands so far"); - unsigned Reg1 = MI->getOperand(1).getReg(); - unsigned Reg2 = MI->getOperand(2).getReg(); - MI->getOperand(2).setReg(Reg1); - MI->getOperand(1).setReg(Reg2); - return MI; +bool TargetInstrInfo::isUnpredicatedTerminator(const MachineInstr *MI) const { + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.isTerminator()) return false; + + // Conditional branch is a special case. + if (TID.isBranch() && !TID.isBarrier()) + return true; + if (!TID.isPredicable()) + return true; + return !isPredicated(MI); +} + + +/// Measure the specified inline asm to determine an approximation of its +/// length. +/// Comments (which run till the next SeparatorChar or newline) do not +/// count as an instruction. +/// Any other non-whitespace text is considered an instruction, with +/// multiple instructions separated by SeparatorChar 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' || *Str == MAI.getSeparatorChar()) + atInsnStart = true; + if (atInsnStart && !isspace(*Str)) { + Length += MAI.getMaxInstLength(); + atInsnStart = false; + } + if (atInsnStart && strncmp(Str, MAI.getCommentString(), + strlen(MAI.getCommentString())) == 0) + atInsnStart = false; + } + + return Length; }