From b2d6d00f8dcb3c2e08b38f0fdb311014c4badd6e Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Mon, 6 Jul 2009 10:18:37 +0000 Subject: [PATCH] Implement _CONFIG macro to allow users to se to configuration settings on the part. Implement _section macro to allow users to place objects in specific sections. Implement _address macro to allow users to place objects at a particular address. Placing objects at a memory address: crate a unique section name from varname, address, object type and put that section at specified address. Mark this section a full (size = banksize) so that other objects do not compete for it while placing objects to sections in AsmPrinter. llvm-svn: 74822 --- lib/CompilerDriver/BuiltinOptions.cpp | 3 +- lib/CompilerDriver/Main.cpp | 11 ++ lib/Target/PIC16/PIC16.h | 22 ++- lib/Target/PIC16/PIC16AsmPrinter.cpp | 25 +-- lib/Target/PIC16/PIC16TargetAsmInfo.cpp | 195 +++++++++++++++++++++++- lib/Target/PIC16/PIC16TargetAsmInfo.h | 17 ++- 6 files changed, 246 insertions(+), 27 deletions(-) diff --git a/lib/CompilerDriver/BuiltinOptions.cpp b/lib/CompilerDriver/BuiltinOptions.cpp index a3364e8a72f..126346f68da 100644 --- a/lib/CompilerDriver/BuiltinOptions.cpp +++ b/lib/CompilerDriver/BuiltinOptions.cpp @@ -52,4 +52,5 @@ cl::opt SaveTemps "Use current working directory"), clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"), clEnumValEnd), - cl::ValueOptional); + //cl::ValueOptional); + cl::Hidden); diff --git a/lib/CompilerDriver/Main.cpp b/lib/CompilerDriver/Main.cpp index 7d1a3d8fbc4..f4cacb38f18 100644 --- a/lib/CompilerDriver/Main.cpp +++ b/lib/CompilerDriver/Main.cpp @@ -31,6 +31,17 @@ namespace { sys::Path getTempDir() { sys::Path tempDir; +///////////////////////////////////////////// + std::string p = "tmp-objs"; + tempDir = sys::Path(p); + if (!tempDir.exists()) { + std::string ErrMsg; + if (tempDir.createDirectoryOnDisk(true, &ErrMsg)) + throw std::runtime_error(ErrMsg); + } + return tempDir; +///////////////////////////////////////////// + // GCC 4.5-style -save-temps handling. if (SaveTemps == SaveTempsEnum::Unset) { tempDir = sys::Path::GetTemporaryDirectory(); diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h index 57b08b730d0..0a71b130a0b 100644 --- a/lib/Target/PIC16/PIC16.h +++ b/lib/Target/PIC16/PIC16.h @@ -221,17 +221,29 @@ namespace PIC16CC { return Func1 + tag + "# CODE"; } - // udata and idata section names are generated by a given number. + // udata, romdata and idata section names are generated by a given number. // @udata..# - static std::string getUdataSectionName(unsigned num) { + static std::string getUdataSectionName(unsigned num, + std::string prefix = "") { std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << "udata." << num << ".# UDATA"; + o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num + << ".# UDATA"; return o.str(); } - static std::string getIdataSectionName(unsigned num) { + static std::string getRomdataSectionName(unsigned num, + std::string prefix = "") { std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << "idata." << num << ".# IDATA"; + o << getTagName(PREFIX_SYMBOL) << prefix << "romdata." << num + << ".# ROMDATA"; + return o.str(); + } + + static std::string getIdataSectionName(unsigned num, + std::string prefix = "") { + std::ostringstream o; + o << getTagName(PREFIX_SYMBOL) << prefix << "idata." << num + << ".# IDATA"; return o.str(); } diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index 1fc1cc186aa..a33fef3c881 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -272,18 +272,19 @@ void PIC16AsmPrinter::EmitDefinedVars (Module &M) // Emit initialized data placed in ROM. void PIC16AsmPrinter::EmitRomData (Module &M) { - - std::vector Items = PTAI->ROSection->Items; - if (! Items.size()) return; - - // Print ROData ection. - O << "\n"; - SwitchToSection(PTAI->ROSection->S_); - for (unsigned j = 0; j < Items.size(); j++) { - O << Mang->getValueName(Items[j]); - Constant *C = Items[j]->getInitializer(); - int AddrSpace = Items[j]->getType()->getAddressSpace(); - EmitGlobalConstant(C, AddrSpace); + // Print ROM Data section. + std::vector ROSections = PTAI->ROSections; + for (unsigned i = 0; i < ROSections.size(); i++) { + std::vector Items = ROSections[i]->Items; + if (! Items.size()) continue; + O << "\n"; + SwitchToSection(PTAI->ROSections[i]->S_); + for (unsigned j = 0; j < Items.size(); j++) { + O << Mang->getValueName(Items[j]); + Constant *C = Items[j]->getInitializer(); + int AddrSpace = Items[j]->getType()->getAddressSpace(); + EmitGlobalConstant(C, AddrSpace); + } } } diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp index d2657f018f8..a81c95f1594 100644 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp +++ b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp @@ -44,7 +44,8 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM) // Need because otherwise a .text symbol is emitted by DwarfWriter // in BeginModule, and gpasm cribbs for that .text symbol. TextSection = getUnnamedSection("", SectionFlags::Code); - ROSection = new PIC16Section(getReadOnlySection()); + PIC16Section *ROSection = new PIC16Section(getReadOnlySection()); + ROSections.push_back(ROSection); ExternalVarDecls = new PIC16Section(getNamedSection("ExternalVarDecls")); ExternalVarDefs = new PIC16Section(getNamedSection("ExternalVarDefs")); // Set it to false because we weed to generate c file name and not bc file @@ -235,10 +236,8 @@ PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { return getIDATASectionForGlobal(GV); // This is initialized data in rom, put it in the readonly section. - if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) { - ROSection->Items.push_back(GV); - return ROSection->S_; - } + if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) + return getROSectionForGlobal(GV); // Else let the default implementation take care of it. return TargetAsmInfo::SelectSectionForGlobal(GV); @@ -258,7 +257,191 @@ PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { delete AutosSections[i]; } - delete ROSection; + for (unsigned i = 0; i < ROSections.size(); i++) { + delete ROSections[i]; + } + delete ExternalVarDecls; delete ExternalVarDefs; } + +// Override the default implementation. Create PIC16sections for variables +// which have a section name or address. +const Section* +PIC16TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { + const Section* S; + // If GV has a sectin name or section address create that section now. + if (GV->hasSection()) { + std::string SectName = GV->getSection(); + // If address for a variable is specified, get the address and create + // section. + std::string AddrStr = "Address="; + if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) { + std::string SectAddr = SectName.substr(AddrStr.length()); + S = CreateSectionForGlobal(GV, SectAddr); + } + else { + S = CreateSectionForGlobal(GV); + } + } else { + // Use section depending on the 'type' of variable + S = SelectSectionForGlobal(GV); + } + return S; +} + +// Create a new section for global variable. If Addr is given then create +// section at that address else create by name. +const Section * +PIC16TargetAsmInfo::CreateSectionForGlobal(const GlobalValue *GV1, + std::string Addr) const { + const GlobalVariable *GV = dyn_cast(GV1); + + if (!GV) + return TargetAsmInfo::SectionForGlobal(GV1); + + // See if this is an uninitialized global. + const Constant *C = GV->getInitializer(); + if (C->isNullValue()) + return CreateBSSSectionForGlobal(GV, Addr); + + // If this is initialized data in RAM. Put it in the correct IDATA section. + if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) + return CreateIDATASectionForGlobal(GV, Addr); + + // This is initialized data in rom, put it in the readonly section. + if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) + return CreateROSectionForGlobal(GV, Addr); + + // Else let the default implementation take care of it. + return TargetAsmInfo::SectionForGlobal(GV); +} + +// Create uninitialized section for a variable. +const Section * +PIC16TargetAsmInfo::CreateBSSSectionForGlobal(const GlobalVariable *GV, + std::string Addr) const { + assert (GV->hasInitializer() && "This global doesn't need space"); + Constant *C = GV->getInitializer(); + assert (C->isNullValue() && "Unitialized globals has non-zero initializer"); + std::string Name; + // If address is given then create a section at that address else create a + // section by section name specified in GV. + PIC16Section *FoundBSS = NULL; + if (Addr.empty()) { + Name = GV->getSection() + " UDATA"; + for (unsigned i = 0; i < BSSSections.size(); i++) { + if (BSSSections[i]->S_->getName() == Name) { + FoundBSS = BSSSections[i]; + break; + } + } + } + else { + std::string Prefix = GV->getName() + "." + Addr + "."; + Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewBSS = FoundBSS; + if (NewBSS == NULL) { + const Section *NewSection = getNamedSection (Name.c_str()); + NewBSS = new PIC16Section(NewSection); + BSSSections.push_back(NewBSS); + } + + // Insert the GV into this BSS. + NewBSS->Items.push_back(GV); + + // We do not want to put any GV without explicit section into this section + // so set its size to DatabankSize. + NewBSS->Size = DataBankSize; + return NewBSS->S_; +} + +// Get rom section for a variable. Currently there can be only one rom section +// unless a variable explicitly requests a section. +const Section * +PIC16TargetAsmInfo::getROSectionForGlobal(const GlobalVariable *GV) const { + ROSections[0]->Items.push_back(GV); + return ROSections[0]->S_; +} + +// Create initialized data section for a variable. +const Section * +PIC16TargetAsmInfo::CreateIDATASectionForGlobal(const GlobalVariable *GV, + std::string Addr) const { + assert (GV->hasInitializer() && "This global doesn't need space"); + Constant *C = GV->getInitializer(); + assert (!C->isNullValue() && "initialized globals has zero initializer"); + assert (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE && + "can be used for initialized RAM data only"); + + std::string Name; + // If address is given then create a section at that address else create a + // section by section name specified in GV. + PIC16Section *FoundIDATASec = NULL; + if (Addr.empty()) { + Name = GV->getSection() + " IDATA"; + for (unsigned i = 0; i < IDATASections.size(); i++) { + if (IDATASections[i]->S_->getName() == Name) { + FoundIDATASec = IDATASections[i]; + break; + } + } + } + else { + std::string Prefix = GV->getName() + "." + Addr + "."; + Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewIDATASec = FoundIDATASec; + if (NewIDATASec == NULL) { + const Section *NewSection = getNamedSection (Name.c_str()); + NewIDATASec = new PIC16Section(NewSection); + IDATASections.push_back(NewIDATASec); + } + // Insert the GV into this IDATA Section. + NewIDATASec->Items.push_back(GV); + // We do not want to put any GV without explicit section into this section + // so set its size to DatabankSize. + NewIDATASec->Size = DataBankSize; + return NewIDATASec->S_; +} + +// Create a section in rom for a variable. +const Section * +PIC16TargetAsmInfo::CreateROSectionForGlobal(const GlobalVariable *GV, + std::string Addr) const { + assert (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE && + "can be used for ROM data only"); + + std::string Name; + // If address is given then create a section at that address else create a + // section by section name specified in GV. + PIC16Section *FoundROSec = NULL; + if (Addr.empty()) { + Name = GV->getSection() + " ROMDATA"; + for (unsigned i = 1; i < ROSections.size(); i++) { + if (ROSections[i]->S_->getName() == Name) { + FoundROSec = ROSections[i]; + break; + } + } + } + else { + std::string Prefix = GV->getName() + "." + Addr + "."; + Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewRomSec = FoundROSec; + if (NewRomSec == NULL) { + const Section *NewSection = getNamedSection (Name.c_str()); + NewRomSec = new PIC16Section(NewSection); + ROSections.push_back(NewRomSec); + } + + // Insert the GV into this ROM Section. + NewRomSec->Items.push_back(GV); + return NewRomSec->S_; +} + diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.h b/lib/Target/PIC16/PIC16TargetAsmInfo.h index b7292b8ea78..b97336bac35 100644 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.h +++ b/lib/Target/PIC16/PIC16TargetAsmInfo.h @@ -48,7 +48,7 @@ namespace llvm { mutable std::vector BSSSections; mutable std::vector IDATASections; mutable std::vector AutosSections; - mutable PIC16Section *ROSection; + mutable std::vector ROSections; mutable PIC16Section *ExternalVarDecls; mutable PIC16Section *ExternalVarDefs; virtual ~PIC16TargetAsmInfo(); @@ -62,9 +62,16 @@ namespace llvm { const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const; const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const; const Section *getSectionForAuto(const GlobalVariable *GV) const; + const Section *CreateBSSSectionForGlobal(const GlobalVariable *GV, + std::string Addr = "") const; + const Section *CreateIDATASectionForGlobal(const GlobalVariable *GV, + std::string Addr = "") const; + const Section *getROSectionForGlobal(const GlobalVariable *GV) const; + const Section *CreateROSectionForGlobal(const GlobalVariable *GV, + std::string Addr = "") const; virtual const Section *SelectSectionForGlobal(const GlobalValue *GV) const; - - + const Section * CreateSectionForGlobal(const GlobalValue *GV, + std::string Addr = "") const; public: void SetSectionForGVs(Module &M); std::vector getBSSSections() const { @@ -76,6 +83,10 @@ namespace llvm { std::vector getAutosSections() const { return AutosSections; } + std::vector getROSections() const { + return ROSections; + } + virtual const Section* SectionForGlobal(const GlobalValue *GV) const; }; } // namespace llvm