diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-10-15 15:02:14 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-10-15 15:02:14 +0000 |
commit | 1ead150c92d07aceca9f139376cb647feb8ff355 (patch) | |
tree | bab63bcd10539b25ada12979d52cb24dbfe0d02b /lib/Target/PIC16/PIC16TargetObjectFile.cpp | |
parent | 8da373cf62d8dfdbf5e8a7c226d8a67153fe0013 (diff) |
Revert "Complete Rewrite of AsmPrinter, TargetObjectFile based on new
PIC16Section class", it breaks globals.ll.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84184 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PIC16/PIC16TargetObjectFile.cpp')
-rw-r--r-- | lib/Target/PIC16/PIC16TargetObjectFile.cpp | 471 |
1 files changed, 273 insertions, 198 deletions
diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp index 330722d4a9..a2a4c09d29 100644 --- a/lib/Target/PIC16/PIC16TargetObjectFile.cpp +++ b/lib/Target/PIC16/PIC16TargetObjectFile.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "PIC16TargetObjectFile.h" +#include "MCSectionPIC16.h" #include "PIC16ISelLowering.h" #include "PIC16TargetMachine.h" -#include "PIC16Section.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" #include "llvm/MC/MCSection.h" @@ -19,111 +19,75 @@ using namespace llvm; -PIC16TargetObjectFile::PIC16TargetObjectFile() { +MCSectionPIC16 *MCSectionPIC16::Create(const StringRef &Name, SectionKind K, + int Address, int Color, MCContext &Ctx) { + return new (Ctx) MCSectionPIC16(Name, K, Address, Color); } -/// Find a pic16 section. If not found, create one. -PIC16Section *PIC16TargetObjectFile:: -getPIC16Section(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - return Entry; +void MCSectionPIC16::PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS) const { + OS << getName() << '\n'; } -/// Find a standard pic16 data section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16DataSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - switch (Ty) { - default: llvm_unreachable ("unknow standard section type."); - case UDATA: UDATASections_.push_back(Entry); break; - case IDATA: IDATASections_.push_back(Entry); break; - case ROMDATA: ROMDATASection_ = Entry; break; - } - return Entry; +PIC16TargetObjectFile::PIC16TargetObjectFile() + : ExternalVarDecls(0), ExternalVarDefs(0) { } - - -/// Find a standard pic16 autos section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16AutoSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; +const MCSectionPIC16 *PIC16TargetObjectFile:: +getPIC16Section(const char *Name, SectionKind Kind, + int Address, int Color) const { + MCSectionPIC16 *&Entry = SectionsByName[Name]; if (Entry) return Entry; - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - - assert (Ty == UDATA_OVR && "incorrect section type for autos"); - AUTOSections_.push_back(Entry); - - return Entry; + return Entry = MCSectionPIC16::Create(Name, Kind, Address, Color, + getContext()); } - -/// Find a pic16 user section. If not found, create one and keep -/// track of it by adding it to appropriate std section list. -PIC16Section *PIC16TargetObjectFile:: -getPIC16UserSection(const std::string &Name, PIC16SectionType Ty, - const std::string &Address, int Color) const { - - /// Return if we have an already existing one. - PIC16Section *&Entry = SectionsByName[Name]; - if (Entry) - return Entry; - - /// Else create a new one and add it to appropriate section list. - Entry = PIC16Section::Create(Name, Ty, Address, Color, getContext()); - USERSections_.push_back(Entry); - - return Entry; -} - -/// Do some standard llvm stuff. PIC16 really does not need any of this. void PIC16TargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &tm){ TargetLoweringObjectFile::Initialize(Ctx, tm); TM = &tm; - // BSSSection = getPIC16DataSection("udata.#", UDATA); - // ReadOnlySection = getPIC16DataSection("romdata.#", ROMDATA); - // DataSection = getPIC16DataSection("idata.#", IDATA); + BSSSection = getPIC16Section("udata.# UDATA", MCSectionPIC16::UDATA_Kind()); + ReadOnlySection = getPIC16Section("romdata.# ROMDATA", + MCSectionPIC16::ROMDATA_Kind()); + DataSection = getPIC16Section("idata.# IDATA", MCSectionPIC16::IDATA_Kind()); // Need because otherwise a .text symbol is emitted by DwarfWriter // in BeginModule, and gpasm cribbs for that .text symbol. - // FIXME: below - // TextSection = getPIC16DataSection("", UDATA); - ROMDATASection_ = NULL; + TextSection = getPIC16Section("", SectionKind::getText()); + + ROSections.push_back(new PIC16Section((MCSectionPIC16*)ReadOnlySection)); + + // FIXME: I don't know what the classification of these sections really is. + // These aren't really objects belonging to any section. Just emit them + // in AsmPrinter and remove this code from here. + ExternalVarDecls = new PIC16Section(getPIC16Section("ExternalVarDecls", + SectionKind::getMetadata())); + ExternalVarDefs = new PIC16Section(getPIC16Section("ExternalVarDefs", + SectionKind::getMetadata())); +} + +const MCSection *PIC16TargetObjectFile:: +getSectionForFunction(const std::string &FnName) const { + std::string T = PAN::getCodeSectionName(FnName); + return getPIC16Section(T.c_str(), SectionKind::getText()); +} + + +const MCSection *PIC16TargetObjectFile:: +getSectionForFunctionFrame(const std::string &FnName) const { + std::string T = PAN::getFrameSectionName(FnName); + return getPIC16Section(T.c_str(), SectionKind::getDataRel()); } -/// allocateUDATA - Allocate a un-initialized global to an existing or new UDATA -/// section and return that section. const MCSection * -PIC16TargetObjectFile::allocateUDATA(const GlobalVariable *GV) const { +PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const { assert(GV->hasInitializer() && "This global doesn't need space"); Constant *C = GV->getInitializer(); assert(C->isNullValue() && "Unitialized globals has non-zero initializer"); @@ -133,37 +97,41 @@ PIC16TargetObjectFile::allocateUDATA(const GlobalVariable *GV) const { const Type *Ty = C->getType(); unsigned ValSize = TD->getTypeAllocSize(Ty); - // Go through all UDATA Sections and assign this variable + // Go through all BSS Sections and assign this variable // to the first available section having enough space. - PIC16Section *Found = NULL; - for (unsigned i = 0; i < UDATASections_.size(); i++) { - if (DataBankSize - UDATASections_[i]->getSize() >= ValSize) { - Found = UDATASections_[i]; + PIC16Section *FoundBSS = NULL; + for (unsigned i = 0; i < BSSSections.size(); i++) { + if (DataBankSize - BSSSections[i]->Size >= ValSize) { + FoundBSS = BSSSections[i]; break; } } - // No UDATA section spacious enough was found. Crate a new one. - if (!Found) { - std::string name = PAN::getUdataSectionName(UDATASections_.size()); - Found = getPIC16DataSection(name.c_str(), UDATA); + // No BSS section spacious enough was found. Crate a new one. + if (!FoundBSS) { + std::string name = PAN::getUdataSectionName(BSSSections.size()); + const MCSectionPIC16 *NewSection + = getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_Kind()); + + FoundBSS = new PIC16Section(NewSection); + + // Add this newly created BSS section to the list of BSSSections. + BSSSections.push_back(FoundBSS); } - // Insert the GV into this UDATA section. - Found->Items.push_back(GV); - Found->setSize(Found->getSize() + ValSize); - return Found; + // Insert the GV into this BSS. + FoundBSS->Items.push_back(GV); + FoundBSS->Size += ValSize; + return FoundBSS->S_; } -/// allocateIDATA - allocate an initialized global into an existing -/// or new section and return that section. const MCSection * -PIC16TargetObjectFile::allocateIDATA(const GlobalVariable *GV) const{ +PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) 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 allocate initialized RAM data only"); + "can split initialized RAM data only"); // Find how much space this global needs. const TargetData *TD = TM->getTargetData(); @@ -172,47 +140,64 @@ PIC16TargetObjectFile::allocateIDATA(const GlobalVariable *GV) const{ // Go through all IDATA Sections and assign this variable // to the first available section having enough space. - PIC16Section *Found = NULL; - for (unsigned i = 0; i < IDATASections_.size(); i++) { - if (DataBankSize - IDATASections_[i]->getSize() >= ValSize) { - Found = IDATASections_[i]; + PIC16Section *FoundIDATA = NULL; + for (unsigned i = 0; i < IDATASections.size(); i++) { + if (DataBankSize - IDATASections[i]->Size >= ValSize) { + FoundIDATA = IDATASections[i]; break; } } // No IDATA section spacious enough was found. Crate a new one. - if (!Found) { - std::string name = PAN::getIdataSectionName(IDATASections_.size()); - Found = getPIC16DataSection(name.c_str(), IDATA); + if (!FoundIDATA) { + std::string name = PAN::getIdataSectionName(IDATASections.size()); + const MCSectionPIC16 *NewSection = + getPIC16Section(name.c_str(), MCSectionPIC16::IDATA_Kind()); + + FoundIDATA = new PIC16Section(NewSection); + + // Add this newly created IDATA section to the list of IDATASections. + IDATASections.push_back(FoundIDATA); } // Insert the GV into this IDATA. - Found->Items.push_back(GV); - Found->setSize(Found->getSize() + ValSize); - return Found; + FoundIDATA->Items.push_back(GV); + FoundIDATA->Size += ValSize; + return FoundIDATA->S_; } -// Allocate a program memory variable into ROMDATA section. -const MCSection * -PIC16TargetObjectFile::allocateROMDATA(const GlobalVariable *GV) const { - - std::string name = PAN::getRomdataSectionName(); - PIC16Section *S = getPIC16DataSection(name.c_str(), ROMDATA); - - S->Items.push_back(GV); - return S; -} - // Get the section for an automatic variable of a function. // For PIC16 they are globals only with mangled names. const MCSection * -PIC16TargetObjectFile::allocateAUTO(const GlobalVariable *GV) const { +PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const { const std::string name = PAN::getSectionNameForSym(GV->getName()); - PIC16Section *S = getPIC16AutoSection(name.c_str()); - S->Items.push_back(GV); - return S; + // Go through all Auto Sections and assign this variable + // to the appropriate section. + PIC16Section *FoundAutoSec = NULL; + for (unsigned i = 0; i < AutosSections.size(); i++) { + if (AutosSections[i]->S_->getName() == name) { + FoundAutoSec = AutosSections[i]; + break; + } + } + + // No Auto section was found. Crate a new one. + if (!FoundAutoSec) { + const MCSectionPIC16 *NewSection = + getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_OVR_Kind()); + + FoundAutoSec = new PIC16Section(NewSection); + + // Add this newly created autos section to the list of AutosSections. + AutosSections.push_back(FoundAutoSec); + } + + // Insert the auto into this section. + FoundAutoSec->Items.push_back(GV); + + return FoundAutoSec->S_; } @@ -229,50 +214,56 @@ PIC16TargetObjectFile::SelectSectionForGlobal(const GlobalValue *GV1, if (!GV) return TargetLoweringObjectFile::SelectSectionForGlobal(GV1, Kind, Mang,TM); + // Record External Var Decls. + if (GV->isDeclaration()) { + ExternalVarDecls->Items.push_back(GV); + return ExternalVarDecls->S_; + } + assert(GV->hasInitializer() && "A def without initializer?"); // First, if this is an automatic variable for a function, get the section // name for it and return. std::string name = GV->getName(); if (PAN::isLocalName(name)) - return allocateAUTO(GV); + return getSectionForAuto(GV); + + // Record Exteranl Var Defs. + if (GV->hasExternalLinkage() || GV->hasCommonLinkage()) + ExternalVarDefs->Items.push_back(GV); // See if this is an uninitialized global. const Constant *C = GV->getInitializer(); if (C->isNullValue()) - return allocateUDATA(GV); + return getBSSSectionForGlobal(GV); // If this is initialized data in RAM. Put it in the correct IDATA section. if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - return allocateIDATA(GV); + return getIDATASectionForGlobal(GV); // This is initialized data in rom, put it in the readonly section. if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - return allocateROMDATA(GV); + return getROSectionForGlobal(GV); // Else let the default implementation take care of it. return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM); } PIC16TargetObjectFile::~PIC16TargetObjectFile() { -#if 0 - for (unsigned i = 0; i < UDATASections_.size(); i++) - delete UDATASections_[i]; - for (unsigned i = 0; i < IDATASections_.size(); i++) - delete IDATASections_[i]; - - delete ROMDATASection_; - - for (unsigned i = 0; i < AUTOSections_.size(); i++) - delete AUTOSections_[i]; - - for (unsigned i = 0; i < USERSections_.size(); i++) - delete USERSections_[i]; -#endif + for (unsigned i = 0; i < BSSSections.size(); i++) + delete BSSSections[i]; + for (unsigned i = 0; i < IDATASections.size(); i++) + delete IDATASections[i]; + for (unsigned i = 0; i < AutosSections.size(); i++) + delete AutosSections[i]; + for (unsigned i = 0; i < ROSections.size(); i++) + delete ROSections[i]; + delete ExternalVarDecls; + delete ExternalVarDefs; } -/// getExplicitSectionGlobal - Allow the target to completely override +/// getSpecialCasedSectionGlobals - Allow the target to completely override /// section assignment of a global. const MCSection *PIC16TargetObjectFile:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, @@ -283,83 +274,167 @@ getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, std::string SectName = GVar->getSection(); // If address for a variable is specified, get the address and create // section. - // FIXME: move this attribute checking in PAN. std::string AddrStr = "Address="; if (SectName.compare(0, AddrStr.length(), AddrStr) == 0) { std::string SectAddr = SectName.substr(AddrStr.length()); - return allocateAtGivenAddress(GVar, SectAddr); + return CreateSectionForGlobal(GVar, Mang, SectAddr); } // Create the section specified with section attribute. - return allocateInGivenSection(GVar); + return CreateSectionForGlobal(GVar, Mang); } - return getPIC16DataSection(GV->getSection().c_str(), UDATA); + return getPIC16Section(GV->getSection().c_str(), Kind); } -// Interface used by AsmPrinter to get a code section for a function. -const PIC16Section * -PIC16TargetObjectFile::SectionForCode(const std::string &FnName) const { - const std::string &sec_name = PAN::getCodeSectionName(FnName); - return getPIC16Section(sec_name, CODE); -} - -// Interface used by AsmPrinter to get a frame section for a function. -const PIC16Section * -PIC16TargetObjectFile::SectionForFrame(const std::string &FnName) const { - const std::string &sec_name = PAN::getFrameSectionName(FnName); - return getPIC16Section(sec_name, UDATA_OVR); -} - -// Allocate a global var in existing or new section of given name. +// Create a new section for global variable. If Addr is given then create +// section at that address else create by name. const MCSection * -PIC16TargetObjectFile::allocateInGivenSection(const GlobalVariable *GV) const { - // Determine the type of section that we need to create. - PIC16SectionType SecTy; - +PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV, + Mangler *Mang, + const std::string &Addr) const { // See if this is an uninitialized global. const Constant *C = GV->getInitializer(); if (C->isNullValue()) - SecTy = UDATA; + return CreateBSSSectionForGlobal(GV, Addr); + // If this is initialized data in RAM. Put it in the correct IDATA section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - SecTy = IDATA; + if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) + return CreateIDATASectionForGlobal(GV, Addr); + // This is initialized data in rom, put it in the readonly section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - SecTy = ROMDATA; - else - llvm_unreachable ("Could not determine section type for global"); - - PIC16Section *S = getPIC16UserSection(GV->getSection().c_str(), SecTy); - S->Items.push_back(GV); - return S; + if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) + return CreateROSectionForGlobal(GV, Addr); + + // Else let the default implementation take care of it. + return TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM); } -// Allocate a global var in a new absolute sections at given address. +// Create uninitialized section for a variable. const MCSection * -PIC16TargetObjectFile::allocateAtGivenAddress(const GlobalVariable *GV, - const std::string &Addr) const { - // Determine the type of section that we need to create. - PIC16SectionType SecTy; +PIC16TargetObjectFile::CreateBSSSectionForGlobal(const GlobalVariable *GV, + std::string Addr) const { + assert(GV->hasInitializer() && "This global doesn't need space"); + assert(GV->getInitializer()->isNullValue() && + "Unitialized global 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->getNameStr() + "." + Addr + "."; + Name = PAN::getUdataSectionName(BSSSections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewBSS = FoundBSS; + if (NewBSS == NULL) { + const MCSectionPIC16 *NewSection = + getPIC16Section(Name.c_str(), MCSectionPIC16::UDATA_Kind()); + NewBSS = new PIC16Section(NewSection); + BSSSections.push_back(NewBSS); + } - // See if this is an uninitialized global. - const Constant *C = GV->getInitializer(); - if (C->isNullValue()) - SecTy = UDATA; - // If this is initialized data in RAM. Put it in the correct IDATA section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - SecTy = IDATA; - // This is initialized data in rom, put it in the readonly section. - else if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - SecTy = ROMDATA; - else - llvm_unreachable ("Could not determine section type for global"); - - std::string Prefix = GV->getNameStr() + "." + Addr + "."; - std::string SName = PAN::getUserSectionName(Prefix); - PIC16Section *S = getPIC16UserSection(SName.c_str(), SecTy, Addr.c_str()); - S->Items.push_back(GV); - return S; + // 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 MCSection * +PIC16TargetObjectFile::getROSectionForGlobal(const GlobalVariable *GV) const { + ROSections[0]->Items.push_back(GV); + return ROSections[0]->S_; } +// Create initialized data section for a variable. +const MCSection * +PIC16TargetObjectFile::CreateIDATASectionForGlobal(const GlobalVariable *GV, + std::string Addr) const { + assert(GV->hasInitializer() && "This global doesn't need space"); + assert(!GV->getInitializer()->isNullValue() && + "initialized global 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->getNameStr() + "." + Addr + "."; + Name = PAN::getIdataSectionName(IDATASections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewIDATASec = FoundIDATASec; + if (NewIDATASec == NULL) { + const MCSectionPIC16 *NewSection = + getPIC16Section(Name.c_str(), MCSectionPIC16::IDATA_Kind()); + 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 MCSection * +PIC16TargetObjectFile::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->getNameStr() + "." + Addr + "."; + Name = PAN::getRomdataSectionName(ROSections.size(), Prefix) + " " + Addr; + } + + PIC16Section *NewRomSec = FoundROSec; + if (NewRomSec == NULL) { + const MCSectionPIC16 *NewSection = + getPIC16Section(Name.c_str(), MCSectionPIC16::ROMDATA_Kind()); + NewRomSec = new PIC16Section(NewSection); + ROSections.push_back(NewRomSec); + } + + // Insert the GV into this ROM Section. + NewRomSec->Items.push_back(GV); + return NewRomSec->S_; +} |