diff --git a/lib/Target/PIC16/PIC16AsmPrinter.cpp b/lib/Target/PIC16/PIC16AsmPrinter.cpp index 1792eaa8351..8c39272e031 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/PIC16AsmPrinter.cpp @@ -164,7 +164,6 @@ void PIC16AsmPrinter::printDecls(void) { for (std::list::const_iterator I = Decls.begin(); I != Decls.end(); I++) { O << TAI->getExternDirective() << *I << "\n"; - // FIXME: Use PAN::getXXXLabel() funtions hrer. O << TAI->getExternDirective() << PAN::getArgsLabel(*I) << "\n"; O << TAI->getExternDirective() << PAN::getRetvalLabel(*I) << "\n"; } @@ -183,8 +182,16 @@ bool PIC16AsmPrinter::doInitialization (Module &M) { assert(DW && "Dwarf Writer is not available"); DW->BeginModule(&M, MMI, O, this, TAI); + // Set the section names for all globals. + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ++I) { + I->setSection(TAI->SectionForGlobal(I)->getName()); + } + EmitExternsAndGlobals (M); - EmitGlobalData(M); + EmitIData(M); + EmitUData(M); + EmitAutos(M); EmitRomData(M); return Result; } @@ -238,31 +245,19 @@ void PIC16AsmPrinter::EmitExternsAndGlobals (Module &M) { void PIC16AsmPrinter::EmitRomData (Module &M) { - SwitchToSection(TAI->getReadOnlySection()); - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - if (!I->hasInitializer()) // External global require no code. - continue; + const PIC16TargetAsmInfo *PTAI = static_cast(TAI); - Constant *C = I->getInitializer(); - const PointerType *PtrTy = I->getType(); - int AddrSpace = PtrTy->getAddressSpace(); - if ((!C->isNullValue()) && (AddrSpace == PIC16ISD::ROM_SPACE)) { + std::vector Items = PTAI->ROSection->Items; + if (! Items.size()) return; - if (EmitSpecialLLVMGlobal(I)) - continue; - - // Any variables reaching here with "." in its name is a local scope - // variable and should not be printed in global data section. - std::string name = Mang->getValueName(I); - if (PAN::isLocalName(name)) - continue; - - I->setSection(TAI->getReadOnlySection()->getName()); - O << name; - EmitGlobalConstant(C, AddrSpace); - O << "\n"; - } + // 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); } } @@ -276,9 +271,7 @@ bool PIC16AsmPrinter::doFinalization(Module &M) { void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { const Function *F = MF.getFunction(); std::string FuncName = Mang->getValueName(F); - Module *M = const_cast(F->getParent()); const TargetData *TD = TM.getTargetData(); - unsigned FrameSize = 0; // Emit the data section name. O << "\n"; const char *SectionName = PAN::getFrameSectionName(CurrentFnName).c_str(); @@ -318,57 +311,15 @@ void PIC16AsmPrinter::emitFunctionData(MachineFunction &MF) { int TempSize = PTLI->GetTmpSize(); if (TempSize > 0 ) O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize <<"\n"; - - // Emit the section name for local variables. - O << "\n"; - const char* SecNameLocals = PAN::getAutosSectionName(CurrentFnName).c_str() ; - - const Section *fADataSection = TAI->getNamedSection(SecNameLocals, - SectionFlags::Writeable); - SwitchToSection(fADataSection); - - // Emit the function variables. - - // In PIC16 all the function arguments and local variables are global. - // Therefore to get the variable belonging to this function entire - // global list will be traversed and variables belonging to this function - // will be emitted in the current data section. - for (Module::global_iterator I = M->global_begin(), E = M->global_end(); - I != E; ++I) { - std::string VarName = Mang->getValueName(I); - - // The variables of a function are of form FuncName.* . If this variable - // does not belong to this function then continue. - // Static local varilabes of a function does not have .auto. in their - // name. They are not printed as part of function data but module - // level global data. - if (! PAN::isLocalToFunc(FuncName, VarName)) - continue; - - I->setSection(TAI->SectionForGlobal(I)->getName()); - Constant *C = I->getInitializer(); - const Type *Ty = C->getType(); - unsigned Size = TD->getTypeAllocSize(Ty); - FrameSize += Size; - // Emit memory reserve directive. - O << VarName << " RES " << Size << "\n"; - } } -void PIC16AsmPrinter::EmitGlobalData (Module &M) -{ - // Set the section names for all globals. - for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) { - I->setSection(TAI->SectionForGlobal(I)->getName()); - } - +void PIC16AsmPrinter::EmitIData (Module &M) { const PIC16TargetAsmInfo *PTAI = static_cast(TAI); - const TargetData *TD = TM.getTargetData(); - // Now print all IDATA sections. + // Print all IDATA sections. std::vector IDATASections = PTAI->IDATASections; for (unsigned i = 0; i < IDATASections.size(); i++) { + O << "\n"; SwitchToSection(IDATASections[i]->S_); std::vector Items = IDATASections[i]->Items; for (unsigned j = 0; j < Items.size(); j++) { @@ -379,10 +330,16 @@ void PIC16AsmPrinter::EmitGlobalData (Module &M) EmitGlobalConstant(C, AddrSpace); } } +} - // Now print all BSS sections. +void PIC16AsmPrinter::EmitUData (Module &M) { + const PIC16TargetAsmInfo *PTAI = static_cast(TAI); + const TargetData *TD = TM.getTargetData(); + + // Print all BSS sections. std::vector BSSSections = PTAI->BSSSections; for (unsigned i = 0; i < BSSSections.size(); i++) { + O << "\n"; SwitchToSection(BSSSections[i]->S_); std::vector Items = BSSSections[i]->Items; for (unsigned j = 0; j < Items.size(); j++) { @@ -397,3 +354,26 @@ void PIC16AsmPrinter::EmitGlobalData (Module &M) } } +void PIC16AsmPrinter::EmitAutos (Module &M) +{ + // Section names for all globals are already set. + + const PIC16TargetAsmInfo *PTAI = static_cast(TAI); + const TargetData *TD = TM.getTargetData(); + + // Now print all Autos sections. + std::vector AutosSections = PTAI->AutosSections; + for (unsigned i = 0; i < AutosSections.size(); i++) { + O << "\n"; + SwitchToSection(AutosSections[i]->S_); + std::vector Items = AutosSections[i]->Items; + for (unsigned j = 0; j < Items.size(); j++) { + std::string VarName = Mang->getValueName(Items[j]); + Constant *C = Items[j]->getInitializer(); + const Type *Ty = C->getType(); + unsigned Size = TD->getTypeAllocSize(Ty); + // Emit memory reserve directive. + O << VarName << " RES " << Size << "\n"; + } + } +} diff --git a/lib/Target/PIC16/PIC16AsmPrinter.h b/lib/Target/PIC16/PIC16AsmPrinter.h index 2bc8a57e717..f021695eab6 100644 --- a/lib/Target/PIC16/PIC16AsmPrinter.h +++ b/lib/Target/PIC16/PIC16AsmPrinter.h @@ -43,7 +43,9 @@ namespace llvm { bool printInstruction(const MachineInstr *MI); // definition autogenerated. bool printMachineInstruction(const MachineInstr *MI); void EmitExternsAndGlobals (Module &M); - void EmitGlobalData (Module &M); + void EmitIData (Module &M); + void EmitUData (Module &M); + void EmitAutos (Module &M); void EmitRomData (Module &M); void emitFunctionData(MachineFunction &MF); void printDecls(void); diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp index 3837f9ef7b5..295188f0b41 100644 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.cpp +++ b/lib/Target/PIC16/PIC16TargetAsmInfo.cpp @@ -44,6 +44,7 @@ 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()); } const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const @@ -154,6 +155,40 @@ PIC16TargetAsmInfo::getIDATASectionForGlobal(const GlobalVariable *GV) const { return FoundIDATA->S_; } +// Get the section for an automatic variable of a function. +// For PIC16 they are globals only with mangled names. +const Section * +PIC16TargetAsmInfo::getSectionForAuto(const GlobalVariable *GV) const { + + const std::string name = PAN::getSectionNameForSym(GV->getName()); + + // 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 Section *NewSection = getNamedSection (name.c_str()); + + 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_; +} + + // Override default implementation to put the true globals into // multiple data sections if required. const Section* @@ -168,8 +203,7 @@ PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { // name for it and return. const std::string name = GV->getName(); if (PAN::isLocalName(name)) { - const std::string Sec_Name = PAN::getSectionNameForSym(name); - return getNamedSection(Sec_Name.c_str()); + return getSectionForAuto(GV); } // See if this is an uninitialized global. @@ -177,11 +211,16 @@ PIC16TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV1) const { if (C->isNullValue()) return getBSSSectionForGlobal(GV); - // This is initialized data. We only deal with initialized data in RAM. + // If this is initialized data in RAM. Put it in the correct IDATA section. if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) 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_; + } + // Else let the default implementation take care of it. return TargetAsmInfo::SelectSectionForGlobal(GV); } @@ -195,4 +234,10 @@ PIC16TargetAsmInfo::~PIC16TargetAsmInfo() { for (unsigned i = 0; i < IDATASections.size(); i++) { delete IDATASections[i]; } + + for (unsigned i = 0; i < AutosSections.size(); i++) { + delete AutosSections[i]; + } + + delete ROSection; } diff --git a/lib/Target/PIC16/PIC16TargetAsmInfo.h b/lib/Target/PIC16/PIC16TargetAsmInfo.h index 8eaa48a96dc..a39209daaf6 100644 --- a/lib/Target/PIC16/PIC16TargetAsmInfo.h +++ b/lib/Target/PIC16/PIC16TargetAsmInfo.h @@ -43,6 +43,8 @@ namespace llvm { PIC16TargetAsmInfo(const PIC16TargetMachine &TM); mutable std::vector BSSSections; mutable std::vector IDATASections; + mutable std::vector AutosSections; + mutable PIC16Section *ROSection; virtual ~PIC16TargetAsmInfo(); private: @@ -53,6 +55,7 @@ namespace llvm { virtual const char *getASDirective(unsigned size, unsigned AS) const; const Section *getBSSSectionForGlobal(const GlobalVariable *GV) const; const Section *getIDATASectionForGlobal(const GlobalVariable *GV) const; + const Section *getSectionForAuto(const GlobalVariable *GV) const; virtual const Section *SelectSectionForGlobal(const GlobalValue *GV) const; public: void SetSectionForGVs(Module &M); @@ -62,6 +65,9 @@ namespace llvm { std::vector getIDATASections() const { return IDATASections; } + std::vector getAutosSections() const { + return AutosSections; + } }; } // namespace llvm