diff options
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp | 177 |
1 files changed, 131 insertions, 46 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp index 39d7329f2663..c10b5b300512 100644 --- a/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/contrib/llvm/lib/Target/Sparc/SparcInstrInfo.cpp @@ -17,19 +17,25 @@ #include "SparcSubtarget.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" -#define GET_INSTRINFO_CTOR +#define GET_INSTRINFO_CTOR_DTOR #include "SparcGenInstrInfo.inc" using namespace llvm; + +// Pin the vtable to this file. +void SparcInstrInfo::anchor() {} + SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) : SparcGenInstrInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP), - RI(ST, *this), Subtarget(ST) { + RI(ST), Subtarget(ST) { } /// isLoadFromStackSlot - If the specified machine instruction is a direct @@ -40,8 +46,10 @@ SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == SP::LDri || + MI->getOpcode() == SP::LDXri || MI->getOpcode() == SP::LDFri || - MI->getOpcode() == SP::LDDFri) { + MI->getOpcode() == SP::LDDFri || + MI->getOpcode() == SP::LDQFri) { if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) { FrameIndex = MI->getOperand(1).getIndex(); @@ -59,8 +67,10 @@ unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { if (MI->getOpcode() == SP::STri || + MI->getOpcode() == SP::STXri || MI->getOpcode() == SP::STFri || - MI->getOpcode() == SP::STDFri) { + MI->getOpcode() == SP::STDFri || + MI->getOpcode() == SP::STQFri) { if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) { FrameIndex = MI->getOperand(0).getIndex(); @@ -96,14 +106,14 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) case SPCC::FCC_U: return SPCC::FCC_O; case SPCC::FCC_O: return SPCC::FCC_U; - case SPCC::FCC_G: return SPCC::FCC_LE; - case SPCC::FCC_LE: return SPCC::FCC_G; - case SPCC::FCC_UG: return SPCC::FCC_ULE; - case SPCC::FCC_ULE: return SPCC::FCC_UG; - case SPCC::FCC_L: return SPCC::FCC_GE; - case SPCC::FCC_GE: return SPCC::FCC_L; - case SPCC::FCC_UL: return SPCC::FCC_UGE; - case SPCC::FCC_UGE: return SPCC::FCC_UL; + case SPCC::FCC_G: return SPCC::FCC_ULE; + case SPCC::FCC_LE: return SPCC::FCC_UG; + case SPCC::FCC_UG: return SPCC::FCC_LE; + case SPCC::FCC_ULE: return SPCC::FCC_G; + case SPCC::FCC_L: return SPCC::FCC_UGE; + case SPCC::FCC_GE: return SPCC::FCC_UL; + case SPCC::FCC_UL: return SPCC::FCC_GE; + case SPCC::FCC_UGE: return SPCC::FCC_L; case SPCC::FCC_LG: return SPCC::FCC_UE; case SPCC::FCC_UE: return SPCC::FCC_LG; case SPCC::FCC_NE: return SPCC::FCC_E; @@ -112,18 +122,6 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) llvm_unreachable("Invalid cond code"); } -MachineInstr * -SparcInstrInfo::emitFrameIndexDebugValue(MachineFunction &MF, - int FrameIx, - uint64_t Offset, - const MDNode *MDPtr, - DebugLoc dl) const { - MachineInstrBuilder MIB = BuildMI(MF, dl, get(SP::DBG_VALUE)) - .addFrameIndex(FrameIx).addImm(0).addImm(Offset).addMetadata(MDPtr); - return &*MIB; -} - - bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, @@ -139,15 +137,15 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, if (I->isDebugValue()) continue; - //When we see a non-terminator, we are done + // When we see a non-terminator, we are done. if (!isUnpredicatedTerminator(I)) break; - //Terminator is not a branch + // Terminator is not a branch. if (!I->isBranch()) return true; - //Handle Unconditional branches + // Handle Unconditional branches. if (I->getOpcode() == SP::BA) { UnCondBrIter = I; @@ -176,7 +174,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, unsigned Opcode = I->getOpcode(); if (Opcode != SP::BCOND && Opcode != SP::FBCOND) - return true; //Unknown Opcode + return true; // Unknown Opcode. SPCC::CondCodes BranchCode = (SPCC::CondCodes)I->getOperand(1).getImm(); @@ -185,7 +183,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, if (AllowModify && UnCondBrIter != MBB.end() && MBB.isLayoutSuccessor(TargetBB)) { - //Transform the code + // Transform the code // // brCC L1 // ba L2 @@ -219,8 +217,8 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, Cond.push_back(MachineOperand::CreateImm(BranchCode)); continue; } - //FIXME: Handle subsequent conditional branches - //For now, we can't handle multiple conditional branches + // FIXME: Handle subsequent conditional branches. + // For now, we can't handle multiple conditional branches. return true; } return false; @@ -241,7 +239,7 @@ SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, return 1; } - //Conditional branch + // Conditional branch unsigned CC = Cond[0].getImm(); if (IsIntegerCC(CC)) @@ -281,17 +279,69 @@ void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const { + unsigned numSubRegs = 0; + unsigned movOpc = 0; + const unsigned *subRegIdx = 0; + + const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd }; + const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 }; + const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd, + SP::sub_odd64_then_sub_even, + SP::sub_odd64_then_sub_odd }; + if (SP::IntRegsRegClass.contains(DestReg, SrcReg)) BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0) .addReg(SrcReg, getKillRegState(KillSrc)); else if (SP::FPRegsRegClass.contains(DestReg, SrcReg)) BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); - else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) - BuildMI(MBB, I, DL, get(Subtarget.isV9() ? SP::FMOVD : SP::FpMOVD), DestReg) - .addReg(SrcReg, getKillRegState(KillSrc)); - else + else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) { + if (Subtarget.isV9()) { + BuildMI(MBB, I, DL, get(SP::FMOVD), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)); + } else { + // Use two FMOVS instructions. + subRegIdx = DFP_FP_SubRegsIdx; + numSubRegs = 2; + movOpc = SP::FMOVS; + } + } else if (SP::QFPRegsRegClass.contains(DestReg, SrcReg)) { + if (Subtarget.isV9()) { + if (Subtarget.hasHardQuad()) { + BuildMI(MBB, I, DL, get(SP::FMOVQ), DestReg) + .addReg(SrcReg, getKillRegState(KillSrc)); + } else { + // Use two FMOVD instructions. + subRegIdx = QFP_DFP_SubRegsIdx; + numSubRegs = 2; + movOpc = SP::FMOVD; + } + } else { + // Use four FMOVS instructions. + subRegIdx = QFP_FP_SubRegsIdx; + numSubRegs = 4; + movOpc = SP::FMOVS; + } + } else llvm_unreachable("Impossible reg-to-reg copy"); + + if (numSubRegs == 0 || subRegIdx == 0 || movOpc == 0) + return; + + const TargetRegisterInfo *TRI = &getRegisterInfo(); + MachineInstr *MovMI = 0; + + for (unsigned i = 0; i != numSubRegs; ++i) { + unsigned Dst = TRI->getSubReg(DestReg, subRegIdx[i]); + unsigned Src = TRI->getSubReg(SrcReg, subRegIdx[i]); + assert(Dst && Src && "Bad sub-register"); + + MovMI = BuildMI(MBB, I, DL, get(movOpc), Dst).addReg(Src); + } + // Add implicit super-register defs and kills to the last MovMI. + MovMI->addRegisterDefined(DestReg, TRI); + if (KillSrc) + MovMI->addRegisterKilled(SrcReg, TRI); } void SparcInstrInfo:: @@ -302,16 +352,32 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), + MachineMemOperand::MOStore, + MFI.getObjectSize(FI), + MFI.getObjectAlignment(FI)); + // On the order of operands here: think "[FrameIdx + 0] = SrcReg". - if (RC == &SP::IntRegsRegClass) + if (RC == &SP::I64RegsRegClass) + BuildMI(MBB, I, DL, get(SP::STXri)).addFrameIndex(FI).addImm(0) + .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); + else if (RC == &SP::IntRegsRegClass) BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, getKillRegState(isKill)); + .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); else if (RC == &SP::FPRegsRegClass) BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, getKillRegState(isKill)); - else if (RC == &SP::DFPRegsRegClass) + .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); + else if (SP::DFPRegsRegClass.hasSubClassEq(RC)) BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0) - .addReg(SrcReg, getKillRegState(isKill)); + .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); + else if (SP::QFPRegsRegClass.hasSubClassEq(RC)) + // Use STQFri irrespective of its legality. If STQ is not legal, it will be + // lowered into two STDs in eliminateFrameIndex. + BuildMI(MBB, I, DL, get(SP::STQFri)).addFrameIndex(FI).addImm(0) + .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); else llvm_unreachable("Can't store this register to stack slot"); } @@ -324,12 +390,31 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL; if (I != MBB.end()) DL = I->getDebugLoc(); - if (RC == &SP::IntRegsRegClass) - BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0); + MachineFunction *MF = MBB.getParent(); + const MachineFrameInfo &MFI = *MF->getFrameInfo(); + MachineMemOperand *MMO = + MF->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI), + MachineMemOperand::MOLoad, + MFI.getObjectSize(FI), + MFI.getObjectAlignment(FI)); + + if (RC == &SP::I64RegsRegClass) + BuildMI(MBB, I, DL, get(SP::LDXri), DestReg).addFrameIndex(FI).addImm(0) + .addMemOperand(MMO); + else if (RC == &SP::IntRegsRegClass) + BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0) + .addMemOperand(MMO); else if (RC == &SP::FPRegsRegClass) - BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0); - else if (RC == &SP::DFPRegsRegClass) - BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0); + BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0) + .addMemOperand(MMO); + else if (SP::DFPRegsRegClass.hasSubClassEq(RC)) + BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0) + .addMemOperand(MMO); + else if (SP::QFPRegsRegClass.hasSubClassEq(RC)) + // Use LDQFri irrespective of its legality. If LDQ is not legal, it will be + // lowered into two LDDs in eliminateFrameIndex. + BuildMI(MBB, I, DL, get(SP::LDQFri), DestReg).addFrameIndex(FI).addImm(0) + .addMemOperand(MMO); else llvm_unreachable("Can't load this register from stack slot"); } |