X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FXCore%2FXCoreInstrInfo.cpp;h=e4129aee9479981ea9bbc7fa1f0279a13c0f3bf9;hb=de0129ac0821e693b08df7269f956f5418b2b5f7;hp=98b4e5cadfd0875dbeeedbe1fc93743748f36a75;hpb=dc54d317e7a381ef8e4aca80d54ad1466bb85dda;p=oota-llvm.git diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp index 98b4e5cadfd..e4129aee947 100644 --- a/lib/Target/XCore/XCoreInstrInfo.cpp +++ b/lib/Target/XCore/XCoreInstrInfo.cpp @@ -1,4 +1,4 @@ -//===- XCoreInstrInfo.cpp - XCore Instruction Information -------*- C++ -*-===// +//===-- XCoreInstrInfo.cpp - XCore Instruction Information ----------------===// // // The LLVM Compiler Infrastructure // @@ -11,16 +11,25 @@ // //===----------------------------------------------------------------------===// -#include "XCoreMachineFunctionInfo.h" #include "XCoreInstrInfo.h" #include "XCore.h" +#include "XCoreMachineFunctionInfo.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineLocation.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "XCoreGenInstrInfo.inc" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineMemOperand.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/MC/MCContext.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" + +using namespace llvm; + +#define GET_INSTRINFO_CTOR_DTOR +#include "XCoreGenInstrInfo.inc" namespace llvm { namespace XCore { @@ -34,44 +43,18 @@ namespace XCore { } } -using namespace llvm; +// Pin the vtable to this file. +void XCoreInstrInfo::anchor() {} -XCoreInstrInfo::XCoreInstrInfo(void) - : TargetInstrInfoImpl(XCoreInsts, array_lengthof(XCoreInsts)), - RI(*this) { +XCoreInstrInfo::XCoreInstrInfo() + : XCoreGenInstrInfo(XCore::ADJCALLSTACKDOWN, XCore::ADJCALLSTACKUP), + RI() { } static bool isZeroImm(const MachineOperand &op) { return op.isImm() && op.getImm() == 0; } -/// Return true if the instruction is a register to register move and -/// leave the source and dest operands in the passed parameters. -/// -bool XCoreInstrInfo::isMoveInstr(const MachineInstr &MI, - unsigned &SrcReg, unsigned &DstReg, - unsigned &SrcSR, unsigned &DstSR) const { - SrcSR = DstSR = 0; // No sub-registers. - - // We look for 4 kinds of patterns here: - // add dst, src, 0 - // sub dst, src, 0 - // or dst, src, src - // and dst, src, src - if ((MI.getOpcode() == XCore::ADD_2rus || MI.getOpcode() == XCore::SUB_2rus) - && isZeroImm(MI.getOperand(2))) { - DstReg = MI.getOperand(0).getReg(); - SrcReg = MI.getOperand(1).getReg(); - return true; - } else if ((MI.getOpcode() == XCore::OR_3r || MI.getOpcode() == XCore::AND_3r) - && MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { - DstReg = MI.getOperand(0).getReg(); - SrcReg = MI.getOperand(1).getReg(); - return true; - } - return false; -} - /// isLoadFromStackSlot - If the specified machine instruction is a direct /// load from a stack slot, return the virtual or physical register number of /// the destination along with the FrameIndex of the loaded stack slot. If @@ -115,30 +98,6 @@ XCoreInstrInfo::isStoreToStackSlot(const MachineInstr *MI, return 0; } -/// isInvariantLoad - Return true if the specified instruction (which is marked -/// mayLoad) is loading from a location whose value is invariant across the -/// function. For example, loading a value from the constant pool or from -/// from the argument area of a function if it does not change. This should -/// only return true of *all* loads the instruction does are invariant (if it -/// does multiple loads). -bool -XCoreInstrInfo::isInvariantLoad(const MachineInstr *MI) const { - // Loads from constants pools and loads from invariant argument slots are - // invariant - int Opcode = MI->getOpcode(); - if (Opcode == XCore::LDWCP_ru6 || Opcode == XCore::LDWCP_lru6) { - return MI->getOperand(1).isCPI(); - } - int FrameIndex; - if (isLoadFromStackSlot(MI, FrameIndex)) { - const MachineFrameInfo &MFI = - *MI->getParent()->getParent()->getFrameInfo(); - return MFI.isFixedObjectIndex(FrameIndex) && - MFI.isImmutableObjectIndex(FrameIndex); - } - return false; -} - //===----------------------------------------------------------------------===// // Branch Analysis //===----------------------------------------------------------------------===// @@ -168,6 +127,11 @@ static inline bool IsCondBranch(unsigned BrOpc) { return IsBRF(BrOpc) || IsBRT(BrOpc); } +static inline bool IsBR_JT(unsigned BrOpc) { + return BrOpc == XCore::BR_JT + || BrOpc == XCore::BR_JT32; +} + /// GetCondFromBranchOpc - Return the XCore CC that matches /// the correspondent Branch instruction opcode. static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) @@ -186,7 +150,7 @@ static XCore::CondCode GetCondFromBranchOpc(unsigned BrOpc) static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) { switch (CC) { - default: assert(0 && "Illegal condition code!"); + default: llvm_unreachable("Illegal condition code!"); case XCore::COND_TRUE : return XCore::BRFT_lru6; case XCore::COND_FALSE : return XCore::BRFF_lru6; } @@ -197,7 +161,7 @@ static inline unsigned GetCondBranchFromCond(XCore::CondCode CC) static inline XCore::CondCode GetOppositeBranchCondition(XCore::CondCode CC) { switch (CC) { - default: assert(0 && "Illegal condition code!"); + default: llvm_unreachable("Illegal condition code!"); case XCore::COND_TRUE : return XCore::COND_FALSE; case XCore::COND_FALSE : return XCore::COND_TRUE; } @@ -232,8 +196,11 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, SmallVectorImpl &Cond, bool AllowModify) const { // If the block has no terminators, it just falls into the block after it. - MachineBasicBlock::iterator I = MBB.end(); - if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); + if (I == MBB.end()) + return false; + + if (!isUnpredicatedTerminator(I)) return false; // Get the last instruction in the block. @@ -294,6 +261,14 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, return false; } + // Likewise if it ends with a branch table followed by an unconditional branch. + if (IsBR_JT(SecondLastInst->getOpcode()) && IsBRU(LastInst->getOpcode())) { + I = LastInst; + if (AllowModify) + I->eraseFromParent(); + return true; + } + // Otherwise, can't handle this. return true; } @@ -301,20 +276,21 @@ XCoreInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, unsigned XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, MachineBasicBlock *FBB, - const SmallVectorImpl &Cond)const{ + ArrayRef Cond, + DebugLoc DL)const{ // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && "Unexpected number of components!"); - if (FBB == 0) { // One way branch. + if (!FBB) { // One way branch. if (Cond.empty()) { // Unconditional branch - BuildMI(&MBB, get(XCore::BRFU_lu6)).addMBB(TBB); + BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(TBB); } else { // Conditional branch. unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); - BuildMI(&MBB, get(Opc)).addReg(Cond[1].getReg()) + BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) .addMBB(TBB); } return 1; @@ -323,17 +299,18 @@ XCoreInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, // Two-way Conditional branch. assert(Cond.size() == 2 && "Unexpected number of components!"); unsigned Opc = GetCondBranchFromCond((XCore::CondCode)Cond[0].getImm()); - BuildMI(&MBB, get(Opc)).addReg(Cond[1].getReg()) + BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()) .addMBB(TBB); - BuildMI(&MBB, get(XCore::BRFU_lu6)).addMBB(FBB); + BuildMI(&MBB, DL, get(XCore::BRFU_lu6)).addMBB(FBB); return 2; } unsigned XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator I = MBB.end(); - if (I == MBB.begin()) return 0; - --I; + MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); + if (I == MBB.end()) + return 0; + if (!IsBRU(I->getOpcode()) && !IsCondBranch(I->getOpcode())) return 0; @@ -352,153 +329,125 @@ XCoreInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { return 2; } -bool XCoreInstrInfo::copyRegToReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, unsigned SrcReg, - const TargetRegisterClass *DestRC, - const TargetRegisterClass *SrcRC) const { - if (DestRC == SrcRC) { - if (DestRC == XCore::GRRegsRegisterClass) { - BuildMI(MBB, I, get(XCore::ADD_2rus), DestReg).addReg(SrcReg).addImm(0); - return true; - } else { - return false; - } +void XCoreInstrInfo::copyPhysReg(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, DebugLoc DL, + unsigned DestReg, unsigned SrcReg, + bool KillSrc) const { + bool GRDest = XCore::GRRegsRegClass.contains(DestReg); + bool GRSrc = XCore::GRRegsRegClass.contains(SrcReg); + + if (GRDest && GRSrc) { + BuildMI(MBB, I, DL, get(XCore::ADD_2rus), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)) + .addImm(0); + return; } - if (SrcRC == XCore::RRegsRegisterClass && SrcReg == XCore::SP && - DestRC == XCore::GRRegsRegisterClass) { - BuildMI(MBB, I, get(XCore::LDAWSP_ru6), DestReg).addImm(0); - return true; + if (GRDest && SrcReg == XCore::SP) { + BuildMI(MBB, I, DL, get(XCore::LDAWSP_ru6), DestReg).addImm(0); + return; } - if (DestRC == XCore::RRegsRegisterClass && DestReg == XCore::SP && - SrcRC == XCore::GRRegsRegisterClass) { - BuildMI(MBB, I, get(XCore::SETSP_1r)).addReg(SrcReg); - return true; + + if (DestReg == XCore::SP && GRSrc) { + BuildMI(MBB, I, DL, get(XCore::SETSP_1r)) + .addReg(SrcReg, getKillRegState(KillSrc)); + return; } - return false; + llvm_unreachable("Impossible reg-to-reg copy"); } void XCoreInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned SrcReg, bool isKill, int FrameIndex, - const TargetRegisterClass *RC) const -{ - BuildMI(MBB, I, get(XCore::STWFI)).addReg(SrcReg, false, false, isKill) - .addFrameIndex(FrameIndex).addImm(0); -} - -void XCoreInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, - bool isKill, SmallVectorImpl &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs) const + MachineBasicBlock::iterator I, + unsigned SrcReg, bool isKill, + int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { - assert(0 && "unimplemented\n"); + DebugLoc DL; + if (I != MBB.end() && !I->isDebugValue()) + DL = I->getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FrameIndex), + MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + BuildMI(MBB, I, DL, get(XCore::STWFI)) + .addReg(SrcReg, getKillRegState(isKill)) + .addFrameIndex(FrameIndex) + .addImm(0) + .addMemOperand(MMO); } void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, - unsigned DestReg, int FrameIndex, - const TargetRegisterClass *RC) const + MachineBasicBlock::iterator I, + unsigned DestReg, int FrameIndex, + const TargetRegisterClass *RC, + const TargetRegisterInfo *TRI) const { - BuildMI(MBB, I, get(XCore::LDWFI), DestReg).addFrameIndex(FrameIndex) - .addImm(0); + DebugLoc DL; + if (I != MBB.end() && !I->isDebugValue()) + DL = I->getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = MF->getMachineMemOperand( + MachinePointerInfo::getFixedStack(*MF, FrameIndex), + MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), + MFI.getObjectAlignment(FrameIndex)); + BuildMI(MBB, I, DL, get(XCore::LDWFI), DestReg) + .addFrameIndex(FrameIndex) + .addImm(0) + .addMemOperand(MMO); } -void XCoreInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, - SmallVectorImpl &Addr, - const TargetRegisterClass *RC, - SmallVectorImpl &NewMIs) const -{ - assert(0 && "unimplemented\n"); +/// ReverseBranchCondition - Return the inverse opcode of the +/// specified Branch instruction. +bool XCoreInstrInfo:: +ReverseBranchCondition(SmallVectorImpl &Cond) const { + assert((Cond.size() == 2) && + "Invalid XCore branch condition!"); + Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); + return false; } -bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const -{ - if (CSI.empty()) { - return true; - } - MachineFunction *MF = MBB.getParent(); - const MachineFrameInfo *MFI = MF->getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - XCoreFunctionInfo *XFI = MF->getInfo(); - - bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); - - for (std::vector::const_iterator it = CSI.begin(); - it != CSI.end(); ++it) { - // Add the callee-saved register as live-in. It's killed at the spill. - MBB.addLiveIn(it->getReg()); - - storeRegToStackSlot(MBB, MI, it->getReg(), true, - it->getFrameIdx(), it->getRegClass()); - if (emitFrameMoves) { - unsigned SaveLabelId = MMI->NextLabelID(); - BuildMI(MBB, MI, get(XCore::DBG_LABEL)).addImm(SaveLabelId); - XFI->getSpillLabels().push_back( - std::pair(SaveLabelId, *it)); - } - } - return true; +static inline bool isImmU6(unsigned val) { + return val < (1 << 6); } -bool XCoreInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI) const -{ - bool AtStart = MI == MBB.begin(); - MachineBasicBlock::iterator BeforeI = MI; - if (!AtStart) - --BeforeI; - for (std::vector::const_iterator it = CSI.begin(); - it != CSI.end(); ++it) { - - loadRegFromStackSlot(MBB, MI, it->getReg(), - it->getFrameIdx(), - it->getRegClass()); - assert(MI != MBB.begin() && - "loadRegFromStackSlot didn't insert any code!"); - // Insert in reverse order. loadRegFromStackSlot can insert multiple - // instructions. - if (AtStart) - MI = MBB.begin(); - else { - MI = BeforeI; - ++MI; - } - } - return true; +static inline bool isImmU16(unsigned val) { + return val < (1 << 16); } -/// BlockHasNoFallThrough - Analyse if MachineBasicBlock does not -/// fall-through into its successor block. -bool XCoreInstrInfo:: -BlockHasNoFallThrough(const MachineBasicBlock &MBB) const -{ - if (MBB.empty()) return false; - - switch (MBB.back().getOpcode()) { - case XCore::RETSP_u6: // Return. - case XCore::RETSP_lu6: - case XCore::BAU_1r: // Indirect branch. - case XCore::BRFU_u6: // Uncond branch. - case XCore::BRFU_lu6: - case XCore::BRBU_u6: - case XCore::BRBU_lu6: - return true; - default: return false; +static bool isImmMskBitp(unsigned val) { + if (!isMask_32(val)) { + return false; } + int N = Log2_32(val) + 1; + return (N >= 1 && N <= 8) || N == 16 || N == 24 || N == 32; } -/// ReverseBranchCondition - Return the inverse opcode of the -/// specified Branch instruction. -bool XCoreInstrInfo:: -ReverseBranchCondition(SmallVectorImpl &Cond) const -{ - assert((Cond.size() == 2) && - "Invalid XCore branch condition!"); - Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); - return false; +MachineBasicBlock::iterator XCoreInstrInfo::loadImmediate( + MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + unsigned Reg, uint64_t Value) const { + DebugLoc dl; + if (MI != MBB.end() && !MI->isDebugValue()) + dl = MI->getDebugLoc(); + if (isImmMskBitp(Value)) { + int N = Log2_32(Value) + 1; + return BuildMI(MBB, MI, dl, get(XCore::MKMSK_rus), Reg) + .addImm(N) + .getInstr(); + } + if (isImmU16(Value)) { + int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; + return BuildMI(MBB, MI, dl, get(Opcode), Reg).addImm(Value).getInstr(); + } + MachineConstantPool *ConstantPool = MBB.getParent()->getConstantPool(); + const Constant *C = ConstantInt::get( + Type::getInt32Ty(MBB.getParent()->getFunction()->getContext()), Value); + unsigned Idx = ConstantPool->getConstantPoolIndex(C, 4); + return BuildMI(MBB, MI, dl, get(XCore::LDWCP_lru6), Reg) + .addConstantPoolIndex(Idx) + .getInstr(); }