diff options
-rw-r--r-- | lib/Target/Mips/Mips16FrameLowering.cpp | 6 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.cpp | 18 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.h | 4 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16InstrInfo.td | 25 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16RegisterInfo.cpp | 20 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16RegisterInfo.h | 3 | ||||
-rw-r--r-- | test/CodeGen/Mips/alloca16.ll | 84 |
7 files changed, 125 insertions, 35 deletions
diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp index 74cffd2..4e6b21f 100644 --- a/lib/Target/Mips/Mips16FrameLowering.cpp +++ b/lib/Target/Mips/Mips16FrameLowering.cpp @@ -115,8 +115,10 @@ bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, bool Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { - // FIXME: implement. - return true; + const MachineFrameInfo *MFI = MF.getFrameInfo(); + // Reserve call frame if the size of the maximum call frame fits into 15-bit + // immediate field and there are no variable sized objects on the stack. + return isInt<15>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); } void Mips16FrameLowering:: diff --git a/lib/Target/Mips/Mips16InstrInfo.cpp b/lib/Target/Mips/Mips16InstrInfo.cpp index fa0876a..619646b 100644 --- a/lib/Target/Mips/Mips16InstrInfo.cpp +++ b/lib/Target/Mips/Mips16InstrInfo.cpp @@ -26,7 +26,7 @@ using namespace llvm; Mips16InstrInfo::Mips16InstrInfo(MipsTargetMachine &tm) : MipsInstrInfo(tm, Mips::BimmX16), - RI(*tm.getSubtargetImpl()) {} + RI(*tm.getSubtargetImpl(), *this) {} const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { return RI; @@ -160,6 +160,22 @@ unsigned Mips16InstrInfo::GetOppositeBranchOpc(unsigned Opc) const { return 0; } +/// Adjust SP by Amount bytes. +void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, + MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const { + DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); + if (isInt<16>(Amount)) { + if (Amount < 0) + BuildMI(MBB, I, DL, get(Mips::SaveDecSpF16)). addImm(-Amount); + else if (Amount > 0) + BuildMI(MBB, I, DL, get(Mips::RestoreIncSpF16)).addImm(Amount); + } + else + // not implemented for large values yet + assert(false && "adjust stack pointer amount exceeded"); +} + unsigned Mips16InstrInfo::GetAnalyzableBrOpc(unsigned Opc) const { return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || Opc == Mips::BnezRxImmX16 || Opc == Mips::BteqzX16 || diff --git a/lib/Target/Mips/Mips16InstrInfo.h b/lib/Target/Mips/Mips16InstrInfo.h index 260c5b6..e06ccfe 100644 --- a/lib/Target/Mips/Mips16InstrInfo.h +++ b/lib/Target/Mips/Mips16InstrInfo.h @@ -64,6 +64,10 @@ public: virtual unsigned GetOppositeBranchOpc(unsigned Opc) const; + /// Adjust SP by Amount bytes. + void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB, + MachineBasicBlock::iterator I) const; + private: virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const; diff --git a/lib/Target/Mips/Mips16InstrInfo.td b/lib/Target/Mips/Mips16InstrInfo.td index 5f8af05..5defc75 100644 --- a/lib/Target/Mips/Mips16InstrInfo.td +++ b/lib/Target/Mips/Mips16InstrInfo.td @@ -686,7 +686,17 @@ def OrRxRxRy16: FRxRxRy16_ins<0b01101, "or", IIAlu>, ArithLogic16Defs<1>; let ra=1, s=0,s0=1,s1=1 in def RestoreRaF16: FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "restore \t$$ra, $$s0, $$s1, $frame_size", [], IILoad >, MayLoad { + "restore\t$$ra, $$s0, $$s1, $frame_size", [], IILoad >, MayLoad { + let isCodeGenOnly = 1; +} + +// Use Restore to increment SP since SP is not a Mip 16 register, this +// is an easy way to do that which does not require a register. +// +let ra=0, s=0,s0=0,s1=0 in +def RestoreIncSpF16: + FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), + "restore\t$frame_size", [], IILoad >, MayLoad { let isCodeGenOnly = 1; } @@ -700,7 +710,18 @@ def RestoreRaF16: let ra=1, s=1,s0=1,s1=1 in def SaveRaF16: FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), - "save \t$$ra, $$s0, $$s1, $frame_size", [], IIStore >, MayStore { + "save\t$$ra, $$s0, $$s1, $frame_size", [], IIStore >, MayStore { + let isCodeGenOnly = 1; +} + +// +// Use Save to decrement the SP by a constant since SP is not +// a Mips16 register. +// +let ra=0, s=0,s0=0,s1=0 in +def SaveDecSpF16: + FI8_SVRS16<0b1, (outs), (ins uimm16:$frame_size), + "save\t$frame_size", [], IIStore >, MayStore { let isCodeGenOnly = 1; } // diff --git a/lib/Target/Mips/Mips16RegisterInfo.cpp b/lib/Target/Mips/Mips16RegisterInfo.cpp index 47a41d6..d7397a3 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.cpp +++ b/lib/Target/Mips/Mips16RegisterInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Mips16RegisterInfo.h" +#include "Mips16InstrInfo.h" #include "Mips.h" #include "MipsAnalyzeImmediate.h" #include "MipsInstrInfo.h" @@ -38,15 +39,28 @@ using namespace llvm; -Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST) - : MipsRegisterInfo(ST) {} +Mips16RegisterInfo::Mips16RegisterInfo(const MipsSubtarget &ST, + const Mips16InstrInfo &I) + : MipsRegisterInfo(ST), TII(I) {} // This function eliminate ADJCALLSTACKDOWN, // ADJCALLSTACKUP pseudo instructions void Mips16RegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { - // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions. + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); + + if (!TFI->hasReservedCallFrame(MF)) { + int64_t Amount = I->getOperand(0).getImm(); + + if (I->getOpcode() == Mips::ADJCALLSTACKDOWN) + Amount = -Amount; + + const Mips16InstrInfo *II = static_cast<const Mips16InstrInfo*>(&TII); + + II->adjustStackPtr(Mips::SP, Amount, MBB, I); + } + MBB.erase(I); } diff --git a/lib/Target/Mips/Mips16RegisterInfo.h b/lib/Target/Mips/Mips16RegisterInfo.h index c702a15..153def2 100644 --- a/lib/Target/Mips/Mips16RegisterInfo.h +++ b/lib/Target/Mips/Mips16RegisterInfo.h @@ -20,8 +20,9 @@ namespace llvm { class Mips16InstrInfo; class Mips16RegisterInfo : public MipsRegisterInfo { + const Mips16InstrInfo &TII; public: - Mips16RegisterInfo(const MipsSubtarget &Subtarget); + Mips16RegisterInfo(const MipsSubtarget &Subtarget, const Mips16InstrInfo &TII); void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, diff --git a/test/CodeGen/Mips/alloca16.ll b/test/CodeGen/Mips/alloca16.ll index ce2e634..731edae 100644 --- a/test/CodeGen/Mips/alloca16.ll +++ b/test/CodeGen/Mips/alloca16.ll @@ -3,41 +3,73 @@ @iiii = global i32 25, align 4 @jjjj = global i32 35, align 4 @kkkk = global i32 100, align 4 +@t = global i32 25, align 4 @riii = common global i32 0, align 4 @rjjj = common global i32 0, align 4 @rkkk = common global i32 0, align 4 +define void @temp(i32 %foo) nounwind { +entry: + %foo.addr = alloca i32, align 4 + store i32 %foo, i32* %foo.addr, align 4 + %0 = load i32* %foo.addr, align 4 + store i32 %0, i32* @t, align 4 + ret void +} + define void @test() nounwind { entry: -; 16: .frame $16,16,$ra -; 16: save $ra, $s0, $s1, 16 +; 16: .frame $16,24,$ra +; 16: save $ra, $s0, $s1, 24 ; 16: move $16, $sp ; 16: move ${{[0-9]+}}, $sp ; 16: subu $[[REGISTER:[0-9]+]], ${{[0-9]+}}, ${{[0-9]+}} ; 16: move $sp, $[[REGISTER]] - %0 = load i32* @kkkk, align 4 - %1 = mul i32 %0, 25 - %2 = alloca i32, i32 %1, align 4 - %3 = load i32* @jjjj, align 4 - %4 = load i32* @iiii, align 4 - %arrayidx = getelementptr inbounds i32* %2, i32 %4 - store i32 %3, i32* %arrayidx, align 4 - %arrayidx1 = getelementptr inbounds i32* %2, i32 %3 - store i32 %0, i32* %arrayidx1, align 4 - %arrayidx2 = getelementptr inbounds i32* %2, i32 %0 - store i32 %4, i32* %arrayidx2, align 4 - %arrayidx3 = getelementptr inbounds i32* %2, i32 25 - %5 = load i32* %arrayidx3, align 4 - store i32 %5, i32* @riii, align 4 - %arrayidx4 = getelementptr inbounds i32* %2, i32 35 - %6 = load i32* %arrayidx4, align 4 - store i32 %6, i32* @rjjj, align 4 - %arrayidx5 = getelementptr inbounds i32* %2, i32 100 - %7 = load i32* %arrayidx5, align 4 - store i32 %7, i32* @rkkk, align 4 -; 16: move $sp, $16 -; 16: restore $ra, $s0, $s1, 16 + %sssi = alloca i32, align 4 + %ip = alloca i32*, align 4 + %sssj = alloca i32, align 4 + %0 = load i32* @iiii, align 4 + store i32 %0, i32* %sssi, align 4 + %1 = load i32* @kkkk, align 4 + %mul = mul nsw i32 %1, 100 + %2 = alloca i8, i32 %mul + %3 = bitcast i8* %2 to i32* + store i32* %3, i32** %ip, align 4 + %4 = load i32* @jjjj, align 4 + store i32 %4, i32* %sssj, align 4 + %5 = load i32* @jjjj, align 4 + %6 = load i32* @iiii, align 4 + %7 = load i32** %ip, align 4 + %arrayidx = getelementptr inbounds i32* %7, i32 %6 + store i32 %5, i32* %arrayidx, align 4 + %8 = load i32* @kkkk, align 4 + %9 = load i32* @jjjj, align 4 + %10 = load i32** %ip, align 4 + %arrayidx1 = getelementptr inbounds i32* %10, i32 %9 + store i32 %8, i32* %arrayidx1, align 4 + %11 = load i32* @iiii, align 4 + %12 = load i32* @kkkk, align 4 + %13 = load i32** %ip, align 4 + %arrayidx2 = getelementptr inbounds i32* %13, i32 %12 + store i32 %11, i32* %arrayidx2, align 4 + %14 = load i32** %ip, align 4 + %arrayidx3 = getelementptr inbounds i32* %14, i32 25 + %15 = load i32* %arrayidx3, align 4 + store i32 %15, i32* @riii, align 4 + %16 = load i32** %ip, align 4 + %arrayidx4 = getelementptr inbounds i32* %16, i32 35 + %17 = load i32* %arrayidx4, align 4 + store i32 %17, i32* @rjjj, align 4 + %18 = load i32** %ip, align 4 + %arrayidx5 = getelementptr inbounds i32* %18, i32 100 + %19 = load i32* %arrayidx5, align 4 + store i32 %19, i32* @rkkk, align 4 + %20 = load i32* @t, align 4 + %21 = load i32** %ip, align 4 + %arrayidx6 = getelementptr inbounds i32* %21, i32 %20 + %22 = load i32* %arrayidx6, align 4 +; 16: save 16 + call void @temp(i32 %22) +; 16: restore 16 ret void } - - |