diff options
author | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-31 22:50:19 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@mips.com> | 2012-07-31 22:50:19 +0000 |
commit | cdb3ba71ce550c5a41c84c3678225a39d6f0a414 (patch) | |
tree | b0d0c70bbaa9f09fc6ade9c6ff6fd113d231da53 | |
parent | d7122b8d3c48eab05d425c99fee53cde07feafe4 (diff) |
Add definitions of two subclasses of MipsFrameLowering, Mips16FrameLowering and
MipsSEFrameLowering.
Implement MipsSEFrameLowering::hasReservedCallFrame. Call frames will not be
reserved if there is a call with a large call frame or there are variable sized
objects on the stack.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@161090 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/Mips/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16FrameLowering.cpp | 82 | ||||
-rw-r--r-- | lib/Target/Mips/Mips16FrameLowering.h | 43 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.cpp | 201 | ||||
-rw-r--r-- | lib/Target/Mips/MipsFrameLowering.h | 13 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEFrameLowering.cpp | 225 | ||||
-rw-r--r-- | lib/Target/Mips/MipsSEFrameLowering.h | 44 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetMachine.cpp | 20 | ||||
-rw-r--r-- | lib/Target/Mips/MipsTargetMachine.h | 4 | ||||
-rw-r--r-- | test/CodeGen/Mips/largeimmprinting.ll | 2 |
10 files changed, 416 insertions, 220 deletions
diff --git a/lib/Target/Mips/CMakeLists.txt b/lib/Target/Mips/CMakeLists.txt index 275279c452..db2fde9d78 100644 --- a/lib/Target/Mips/CMakeLists.txt +++ b/lib/Target/Mips/CMakeLists.txt @@ -13,6 +13,7 @@ tablegen(LLVM MipsGenEDInfo.inc -gen-enhanced-disassembly-info) add_public_tablegen_target(MipsCommonTableGen) add_llvm_target(MipsCodeGen + Mips16FrameLowering.cpp Mips16InstrInfo.cpp MipsAnalyzeImmediate.cpp MipsAsmPrinter.cpp @@ -27,6 +28,7 @@ add_llvm_target(MipsCodeGen MipsMCInstLower.cpp MipsMachineFunction.cpp MipsRegisterInfo.cpp + MipsSEFrameLowering.cpp MipsSEInstrInfo.cpp MipsSubtarget.cpp MipsTargetMachine.cpp diff --git a/lib/Target/Mips/Mips16FrameLowering.cpp b/lib/Target/Mips/Mips16FrameLowering.cpp new file mode 100644 index 0000000000..3df7d5f9f1 --- /dev/null +++ b/lib/Target/Mips/Mips16FrameLowering.cpp @@ -0,0 +1,82 @@ +//===-- Mips16FrameLowering.cpp - Mips16 Frame Information ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the Mips16 implementation of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#include "Mips16FrameLowering.h" +#include "MipsInstrInfo.h" +#include "MCTargetDesc/MipsBaseInfo.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +void Mips16FrameLowering::emitPrologue(MachineFunction &MF) const { + MachineBasicBlock &MBB = MF.front(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const MipsInstrInfo &TII = + *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); + MachineBasicBlock::iterator MBBI = MBB.begin(); + DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + uint64_t StackSize = MFI->getStackSize(); + + // No need to allocate space on the stack. + if (StackSize == 0 && !MFI->adjustsStack()) return; + + // Adjust stack. + if (isInt<16>(-StackSize)) + BuildMI(MBB, MBBI, dl, TII.get(Mips::SaveRaF16)).addImm(StackSize); +} + +void Mips16FrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const MipsInstrInfo &TII = + *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); + DebugLoc dl = MBBI->getDebugLoc(); + uint64_t StackSize = MFI->getStackSize(); + + if (!StackSize) + return; + + // Adjust stack. + if (isInt<16>(StackSize)) + // assumes stacksize multiple of 8 + BuildMI(MBB, MBBI, dl, TII.get(Mips::RestoreRaF16)).addImm(StackSize); +} + +bool Mips16FrameLowering:: +spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector<CalleeSavedInfo> &CSI, + const TargetRegisterInfo *TRI) const { + // FIXME: implement. + return true; +} + +bool +Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { + // FIXME: implement. + return true; +} + +void Mips16FrameLowering:: +processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const { +} diff --git a/lib/Target/Mips/Mips16FrameLowering.h b/lib/Target/Mips/Mips16FrameLowering.h new file mode 100644 index 0000000000..25cc37b815 --- /dev/null +++ b/lib/Target/Mips/Mips16FrameLowering.h @@ -0,0 +1,43 @@ +//===-- Mips16FrameLowering.h - Mips16 frame lowering ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +// +//===----------------------------------------------------------------------===// + +#ifndef MIPS16_FRAMEINFO_H +#define MIPS16_FRAMEINFO_H + +#include "MipsFrameLowering.h" + +namespace llvm { +class Mips16FrameLowering : public MipsFrameLowering { +public: + explicit Mips16FrameLowering(const MipsSubtarget &STI) + : MipsFrameLowering(STI) {} + + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into + /// the function. + 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 hasReservedCallFrame(const MachineFunction &MF) const; + + void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const; +}; + +} // End llvm namespace + +#endif diff --git a/lib/Target/Mips/MipsFrameLowering.cpp b/lib/Target/Mips/MipsFrameLowering.cpp index ca7ba124e6..f2ee41d00e 100644 --- a/lib/Target/Mips/MipsFrameLowering.cpp +++ b/lib/Target/Mips/MipsFrameLowering.cpp @@ -89,204 +89,3 @@ bool MipsFrameLowering::hasFP(const MachineFunction &MF) const { return MF.getTarget().Options.DisableFramePointerElim(MF) || MFI->hasVarSizedObjects() || MFI->isFrameAddressTaken(); } - -void MipsFrameLowering::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - const MipsRegisterInfo *RegInfo = - static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); - const MipsInstrInfo &TII = - *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); - MachineBasicBlock::iterator MBBI = MBB.begin(); - DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); - unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; - unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; - unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; - unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; - unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; - - // First, compute final stack size. - uint64_t StackSize = MFI->getStackSize(); - - // No need to allocate space on the stack. - if (StackSize == 0 && !MFI->adjustsStack()) return; - - MachineModuleInfo &MMI = MF.getMMI(); - std::vector<MachineMove> &Moves = MMI.getFrameMoves(); - MachineLocation DstML, SrcML; - - // Adjust stack. - if (isInt<16>(-StackSize)) {// addi sp, sp, (-stacksize) - if (STI.inMips16Mode()) - BuildMI(MBB, MBBI, dl, - TII.get(Mips::SaveRaF16)).addImm(StackSize); // cleanup - else - BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize); - } - else { // Expand immediate that doesn't fit in 16-bit. - unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; - - MF.getInfo<MipsFunctionInfo>()->setEmitNOAT(); - Mips::loadImmediate(-StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl, false, - 0); - BuildMI(MBB, MBBI, dl, TII.get(ADDu), SP).addReg(SP).addReg(ATReg); - } - - // emit ".cfi_def_cfa_offset StackSize" - MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, - TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); - DstML = MachineLocation(MachineLocation::VirtualFP); - SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); - Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); - - const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); - - if (CSI.size()) { - // Find the instruction past the last instruction that saves a callee-saved - // register to the stack. - for (unsigned i = 0; i < CSI.size(); ++i) - ++MBBI; - - // Iterate over list of callee-saved registers and emit .cfi_offset - // directives. - MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, - TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); - - for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), - E = CSI.end(); I != E; ++I) { - int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); - unsigned Reg = I->getReg(); - - // If Reg is a double precision register, emit two cfa_offsets, - // one for each of the paired single precision registers. - if (Mips::AFGR64RegClass.contains(Reg)) { - MachineLocation DstML0(MachineLocation::VirtualFP, Offset); - MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); - MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); - MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); - - if (!STI.isLittle()) - std::swap(SrcML0, SrcML1); - - Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); - Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); - } else { - // Reg is either in CPURegs or FGR32. - DstML = MachineLocation(MachineLocation::VirtualFP, Offset); - SrcML = MachineLocation(Reg); - Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); - } - } - } - - // if framepointer enabled, set it to point to the stack pointer. - if (hasFP(MF)) { - // Insert instruction "move $fp, $sp" at this location. - BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); - - // emit ".cfi_def_cfa_register $fp" - MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, - TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); - DstML = MachineLocation(FP); - SrcML = MachineLocation(MachineLocation::VirtualFP); - Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); - } -} - -void MipsFrameLowering::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - const MipsInstrInfo &TII = - *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); - DebugLoc dl = MBBI->getDebugLoc(); - unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; - unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; - unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; - unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; - unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; - - // if framepointer enabled, restore the stack pointer. - if (hasFP(MF)) { - // Find the first instruction that restores a callee-saved register. - MachineBasicBlock::iterator I = MBBI; - - for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) - --I; - - // Insert instruction "move $sp, $fp" at this location. - BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); - } - - // Get the number of bytes from FrameInfo - uint64_t StackSize = MFI->getStackSize(); - - if (!StackSize) - return; - - // Adjust stack. - if (isInt<16>(StackSize)) { // addi sp, sp, (-stacksize) - if (STI.inMips16Mode()) - // assumes stacksize multiple of 8 - BuildMI(MBB, MBBI, dl, - TII.get(Mips::RestoreRaF16)).addImm(StackSize); - else - BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(StackSize); - } - else { // Expand immediate that doesn't fit in 16-bit. - unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; - - MF.getInfo<MipsFunctionInfo>()->setEmitNOAT(); - Mips::loadImmediate(StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl, false, - 0); - BuildMI(MBB, MBBI, dl, TII.get(ADDu), SP).addReg(SP).addReg(ATReg); - } -} - -void MipsFrameLowering:: -processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS) const { - MachineRegisterInfo &MRI = MF.getRegInfo(); - unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; - - // FIXME: remove this code if register allocator can correctly mark - // $fp and $ra used or unused. - - // Mark $fp and $ra as used or unused. - if (hasFP(MF)) - MRI.setPhysRegUsed(FP); -} - -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. Do not add if the register is - // RA and return address is taken, because it has already been added in - // method MipsTargetLowering::LowerRETURNADDR. - // It's killed at the spill, unless the register is RA and return address - // is taken. - unsigned Reg = CSI[i].getReg(); - bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) - && MF->getFrameInfo()->isReturnAddressTaken(); - if (!IsRAAndRetAddrIsTaken) - EntryBlock->addLiveIn(Reg); - - // Insert the spill to the stack frame. - bool IsKill = !IsRAAndRetAddrIsTaken; - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, - CSI[i].getFrameIdx(), RC, TRI); - } - - return true; -} diff --git a/lib/Target/Mips/MipsFrameLowering.h b/lib/Target/Mips/MipsFrameLowering.h index 2cd8340b07..cf8401faec 100644 --- a/lib/Target/Mips/MipsFrameLowering.h +++ b/lib/Target/Mips/MipsFrameLowering.h @@ -31,20 +31,7 @@ public: STI(sti) { } - /// emitProlog/emitEpilog - These methods insert prolog and epilog code into - /// the function. - 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, - RegScavenger *RS) const; }; } // End llvm namespace diff --git a/lib/Target/Mips/MipsSEFrameLowering.cpp b/lib/Target/Mips/MipsSEFrameLowering.cpp new file mode 100644 index 0000000000..2ae06608c8 --- /dev/null +++ b/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -0,0 +1,225 @@ +//===-- MipsSEFrameLowering.cpp - Mips32/64 Frame Information -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains the Mips32/64 implementation of TargetFrameLowering class. +// +//===----------------------------------------------------------------------===// + +#include "MipsSEFrameLowering.h" +#include "MipsAnalyzeImmediate.h" +#include "MipsInstrInfo.h" +#include "MipsMachineFunction.h" +#include "MCTargetDesc/MipsBaseInfo.h" +#include "llvm/Function.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/CommandLine.h" + +using namespace llvm; + +void MipsSEFrameLowering::emitPrologue(MachineFunction &MF) const { + MachineBasicBlock &MBB = MF.front(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const MipsRegisterInfo *RegInfo = + static_cast<const MipsRegisterInfo*>(MF.getTarget().getRegisterInfo()); + const MipsInstrInfo &TII = + *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); + MachineBasicBlock::iterator MBBI = MBB.begin(); + DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; + unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; + unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; + unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; + unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; + + // First, compute final stack size. + uint64_t StackSize = MFI->getStackSize(); + + // No need to allocate space on the stack. + if (StackSize == 0 && !MFI->adjustsStack()) return; + + MachineModuleInfo &MMI = MF.getMMI(); + std::vector<MachineMove> &Moves = MMI.getFrameMoves(); + MachineLocation DstML, SrcML; + + // Adjust stack. + if (isInt<16>(-StackSize))// addi sp, sp, (-stacksize) + BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(-StackSize); + else { // Expand immediate that doesn't fit in 16-bit. + unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; + + MF.getInfo<MipsFunctionInfo>()->setEmitNOAT(); + Mips::loadImmediate(-StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl, false, + 0); + BuildMI(MBB, MBBI, dl, TII.get(ADDu), SP).addReg(SP).addReg(ATReg); + } + + // emit ".cfi_def_cfa_offset StackSize" + MCSymbol *AdjustSPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, + TII.get(TargetOpcode::PROLOG_LABEL)).addSym(AdjustSPLabel); + DstML = MachineLocation(MachineLocation::VirtualFP); + SrcML = MachineLocation(MachineLocation::VirtualFP, -StackSize); + Moves.push_back(MachineMove(AdjustSPLabel, DstML, SrcML)); + + const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); + + if (CSI.size()) { + // Find the instruction past the last instruction that saves a callee-saved + // register to the stack. + for (unsigned i = 0; i < CSI.size(); ++i) + ++MBBI; + + // Iterate over list of callee-saved registers and emit .cfi_offset + // directives. + MCSymbol *CSLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, + TII.get(TargetOpcode::PROLOG_LABEL)).addSym(CSLabel); + + for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), + E = CSI.end(); I != E; ++I) { + int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); + unsigned Reg = I->getReg(); + + // If Reg is a double precision register, emit two cfa_offsets, + // one for each of the paired single precision registers. + if (Mips::AFGR64RegClass.contains(Reg)) { + MachineLocation DstML0(MachineLocation::VirtualFP, Offset); + MachineLocation DstML1(MachineLocation::VirtualFP, Offset + 4); + MachineLocation SrcML0(RegInfo->getSubReg(Reg, Mips::sub_fpeven)); + MachineLocation SrcML1(RegInfo->getSubReg(Reg, Mips::sub_fpodd)); + + if (!STI.isLittle()) + std::swap(SrcML0, SrcML1); + + Moves.push_back(MachineMove(CSLabel, DstML0, SrcML0)); + Moves.push_back(MachineMove(CSLabel, DstML1, SrcML1)); + } else { + // Reg is either in CPURegs or FGR32. + DstML = MachineLocation(MachineLocation::VirtualFP, Offset); + SrcML = MachineLocation(Reg); + Moves.push_back(MachineMove(CSLabel, DstML, SrcML)); + } + } + } + + // if framepointer enabled, set it to point to the stack pointer. + if (hasFP(MF)) { + // Insert instruction "move $fp, $sp" at this location. + BuildMI(MBB, MBBI, dl, TII.get(ADDu), FP).addReg(SP).addReg(ZERO); + + // emit ".cfi_def_cfa_register $fp" + MCSymbol *SetFPLabel = MMI.getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, + TII.get(TargetOpcode::PROLOG_LABEL)).addSym(SetFPLabel); + DstML = MachineLocation(FP); + SrcML = MachineLocation(MachineLocation::VirtualFP); + Moves.push_back(MachineMove(SetFPLabel, DstML, SrcML)); + } +} + +void MipsSEFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + const MipsInstrInfo &TII = + *static_cast<const MipsInstrInfo*>(MF.getTarget().getInstrInfo()); + DebugLoc dl = MBBI->getDebugLoc(); + unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP; + unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; + unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO; + unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu; + unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu; + + // if framepointer enabled, restore the stack pointer. + if (hasFP(MF)) { + // Find the first instruction that restores a callee-saved register. + MachineBasicBlock::iterator I = MBBI; + + for (unsigned i = 0; i < MFI->getCalleeSavedInfo().size(); ++i) + --I; + + // Insert instruction "move $sp, $fp" at this location. + BuildMI(MBB, I, dl, TII.get(ADDu), SP).addReg(FP).addReg(ZERO); + } + + // Get the number of bytes from FrameInfo + uint64_t StackSize = MFI->getStackSize(); + + if (!StackSize) + return; + + // Adjust stack. + if (isInt<16>(StackSize)) // addi sp, sp, (-stacksize) + BuildMI(MBB, MBBI, dl, TII.get(ADDiu), SP).addReg(SP).addImm(StackSize); + else { // Expand immediate that doesn't fit in 16-bit. + unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT; + + MF.getInfo<MipsFunctionInfo>()->setEmitNOAT(); + Mips::loadImmediate(StackSize, STI.isABI_N64(), TII, MBB, MBBI, dl, false, + 0); + BuildMI(MBB, MBBI, dl, TII.get(ADDu), SP).addReg(SP).addReg(ATReg); + } +} + +bool MipsSEFrameLowering:: +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. Do not add if the register is + // RA and return address is taken, because it has already been added in + // method MipsTargetLowering::LowerRETURNADDR. + // It's killed at the spill, unless the register is RA and return address + // is taken. + unsigned Reg = CSI[i].getReg(); + bool IsRAAndRetAddrIsTaken = (Reg == Mips::RA || Reg == Mips::RA_64) + && MF->getFrameInfo()->isReturnAddressTaken(); + if (!IsRAAndRetAddrIsTaken) + EntryBlock->addLiveIn(Reg); + + // Insert the spill to the stack frame. + bool IsKill = !IsRAAndRetAddrIsTaken; + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.storeRegToStackSlot(*EntryBlock, MI, Reg, IsKill, + CSI[i].getFrameIdx(), RC, TRI); + } + + return true; +} + +bool +MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { + const MachineFrameInfo *MFI = MF.getFrameInfo(); + + // Reserve call frame if the size of the maximum call frame fits into 16-bit + // immediate field and there are no variable sized objects on the stack. + return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects(); +} + +void MipsSEFrameLowering:: +processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const { + MachineRegisterInfo &MRI = MF.getRegInfo(); + unsigned FP = STI.isABI_N64() ? Mips::FP_64 : Mips::FP; + + // Mark $fp as used if function has dedicated frame pointer. + if (hasFP(MF)) + MRI.setPhysRegUsed(FP); +} diff --git a/lib/Target/Mips/MipsSEFrameLowering.h b/lib/Target/Mips/MipsSEFrameLowering.h new file mode 100644 index 0000000000..6481a0ac86 --- /dev/null +++ b/lib/Target/Mips/MipsSEFrameLowering.h @@ -0,0 +1,44 @@ +//===-- MipsSEFrameLowering.h - Mips32/64 frame lowering --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +// +//===----------------------------------------------------------------------===// + +#ifndef MIPSSE_FRAMEINFO_H +#define MIPSSE_FRAMEINFO_H + +#include "MipsFrameLowering.h" + +namespace llvm { + +class MipsSEFrameLowering : public MipsFrameLowering { +public: + explicit MipsSEFrameLowering(const MipsSubtarget &STI) + : MipsFrameLowering(STI) {} + + /// emitProlog/emitEpilog - These methods insert prolog and epilog code into + /// the function. + 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 hasReservedCallFrame(const MachineFunction &MF) const; + + void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const; +}; + +} // End llvm namespace + +#endif diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index d16632453b..9480a77c74 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -12,9 +12,11 @@ //===----------------------------------------------------------------------===// #include "MipsTargetMachine.h" -#include "MipsSEInstrInfo.h" -#include "Mips16InstrInfo.h" #include "Mips.h" +#include "Mips16FrameLowering.h" +#include "Mips16InstrInfo.h" +#include "MipsSEFrameLowering.h" +#include "MipsSEInstrInfo.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/Passes.h" #include "llvm/Support/TargetRegistry.h" @@ -39,6 +41,18 @@ static const MipsInstrInfo *genInstrInfo(MipsTargetMachine &TM) { return II; } +static const MipsFrameLowering *genFrameLowering(MipsTargetMachine &TM, + const MipsSubtarget &ST) { + const MipsFrameLowering *FL; + + if (TM.getSubtargetImpl()->inMips16Mode()) + FL = new Mips16FrameLowering(ST); + else + FL = new MipsSEFrameLowering(ST); + + return FL; +} + // DataLayout --> Big-endian, 32-bit pointer/ABI/alignment // The stack is always 8 byte aligned // On function prologue, the stack is created by decrementing @@ -62,7 +76,7 @@ MipsTargetMachine(const Target &T, StringRef TT, "E-p:64:64:64-i8:8:32-i16:16:32-i64:64:64-f128:128:128-n32" : "E-p:32:32:32-i8:8:32-i16:16:32-i64:64:64-n32")), InstrInfo(genInstrInfo(*this)), - FrameLowering(Subtarget), + FrameLowering(genFrameLowering(*this, Subtarget)), TLInfo(*this), TSInfo(*this), JITInfo() { } diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index 958f13624e..21b49e673c 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -32,7 +32,7 @@ class MipsTargetMachine : public LLVMTargetMachine { MipsSubtarget Subtarget; const TargetData DataLayout; // Calculates type size & alignment const MipsInstrInfo *InstrInfo; - MipsFrameLowering FrameLowering; + const MipsFrameLowering *FrameLowering; MipsTargetLowering TLInfo; MipsSelectionDAGInfo TSInfo; MipsJITInfo JITInfo; @@ -49,7 +49,7 @@ public: virtual const MipsInstrInfo *getInstrInfo() const { return InstrInfo; } virtual const TargetFrameLowering *getFrameLowering() const - { return &FrameLowering; } + { return FrameLowering; } virtual const MipsSubtarget *getSubtargetImpl() const { return &Subtarget; } virtual const TargetData *getTargetData() const diff --git a/test/CodeGen/Mips/largeimmprinting.ll b/test/CodeGen/Mips/largeimmprinting.ll index 0272dea5a7..2e548790cd 100644 --- a/test/CodeGen/Mips/largeimmprinting.ll +++ b/test/CodeGen/Mips/largeimmprinting.ll @@ -6,7 +6,7 @@ define void @f() nounwind { entry: -; CHECK: lui $at, 65534 +; CHECK: lui $at, 65535 ; CHECK: addiu $at, $at, -16 ; CHECK: addu $sp, $sp, $at |