From cf099d11218cb6f6c5cce947d6738e347f07fb12 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 20 Feb 2011 12:57:14 +0000 Subject: Vendor import of llvm trunk r126079: http://llvm.org/svn/llvm-project/llvm/trunk@126079 --- lib/Target/XCore/AsmPrinter/CMakeLists.txt | 6 - lib/Target/XCore/AsmPrinter/Makefile | 16 - lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp | 280 ----------------- lib/Target/XCore/CMakeLists.txt | 5 +- lib/Target/XCore/Makefile | 2 +- lib/Target/XCore/TargetInfo/CMakeLists.txt | 2 +- lib/Target/XCore/XCoreAsmPrinter.cpp | 280 +++++++++++++++++ lib/Target/XCore/XCoreCallingConv.td | 3 + lib/Target/XCore/XCoreFrameInfo.cpp | 27 -- lib/Target/XCore/XCoreFrameInfo.h | 34 --- lib/Target/XCore/XCoreFrameLowering.cpp | 387 ++++++++++++++++++++++++ lib/Target/XCore/XCoreFrameLowering.h | 59 ++++ lib/Target/XCore/XCoreISelDAGToDAG.cpp | 21 +- lib/Target/XCore/XCoreISelLowering.cpp | 172 +++++++---- lib/Target/XCore/XCoreISelLowering.h | 1 + lib/Target/XCore/XCoreInstrInfo.cpp | 66 +--- lib/Target/XCore/XCoreInstrInfo.h | 9 - lib/Target/XCore/XCoreInstrInfo.td | 76 ++++- lib/Target/XCore/XCoreRegisterInfo.cpp | 284 ++--------------- lib/Target/XCore/XCoreRegisterInfo.h | 11 - lib/Target/XCore/XCoreRegisterInfo.td | 4 +- lib/Target/XCore/XCoreTargetMachine.cpp | 2 +- lib/Target/XCore/XCoreTargetMachine.h | 8 +- lib/Target/XCore/XCoreTargetObjectFile.cpp | 49 +-- 24 files changed, 979 insertions(+), 825 deletions(-) delete mode 100644 lib/Target/XCore/AsmPrinter/CMakeLists.txt delete mode 100644 lib/Target/XCore/AsmPrinter/Makefile delete mode 100644 lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp create mode 100644 lib/Target/XCore/XCoreAsmPrinter.cpp delete mode 100644 lib/Target/XCore/XCoreFrameInfo.cpp delete mode 100644 lib/Target/XCore/XCoreFrameInfo.h create mode 100644 lib/Target/XCore/XCoreFrameLowering.cpp create mode 100644 lib/Target/XCore/XCoreFrameLowering.h (limited to 'lib/Target/XCore') diff --git a/lib/Target/XCore/AsmPrinter/CMakeLists.txt b/lib/Target/XCore/AsmPrinter/CMakeLists.txt deleted file mode 100644 index 7c7c2f4ded04..000000000000 --- a/lib/Target/XCore/AsmPrinter/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) - -add_llvm_library(LLVMXCoreAsmPrinter - XCoreAsmPrinter.cpp - ) -add_dependencies(LLVMXCoreAsmPrinter XCoreCodeGenTable_gen) diff --git a/lib/Target/XCore/AsmPrinter/Makefile b/lib/Target/XCore/AsmPrinter/Makefile deleted file mode 100644 index 581f736b7431..000000000000 --- a/lib/Target/XCore/AsmPrinter/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -##===- lib/Target/XCore/AsmPrinter/Makefile ----------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../../.. -LIBRARYNAME = LLVMXCoreAsmPrinter - -# Hack: we need to include 'main' XCore target directory to grab private headers -CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp b/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp deleted file mode 100644 index 8f06dd32662f..000000000000 --- a/lib/Target/XCore/AsmPrinter/XCoreAsmPrinter.cpp +++ /dev/null @@ -1,280 +0,0 @@ -//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to the XAS-format XCore assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "asm-printer" -#include "XCore.h" -#include "XCoreInstrInfo.h" -#include "XCoreSubtarget.h" -#include "XCoreMCAsmInfo.h" -#include "XCoreTargetMachine.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/CodeGen/MachineJumpTableInfo.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include -#include -using namespace llvm; - -static cl::opt MaxThreads("xcore-max-threads", cl::Optional, - cl::desc("Maximum number of threads (for emulation thread-local storage)"), - cl::Hidden, - cl::value_desc("number"), - cl::init(8)); - -namespace { - class XCoreAsmPrinter : public AsmPrinter { - const XCoreSubtarget &Subtarget; - public: - explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget()){} - - virtual const char *getPassName() const { - return "XCore Assembly Printer"; - } - - void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O); - void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, - const std::string &directive = ".jmptable"); - void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) { - printInlineJT(MI, opNum, O, ".jmptable32"); - } - void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); - - void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); - virtual void EmitGlobalVariable(const GlobalVariable *GV); - - void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd. - static const char *getRegisterName(unsigned RegNo); - - void EmitFunctionEntryLabel(); - void EmitInstruction(const MachineInstr *MI); - void EmitFunctionBodyEnd(); - }; -} // end of anonymous namespace - -#include "XCoreGenAsmWriter.inc" - -void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) { - assert(((GV->hasExternalLinkage() || - GV->hasWeakLinkage()) || - GV->hasLinkOnceLinkage()) && "Unexpected linkage"); - if (const ArrayType *ATy = dyn_cast( - cast(GV->getType())->getElementType())) { - OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); - // FIXME: MCStreamerize. - OutStreamer.EmitRawText(StringRef(".globound")); - OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName())); - OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements())); - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { - // TODO Use COMDAT groups for LinkOnceLinkage - OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+ - ".globound"); - } - } -} - -void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { - // Check to see if this is a special global used by LLVM, if so, emit it. - if (!GV->hasInitializer() || - EmitSpecialLLVMGlobal(GV)) - return; - - const TargetData *TD = TM.getTargetData(); - OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); - - - MCSymbol *GVSym = Mang->getSymbol(GV); - Constant *C = GV->getInitializer(); - unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); - - // Mark the start of the global - OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," + - GVSym->getName()); - - switch (GV->getLinkage()) { - case GlobalValue::AppendingLinkage: - report_fatal_error("AppendingLinkage is not supported by this target!"); - case GlobalValue::LinkOnceAnyLinkage: - case GlobalValue::LinkOnceODRLinkage: - case GlobalValue::WeakAnyLinkage: - case GlobalValue::WeakODRLinkage: - case GlobalValue::ExternalLinkage: - emitArrayBound(GVSym, GV); - OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); - - // TODO Use COMDAT groups for LinkOnceLinkage - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) - OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); - // FALL THROUGH - case GlobalValue::InternalLinkage: - case GlobalValue::PrivateLinkage: - break; - case GlobalValue::DLLImportLinkage: - llvm_unreachable("DLLImport linkage is not supported by this target!"); - case GlobalValue::DLLExportLinkage: - llvm_unreachable("DLLExport linkage is not supported by this target!"); - default: - llvm_unreachable("Unknown linkage type!"); - } - - EmitAlignment(Align > 2 ? Align : 2, GV); - - unsigned Size = TD->getTypeAllocSize(C->getType()); - if (GV->isThreadLocal()) { - Size *= MaxThreads; - } - if (MAI->hasDotTypeDotSizeDirective()) { - OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); - OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," + - Twine(Size)); - } - OutStreamer.EmitLabel(GVSym); - - EmitGlobalConstant(C); - if (GV->isThreadLocal()) { - for (unsigned i = 1; i < MaxThreads; ++i) - EmitGlobalConstant(C); - } - // The ABI requires that unsigned scalar types smaller than 32 bits - // are padded to 32 bits. - if (Size < 4) - OutStreamer.EmitZeros(4 - Size, 0); - - // Mark the end of the global - OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data"); -} - -/// EmitFunctionBodyEnd - Targets can override this to emit stuff after -/// the last basic block in the function. -void XCoreAsmPrinter::EmitFunctionBodyEnd() { - // Emit function end directives - OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) + - ".function"); -} - -void XCoreAsmPrinter::EmitFunctionEntryLabel() { - // Mark the start of the function - OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) + - ".function," + CurrentFnSym->getName()); - OutStreamer.EmitLabel(CurrentFnSym); -} - -void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - printOperand(MI, opNum, O); - - if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0) - return; - - O << "+"; - printOperand(MI, opNum+1, O); -} - -void XCoreAsmPrinter:: -printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, - const std::string &directive) { - unsigned JTI = MI->getOperand(opNum).getIndex(); - const MachineFunction *MF = MI->getParent()->getParent(); - const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); - const std::vector &JT = MJTI->getJumpTables(); - const std::vector &JTBBs = JT[JTI].MBBs; - O << "\t" << directive << " "; - for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { - MachineBasicBlock *MBB = JTBBs[i]; - if (i > 0) - O << ","; - O << *MBB->getSymbol(); - } -} - -void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); - switch (MO.getType()) { - case MachineOperand::MO_Register: - O << getRegisterName(MO.getReg()); - break; - case MachineOperand::MO_Immediate: - O << MO.getImm(); - break; - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - break; - case MachineOperand::MO_GlobalAddress: - O << *Mang->getSymbol(MO.getGlobal()); - break; - case MachineOperand::MO_ExternalSymbol: - O << MO.getSymbolName(); - break; - case MachineOperand::MO_ConstantPoolIndex: - O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - case MachineOperand::MO_JumpTableIndex: - O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - case MachineOperand::MO_BlockAddress: - O << *GetBlockAddressSymbol(MO.getBlockAddress()); - break; - default: - llvm_unreachable("not implemented"); - } -} - -/// PrintAsmOperand - Print out an operand for an inline asm expression. -/// -bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant,const char *ExtraCode, - raw_ostream &O) { - printOperand(MI, OpNo, O); - return false; -} - -void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { - SmallString<128> Str; - raw_svector_ostream O(Str); - - // Check for mov mnemonic - if (MI->getOpcode() == XCore::ADD_2rus && !MI->getOperand(2).getImm()) - O << "\tmov " << getRegisterName(MI->getOperand(0).getReg()) << ", " - << getRegisterName(MI->getOperand(1).getReg()); - else - printInstruction(MI, O); - OutStreamer.EmitRawText(O.str()); -} - -// Force static initialization. -extern "C" void LLVMInitializeXCoreAsmPrinter() { - RegisterAsmPrinter X(TheXCoreTarget); -} diff --git a/lib/Target/XCore/CMakeLists.txt b/lib/Target/XCore/CMakeLists.txt index 38b35d7666c0..9093de691582 100644 --- a/lib/Target/XCore/CMakeLists.txt +++ b/lib/Target/XCore/CMakeLists.txt @@ -11,7 +11,8 @@ tablegen(XCoreGenCallingConv.inc -gen-callingconv) tablegen(XCoreGenSubtarget.inc -gen-subtarget) add_llvm_target(XCoreCodeGen - XCoreFrameInfo.cpp + XCoreAsmPrinter.cpp + XCoreFrameLowering.cpp XCoreInstrInfo.cpp XCoreISelDAGToDAG.cpp XCoreISelLowering.cpp @@ -22,3 +23,5 @@ add_llvm_target(XCoreCodeGen XCoreTargetObjectFile.cpp XCoreSelectionDAGInfo.cpp ) + +add_subdirectory(TargetInfo) diff --git a/lib/Target/XCore/Makefile b/lib/Target/XCore/Makefile index 1b709745041a..6c1ef886031b 100644 --- a/lib/Target/XCore/Makefile +++ b/lib/Target/XCore/Makefile @@ -18,7 +18,7 @@ BUILT_SOURCES = XCoreGenRegisterInfo.h.inc XCoreGenRegisterNames.inc \ XCoreGenDAGISel.inc XCoreGenCallingConv.inc \ XCoreGenSubtarget.inc -DIRS = AsmPrinter TargetInfo +DIRS = TargetInfo include $(LEVEL)/Makefile.common diff --git a/lib/Target/XCore/TargetInfo/CMakeLists.txt b/lib/Target/XCore/TargetInfo/CMakeLists.txt index 0a568de1624b..c147b8a66bc3 100644 --- a/lib/Target/XCore/TargetInfo/CMakeLists.txt +++ b/lib/Target/XCore/TargetInfo/CMakeLists.txt @@ -4,4 +4,4 @@ add_llvm_library(LLVMXCoreInfo XCoreTargetInfo.cpp ) -add_dependencies(LLVMXCoreInfo XCoreTable_gen) +add_dependencies(LLVMXCoreInfo XCoreCodeGenTable_gen) diff --git a/lib/Target/XCore/XCoreAsmPrinter.cpp b/lib/Target/XCore/XCoreAsmPrinter.cpp new file mode 100644 index 000000000000..8f06dd32662f --- /dev/null +++ b/lib/Target/XCore/XCoreAsmPrinter.cpp @@ -0,0 +1,280 @@ +//===-- XCoreAsmPrinter.cpp - XCore LLVM assembly writer ------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to the XAS-format XCore assembly language. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "XCore.h" +#include "XCoreInstrInfo.h" +#include "XCoreSubtarget.h" +#include "XCoreMCAsmInfo.h" +#include "XCoreTargetMachine.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineJumpTableInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include +#include +using namespace llvm; + +static cl::opt MaxThreads("xcore-max-threads", cl::Optional, + cl::desc("Maximum number of threads (for emulation thread-local storage)"), + cl::Hidden, + cl::value_desc("number"), + cl::init(8)); + +namespace { + class XCoreAsmPrinter : public AsmPrinter { + const XCoreSubtarget &Subtarget; + public: + explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget()){} + + virtual const char *getPassName() const { + return "XCore Assembly Printer"; + } + + void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O); + void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, + const std::string &directive = ".jmptable"); + void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) { + printInlineJT(MI, opNum, O, ".jmptable32"); + } + void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); + + void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV); + virtual void EmitGlobalVariable(const GlobalVariable *GV); + + void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd. + static const char *getRegisterName(unsigned RegNo); + + void EmitFunctionEntryLabel(); + void EmitInstruction(const MachineInstr *MI); + void EmitFunctionBodyEnd(); + }; +} // end of anonymous namespace + +#include "XCoreGenAsmWriter.inc" + +void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) { + assert(((GV->hasExternalLinkage() || + GV->hasWeakLinkage()) || + GV->hasLinkOnceLinkage()) && "Unexpected linkage"); + if (const ArrayType *ATy = dyn_cast( + cast(GV->getType())->getElementType())) { + OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global); + // FIXME: MCStreamerize. + OutStreamer.EmitRawText(StringRef(".globound")); + OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName())); + OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements())); + if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) { + // TODO Use COMDAT groups for LinkOnceLinkage + OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+ + ".globound"); + } + } +} + +void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { + // Check to see if this is a special global used by LLVM, if so, emit it. + if (!GV->hasInitializer() || + EmitSpecialLLVMGlobal(GV)) + return; + + const TargetData *TD = TM.getTargetData(); + OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(GV, Mang,TM)); + + + MCSymbol *GVSym = Mang->getSymbol(GV); + Constant *C = GV->getInitializer(); + unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType()); + + // Mark the start of the global + OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," + + GVSym->getName()); + + switch (GV->getLinkage()) { + case GlobalValue::AppendingLinkage: + report_fatal_error("AppendingLinkage is not supported by this target!"); + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: + case GlobalValue::ExternalLinkage: + emitArrayBound(GVSym, GV); + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); + + // TODO Use COMDAT groups for LinkOnceLinkage + if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); + // FALL THROUGH + case GlobalValue::InternalLinkage: + case GlobalValue::PrivateLinkage: + break; + case GlobalValue::DLLImportLinkage: + llvm_unreachable("DLLImport linkage is not supported by this target!"); + case GlobalValue::DLLExportLinkage: + llvm_unreachable("DLLExport linkage is not supported by this target!"); + default: + llvm_unreachable("Unknown linkage type!"); + } + + EmitAlignment(Align > 2 ? Align : 2, GV); + + unsigned Size = TD->getTypeAllocSize(C->getType()); + if (GV->isThreadLocal()) { + Size *= MaxThreads; + } + if (MAI->hasDotTypeDotSizeDirective()) { + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject); + OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," + + Twine(Size)); + } + OutStreamer.EmitLabel(GVSym); + + EmitGlobalConstant(C); + if (GV->isThreadLocal()) { + for (unsigned i = 1; i < MaxThreads; ++i) + EmitGlobalConstant(C); + } + // The ABI requires that unsigned scalar types smaller than 32 bits + // are padded to 32 bits. + if (Size < 4) + OutStreamer.EmitZeros(4 - Size, 0); + + // Mark the end of the global + OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data"); +} + +/// EmitFunctionBodyEnd - Targets can override this to emit stuff after +/// the last basic block in the function. +void XCoreAsmPrinter::EmitFunctionBodyEnd() { + // Emit function end directives + OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) + + ".function"); +} + +void XCoreAsmPrinter::EmitFunctionEntryLabel() { + // Mark the start of the function + OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) + + ".function," + CurrentFnSym->getName()); + OutStreamer.EmitLabel(CurrentFnSym); +} + +void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum, + raw_ostream &O) { + printOperand(MI, opNum, O); + + if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0) + return; + + O << "+"; + printOperand(MI, opNum+1, O); +} + +void XCoreAsmPrinter:: +printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O, + const std::string &directive) { + unsigned JTI = MI->getOperand(opNum).getIndex(); + const MachineFunction *MF = MI->getParent()->getParent(); + const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); + const std::vector &JT = MJTI->getJumpTables(); + const std::vector &JTBBs = JT[JTI].MBBs; + O << "\t" << directive << " "; + for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) { + MachineBasicBlock *MBB = JTBBs[i]; + if (i > 0) + O << ","; + O << *MBB->getSymbol(); + } +} + +void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(opNum); + switch (MO.getType()) { + case MachineOperand::MO_Register: + O << getRegisterName(MO.getReg()); + break; + case MachineOperand::MO_Immediate: + O << MO.getImm(); + break; + case MachineOperand::MO_MachineBasicBlock: + O << *MO.getMBB()->getSymbol(); + break; + case MachineOperand::MO_GlobalAddress: + O << *Mang->getSymbol(MO.getGlobal()); + break; + case MachineOperand::MO_ExternalSymbol: + O << MO.getSymbolName(); + break; + case MachineOperand::MO_ConstantPoolIndex: + O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() + << '_' << MO.getIndex(); + break; + case MachineOperand::MO_JumpTableIndex: + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << '_' << MO.getIndex(); + break; + case MachineOperand::MO_BlockAddress: + O << *GetBlockAddressSymbol(MO.getBlockAddress()); + break; + default: + llvm_unreachable("not implemented"); + } +} + +/// PrintAsmOperand - Print out an operand for an inline asm expression. +/// +bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant,const char *ExtraCode, + raw_ostream &O) { + printOperand(MI, OpNo, O); + return false; +} + +void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) { + SmallString<128> Str; + raw_svector_ostream O(Str); + + // Check for mov mnemonic + if (MI->getOpcode() == XCore::ADD_2rus && !MI->getOperand(2).getImm()) + O << "\tmov " << getRegisterName(MI->getOperand(0).getReg()) << ", " + << getRegisterName(MI->getOperand(1).getReg()); + else + printInstruction(MI, O); + OutStreamer.EmitRawText(O.str()); +} + +// Force static initialization. +extern "C" void LLVMInitializeXCoreAsmPrinter() { + RegisterAsmPrinter X(TheXCoreTarget); +} diff --git a/lib/Target/XCore/XCoreCallingConv.td b/lib/Target/XCore/XCoreCallingConv.td index 8107e329bd58..b20d71f49cfd 100644 --- a/lib/Target/XCore/XCoreCallingConv.td +++ b/lib/Target/XCore/XCoreCallingConv.td @@ -24,6 +24,9 @@ def CC_XCore : CallingConv<[ // Promote i8/i16 arguments to i32. CCIfType<[i8, i16], CCPromoteToType>, + // The 'nest' parameter, if any, is passed in R11. + CCIfNest>, + // The first 4 integer arguments are passed in integer registers. CCIfType<[i32], CCAssignToReg<[R0, R1, R2, R3]>>, diff --git a/lib/Target/XCore/XCoreFrameInfo.cpp b/lib/Target/XCore/XCoreFrameInfo.cpp deleted file mode 100644 index f50dc96c6ba9..000000000000 --- a/lib/Target/XCore/XCoreFrameInfo.cpp +++ /dev/null @@ -1,27 +0,0 @@ -//===-- XCoreFrameInfo.cpp - Frame info for XCore Target ---------*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains XCore frame information that doesn't fit anywhere else -// cleanly... -// -//===----------------------------------------------------------------------===// - -#include "XCore.h" -#include "XCoreFrameInfo.h" -using namespace llvm; - -//===----------------------------------------------------------------------===// -// XCoreFrameInfo: -//===----------------------------------------------------------------------===// - -XCoreFrameInfo::XCoreFrameInfo(const TargetMachine &tm): - TargetFrameInfo(TargetFrameInfo::StackGrowsDown, 4, 0) -{ - // Do nothing -} diff --git a/lib/Target/XCore/XCoreFrameInfo.h b/lib/Target/XCore/XCoreFrameInfo.h deleted file mode 100644 index 2c67577181ec..000000000000 --- a/lib/Target/XCore/XCoreFrameInfo.h +++ /dev/null @@ -1,34 +0,0 @@ -//===-- XCoreFrameInfo.h - Frame info for XCore Target -----------*- C++ -*-==// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains XCore frame information that doesn't fit anywhere else -// cleanly... -// -//===----------------------------------------------------------------------===// - -#ifndef XCOREFRAMEINFO_H -#define XCOREFRAMEINFO_H - -#include "llvm/Target/TargetFrameInfo.h" -#include "llvm/Target/TargetMachine.h" - -namespace llvm { - class XCoreFrameInfo: public TargetFrameInfo { - - public: - XCoreFrameInfo(const TargetMachine &tm); - - //! Stack slot size (4 bytes) - static int stackSlotSize() { - return 4; - } - }; -} - -#endif // XCOREFRAMEINFO_H diff --git a/lib/Target/XCore/XCoreFrameLowering.cpp b/lib/Target/XCore/XCoreFrameLowering.cpp new file mode 100644 index 000000000000..057822074e54 --- /dev/null +++ b/lib/Target/XCore/XCoreFrameLowering.cpp @@ -0,0 +1,387 @@ +//===-- XCoreFrameLowering.cpp - Frame info for XCore Target -----*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains XCore frame information that doesn't fit anywhere else +// cleanly... +// +//===----------------------------------------------------------------------===// + +#include "XCore.h" +#include "XCoreFrameLowering.h" +#include "XCoreInstrInfo.h" +#include "XCoreMachineFunctionInfo.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/CodeGen/RegisterScavenging.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +// helper functions. FIXME: Eliminate. +static inline bool isImmUs(unsigned val) { + return val <= 11; +} + +static inline bool isImmU6(unsigned val) { + return val < (1 << 6); +} + +static inline bool isImmU16(unsigned val) { + return val < (1 << 16); +} + +static void loadFromStack(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned DstReg, int Offset, DebugLoc dl, + const TargetInstrInfo &TII) { + assert(Offset%4 == 0 && "Misaligned stack offset"); + Offset/=4; + bool isU6 = isImmU6(Offset); + if (!isU6 && !isImmU16(Offset)) + report_fatal_error("loadFromStack offset too big " + Twine(Offset)); + int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; + BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) + .addImm(Offset); +} + + +static void storeToStack(MachineBasicBlock &MBB, + MachineBasicBlock::iterator I, + unsigned SrcReg, int Offset, DebugLoc dl, + const TargetInstrInfo &TII) { + assert(Offset%4 == 0 && "Misaligned stack offset"); + Offset/=4; + bool isU6 = isImmU6(Offset); + if (!isU6 && !isImmU16(Offset)) + report_fatal_error("storeToStack offset too big " + Twine(Offset)); + int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; + BuildMI(MBB, I, dl, TII.get(Opcode)) + .addReg(SrcReg) + .addImm(Offset); +} + + +//===----------------------------------------------------------------------===// +// XCoreFrameLowering: +//===----------------------------------------------------------------------===// + +XCoreFrameLowering::XCoreFrameLowering(const XCoreSubtarget &sti) + : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, 4, 0), + STI(sti) { + // Do nothing +} + +bool XCoreFrameLowering::hasFP(const MachineFunction &MF) const { + return DisableFramePointerElim(MF) || MF.getFrameInfo()->hasVarSizedObjects(); +} + +void XCoreFrameLowering::emitPrologue(MachineFunction &MF) const { + MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB + MachineBasicBlock::iterator MBBI = MBB.begin(); + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineModuleInfo *MMI = &MF.getMMI(); + const XCoreRegisterInfo *RegInfo = + static_cast(MF.getTarget().getRegisterInfo()); + const XCoreInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + XCoreFunctionInfo *XFI = MF.getInfo(); + DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); + + bool FP = hasFP(MF); + bool Nested = MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::Nest); + + if (Nested) { + loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII); + } + + // Work out frame sizes. + int FrameSize = MFI->getStackSize(); + assert(FrameSize%4 == 0 && "Misaligned frame size"); + FrameSize/=4; + + bool isU6 = isImmU6(FrameSize); + + if (!isU6 && !isImmU16(FrameSize)) { + // FIXME could emit multiple instructions. + report_fatal_error("emitPrologue Frame size too big: " + Twine(FrameSize)); + } + bool emitFrameMoves = RegInfo->needsFrameMoves(MF); + + // Do we need to allocate space on the stack? + if (FrameSize) { + bool saveLR = XFI->getUsesLR(); + bool LRSavedOnEntry = false; + int Opcode; + if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { + Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; + MBB.addLiveIn(XCore::LR); + saveLR = false; + LRSavedOnEntry = true; + } else { + Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; + } + BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + + if (emitFrameMoves) { + std::vector &Moves = MMI->getFrameMoves(); + + // Show update of SP. + MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); + + MachineLocation SPDst(MachineLocation::VirtualFP); + MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); + Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); + + if (LRSavedOnEntry) { + MachineLocation CSDst(MachineLocation::VirtualFP, 0); + MachineLocation CSSrc(XCore::LR); + Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); + } + } + if (saveLR) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl, TII); + MBB.addLiveIn(XCore::LR); + + if (emitFrameMoves) { + MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); + MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); + MachineLocation CSSrc(XCore::LR); + MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); + } + } + } + + if (FP) { + // Save R10 to the stack. + int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); + storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl, TII); + // R10 is live-in. It is killed at the spill. + MBB.addLiveIn(XCore::R10); + if (emitFrameMoves) { + MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label); + MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); + MachineLocation CSSrc(XCore::R10); + MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc)); + } + // Set the FP from the SP. + unsigned FramePtr = XCore::R10; + BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) + .addImm(0); + if (emitFrameMoves) { + // Show FP is now valid. + MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); + BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); + MachineLocation SPDst(FramePtr); + MachineLocation SPSrc(MachineLocation::VirtualFP); + MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc)); + } + } + + if (emitFrameMoves) { + // Frame moves for callee saved. + std::vector &Moves = MMI->getFrameMoves(); + std::vector >&SpillLabels = + XFI->getSpillLabels(); + for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { + MCSymbol *SpillLabel = SpillLabels[I].first; + CalleeSavedInfo &CSI = SpillLabels[I].second; + int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); + unsigned Reg = CSI.getReg(); + MachineLocation CSDst(MachineLocation::VirtualFP, Offset); + MachineLocation CSSrc(Reg); + Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); + } + } +} + +void XCoreFrameLowering::emitEpilogue(MachineFunction &MF, + MachineBasicBlock &MBB) const { + MachineFrameInfo *MFI = MF.getFrameInfo(); + MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); + const XCoreInstrInfo &TII = + *static_cast(MF.getTarget().getInstrInfo()); + DebugLoc dl = MBBI->getDebugLoc(); + + bool FP = hasFP(MF); + if (FP) { + // Restore the stack pointer. + unsigned FramePtr = XCore::R10; + BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) + .addReg(FramePtr); + } + + // Work out frame sizes. + int FrameSize = MFI->getStackSize(); + + assert(FrameSize%4 == 0 && "Misaligned frame size"); + + FrameSize/=4; + + bool isU6 = isImmU6(FrameSize); + + if (!isU6 && !isImmU16(FrameSize)) { + // FIXME could emit multiple instructions. + report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); + } + + if (FrameSize) { + XCoreFunctionInfo *XFI = MF.getInfo(); + + if (FP) { + // Restore R10 + int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); + FPSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl, TII); + } + bool restoreLR = XFI->getUsesLR(); + if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { + int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); + LRSpillOffset += FrameSize*4; + loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl, TII); + restoreLR = false; + } + if (restoreLR) { + // Fold prologue into return instruction + assert(MBBI->getOpcode() == XCore::RETSP_u6 + || MBBI->getOpcode() == XCore::RETSP_lu6); + int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; + BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); + MBB.erase(MBBI); + } else { + int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; + BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); + } + } +} + +void XCoreFrameLowering::getInitialFrameState(std::vector &Moves) + const { + // Initial state of the frame pointer is SP. + MachineLocation Dst(MachineLocation::VirtualFP); + MachineLocation Src(XCore::SP, 0); + Moves.push_back(MachineMove(0, Dst, Src)); +} + +bool XCoreFrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI, + const TargetRegisterInfo *TRI) const { + if (CSI.empty()) + return true; + + MachineFunction *MF = MBB.getParent(); + const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); + + XCoreFunctionInfo *XFI = MF->getInfo(); + bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); + + DebugLoc DL; + if (MI != MBB.end()) DL = MI->getDebugLoc(); + + for (std::vector::const_iterator it = CSI.begin(); + it != CSI.end(); ++it) { + // Add the callee-saved register as live-in. It's killed at the spill. + MBB.addLiveIn(it->getReg()); + + unsigned Reg = it->getReg(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.storeRegToStackSlot(MBB, MI, Reg, true, + it->getFrameIdx(), RC, TRI); + if (emitFrameMoves) { + MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol(); + BuildMI(MBB, MI, DL, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLabel); + XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it)); + } + } + return true; +} + +bool XCoreFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI, + const TargetRegisterInfo *TRI) const{ + MachineFunction *MF = MBB.getParent(); + const TargetInstrInfo &TII = *MF->getTarget().getInstrInfo(); + + bool AtStart = MI == MBB.begin(); + MachineBasicBlock::iterator BeforeI = MI; + if (!AtStart) + --BeforeI; + for (std::vector::const_iterator it = CSI.begin(); + it != CSI.end(); ++it) { + unsigned Reg = it->getReg(); + const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); + TII.loadRegFromStackSlot(MBB, MI, it->getReg(), it->getFrameIdx(), + RC, TRI); + assert(MI != MBB.begin() && + "loadRegFromStackSlot didn't insert any code!"); + // Insert in reverse order. loadRegFromStackSlot can insert multiple + // instructions. + if (AtStart) + MI = MBB.begin(); + else { + MI = BeforeI; + ++MI; + } + } + return true; +} + +void +XCoreFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const { + MachineFrameInfo *MFI = MF.getFrameInfo(); + const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo(); + bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); + const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; + XCoreFunctionInfo *XFI = MF.getInfo(); + if (LRUsed) { + MF.getRegInfo().setPhysRegUnused(XCore::LR); + + bool isVarArg = MF.getFunction()->isVarArg(); + int FrameIdx; + if (! isVarArg) { + // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. + FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true); + } else { + FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), + false); + } + XFI->setUsesLR(FrameIdx); + XFI->setLRSpillSlot(FrameIdx); + } + if (RegInfo->requiresRegisterScavenging(MF)) { + // Reserve a slot close to SP or frame pointer. + RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), + RC->getAlignment(), + false)); + } + if (hasFP(MF)) { + // A callee save register is used to hold the FP. + // This needs saving / restoring in the epilogue / prologue. + XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), + RC->getAlignment(), + false)); + } +} + +void XCoreFrameLowering:: +processFunctionBeforeFrameFinalized(MachineFunction &MF) const { + +} diff --git a/lib/Target/XCore/XCoreFrameLowering.h b/lib/Target/XCore/XCoreFrameLowering.h new file mode 100644 index 000000000000..7da19f0deb1b --- /dev/null +++ b/lib/Target/XCore/XCoreFrameLowering.h @@ -0,0 +1,59 @@ +//===-- XCoreFrameLowering.h - Frame info for XCore Target -------*- C++ -*-==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains XCore frame information that doesn't fit anywhere else +// cleanly... +// +//===----------------------------------------------------------------------===// + +#ifndef XCOREFRAMEINFO_H +#define XCOREFRAMEINFO_H + +#include "llvm/Target/TargetFrameLowering.h" +#include "llvm/Target/TargetMachine.h" + +namespace llvm { + class XCoreSubtarget; + + class XCoreFrameLowering: public TargetFrameLowering { + const XCoreSubtarget &STI; + public: + XCoreFrameLowering(const XCoreSubtarget &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 &CSI, + const TargetRegisterInfo *TRI) const; + bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + const std::vector &CSI, + const TargetRegisterInfo *TRI) const; + + bool hasFP(const MachineFunction &MF) const; + + void getInitialFrameState(std::vector &Moves) const; + + void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS = NULL) const; + + void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; + + //! Stack slot size (4 bytes) + static int stackSlotSize() { + return 4; + } + }; +} + +#endif // XCOREFRAMEINFO_H diff --git a/lib/Target/XCore/XCoreISelDAGToDAG.cpp b/lib/Target/XCore/XCoreISelDAGToDAG.cpp index 755ece7e9aba..fc8a07aad73b 100644 --- a/lib/Target/XCore/XCoreISelDAGToDAG.cpp +++ b/lib/Target/XCore/XCoreISelDAGToDAG.cpp @@ -68,12 +68,9 @@ namespace { } // Complex Pattern Selectors. - bool SelectADDRspii(SDNode *Op, SDValue Addr, SDValue &Base, - SDValue &Offset); - bool SelectADDRdpii(SDNode *Op, SDValue Addr, SDValue &Base, - SDValue &Offset); - bool SelectADDRcpii(SDNode *Op, SDValue Addr, SDValue &Base, - SDValue &Offset); + bool SelectADDRspii(SDValue Addr, SDValue &Base, SDValue &Offset); + bool SelectADDRdpii(SDValue Addr, SDValue &Base, SDValue &Offset); + bool SelectADDRcpii(SDValue Addr, SDValue &Base, SDValue &Offset); virtual const char *getPassName() const { return "XCore DAG->DAG Pattern Instruction Selection"; @@ -91,8 +88,8 @@ FunctionPass *llvm::createXCoreISelDag(XCoreTargetMachine &TM) { return new XCoreDAGToDAGISel(TM); } -bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr, - SDValue &Base, SDValue &Offset) { +bool XCoreDAGToDAGISel::SelectADDRspii(SDValue Addr, SDValue &Base, + SDValue &Offset) { FrameIndexSDNode *FIN = 0; if ((FIN = dyn_cast(Addr))) { Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); @@ -113,8 +110,8 @@ bool XCoreDAGToDAGISel::SelectADDRspii(SDNode *Op, SDValue Addr, return false; } -bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr, - SDValue &Base, SDValue &Offset) { +bool XCoreDAGToDAGISel::SelectADDRdpii(SDValue Addr, SDValue &Base, + SDValue &Offset) { if (Addr.getOpcode() == XCoreISD::DPRelativeWrapper) { Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(0, MVT::i32); @@ -134,8 +131,8 @@ bool XCoreDAGToDAGISel::SelectADDRdpii(SDNode *Op, SDValue Addr, return false; } -bool XCoreDAGToDAGISel::SelectADDRcpii(SDNode *Op, SDValue Addr, - SDValue &Base, SDValue &Offset) { +bool XCoreDAGToDAGISel::SelectADDRcpii(SDValue Addr, SDValue &Base, + SDValue &Offset) { if (Addr.getOpcode() == XCoreISD::CPRelativeWrapper) { Base = Addr.getOperand(0); Offset = CurDAG->getTargetConstant(0, MVT::i32); diff --git a/lib/Target/XCore/XCoreISelLowering.cpp b/lib/Target/XCore/XCoreISelLowering.cpp index abe7b2fd42be..828d6f92caf4 100644 --- a/lib/Target/XCore/XCoreISelLowering.cpp +++ b/lib/Target/XCore/XCoreISelLowering.cpp @@ -148,9 +148,13 @@ XCoreTargetLowering::XCoreTargetLowering(XCoreTargetMachine &XTM) setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); - - maxStoresPerMemset = 4; - maxStoresPerMemmove = maxStoresPerMemcpy = 2; + + // TRAMPOLINE is custom lowered. + setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom); + + maxStoresPerMemset = maxStoresPerMemsetOptSize = 4; + maxStoresPerMemmove = maxStoresPerMemmoveOptSize + = maxStoresPerMemcpy = maxStoresPerMemcpyOptSize = 2; // We have target-specific dag combine patterns for the following nodes: setTargetDAGCombine(ISD::STORE); @@ -177,6 +181,7 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::ADD: case ISD::SUB: return ExpandADDSUB(Op.getNode(), DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + case ISD::TRAMPOLINE: return LowerTRAMPOLINE(Op, DAG); default: llvm_unreachable("unimplemented operand"); return SDValue(); @@ -392,24 +397,23 @@ IsWordAlignedBasePlusConstantOffset(SDValue Addr, SDValue &AlignedBase, } SDValue XCoreTargetLowering:: -LowerLOAD(SDValue Op, SelectionDAG &DAG) const -{ +LowerLOAD(SDValue Op, SelectionDAG &DAG) const { LoadSDNode *LD = cast(Op); assert(LD->getExtensionType() == ISD::NON_EXTLOAD && "Unexpected extension type"); assert(LD->getMemoryVT() == MVT::i32 && "Unexpected load EVT"); - if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { + if (allowsUnalignedMemoryAccesses(LD->getMemoryVT())) return SDValue(); - } + unsigned ABIAlignment = getTargetData()-> getABITypeAlignment(LD->getMemoryVT().getTypeForEVT(*DAG.getContext())); // Leave aligned load alone. - if (LD->getAlignment() >= ABIAlignment) { + if (LD->getAlignment() >= ABIAlignment) return SDValue(); - } + SDValue Chain = LD->getChain(); SDValue BasePtr = LD->getBasePtr(); - DebugLoc dl = Op.getDebugLoc(); + DebugLoc DL = Op.getDebugLoc(); SDValue Base; int64_t Offset; @@ -419,10 +423,8 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const // We've managed to infer better alignment information than the load // already has. Use an aligned load. // - // FIXME: No new alignment information is actually passed here. - // Should the offset really be 4? - // - return DAG.getLoad(getPointerTy(), dl, Chain, BasePtr, NULL, 4, + return DAG.getLoad(getPointerTy(), DL, Chain, BasePtr, + MachinePointerInfo(), false, false, 0); } // Lower to @@ -436,40 +438,40 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const SDValue LowShift = DAG.getConstant((Offset & 0x3) * 8, MVT::i32); SDValue HighShift = DAG.getConstant(32 - (Offset & 0x3) * 8, MVT::i32); - SDValue LowAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, LowOffset); - SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, Base, HighOffset); + SDValue LowAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, LowOffset); + SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, Base, HighOffset); - SDValue Low = DAG.getLoad(getPointerTy(), dl, Chain, - LowAddr, NULL, 4, false, false, 0); - SDValue High = DAG.getLoad(getPointerTy(), dl, Chain, - HighAddr, NULL, 4, false, false, 0); - SDValue LowShifted = DAG.getNode(ISD::SRL, dl, MVT::i32, Low, LowShift); - SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, HighShift); - SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, LowShifted, HighShifted); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), + SDValue Low = DAG.getLoad(getPointerTy(), DL, Chain, + LowAddr, MachinePointerInfo(), false, false, 0); + SDValue High = DAG.getLoad(getPointerTy(), DL, Chain, + HighAddr, MachinePointerInfo(), false, false, 0); + SDValue LowShifted = DAG.getNode(ISD::SRL, DL, MVT::i32, Low, LowShift); + SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, HighShift); + SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, LowShifted, HighShifted); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), High.getValue(1)); SDValue Ops[] = { Result, Chain }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, 2, DL); } if (LD->getAlignment() == 2) { - int SVOffset = LD->getSrcValueOffset(); - SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, MVT::i32, dl, Chain, - BasePtr, LD->getSrcValue(), SVOffset, MVT::i16, + SDValue Low = DAG.getExtLoad(ISD::ZEXTLOAD, DL, MVT::i32, Chain, + BasePtr, LD->getPointerInfo(), MVT::i16, LD->isVolatile(), LD->isNonTemporal(), 2); - SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, + SDValue HighAddr = DAG.getNode(ISD::ADD, DL, MVT::i32, BasePtr, DAG.getConstant(2, MVT::i32)); - SDValue High = DAG.getExtLoad(ISD::EXTLOAD, MVT::i32, dl, Chain, - HighAddr, LD->getSrcValue(), SVOffset + 2, + SDValue High = DAG.getExtLoad(ISD::EXTLOAD, DL, MVT::i32, Chain, + HighAddr, + LD->getPointerInfo().getWithOffset(2), MVT::i16, LD->isVolatile(), LD->isNonTemporal(), 2); - SDValue HighShifted = DAG.getNode(ISD::SHL, dl, MVT::i32, High, + SDValue HighShifted = DAG.getNode(ISD::SHL, DL, MVT::i32, High, DAG.getConstant(16, MVT::i32)); - SDValue Result = DAG.getNode(ISD::OR, dl, MVT::i32, Low, HighShifted); - Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Low.getValue(1), + SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Low, HighShifted); + Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Low.getValue(1), High.getValue(1)); SDValue Ops[] = { Result, Chain }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, 2, DL); } // Lower to a call to __misaligned_load(BasePtr). @@ -486,12 +488,12 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG) const false, false, 0, CallingConv::C, false, /*isReturnValueUsed=*/true, DAG.getExternalSymbol("__misaligned_load", getPointerTy()), - Args, DAG, dl); + Args, DAG, DL); SDValue Ops[] = { CallResult.first, CallResult.second }; - return DAG.getMergeValues(Ops, 2, dl); + return DAG.getMergeValues(Ops, 2, DL); } SDValue XCoreTargetLowering:: @@ -515,18 +517,17 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG) const DebugLoc dl = Op.getDebugLoc(); if (ST->getAlignment() == 2) { - int SVOffset = ST->getSrcValueOffset(); SDValue Low = Value; SDValue High = DAG.getNode(ISD::SRL, dl, MVT::i32, Value, DAG.getConstant(16, MVT::i32)); SDValue StoreLow = DAG.getTruncStore(Chain, dl, Low, BasePtr, - ST->getSrcValue(), SVOffset, MVT::i16, + ST->getPointerInfo(), MVT::i16, ST->isVolatile(), ST->isNonTemporal(), 2); SDValue HighAddr = DAG.getNode(ISD::ADD, dl, MVT::i32, BasePtr, DAG.getConstant(2, MVT::i32)); SDValue StoreHigh = DAG.getTruncStore(Chain, dl, High, HighAddr, - ST->getSrcValue(), SVOffset + 2, + ST->getPointerInfo().getWithOffset(2), MVT::i16, ST->isVolatile(), ST->isNonTemporal(), 2); return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, StoreLow, StoreHigh); @@ -757,16 +758,18 @@ LowerVAARG(SDValue Op, SelectionDAG &DAG) const const Value *V = cast(Node->getOperand(2))->getValue(); EVT VT = Node->getValueType(0); SDValue VAList = DAG.getLoad(getPointerTy(), dl, Node->getOperand(0), - Node->getOperand(1), V, 0, false, false, 0); + Node->getOperand(1), MachinePointerInfo(V), + false, false, 0); // Increment the pointer, VAList, to the next vararg SDValue Tmp3 = DAG.getNode(ISD::ADD, dl, getPointerTy(), VAList, DAG.getConstant(VT.getSizeInBits(), getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), V, 0, - false, false, 0); + Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Node->getOperand(1), + MachinePointerInfo(V), false, false, 0); // Load the actual argument out of the pointer VAList - return DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0, false, false, 0); + return DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), + false, false, 0); } SDValue XCoreTargetLowering:: @@ -778,9 +781,8 @@ LowerVASTART(SDValue Op, SelectionDAG &DAG) const MachineFunction &MF = DAG.getMachineFunction(); XCoreFunctionInfo *XFI = MF.getInfo(); SDValue Addr = DAG.getFrameIndex(XFI->getVarArgsFrameIndex(), MVT::i32); - const Value *SV = cast(Op.getOperand(2))->getValue(); - return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), SV, 0, - false, false, 0); + return DAG.getStore(Op.getOperand(0), dl, Addr, Op.getOperand(1), + MachinePointerInfo(), false, false, 0); } SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, @@ -796,6 +798,64 @@ SDValue XCoreTargetLowering::LowerFRAMEADDR(SDValue Op, RegInfo->getFrameRegister(MF), MVT::i32); } +SDValue XCoreTargetLowering:: +LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) const { + SDValue Chain = Op.getOperand(0); + SDValue Trmp = Op.getOperand(1); // trampoline + SDValue FPtr = Op.getOperand(2); // nested function + SDValue Nest = Op.getOperand(3); // 'nest' parameter value + + const Value *TrmpAddr = cast(Op.getOperand(4))->getValue(); + + // .align 4 + // LDAPF_u10 r11, nest + // LDW_2rus r11, r11[0] + // STWSP_ru6 r11, sp[0] + // LDAPF_u10 r11, fptr + // LDW_2rus r11, r11[0] + // BAU_1r r11 + // nest: + // .word nest + // fptr: + // .word fptr + SDValue OutChains[5]; + + SDValue Addr = Trmp; + + DebugLoc dl = Op.getDebugLoc(); + OutChains[0] = DAG.getStore(Chain, dl, DAG.getConstant(0x0a3cd805, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr), false, false, + 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(4, MVT::i32)); + OutChains[1] = DAG.getStore(Chain, dl, DAG.getConstant(0xd80456c0, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr, 4), false, + false, 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(8, MVT::i32)); + OutChains[2] = DAG.getStore(Chain, dl, DAG.getConstant(0x27fb0a3c, MVT::i32), + Addr, MachinePointerInfo(TrmpAddr, 8), false, + false, 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(12, MVT::i32)); + OutChains[3] = DAG.getStore(Chain, dl, Nest, Addr, + MachinePointerInfo(TrmpAddr, 12), false, false, + 0); + + Addr = DAG.getNode(ISD::ADD, dl, MVT::i32, Trmp, + DAG.getConstant(16, MVT::i32)); + OutChains[4] = DAG.getStore(Chain, dl, FPtr, Addr, + MachinePointerInfo(TrmpAddr, 16), false, false, + 0); + + SDValue Ops[] = + { Trmp, DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains, 5) }; + return DAG.getMergeValues(Ops, 2, dl); +} + //===----------------------------------------------------------------------===// // Calling Convention Implementation //===----------------------------------------------------------------------===// @@ -929,7 +989,7 @@ XCoreTargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee, // = Chain, Callee, Reg#1, Reg#2, ... // // Returns a chain & a flag for retval copy to use. - SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); + SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SmallVector Ops; Ops.push_back(Chain); Ops.push_back(Callee); @@ -1035,7 +1095,7 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, CCInfo.AnalyzeFormalArguments(Ins, CC_XCore); - unsigned StackSlotSize = XCoreFrameInfo::stackSlotSize(); + unsigned StackSlotSize = XCoreFrameLowering::stackSlotSize(); unsigned LRSaveSize = StackSlotSize; @@ -1068,7 +1128,7 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, unsigned ObjSize = VA.getLocVT().getSizeInBits()/8; if (ObjSize > StackSlotSize) { errs() << "LowerFormalArguments Unhandled argument type: " - << (unsigned)VA.getLocVT().getSimpleVT().SimpleTy + << EVT(VA.getLocVT()).getEVTString() << "\n"; } // Create the frame index object for this incoming parameter... @@ -1079,7 +1139,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i32); - InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, NULL, 0, + InVals.push_back(DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, + MachinePointerInfo::getFixedStack(FI), false, false, 0)); } } @@ -1111,8 +1172,8 @@ XCoreTargetLowering::LowerCCCArguments(SDValue Chain, RegInfo.addLiveIn(ArgRegs[i], VReg); SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32); // Move argument from virt reg -> stack - SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, NULL, 0, - false, false, 0); + SDValue Store = DAG.getStore(Val.getValue(1), dl, Val, FIN, + MachinePointerInfo(), false, false, 0); MemOps.push_back(Store); } if (!MemOps.empty()) @@ -1443,9 +1504,8 @@ SDValue XCoreTargetLowering::PerformDAGCombine(SDNode *N, return DAG.getMemmove(Chain, dl, ST->getBasePtr(), LD->getBasePtr(), DAG.getConstant(StoreBits/8, MVT::i32), - Alignment, false, ST->getSrcValue(), - ST->getSrcValueOffset(), LD->getSrcValue(), - LD->getSrcValueOffset()); + Alignment, false, ST->getPointerInfo(), + LD->getPointerInfo()); } } break; diff --git a/lib/Target/XCore/XCoreISelLowering.h b/lib/Target/XCore/XCoreISelLowering.h index febc198f4faf..7e5dd2e8e512 100644 --- a/lib/Target/XCore/XCoreISelLowering.h +++ b/lib/Target/XCore/XCoreISelLowering.h @@ -147,6 +147,7 @@ namespace llvm { SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; + SDValue LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; // Inline asm support std::vector diff --git a/lib/Target/XCore/XCoreInstrInfo.cpp b/lib/Target/XCore/XCoreInstrInfo.cpp index ad00046af17d..9cb6a7d17b5e 100644 --- a/lib/Target/XCore/XCoreInstrInfo.cpp +++ b/lib/Target/XCore/XCoreInstrInfo.cpp @@ -384,74 +384,10 @@ void XCoreInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, .addImm(0); } -bool XCoreInstrInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const { - if (CSI.empty()) { - return true; - } - MachineFunction *MF = MBB.getParent(); - XCoreFunctionInfo *XFI = MF->getInfo(); - - bool emitFrameMoves = XCoreRegisterInfo::needsFrameMoves(*MF); - - DebugLoc DL; - if (MI != MBB.end()) DL = MI->getDebugLoc(); - - for (std::vector::const_iterator it = CSI.begin(); - it != CSI.end(); ++it) { - // Add the callee-saved register as live-in. It's killed at the spill. - MBB.addLiveIn(it->getReg()); - - unsigned Reg = it->getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - storeRegToStackSlot(MBB, MI, Reg, true, - it->getFrameIdx(), RC, &RI); - if (emitFrameMoves) { - MCSymbol *SaveLabel = MF->getContext().CreateTempSymbol(); - BuildMI(MBB, MI, DL, get(XCore::PROLOG_LABEL)).addSym(SaveLabel); - XFI->getSpillLabels().push_back(std::make_pair(SaveLabel, *it)); - } - } - return true; -} - -bool XCoreInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const -{ - bool AtStart = MI == MBB.begin(); - MachineBasicBlock::iterator BeforeI = MI; - if (!AtStart) - --BeforeI; - for (std::vector::const_iterator it = CSI.begin(); - it != CSI.end(); ++it) { - unsigned Reg = it->getReg(); - const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); - loadRegFromStackSlot(MBB, MI, it->getReg(), - it->getFrameIdx(), - RC, &RI); - assert(MI != MBB.begin() && - "loadRegFromStackSlot didn't insert any code!"); - // Insert in reverse order. loadRegFromStackSlot can insert multiple - // instructions. - if (AtStart) - MI = MBB.begin(); - else { - MI = BeforeI; - ++MI; - } - } - return true; -} - /// ReverseBranchCondition - Return the inverse opcode of the /// specified Branch instruction. bool XCoreInstrInfo:: -ReverseBranchCondition(SmallVectorImpl &Cond) const -{ +ReverseBranchCondition(SmallVectorImpl &Cond) const { assert((Cond.size() == 2) && "Invalid XCore branch condition!"); Cond[0].setImm(GetOppositeBranchCondition((XCore::CondCode)Cond[0].getImm())); diff --git a/lib/Target/XCore/XCoreInstrInfo.h b/lib/Target/XCore/XCoreInstrInfo.h index d2b116eef0d8..977fe8dd550a 100644 --- a/lib/Target/XCore/XCoreInstrInfo.h +++ b/lib/Target/XCore/XCoreInstrInfo.h @@ -75,15 +75,6 @@ public: const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const; - virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; - - virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - const std::vector &CSI, - const TargetRegisterInfo *TRI) const; virtual bool ReverseBranchCondition( SmallVectorImpl &Cond) const; diff --git a/lib/Target/XCore/XCoreInstrInfo.td b/lib/Target/XCore/XCoreInstrInfo.td index 6b3b39ba1d49..38cc734ce7c3 100644 --- a/lib/Target/XCore/XCoreInstrInfo.td +++ b/lib/Target/XCore/XCoreInstrInfo.td @@ -29,11 +29,11 @@ include "XCoreInstrFormats.td" // Call def SDT_XCoreBranchLink : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>; def XCoreBranchLink : SDNode<"XCoreISD::BL",SDT_XCoreBranchLink, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue, SDNPVariadic]>; def XCoreRetsp : SDNode<"XCoreISD::RETSP", SDTBrind, - [SDNPHasChain, SDNPOptInFlag]>; + [SDNPHasChain, SDNPOptInGlue]>; def SDT_XCoreBR_JT : SDTypeProfile<0, 2, [SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; @@ -66,9 +66,9 @@ def SDT_XCoreCallSeqEnd : SDCallSeqEnd<[ SDTCisVT<0, i32>, SDTCisVT<1, i32> ]>; def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_XCoreCallSeqStart, - [SDNPHasChain, SDNPOutFlag]>; + [SDNPHasChain, SDNPOutGlue]>; def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_XCoreCallSeqEnd, - [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; + [SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>; //===----------------------------------------------------------------------===// // Instruction Pattern Stuff @@ -610,8 +610,15 @@ def LDC_lru6 : _FLRU6< [(set GRRegs:$dst, immU16:$b)]>; } +def SETC_ru6 : _FRU6<(outs), (ins GRRegs:$r, i32imm:$val), + "setc res[$r], $val", + [(int_xcore_setc GRRegs:$r, immU6:$val)]>; + +def SETC_lru6 : _FLRU6<(outs), (ins GRRegs:$r, i32imm:$val), + "setc res[$r], $val", + [(int_xcore_setc GRRegs:$r, immU16:$val)]>; + // Operand register - U6 -// TODO setc let isBranch = 1, isTerminator = 1 in { defm BRFT: FRU6_LRU6_branch<"bt">; defm BRBT: FRU6_LRU6_branch<"bt">; @@ -720,9 +727,8 @@ def NEG : _F2R<(outs GRRegs:$dst), (ins GRRegs:$b), "neg $dst, $b", [(set GRRegs:$dst, (ineg GRRegs:$b))]>; -// TODO setd, eet, eef, getts, setpt, outct, inct, chkct, outt, intt, out, -// in, outshr, inshr, testct, testwct, tinitpc, tinitdp, tinitsp, tinitcp, -// tsetmr, sext (reg), zext (reg) +// TODO setd, eet, eef, getts, setpt, outshr, inshr, testwct, tinitpc, tinitdp, +// tinitsp, tinitcp, tsetmr, sext (reg), zext (reg) let Constraints = "$src1 = $dst" in { let neverHasSideEffects = 1 in def SEXT_rus : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$src1, i32imm:$src2), @@ -748,6 +754,50 @@ def MKMSK_2r : _FRUS<(outs GRRegs:$dst), (ins GRRegs:$size), "mkmsk $dst, $size", [(set GRRegs:$dst, (add (shl 1, GRRegs:$size), 0xffffffff))]>; +def GETR_rus : _FRUS<(outs GRRegs:$dst), (ins i32imm:$type), + "getr $dst, $type", + [(set GRRegs:$dst, (int_xcore_getr immUs:$type))]>; + +def OUTCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), + "outct res[$r], $val", + [(int_xcore_outct GRRegs:$r, GRRegs:$val)]>; + +def OUTCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), + "outct res[$r], $val", + [(int_xcore_outct GRRegs:$r, immUs:$val)]>; + +def OUTT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), + "outt res[$r], $val", + [(int_xcore_outt GRRegs:$r, GRRegs:$val)]>; + +def OUT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), + "out res[$r], $val", + [(int_xcore_out GRRegs:$r, GRRegs:$val)]>; + +def INCT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), + "inct $dst, res[$r]", + [(set GRRegs:$dst, (int_xcore_inct GRRegs:$r))]>; + +def INT_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), + "int $dst, res[$r]", + [(set GRRegs:$dst, (int_xcore_int GRRegs:$r))]>; + +def IN_2r : _F2R<(outs GRRegs:$dst), (ins GRRegs:$r), + "in $dst, res[$r]", + [(set GRRegs:$dst, (int_xcore_in GRRegs:$r))]>; + +def CHKCT_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), + "chkct res[$r], $val", + [(int_xcore_chkct GRRegs:$r, GRRegs:$val)]>; + +def CHKCT_rus : _F2R<(outs), (ins GRRegs:$r, i32imm:$val), + "chkct res[$r], $val", + [(int_xcore_chkct GRRegs:$r, immUs:$val)]>; + +def SETD_2r : _F2R<(outs), (ins GRRegs:$r, GRRegs:$val), + "setd res[$r], $val", + [(int_xcore_setd GRRegs:$r, GRRegs:$val)]>; + // Two operand long // TODO settw, setclk, setrdy, setpsc, endin, peek, // getd, testlcl, tinitlr, getps, setps @@ -763,8 +813,12 @@ def CLZ_l2r : _FL2R<(outs GRRegs:$dst), (ins GRRegs:$src), "clz $dst, $src", [(set GRRegs:$dst, (ctlz GRRegs:$src))]>; +def SETC_l2r : _FRU6<(outs), (ins GRRegs:$r, GRRegs:$val), + "setc res[$r], $val", + [(int_xcore_setc GRRegs:$r, GRRegs:$val)]>; + // One operand short -// TODO edu, eeu, waitet, waitef, freer, tstart, msync, mjoin, syncr, clrtp +// TODO edu, eeu, waitet, waitef, tstart, msync, mjoin, syncr, clrtp // setdp, setcp, setv, setev, kcall // dgetreg let isBranch=1, isIndirectBranch=1, isTerminator=1, isBarrier = 1 in @@ -805,6 +859,10 @@ def BLA_1r : _F1R<(outs), (ins GRRegs:$addr, variable_ops), [(XCoreBranchLink GRRegs:$addr)]>; } +def FREER_1r : _F1R<(outs), (ins GRRegs:$r), + "freer res[$r]", + [(int_xcore_freer GRRegs:$r)]>; + // Zero operand short // TODO waiteu, clre, ssync, freet, ldspc, stspc, ldssr, stssr, ldsed, stsed, // stet, geted, getet, getkep, getksp, setkep, getid, kret, dcall, dret, diff --git a/lib/Target/XCore/XCoreRegisterInfo.cpp b/lib/Target/XCore/XCoreRegisterInfo.cpp index f82e59814e77..56c0879cc8fc 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.cpp +++ b/lib/Target/XCore/XCoreRegisterInfo.cpp @@ -21,7 +21,7 @@ #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" -#include "llvm/Target/TargetFrameInfo.h" +#include "llvm/Target/TargetFrameLowering.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetInstrInfo.h" @@ -84,11 +84,13 @@ const unsigned* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); + Reserved.set(XCore::CP); Reserved.set(XCore::DP); Reserved.set(XCore::SP); Reserved.set(XCore::LR); - if (hasFP(MF)) { + if (TFI->hasFP(MF)) { Reserved.set(XCore::R10); } return Reserved; @@ -96,12 +98,10 @@ BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { bool XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { - // TODO can we estimate stack size? - return hasFP(MF); -} + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); -bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { - return DisableFramePointerElim(MF) || MF.getFrameInfo()->hasVarSizedObjects(); + // TODO can we estimate stack size? + return TFI->hasFP(MF); } // This function eliminates ADJCALLSTACKDOWN, @@ -109,7 +109,9 @@ bool XCoreRegisterInfo::hasFP(const MachineFunction &MF) const { void XCoreRegisterInfo:: eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const { - if (!hasReservedCallFrame(MF)) { + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); + + if (!TFI->hasReservedCallFrame(MF)) { // Turn the adjcallstackdown instruction into 'extsp ' and the // adjcallstackup instruction into 'ldaw sp, sp[]' MachineInstr *Old = I; @@ -118,14 +120,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, // We need to keep the stack aligned properly. To do this, we round the // amount of space needed for the outgoing arguments up to the next // alignment boundary. - unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment(); + unsigned Align = TFI->getStackAlignment(); Amount = (Amount+Align-1)/Align*Align; assert(Amount%4 == 0); Amount /= 4; - + bool isU6 = isImmU6(Amount); - if (!isU6 && !isImmU16(Amount)) { // FIX could emit multiple instructions in this case. #ifndef NDEBUG @@ -172,6 +173,7 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int FrameIndex = FrameOp.getIndex(); MachineFunction &MF = *MI.getParent()->getParent(); + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); int StackSize = MF.getFrameInfo()->getStackSize(); @@ -197,7 +199,7 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, Offset/=4; - bool FP = hasFP(MF); + bool FP = TFI->hasFP(MF); unsigned Reg = MI.getOperand(0).getReg(); bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); @@ -292,48 +294,6 @@ XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MBB.erase(II); } -void -XCoreRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS) const { - MachineFrameInfo *MFI = MF.getFrameInfo(); - bool LRUsed = MF.getRegInfo().isPhysRegUsed(XCore::LR); - const TargetRegisterClass *RC = XCore::GRRegsRegisterClass; - XCoreFunctionInfo *XFI = MF.getInfo(); - if (LRUsed) { - MF.getRegInfo().setPhysRegUnused(XCore::LR); - - bool isVarArg = MF.getFunction()->isVarArg(); - int FrameIdx; - if (! isVarArg) { - // A fixed offset of 0 allows us to save / restore LR using entsp / retsp. - FrameIdx = MFI->CreateFixedObject(RC->getSize(), 0, true); - } else { - FrameIdx = MFI->CreateStackObject(RC->getSize(), RC->getAlignment(), - false); - } - XFI->setUsesLR(FrameIdx); - XFI->setLRSpillSlot(FrameIdx); - } - if (requiresRegisterScavenging(MF)) { - // Reserve a slot close to SP or frame pointer. - RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), - RC->getAlignment(), - false)); - } - if (hasFP(MF)) { - // A callee save register is used to hold the FP. - // This needs saving / restoring in the epilogue / prologue. - XFI->setFPSpillSlot(MFI->CreateStackObject(RC->getSize(), - RC->getAlignment(), - false)); - } -} - -void XCoreRegisterInfo:: -processFunctionBeforeFrameFinalized(MachineFunction &MF) const { - -} - void XCoreRegisterInfo:: loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DstReg, int64_t Value, DebugLoc dl) const { @@ -346,229 +306,19 @@ loadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); } -void XCoreRegisterInfo:: -storeToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned SrcReg, int Offset, DebugLoc dl) const { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) - report_fatal_error("storeToStack offset too big " + Twine(Offset)); - int Opcode = isU6 ? XCore::STWSP_ru6 : XCore::STWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode)) - .addReg(SrcReg) - .addImm(Offset); -} - -void XCoreRegisterInfo:: -loadFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, - unsigned DstReg, int Offset, DebugLoc dl) const { - assert(Offset%4 == 0 && "Misaligned stack offset"); - Offset/=4; - bool isU6 = isImmU6(Offset); - if (!isU6 && !isImmU16(Offset)) - report_fatal_error("loadFromStack offset too big " + Twine(Offset)); - int Opcode = isU6 ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; - BuildMI(MBB, I, dl, TII.get(Opcode), DstReg) - .addImm(Offset); -} - -void XCoreRegisterInfo::emitPrologue(MachineFunction &MF) const { - MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB - MachineBasicBlock::iterator MBBI = MBB.begin(); - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo *MMI = &MF.getMMI(); - XCoreFunctionInfo *XFI = MF.getInfo(); - DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); - - bool FP = hasFP(MF); - - // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - - assert(FrameSize%4 == 0 && "Misaligned frame size"); - - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - report_fatal_error("emitPrologue Frame size too big: " + Twine(FrameSize)); - } - bool emitFrameMoves = needsFrameMoves(MF); - - // Do we need to allocate space on the stack? - if (FrameSize) { - bool saveLR = XFI->getUsesLR(); - bool LRSavedOnEntry = false; - int Opcode; - if (saveLR && (MFI->getObjectOffset(XFI->getLRSpillSlot()) == 0)) { - Opcode = (isU6) ? XCore::ENTSP_u6 : XCore::ENTSP_lu6; - MBB.addLiveIn(XCore::LR); - saveLR = false; - LRSavedOnEntry = true; - } else { - Opcode = (isU6) ? XCore::EXTSP_u6 : XCore::EXTSP_lu6; - } - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); - - if (emitFrameMoves) { - std::vector &Moves = MMI->getFrameMoves(); - - // Show update of SP. - MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - - MachineLocation SPDst(MachineLocation::VirtualFP); - MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize * 4); - Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc)); - - if (LRSavedOnEntry) { - MachineLocation CSDst(MachineLocation::VirtualFP, 0); - MachineLocation CSSrc(XCore::LR); - Moves.push_back(MachineMove(FrameLabel, CSDst, CSSrc)); - } - } - if (saveLR) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - storeToStack(MBB, MBBI, XCore::LR, LRSpillOffset + FrameSize*4, dl); - MBB.addLiveIn(XCore::LR); - - if (emitFrameMoves) { - MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveLRLabel); - MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset); - MachineLocation CSSrc(XCore::LR); - MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc)); - } - } - } - - if (FP) { - // Save R10 to the stack. - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - storeToStack(MBB, MBBI, XCore::R10, FPSpillOffset + FrameSize*4, dl); - // R10 is live-in. It is killed at the spill. - MBB.addLiveIn(XCore::R10); - if (emitFrameMoves) { - MCSymbol *SaveR10Label = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(SaveR10Label); - MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset); - MachineLocation CSSrc(XCore::R10); - MMI->getFrameMoves().push_back(MachineMove(SaveR10Label, CSDst, CSSrc)); - } - // Set the FP from the SP. - unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::LDAWSP_ru6), FramePtr) - .addImm(0); - if (emitFrameMoves) { - // Show FP is now valid. - MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol(); - BuildMI(MBB, MBBI, dl, TII.get(XCore::PROLOG_LABEL)).addSym(FrameLabel); - MachineLocation SPDst(FramePtr); - MachineLocation SPSrc(MachineLocation::VirtualFP); - MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc)); - } - } - - if (emitFrameMoves) { - // Frame moves for callee saved. - std::vector &Moves = MMI->getFrameMoves(); - std::vector >&SpillLabels = - XFI->getSpillLabels(); - for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) { - MCSymbol *SpillLabel = SpillLabels[I].first; - CalleeSavedInfo &CSI = SpillLabels[I].second; - int Offset = MFI->getObjectOffset(CSI.getFrameIdx()); - unsigned Reg = CSI.getReg(); - MachineLocation CSDst(MachineLocation::VirtualFP, Offset); - MachineLocation CSSrc(Reg); - Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc)); - } - } -} - -void XCoreRegisterInfo::emitEpilogue(MachineFunction &MF, - MachineBasicBlock &MBB) const { - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineBasicBlock::iterator MBBI = prior(MBB.end()); - DebugLoc dl = MBBI->getDebugLoc(); - - bool FP = hasFP(MF); - - if (FP) { - // Restore the stack pointer. - unsigned FramePtr = XCore::R10; - BuildMI(MBB, MBBI, dl, TII.get(XCore::SETSP_1r)) - .addReg(FramePtr); - } - - // Work out frame sizes. - int FrameSize = MFI->getStackSize(); - - assert(FrameSize%4 == 0 && "Misaligned frame size"); - - FrameSize/=4; - - bool isU6 = isImmU6(FrameSize); - - if (!isU6 && !isImmU16(FrameSize)) { - // FIXME could emit multiple instructions. - report_fatal_error("emitEpilogue Frame size too big: " + Twine(FrameSize)); - } - - if (FrameSize) { - XCoreFunctionInfo *XFI = MF.getInfo(); - - if (FP) { - // Restore R10 - int FPSpillOffset = MFI->getObjectOffset(XFI->getFPSpillSlot()); - FPSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::R10, FPSpillOffset, dl); - } - bool restoreLR = XFI->getUsesLR(); - if (restoreLR && MFI->getObjectOffset(XFI->getLRSpillSlot()) != 0) { - int LRSpillOffset = MFI->getObjectOffset(XFI->getLRSpillSlot()); - LRSpillOffset += FrameSize*4; - loadFromStack(MBB, MBBI, XCore::LR, LRSpillOffset, dl); - restoreLR = false; - } - if (restoreLR) { - // Fold prologue into return instruction - assert(MBBI->getOpcode() == XCore::RETSP_u6 - || MBBI->getOpcode() == XCore::RETSP_lu6); - int Opcode = (isU6) ? XCore::RETSP_u6 : XCore::RETSP_lu6; - BuildMI(MBB, MBBI, dl, TII.get(Opcode)).addImm(FrameSize); - MBB.erase(MBBI); - } else { - int Opcode = (isU6) ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs; - BuildMI(MBB, MBBI, dl, TII.get(Opcode), XCore::SP).addImm(FrameSize); - } - } -} - int XCoreRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { return XCoreGenRegisterInfo::getDwarfRegNumFull(RegNum, 0); } unsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { - bool FP = hasFP(MF); - - return FP ? XCore::R10 : XCore::SP; + const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); + + return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; } unsigned XCoreRegisterInfo::getRARegister() const { return XCore::LR; } -void XCoreRegisterInfo::getInitialFrameState(std::vector &Moves) - const { - // Initial state of the frame pointer is SP. - MachineLocation Dst(MachineLocation::VirtualFP); - MachineLocation Src(XCore::SP, 0); - Moves.push_back(MachineMove(0, Dst, Src)); -} - #include "XCoreGenRegisterInfo.inc" diff --git a/lib/Target/XCore/XCoreRegisterInfo.h b/lib/Target/XCore/XCoreRegisterInfo.h index e636c1c7298a..218575581d4a 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.h +++ b/lib/Target/XCore/XCoreRegisterInfo.h @@ -48,8 +48,6 @@ public: bool requiresRegisterScavenging(const MachineFunction &MF) const; - bool hasFP(const MachineFunction &MF) const; - void eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const; @@ -57,18 +55,9 @@ public: void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, RegScavenger *RS = NULL) const; - void processFunctionBeforeCalleeSavedScan(MachineFunction &MF, - RegScavenger *RS = NULL) const; - - void processFunctionBeforeFrameFinalized(MachineFunction &MF) const; - - void emitPrologue(MachineFunction &MF) const; - void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const; - // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const; - void getInitialFrameState(std::vector &Moves) const; //! Return the array of argument passing registers /*! diff --git a/lib/Target/XCore/XCoreRegisterInfo.td b/lib/Target/XCore/XCoreRegisterInfo.td index 62daf5d4567b..765f717e206e 100644 --- a/lib/Target/XCore/XCoreRegisterInfo.td +++ b/lib/Target/XCore/XCoreRegisterInfo.td @@ -61,8 +61,8 @@ def GRRegs : RegisterClass<"XCore", [i32], 32, GRRegsClass::iterator GRRegsClass::allocation_order_end(const MachineFunction &MF) const { const TargetMachine &TM = MF.getTarget(); - const TargetRegisterInfo *RI = TM.getRegisterInfo(); - if (RI->hasFP(MF)) + const TargetFrameLowering *TFI = TM.getFrameLowering(); + if (TFI->hasFP(MF)) return end()-1; // don't allocate R10 else return end(); diff --git a/lib/Target/XCore/XCoreTargetMachine.cpp b/lib/Target/XCore/XCoreTargetMachine.cpp index b0013eb01df9..30da2c896c0f 100644 --- a/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/lib/Target/XCore/XCoreTargetMachine.cpp @@ -27,7 +27,7 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, const std::string &TT, DataLayout("e-p:32:32:32-a0:0:32-f32:32:32-f64:32:32-i1:8:32-i8:8:32-" "i16:16:32-i32:32:32-i64:32:32-n32"), InstrInfo(), - FrameInfo(*this), + FrameLowering(Subtarget), TLInfo(*this), TSInfo(*this) { } diff --git a/lib/Target/XCore/XCoreTargetMachine.h b/lib/Target/XCore/XCoreTargetMachine.h index 14073baf0f94..24daadcb6bf4 100644 --- a/lib/Target/XCore/XCoreTargetMachine.h +++ b/lib/Target/XCore/XCoreTargetMachine.h @@ -16,7 +16,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetData.h" -#include "XCoreFrameInfo.h" +#include "XCoreFrameLowering.h" #include "XCoreSubtarget.h" #include "XCoreInstrInfo.h" #include "XCoreISelLowering.h" @@ -28,7 +28,7 @@ class XCoreTargetMachine : public LLVMTargetMachine { XCoreSubtarget Subtarget; const TargetData DataLayout; // Calculates type size & alignment XCoreInstrInfo InstrInfo; - XCoreFrameInfo FrameInfo; + XCoreFrameLowering FrameLowering; XCoreTargetLowering TLInfo; XCoreSelectionDAGInfo TSInfo; public: @@ -36,7 +36,9 @@ public: const std::string &FS); virtual const XCoreInstrInfo *getInstrInfo() const { return &InstrInfo; } - virtual const XCoreFrameInfo *getFrameInfo() const { return &FrameInfo; } + virtual const XCoreFrameLowering *getFrameLowering() const { + return &FrameLowering; + } virtual const XCoreSubtarget *getSubtargetImpl() const { return &Subtarget; } virtual const XCoreTargetLowering *getTargetLowering() const { return &TLInfo; diff --git a/lib/Target/XCore/XCoreTargetObjectFile.cpp b/lib/Target/XCore/XCoreTargetObjectFile.cpp index cdf5a5371e22..7f4e1c1b4fd7 100644 --- a/lib/Target/XCore/XCoreTargetObjectFile.cpp +++ b/lib/Target/XCore/XCoreTargetObjectFile.cpp @@ -12,6 +12,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Support/ELF.h" using namespace llvm; @@ -19,31 +20,31 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TargetLoweringObjectFileELF::Initialize(Ctx, TM); DataSection = - Ctx.getELFSection(".dp.data", MCSectionELF::SHT_PROGBITS, - MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE | - MCSectionELF::XCORE_SHF_DP_SECTION, - SectionKind::getDataRel(), false); + Ctx.getELFSection(".dp.data", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE | + ELF::XCORE_SHF_DP_SECTION, + SectionKind::getDataRel()); BSSSection = - Ctx.getELFSection(".dp.bss", MCSectionELF::SHT_NOBITS, - MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_WRITE | - MCSectionELF::XCORE_SHF_DP_SECTION, - SectionKind::getBSS(), false); + Ctx.getELFSection(".dp.bss", ELF::SHT_NOBITS, + ELF::SHF_ALLOC | ELF::SHF_WRITE | + ELF::XCORE_SHF_DP_SECTION, + SectionKind::getBSS()); MergeableConst4Section = - Ctx.getELFSection(".cp.rodata.cst4", MCSectionELF::SHT_PROGBITS, - MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE | - MCSectionELF::XCORE_SHF_CP_SECTION, - SectionKind::getMergeableConst4(), false); + Ctx.getELFSection(".cp.rodata.cst4", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getMergeableConst4()); MergeableConst8Section = - Ctx.getELFSection(".cp.rodata.cst8", MCSectionELF::SHT_PROGBITS, - MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE | - MCSectionELF::XCORE_SHF_CP_SECTION, - SectionKind::getMergeableConst8(), false); + Ctx.getELFSection(".cp.rodata.cst8", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getMergeableConst8()); MergeableConst16Section = - Ctx.getELFSection(".cp.rodata.cst16", MCSectionELF::SHT_PROGBITS, - MCSectionELF::SHF_ALLOC | MCSectionELF::SHF_MERGE | - MCSectionELF::XCORE_SHF_CP_SECTION, - SectionKind::getMergeableConst16(), false); + Ctx.getELFSection(".cp.rodata.cst16", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | ELF::SHF_MERGE | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getMergeableConst16()); // TLS globals are lowered in the backend to arrays indexed by the current // thread id. After lowering they require no special handling by the linker @@ -52,10 +53,10 @@ void XCoreTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM){ TLSBSSSection = BSSSection; ReadOnlySection = - Ctx.getELFSection(".cp.rodata", MCSectionELF::SHT_PROGBITS, - MCSectionELF::SHF_ALLOC | - MCSectionELF::XCORE_SHF_CP_SECTION, - SectionKind::getReadOnlyWithRel(), false); + Ctx.getELFSection(".cp.rodata", ELF::SHT_PROGBITS, + ELF::SHF_ALLOC | + ELF::XCORE_SHF_CP_SECTION, + SectionKind::getReadOnlyWithRel()); // Dynamic linking is not supported. Data with relocations is placed in the // same section as data without relocations. -- cgit v1.3