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
This commit is contained in:
Sanjiv Gupta 2009-07-06 10:18:37 +00:00
parent f03970cf37
commit b2d6d00f8d
6 changed files with 246 additions and 27 deletions

View File

@ -52,4 +52,5 @@ cl::opt<SaveTempsEnum::Values> SaveTemps
"Use current working directory"),
clEnumValN(SaveTempsEnum::Obj, "", "Same as 'cwd'"),
clEnumValEnd),
cl::ValueOptional);
//cl::ValueOptional);
cl::Hidden);

View File

@ -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();

View File

@ -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.<num>.#
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();
}

View File

@ -272,18 +272,19 @@ void PIC16AsmPrinter::EmitDefinedVars (Module &M)
// Emit initialized data placed in ROM.
void PIC16AsmPrinter::EmitRomData (Module &M)
{
std::vector<const GlobalVariable*> 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 <PIC16Section *>ROSections = PTAI->ROSections;
for (unsigned i = 0; i < ROSections.size(); i++) {
std::vector<const GlobalVariable*> 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);
}
}
}

View File

@ -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<GlobalVariable>(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_;
}

View File

@ -48,7 +48,7 @@ namespace llvm {
mutable std::vector<PIC16Section *> BSSSections;
mutable std::vector<PIC16Section *> IDATASections;
mutable std::vector<PIC16Section *> AutosSections;
mutable PIC16Section *ROSection;
mutable std::vector<PIC16Section *> 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<PIC16Section *> getBSSSections() const {
@ -76,6 +83,10 @@ namespace llvm {
std::vector<PIC16Section *> getAutosSections() const {
return AutosSections;
}
std::vector<PIC16Section *> getROSections() const {
return ROSections;
}
virtual const Section* SectionForGlobal(const GlobalValue *GV) const;
};
} // namespace llvm