diff options
Diffstat (limited to 'lib/Target/Sparc/SparcInstrInfo.cpp')
-rw-r--r-- | lib/Target/Sparc/SparcInstrInfo.cpp | 107 |
1 files changed, 71 insertions, 36 deletions
diff --git a/lib/Target/Sparc/SparcInstrInfo.cpp b/lib/Target/Sparc/SparcInstrInfo.cpp index 05006ac5772b3..cfd342410550f 100644 --- a/lib/Target/Sparc/SparcInstrInfo.cpp +++ b/lib/Target/Sparc/SparcInstrInfo.cpp @@ -41,17 +41,15 @@ SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST) /// the destination along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than loading from the stack slot. -unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, +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::LDQFri) { - if (MI->getOperand(1).isFI() && MI->getOperand(2).isImm() && - MI->getOperand(2).getImm() == 0) { - FrameIndex = MI->getOperand(1).getIndex(); - return MI->getOperand(0).getReg(); + if (MI.getOpcode() == SP::LDri || MI.getOpcode() == SP::LDXri || + MI.getOpcode() == SP::LDFri || 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(); + return MI.getOperand(0).getReg(); } } return 0; @@ -62,17 +60,15 @@ unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, /// the source reg along with the FrameIndex of the loaded stack slot. If /// not, return 0. This predicate must return 0 if the instruction has /// any side effects other than storing to the stack slot. -unsigned SparcInstrInfo::isStoreToStackSlot(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::STQFri) { - if (MI->getOperand(0).isFI() && MI->getOperand(1).isImm() && - MI->getOperand(1).getImm() == 0) { - FrameIndex = MI->getOperand(0).getIndex(); - return MI->getOperand(2).getReg(); + if (MI.getOpcode() == SP::STri || MI.getOpcode() == SP::STXri || + MI.getOpcode() == SP::STFri || 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(); + return MI.getOperand(2).getReg(); } } return 0; @@ -119,6 +115,28 @@ static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC) case SPCC::FCC_UE: return SPCC::FCC_LG; case SPCC::FCC_NE: return SPCC::FCC_E; case SPCC::FCC_E: return SPCC::FCC_NE; + + case SPCC::CPCC_A: return SPCC::CPCC_N; + case SPCC::CPCC_N: return SPCC::CPCC_A; + case SPCC::CPCC_3: // Fall through + case SPCC::CPCC_2: // Fall through + case SPCC::CPCC_23: // Fall through + case SPCC::CPCC_1: // Fall through + case SPCC::CPCC_13: // Fall through + case SPCC::CPCC_12: // Fall through + case SPCC::CPCC_123: // Fall through + case SPCC::CPCC_0: // Fall through + case SPCC::CPCC_03: // Fall through + case SPCC::CPCC_02: // Fall through + case SPCC::CPCC_023: // Fall through + case SPCC::CPCC_01: // Fall through + case SPCC::CPCC_013: // Fall through + case SPCC::CPCC_012: + // "Opposite" code is not meaningful, as we don't know + // what the CoProc condition means here. The cond-code will + // only be used in inline assembler, so this code should + // not be reached in a normal compilation pass. + llvm_unreachable("Meaningless inversion of co-processor cond code"); } llvm_unreachable("Invalid cond code"); } @@ -139,7 +157,7 @@ static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, Target = LastInst->getOperand(0).getMBB(); } -bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, +bool SparcInstrInfo::analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl<MachineOperand> &Cond, @@ -148,15 +166,15 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, if (I == MBB.end()) return false; - if (!isUnpredicatedTerminator(I)) + if (!isUnpredicatedTerminator(*I)) return false; // Get the last instruction in the block. - MachineInstr *LastInst = I; + MachineInstr *LastInst = &*I; unsigned LastOpc = LastInst->getOpcode(); // If there is only one terminator instruction, process it. - if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { + if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { if (isUncondBranchOpcode(LastOpc)) { TBB = LastInst->getOperand(0).getMBB(); return false; @@ -170,7 +188,7 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, } // Get the instruction before it if it is a terminator. - MachineInstr *SecondLastInst = I; + MachineInstr *SecondLastInst = &*I; unsigned SecondLastOpc = SecondLastInst->getOpcode(); // If AllowModify is true and the block ends with two or more unconditional @@ -180,19 +198,19 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, LastInst->eraseFromParent(); LastInst = SecondLastInst; LastOpc = LastInst->getOpcode(); - if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { + if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { // Return now the only terminator is an unconditional branch. TBB = LastInst->getOperand(0).getMBB(); return false; } else { - SecondLastInst = I; + SecondLastInst = &*I; SecondLastOpc = SecondLastInst->getOpcode(); } } } // If there are three terminators, we don't know what sort of block this is. - if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) + if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) return true; // If the block ends with a B and a Bcc, handle it. @@ -222,11 +240,11 @@ bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, return true; } -unsigned -SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - ArrayRef<MachineOperand> Cond, - DebugLoc DL) const { +unsigned SparcInstrInfo::InsertBranch(MachineBasicBlock &MBB, + MachineBasicBlock *TBB, + MachineBasicBlock *FBB, + ArrayRef<MachineOperand> Cond, + const DebugLoc &DL) const { assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 1 || Cond.size() == 0) && "Sparc branch conditions should have one component!"); @@ -282,9 +300,9 @@ bool SparcInstrInfo::ReverseBranchCondition( } void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB, - MachineBasicBlock::iterator I, DebugLoc DL, - unsigned DestReg, unsigned SrcReg, - bool KillSrc) const { + MachineBasicBlock::iterator I, + const DebugLoc &DL, unsigned DestReg, + unsigned SrcReg, bool KillSrc) const { unsigned numSubRegs = 0; unsigned movOpc = 0; const unsigned *subRegIdx = nullptr; @@ -469,3 +487,20 @@ unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const SparcFI->setGlobalBaseReg(GlobalBaseReg); return GlobalBaseReg; } + +bool SparcInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { + switch (MI.getOpcode()) { + case TargetOpcode::LOAD_STACK_GUARD: { + assert(Subtarget.isTargetLinux() && + "Only Linux target is expected to contain LOAD_STACK_GUARD"); + // offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc. + const int64_t Offset = Subtarget.is64Bit() ? 0x28 : 0x14; + MI.setDesc(get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri)); + MachineInstrBuilder(*MI.getParent()->getParent(), MI) + .addReg(SP::G7) + .addImm(Offset); + return true; + } + } + return false; +} |