diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-10 00:19:06 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-10 00:19:06 +0000 |
commit | 182ef6fcaacbf44e17a96ea6614cbb5e1af1c3c2 (patch) | |
tree | decad739be2bc54c93de22590effcc899df32658 /lib | |
parent | 655b5a48b956d91e8656d8d2ef062dd9c2bf8591 (diff) |
Make register Mips::RA allocatable if not in mips16 mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@159971 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 10 | ||||
-rw-r--r-- | lib/Target/Mips/Mips64InstrInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.cpp | 32 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.h | 5 | ||||
-rw-r--r-- | lib/Target/Mips/MipsISelLowering.cpp | 9 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.cpp | 13 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/Mips/MipsInstrInfo.td | 40 | ||||
-rw-r--r-- | lib/Target/Mips/MipsRegisterInfo.cpp | 12 |
9 files changed, 88 insertions, 37 deletions
diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 2e0239377d..f6b8762125 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -15,6 +15,11 @@ class Mips16Pat<dag pattern, dag result> : Pat<pattern, result> { let Predicates = [InMips16Mode]; } +// Mips16 pseudos +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1, + hasExtraSrcRegAllocReq = 1 in +def RetRA16 : MipsPseudo16<(outs), (ins), "", [(MipsRet)]>; + def LI16E : FEXT_RI16<0b01101, (outs CPU16Regs:$rx), (ins uimm16:$amt), !strconcat("li", "\t$rx, $amt"), @@ -22,9 +27,8 @@ def LI16E : FEXT_RI16<0b01101, (outs CPU16Regs:$rx), let isReturn=1, isTerminator=1, hasDelaySlot=1, isCodeGenOnly=1, isBarrier=1, hasCtrlDep=1, rx=0, nd=0, l=0, ra=0 in -def RET16 : FRR16_JALRC - < (outs), (ins CPURAReg:$target), - "jr\t$target", [(MipsRet CPURAReg:$target)], IIBranch>; +def RET16 : FRR16_JALRC<(outs), (ins CPURAReg:$target), "jr\t$target", [], + IIBranch>; // As stack alignment is always done with addiu, we need a 16-bit immediate let Defs = [SP], Uses = [SP] in { diff --git a/lib/Target/Mips/Mips64InstrInfo.td b/lib/Target/Mips/Mips64InstrInfo.td index a5a3038827..7a9d41bae8 100644 --- a/lib/Target/Mips/Mips64InstrInfo.td +++ b/lib/Target/Mips/Mips64InstrInfo.td @@ -168,7 +168,7 @@ def SCD_P8 : SCBase<0x3c, "scd", CPU64Regs, mem64>, } /// Jump and Branch Instructions -def JR64 : JumpFR<0x00, 0x08, "jr", CPU64Regs>; +def JR64 : IndirectBranch<CPU64Regs>; def BEQ64 : CBranch<0x04, "beq", seteq, CPU64Regs>; def BNE64 : CBranch<0x05, "bne", setne, CPU64Regs>; def BGEZ64 : CBranchZero<0x01, 1, "bgez", setge, CPU64Regs>; diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp index 5afd2fc576..95e2357dd7 100644 --- a/lib/Target/Mips/MipsFrameLowering.cpp +++ b/lib/Target/Mips/MipsFrameLowering.cpp @@ -261,16 +261,28 @@ processFunctionBeforeCalleeSavedScan(MachineFunction &MF, // Mark $fp and $ra as used or unused. if (hasFP(MF)) MRI.setPhysRegUsed(FP); +} - // The register allocator might determine $ra is used after seeing - // instruction "jr $ra", but we do not want PrologEpilogInserter to insert - // instructions to save/restore $ra unless there is a function call. - // To correct this, $ra is explicitly marked unused if there is no - // function call. - if (MF.getFrameInfo()->hasCalls()) - MRI.setPhysRegUsed(Mips::RA); - else { - MRI.setPhysRegUnused(Mips::RA); - MRI.setPhysRegUnused(Mips::RA_64); +bool MipsFrameLowering:: +spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const { + MachineFunction *MF = MBB.getParent(); + MachineBasicBlock *EntryBlock = MF->begin(); + const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); + + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + // Add the callee-saved register as live-in. + // It's killed at the spill. + EntryBlock->addLiveIn(CSI[i].getReg()); + + // Insert the spill to the stack frame. + unsigned Reg = CSI[i].getReg(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.storeRegToStackSlot(*EntryBlock, MI, Reg, true, + CSI[i].getFrameIdx(), RC, TRI); } + + return true; } diff --git a/lib/Target/Mips/MipsFrameLowering.h b/lib/Target/Mips/MipsFrameLowering.h index bd1d89f04b..e364dedff2 100644 --- a/lib/Target/Mips/MipsFrameLowering.h +++ b/lib/Target/Mips/MipsFrameLowering.h @@ -38,6 +38,11 @@ public: void emitPrologue(MachineFunction &MF) const; void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; + bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const; + bool hasFP(const MachineFunction &MF) const; void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index a7e2aa32fc..ca002c0fc1 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -3253,11 +3253,10 @@ MipsTargetLowering::LowerReturn(SDValue Chain, // Return on Mips is always a "jr $ra" if (Flag.getNode()) - return DAG.getNode(MipsISD::Ret, dl, MVT::Other, - Chain, DAG.getRegister(Mips::RA, MVT::i32), Flag); - else // Return Void - return DAG.getNode(MipsISD::Ret, dl, MVT::Other, - Chain, DAG.getRegister(Mips::RA, MVT::i32)); + return DAG.getNode(MipsISD::Ret, dl, MVT::Other, Chain, Flag); + + // Return Void + return DAG.getNode(MipsISD::Ret, dl, MVT::Other, Chain); } //===----------------------------------------------------------------------===// diff --git a/lib/Target/Mips/MipsInstrInfo.cpp b/lib/Target/Mips/MipsInstrInfo.cpp index e4eefb9905..7d8488f0b8 100644 --- a/lib/Target/Mips/MipsInstrInfo.cpp +++ b/lib/Target/Mips/MipsInstrInfo.cpp @@ -233,6 +233,13 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, .addMemOperand(MMO); } +void MipsInstrInfo::ExpandRetRA(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned Opc) const { + BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(Opc)) + .addReg(Mips::RA); +} + void MipsInstrInfo::ExpandExtractElementF64(MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { const TargetInstrInfo *TII = TM.getInstrInfo(); @@ -272,6 +279,12 @@ bool MipsInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { switch(MI->getDesc().getOpcode()) { default: return false; + case Mips::RetRA: + ExpandRetRA(MBB, MI, Mips::RET); + break; + case Mips::RetRA16: + ExpandRetRA(MBB, MI, Mips::RET16); + break; case Mips::BuildPairF64: ExpandBuildPairF64(MBB, MI); break; diff --git a/lib/Target/Mips/MipsInstrInfo.h b/lib/Target/Mips/MipsInstrInfo.h index 7a0065b634..b4721a7b39 100644 --- a/lib/Target/Mips/MipsInstrInfo.h +++ b/lib/Target/Mips/MipsInstrInfo.h @@ -63,6 +63,8 @@ public: virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; private: + void ExpandRetRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, + unsigned Opc) const; void BuildCondBr(MachineBasicBlock &MBB, MachineBasicBlock *TBB, DebugLoc DL, const SmallVectorImpl<MachineOperand>& Cond) const; void ExpandExtractElementF64(MachineBasicBlock &MBB, diff --git a/lib/Target/Mips/MipsInstrInfo.td b/lib/Target/Mips/MipsInstrInfo.td index b9a7273f21..973d00bb01 100644 --- a/lib/Target/Mips/MipsInstrInfo.td +++ b/lib/Target/Mips/MipsInstrInfo.td @@ -16,7 +16,6 @@ // Mips profiles and nodes //===----------------------------------------------------------------------===// -def SDT_MipsRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_MipsJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, iPTR>]>; def SDT_MipsCMov : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, @@ -71,8 +70,7 @@ def MipsTprelLo : SDNode<"MipsISD::TprelLo", SDTIntUnaryOp>; def MipsThreadPointer: SDNode<"MipsISD::ThreadPointer", SDT_MipsThreadPointer>; // Return -def MipsRet : SDNode<"MipsISD::Ret", SDT_MipsRet, [SDNPHasChain, - SDNPOptInGlue]>; +def MipsRet : SDNode<"MipsISD::Ret", SDTNone, [SDNPHasChain, SDNPOptInGlue]>; // These are target-independent nodes, but have target-specific formats. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MipsCallSeqStart, @@ -625,18 +623,31 @@ class UncondBranch<bits<6> op, string instr_asm>: let Defs = [AT]; } -let isBranch=1, isTerminator=1, isBarrier=1, rd=0, hasDelaySlot = 1, - isIndirectBranch = 1 in -class JumpFR<bits<6> op, bits<6> func, string instr_asm, RegisterClass RC>: - FR<op, func, (outs), (ins RC:$rs), - !strconcat(instr_asm, "\t$rs"), [(brind RC:$rs)], IIBranch> { +// Base class for indirect branch and return instruction classes. +let isTerminator=1, isBarrier=1, hasDelaySlot = 1 in +class JumpFR<RegisterClass RC, list<dag> pattern>: + FR<0, 0x8, (outs), (ins RC:$rs), "jr\t$rs", pattern, IIBranch> { let rt = 0; let rd = 0; let shamt = 0; } +// Indirect branch +class IndirectBranch<RegisterClass RC>: JumpFR<RC, [(brind RC:$rs)]> { + let isBranch = 1; + let isIndirectBranch = 1; +} + +// Return instruction +class RetBase<RegisterClass RC>: JumpFR<RC, []> { + let isReturn = 1; + let isCodeGenOnly = 1; + let hasCtrlDep = 1; + let hasExtraSrcRegAllocReq = 1; +} + // Jump and Link (Call) -let isCall=1, hasDelaySlot=1 in { +let isCall=1, hasDelaySlot=1, Defs = [RA] in { class JumpLink<bits<6> op, string instr_asm>: FJ<op, (outs), (ins calltarget:$target, variable_ops), !strconcat(instr_asm, "\t$target"), [(MipsJmpLink imm:$target)], @@ -838,6 +849,10 @@ class SCBase<bits<6> Opc, string opstring, RegisterClass RC, Operand Mem> : // Pseudo instructions //===----------------------------------------------------------------------===// +// Return RA. +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, hasCtrlDep=1 in +def RetRA : MipsPseudo<(outs), (ins), "", [(MipsRet)]>; + // As stack alignment is always done with addiu, we need a 16-bit immediate let Defs = [SP], Uses = [SP] in { def ADJCALLSTACKDOWN : MipsPseudo<(outs), (ins uimm16:$amt), @@ -981,7 +996,7 @@ def SC_P8 : SCBase<0x38, "sc", CPURegs, mem64>, /// Jump and Branch Instructions def J : JumpFJ<0x02, "j">; -def JR : JumpFR<0x00, 0x08, "jr", CPURegs>; +def JR : IndirectBranch<CPURegs>; def B : UncondBranch<0x04, "b">; def BEQ : CBranch<0x04, "beq", seteq, CPURegs>; def BNE : CBranch<0x05, "bne", setne, CPURegs>; @@ -995,10 +1010,7 @@ def JALR : JumpLinkReg<0x00, 0x09, "jalr", CPURegs>; def BGEZAL : BranchLink<"bgezal", 0x11, CPURegs>; def BLTZAL : BranchLink<"bltzal", 0x10, CPURegs>; -let isReturn=1, isTerminator=1, hasDelaySlot=1, isCodeGenOnly=1, - isBarrier=1, hasCtrlDep=1, rd=0, rt=0, shamt=0 in - def RET : FR <0x00, 0x08, (outs), (ins CPURegs:$target), - "jr\t$target", [(MipsRet CPURegs:$target)], IIBranch>; +def RET : RetBase<CPURegs>; /// Multiply and Divide Instructions. def MULT : Mult32<0x18, "mult", IIImul>; diff --git a/lib/Target/Mips/MipsRegisterInfo.cpp b/lib/Target/Mips/MipsRegisterInfo.cpp index c7a168a51f..a3ce236164 100644 --- a/lib/Target/Mips/MipsRegisterInfo.cpp +++ b/lib/Target/Mips/MipsRegisterInfo.cpp @@ -83,13 +83,11 @@ MipsRegisterInfo::getCallPreservedMask(CallingConv::ID) const { BitVector MipsRegisterInfo:: getReservedRegs(const MachineFunction &MF) const { static const uint16_t ReservedCPURegs[] = { - Mips::ZERO, Mips::AT, Mips::K0, Mips::K1, - Mips::SP, Mips::RA + Mips::ZERO, Mips::AT, Mips::K0, Mips::K1, Mips::SP }; static const uint16_t ReservedCPU64Regs[] = { - Mips::ZERO_64, Mips::AT_64, Mips::K0_64, Mips::K1_64, - Mips::SP_64, Mips::RA_64 + Mips::ZERO_64, Mips::AT_64, Mips::K0_64, Mips::K1_64, Mips::SP_64 }; BitVector Reserved(getNumRegs()); @@ -127,6 +125,12 @@ getReservedRegs(const MachineFunction &MF) const { Reserved.set(Mips::HWR29); Reserved.set(Mips::HWR29_64); + // Reserve RA if in mips16 mode. + if (Subtarget.inMips16Mode()) { + Reserved.set(Mips::RA); + Reserved.set(Mips::RA_64); + } + return Reserved; } |