diff options
author | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-10-15 19:26:25 +0000 |
---|---|---|
committer | Sanjiv Gupta <sanjiv.gupta@microchip.com> | 2009-10-15 19:26:25 +0000 |
commit | ac2620eaebfccc759fbd341cfa5cfda563b7a71d (patch) | |
tree | 2f4623142c423413b4ebfac930162f9b79866c39 | |
parent | 1b2cfa4be33b01c9fe32b1dcb7a9ba2298e8e25c (diff) | |
download | external_llvm-ac2620eaebfccc759fbd341cfa5cfda563b7a71d.zip external_llvm-ac2620eaebfccc759fbd341cfa5cfda563b7a71d.tar.gz external_llvm-ac2620eaebfccc759fbd341cfa5cfda563b7a71d.tar.bz2 |
Re-apply 84180 with the fixed test case.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84195 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp | 170 | ||||
-rw-r--r-- | lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h | 8 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16.h | 267 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16DebugInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16ISelLowering.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16InstrInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16MCAsmInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16MemSelOpt.cpp | 1 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16TargetObjectFile.cpp | 471 | ||||
-rw-r--r-- | lib/Target/PIC16/PIC16TargetObjectFile.h | 159 | ||||
-rw-r--r-- | test/CodeGen/PIC16/globals.ll | 6 |
11 files changed, 394 insertions, 692 deletions
diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp index 3f415af..1afd3ee 100644 --- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp +++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.cpp @@ -12,8 +12,9 @@ // //===----------------------------------------------------------------------===// +#include "PIC16ABINames.h" #include "PIC16AsmPrinter.h" -#include "MCSectionPIC16.h" +#include "PIC16Section.h" #include "PIC16MCAsmInfo.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -39,7 +40,7 @@ PIC16AsmPrinter::PIC16AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM, : AsmPrinter(O, TM, T, V), DbgInfo(O, T) { PTLI = static_cast<PIC16TargetLowering*>(TM.getTargetLowering()); PMAI = static_cast<const PIC16MCAsmInfo*>(T); - PTOF = (PIC16TargetObjectFile*)&PTLI->getObjFileLowering(); + PTOF = (PIC16TargetObjectFile *)&PTLI->getObjFileLowering(); } bool PIC16AsmPrinter::printMachineInstruction(const MachineInstr *MI) { @@ -73,11 +74,12 @@ bool PIC16AsmPrinter::runOnMachineFunction(MachineFunction &MF) { DbgInfo.BeginFunction(MF); // Emit the autos section of function. - EmitAutos(CurrentFnName); + // EmitAutos(CurrentFnName); // Now emit the instructions of function in its code section. - const MCSection *fCodeSection = - getObjFileLowering().getSectionForFunction(CurrentFnName); + const MCSection *fCodeSection + = getObjFileLowering().SectionForCode(CurrentFnName); + // Start the Code Section. O << "\n"; OutStreamer.SwitchSection(fCodeSection); @@ -229,12 +231,26 @@ bool PIC16AsmPrinter::doInitialization(Module &M) { // Set the section names for all globals. for (Module::global_iterator I = M.global_begin(), E = M.global_end(); - I != E; ++I) - if (!I->isDeclaration() && !I->hasAvailableExternallyLinkage()) { + I != E; ++I) { + + // Record External Var Decls. + if (I->isDeclaration()) { + ExternalVarDecls.push_back(I); + continue; + } + + // Record Exteranl Var Defs. + if (I->hasExternalLinkage() || I->hasCommonLinkage()) { + ExternalVarDefs.push_back(I); + } + + // Sectionify actual data. + if (!I->hasAvailableExternallyLinkage()) { const MCSection *S = getObjFileLowering().SectionForGlobal(I, Mang, TM); - I->setSection(((const MCSectionPIC16*)S)->getName()); + I->setSection(((const PIC16Section *)S)->getName()); } + } DbgInfo.BeginModule(M); EmitFunctionDecls(M); @@ -242,7 +258,9 @@ bool PIC16AsmPrinter::doInitialization(Module &M) { EmitDefinedVars(M); EmitIData(M); EmitUData(M); + EmitAllAutos(M); EmitRomData(M); + EmitUserSections(M); return Result; } @@ -287,7 +305,7 @@ void PIC16AsmPrinter::EmitFunctionDecls(Module &M) { // Emit variables imported from other Modules. void PIC16AsmPrinter::EmitUndefinedVars(Module &M) { - std::vector<const GlobalVariable*> Items = PTOF->ExternalVarDecls->Items; + std::vector<const GlobalVariable*> Items = ExternalVarDecls; if (!Items.size()) return; O << "\n" << MAI->getCommentString() << "Imported Variables - BEGIN" << "\n"; @@ -299,7 +317,7 @@ void PIC16AsmPrinter::EmitUndefinedVars(Module &M) { // Emit variables defined in this module and are available to other modules. void PIC16AsmPrinter::EmitDefinedVars(Module &M) { - std::vector<const GlobalVariable*> Items = PTOF->ExternalVarDefs->Items; + std::vector<const GlobalVariable*> Items = ExternalVarDefs; if (!Items.size()) return; O << "\n" << MAI->getCommentString() << "Exported Variables - BEGIN" << "\n"; @@ -312,24 +330,14 @@ void PIC16AsmPrinter::EmitDefinedVars(Module &M) { // Emit initialized data placed in ROM. void PIC16AsmPrinter::EmitRomData(Module &M) { // Print ROM Data section. - const std::vector<PIC16Section*> &ROSections = PTOF->ROSections; - for (unsigned i = 0; i < ROSections.size(); i++) { - const std::vector<const GlobalVariable*> &Items = ROSections[i]->Items; - if (!Items.size()) continue; - O << "\n"; - OutStreamer.SwitchSection(PTOF->ROSections[i]->S_); - for (unsigned j = 0; j < Items.size(); j++) { - O << Mang->getMangledName(Items[j]); - Constant *C = Items[j]->getInitializer(); - int AddrSpace = Items[j]->getType()->getAddressSpace(); - EmitGlobalConstant(C, AddrSpace); - } - } + const PIC16Section *ROSection = PTOF->ROMDATASection(); + if (ROSection == NULL) return; + EmitInitializedDataSection(ROSection); } bool PIC16AsmPrinter::doFinalization(Module &M) { printLibcallDecls(); - EmitRemainingAutos(); + // EmitRemainingAutos(); DbgInfo.EndModule(M); O << "\n\t" << "END\n"; return AsmPrinter::doFinalization(M); @@ -343,7 +351,7 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) { O << "\n"; const MCSection *fPDataSection = - getObjFileLowering().getSectionForFunctionFrame(CurrentFnName); + getObjFileLowering().SectionForFrame(CurrentFnName); OutStreamer.SwitchSection(fPDataSection); // Emit function frame label @@ -379,103 +387,79 @@ void PIC16AsmPrinter::EmitFunctionFrame(MachineFunction &MF) { O << PAN::getTempdataLabel(CurrentFnName) << " RES " << TempSize << '\n'; } -void PIC16AsmPrinter::EmitIData(Module &M) { - // Print all IDATA sections. - const std::vector<PIC16Section*> &IDATASections = PTOF->IDATASections; - for (unsigned i = 0; i < IDATASections.size(); i++) { - O << "\n"; - if (IDATASections[i]->S_->getName().find("llvm.") != std::string::npos) - continue; - OutStreamer.SwitchSection(IDATASections[i]->S_); - std::vector<const GlobalVariable*> Items = IDATASections[i]->Items; +void PIC16AsmPrinter::EmitInitializedDataSection(const PIC16Section *S) { + /// Emit Section header. + OutStreamer.SwitchSection(S); + + std::vector<const GlobalVariable*> Items = S->Items; for (unsigned j = 0; j < Items.size(); j++) { std::string Name = Mang->getMangledName(Items[j]); Constant *C = Items[j]->getInitializer(); int AddrSpace = Items[j]->getType()->getAddressSpace(); O << Name; EmitGlobalConstant(C, AddrSpace); - } - } + } } -void PIC16AsmPrinter::EmitUData(Module &M) { - const TargetData *TD = TM.getTargetData(); +void PIC16AsmPrinter::EmitIData(Module &M) { - // Print all BSS sections. - const std::vector<PIC16Section*> &BSSSections = PTOF->BSSSections; - for (unsigned i = 0; i < BSSSections.size(); i++) { + // Print all IDATA sections. + const std::vector<PIC16Section *> &IDATASections = PTOF->IDATASections(); + for (unsigned i = 0; i < IDATASections.size(); i++) { O << "\n"; - OutStreamer.SwitchSection(BSSSections[i]->S_); - std::vector<const GlobalVariable*> Items = BSSSections[i]->Items; + if (IDATASections[i]->getName().find("llvm.") != std::string::npos) + continue; + + EmitInitializedDataSection(IDATASections[i]); + } +} + +void PIC16AsmPrinter::EmitUninitializedDataSection(const PIC16Section *S) { + const TargetData *TD = TM.getTargetData(); + OutStreamer.SwitchSection(S); + std::vector<const GlobalVariable*> Items = S->Items; for (unsigned j = 0; j < Items.size(); j++) { std::string Name = Mang->getMangledName(Items[j]); Constant *C = Items[j]->getInitializer(); const Type *Ty = C->getType(); unsigned Size = TD->getTypeAllocSize(Ty); - O << Name << " RES " << Size << "\n"; } - } } -void PIC16AsmPrinter::EmitAutos(std::string FunctName) { - // Section names for all globals are already set. - const TargetData *TD = TM.getTargetData(); - - // Now print Autos section for this function. - std::string SectionName = PAN::getAutosSectionName(FunctName); - const std::vector<PIC16Section*> &AutosSections = PTOF->AutosSections; - for (unsigned i = 0; i < AutosSections.size(); i++) { +void PIC16AsmPrinter::EmitUData(Module &M) { + // Print all UDATA sections. + const std::vector<PIC16Section*> &UDATASections = PTOF->UDATASections(); + for (unsigned i = 0; i < UDATASections.size(); i++) { O << "\n"; - if (AutosSections[i]->S_->getName() == SectionName) { - // Set the printing status to true - AutosSections[i]->setPrintedStatus(true); - OutStreamer.SwitchSection(AutosSections[i]->S_); - const std::vector<const GlobalVariable*> &Items = AutosSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string VarName = Mang->getMangledName(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"; - } - break; - } + EmitUninitializedDataSection(UDATASections[i]); } } -// Print autos that were not printed during the code printing of functions. -// As the functions might themselves would have got deleted by the optimizer. -void PIC16AsmPrinter::EmitRemainingAutos() { - const TargetData *TD = TM.getTargetData(); - - // Now print Autos section for this function. - std::vector <PIC16Section *>AutosSections = PTOF->AutosSections; - for (unsigned i = 0; i < AutosSections.size(); i++) { - - // if the section is already printed then don't print again - if (AutosSections[i]->isPrinted()) - continue; - - // Set status as printed - AutosSections[i]->setPrintedStatus(true); - +void PIC16AsmPrinter::EmitUserSections(Module &M) { + const std::vector<PIC16Section*> &USERSections = PTOF->USERSections(); + for (unsigned i = 0; i < USERSections.size(); i++) { O << "\n"; - OutStreamer.SwitchSection(AutosSections[i]->S_); - const std::vector<const GlobalVariable*> &Items = AutosSections[i]->Items; - for (unsigned j = 0; j < Items.size(); j++) { - std::string VarName = Mang->getMangledName(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"; + const PIC16Section *S = USERSections[i]; + if (S->isUDATA_Type()) { + EmitUninitializedDataSection(S); + } else if (S->isIDATA_Type() || S->isROMDATA_Type()) { + EmitInitializedDataSection(S); + } else { + llvm_unreachable ("unknow user section type"); } } } +void PIC16AsmPrinter::EmitAllAutos(Module &M) { + // Print all AUTO sections. + const std::vector<PIC16Section*> &AUTOSections = PTOF->AUTOSections(); + for (unsigned i = 0; i < AUTOSections.size(); i++) { + O << "\n"; + EmitUninitializedDataSection(AUTOSections[i]); + } +} extern "C" void LLVMInitializePIC16AsmPrinter() { RegisterAsmPrinter<PIC16AsmPrinter> X(ThePIC16Target); diff --git a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h index 2dd4600..686d080 100644 --- a/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h +++ b/lib/Target/PIC16/AsmPrinter/PIC16AsmPrinter.h @@ -53,11 +53,13 @@ namespace llvm { void EmitDefinedVars (Module &M); void EmitIData (Module &M); void EmitUData (Module &M); - void EmitAutos (std::string FunctName); - void EmitRemainingAutos (); + void EmitAllAutos (Module &M); void EmitRomData (Module &M); + void EmitUserSections (Module &M); void EmitFunctionFrame(MachineFunction &MF); void printLibcallDecls(); + void EmitUninitializedDataSection(const PIC16Section *S); + void EmitInitializedDataSection(const PIC16Section *S); protected: bool doInitialization(Module &M); bool doFinalization(Module &M); @@ -74,6 +76,8 @@ namespace llvm { PIC16DbgInfo DbgInfo; const PIC16MCAsmInfo *PMAI; std::list<const char *> LibcallDecls; // List of extern decls. + std::vector<const GlobalVariable *> ExternalVarDecls; + std::vector<const GlobalVariable *> ExternalVarDefs; }; } // end of namespace diff --git a/lib/Target/PIC16/PIC16.h b/lib/Target/PIC16/PIC16.h index 8a3704d..e46c9b2 100644 --- a/lib/Target/PIC16/PIC16.h +++ b/lib/Target/PIC16/PIC16.h @@ -42,266 +42,15 @@ namespace PIC16CC { UGE }; } - // A Central class to manage all ABI naming conventions. - // PAN - [P]ic16 [A]BI [N]ames - class PAN { - public: - // Map the name of the symbol to its section name. - // Current ABI: - // ----------------------------------------------------- - // ALL Names are prefixed with the symobl '@'. - // ------------------------------------------------------ - // Global variables do not have any '.' in their names. - // These are maily function names and global variable names. - // Example - @foo, @i - // ------------------------------------------------------- - // Functions and auto variables. - // Names are mangled as <prefix><funcname>.<tag>.<varname> - // Where <prefix> is '@' and <tag> is any one of - // the following - // .auto. - an automatic var of a function. - // .temp. - temproray data of a function. - // .ret. - return value label for a function. - // .frame. - Frame label for a function where retval, args - // and temps are stored. - // .args. - Label used to pass arguments to a direct call. - // Example - Function name: @foo - // Its frame: @foo.frame. - // Its retval: @foo.ret. - // Its local vars: @foo.auto.a - // Its temp data: @foo.temp. - // Its arg passing: @foo.args. - //---------------------------------------------- - // Libcall - compiler generated libcall names must start with .lib. - // This id will be used to emit extern decls for libcalls. - // Example - libcall name: @.lib.sra.i8 - // To pass args: @.lib.sra.i8.args. - // To return val: @.lib.sra.i8.ret. - //---------------------------------------------- - // SECTION Names - // uninitialized globals - @udata.<num>.# - // initialized globals - @idata.<num>.# - // Function frame - @<func>.frame_section. - // Function autos - @<func>.autos_section. - // Declarations - Enclosed in comments. No section for them. - //---------------------------------------------------------- - - // Tags used to mangle different names. - enum TAGS { - PREFIX_SYMBOL, - GLOBAL, - STATIC_LOCAL, - AUTOS_LABEL, - FRAME_LABEL, - RET_LABEL, - ARGS_LABEL, - TEMPS_LABEL, - - LIBCALL, - - FRAME_SECTION, - AUTOS_SECTION, - CODE_SECTION - }; - - // Textual names of the tags. - inline static const char *getTagName(TAGS tag) { - switch (tag) { - default: return ""; - case PREFIX_SYMBOL: return "@"; - case AUTOS_LABEL: return ".auto."; - case FRAME_LABEL: return ".frame."; - case TEMPS_LABEL: return ".temp."; - case ARGS_LABEL: return ".args."; - case RET_LABEL: return ".ret."; - case LIBCALL: return ".lib."; - case FRAME_SECTION: return ".frame_section."; - case AUTOS_SECTION: return ".autos_section."; - case CODE_SECTION: return ".code_section."; - } - } - - // Get tag type for the Symbol. - inline static TAGS getSymbolTag(const std::string &Sym) { - if (Sym.find(getTagName(TEMPS_LABEL)) != std::string::npos) - return TEMPS_LABEL; - - if (Sym.find(getTagName(FRAME_LABEL)) != std::string::npos) - return FRAME_LABEL; - - if (Sym.find(getTagName(RET_LABEL)) != std::string::npos) - return RET_LABEL; - - if (Sym.find(getTagName(ARGS_LABEL)) != std::string::npos) - return ARGS_LABEL; - - if (Sym.find(getTagName(AUTOS_LABEL)) != std::string::npos) - return AUTOS_LABEL; - - if (Sym.find(getTagName(LIBCALL)) != std::string::npos) - return LIBCALL; - - // It does not have any Tag. So its a true global or static local. - if (Sym.find(".") == std::string::npos) - return GLOBAL; - - // If a . is there, then it may be static local. - // We should mangle these as well in clang. - if (Sym.find(".") != std::string::npos) - return STATIC_LOCAL; - - assert (0 && "Could not determine Symbol's tag"); - return PREFIX_SYMBOL; // Silence warning when assertions are turned off. - } - - // addPrefix - add prefix symbol to a name if there isn't one already. - inline static std::string addPrefix (const std::string &Name) { - std::string prefix = getTagName (PREFIX_SYMBOL); - - // If this name already has a prefix, nothing to do. - if (Name.compare(0, prefix.size(), prefix) == 0) - return Name; - - return prefix + Name; - } - - // Get mangled func name from a mangled sym name. - // In all cases func name is the first component before a '.'. - static inline std::string getFuncNameForSym(const std::string &Sym1) { - assert (getSymbolTag(Sym1) != GLOBAL && "not belongs to a function"); - - std::string Sym = addPrefix(Sym1); - - // Position of the . after func name. That's where func name ends. - size_t func_name_end = Sym.find ('.'); - - return Sym.substr (0, func_name_end); - } - - // Get Frame start label for a func. - static std::string getFrameLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(FRAME_LABEL); - return Func1 + tag; - } - - static std::string getRetvalLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(RET_LABEL); - return Func1 + tag; - } - - static std::string getArgsLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(ARGS_LABEL); - return Func1 + tag; - } - - static std::string getTempdataLabel(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(TEMPS_LABEL); - return Func1 + tag; - } - static std::string getFrameSectionName(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(FRAME_SECTION); - return Func1 + tag + "# UDATA_OVR"; - } - - static std::string getAutosSectionName(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(AUTOS_SECTION); - return Func1 + tag + "# UDATA_OVR"; - } - - static std::string getCodeSectionName(const std::string &Func) { - std::string Func1 = addPrefix(Func); - std::string tag = getTagName(CODE_SECTION); - return Func1 + tag + "# CODE"; - } - - // udata, romdata and idata section names are generated by a given number. - // @udata.<num>.# - static std::string getUdataSectionName(unsigned num, - std::string prefix = "") { - std::ostringstream o; - o << getTagName(PREFIX_SYMBOL) << prefix << "udata." << num - << ".# UDATA"; - return o.str(); - } - - static std::string getRomdataSectionName(unsigned num, - std::string prefix = "") { - std::ostringstream o; - 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(); - } - - inline static bool isLocalName (const std::string &Name) { - if (getSymbolTag(Name) == AUTOS_LABEL) - return true; - - return false; - } - - inline static bool isMemIntrinsic (const std::string &Name) { - if (Name.compare("@memcpy") == 0 || Name.compare("@memset") == 0 || - Name.compare("@memmove") == 0) { - return true; - } - - return false; - } - - inline static bool isLocalToFunc (std::string &Func, std::string &Var) { - if (! isLocalName(Var)) return false; - - std::string Func1 = addPrefix(Func); - // Extract func name of the varilable. - const std::string &fname = getFuncNameForSym(Var); - - if (fname.compare(Func1) == 0) - return true; - - return false; - } - - - // Get the section for the given external symbol names. - // This tries to find the type (Tag) of the symbol from its mangled name - // and return appropriate section name for it. - static inline std::string getSectionNameForSym(const std::string &Sym1) { - std::string Sym = addPrefix(Sym1); - - std::string SectionName; - - std::string Fname = getFuncNameForSym (Sym); - TAGS id = getSymbolTag (Sym); - - switch (id) { - default : assert (0 && "Could not determine external symbol type"); - case FRAME_LABEL: - case RET_LABEL: - case TEMPS_LABEL: - case ARGS_LABEL: { - return getFrameSectionName(Fname); - } - case AUTOS_LABEL: { - return getAutosSectionName(Fname); - } - } - } - }; // class PAN. + enum PIC16SectionType { + CODE, + UDATA, + IDATA, + ROMDATA, + UDATA_OVR, + UDATA_SHR + }; // External symbol names require memory to live till the program end. diff --git a/lib/Target/PIC16/PIC16DebugInfo.cpp b/lib/Target/PIC16/PIC16DebugInfo.cpp index dd20f20..0ed44d2 100644 --- a/lib/Target/PIC16/PIC16DebugInfo.cpp +++ b/lib/Target/PIC16/PIC16DebugInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "PIC16.h" +#include "PIC16ABINames.h" #include "PIC16DebugInfo.h" #include "llvm/GlobalVariable.h" #include "llvm/CodeGen/MachineFunction.h" diff --git a/lib/Target/PIC16/PIC16ISelLowering.cpp b/lib/Target/PIC16/PIC16ISelLowering.cpp index bf986b1..635befe 100644 --- a/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "pic16-lower" +#include "PIC16ABINames.h" #include "PIC16ISelLowering.h" #include "PIC16TargetObjectFile.h" #include "PIC16TargetMachine.h" diff --git a/lib/Target/PIC16/PIC16InstrInfo.cpp b/lib/Target/PIC16/PIC16InstrInfo.cpp index cb0c41b..87bd3d9 100644 --- a/lib/Target/PIC16/PIC16InstrInfo.cpp +++ b/lib/Target/PIC16/PIC16InstrInfo.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "PIC16.h" +#include "PIC16ABINames.h" #include "PIC16InstrInfo.h" #include "PIC16TargetMachine.h" #include "PIC16GenInstrInfo.inc" diff --git a/lib/Target/PIC16/PIC16MCAsmInfo.cpp b/lib/Target/PIC16/PIC16MCAsmInfo.cpp index a17d1a8..827315e 100644 --- a/lib/Target/PIC16/PIC16MCAsmInfo.cpp +++ b/lib/Target/PIC16/PIC16MCAsmInfo.cpp @@ -16,6 +16,7 @@ // FIXME: Layering violation to get enums and static function, should be moved // to separate headers. #include "PIC16.h" +#include "PIC16ABINames.h" #include "PIC16ISelLowering.h" using namespace llvm; diff --git a/lib/Target/PIC16/PIC16MemSelOpt.cpp b/lib/Target/PIC16/PIC16MemSelOpt.cpp index c9ebb57..a97dc35 100644 --- a/lib/Target/PIC16/PIC16MemSelOpt.cpp +++ b/lib/Target/PIC16/PIC16MemSelOpt.cpp @@ -21,6 +21,7 @@ #define DEBUG_TYPE "pic16-codegen" #include "PIC16.h" +#include "PIC16ABINames.h" #include "PIC16InstrInfo.h" #include "PIC16MCAsmInfo.h" #include "PIC16TargetMachine.h" diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.cpp b/lib/Target/PIC16/PIC16TargetObjectFile.cpp index a2a4c09..330722d 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,75 +19,111 @@ using namespace llvm; -MCSectionPIC16 *MCSectionPIC16::Create(const StringRef &Name, SectionKind K, - int Address, int Color, MCContext &Ctx) { - return new (Ctx) MCSectionPIC16(Name, K, Address, Color); +PIC16TargetObjectFile::PIC16TargetObjectFile() { } +/// 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 { -void MCSectionPIC16::PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const { - OS << getName() << '\n'; + /// 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; } +/// 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; + } -PIC16TargetObjectFile::PIC16TargetObjectFile() - : ExternalVarDecls(0), ExternalVarDefs(0) { + return Entry; } + + +/// 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 { -const MCSectionPIC16 *PIC16TargetObjectFile:: -getPIC16Section(const char *Name, SectionKind Kind, - int Address, int Color) const { - MCSectionPIC16 *&Entry = SectionsByName[Name]; + /// Return if we have an already existing one. + PIC16Section *&Entry = SectionsByName[Name]; if (Entry) return Entry; - return Entry = MCSectionPIC16::Create(Name, Kind, Address, Color, - getContext()); + + /// 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; } + +/// 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 = getPIC16Section("udata.# UDATA", MCSectionPIC16::UDATA_Kind()); - ReadOnlySection = getPIC16Section("romdata.# ROMDATA", - MCSectionPIC16::ROMDATA_Kind()); - DataSection = getPIC16Section("idata.# IDATA", MCSectionPIC16::IDATA_Kind()); + // BSSSection = getPIC16DataSection("udata.#", UDATA); + // ReadOnlySection = getPIC16DataSection("romdata.#", ROMDATA); + // DataSection = getPIC16DataSection("idata.#", IDATA); // Need because otherwise a .text symbol is emitted by DwarfWriter // in BeginModule, and gpasm cribbs for that .text symbol. - 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()); + // FIXME: below + // TextSection = getPIC16DataSection("", UDATA); + ROMDATASection_ = NULL; } +/// allocateUDATA - Allocate a un-initialized global to an existing or new UDATA +/// section and return that section. const MCSection * -PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const { +PIC16TargetObjectFile::allocateUDATA(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"); @@ -97,41 +133,37 @@ PIC16TargetObjectFile::getBSSSectionForGlobal(const GlobalVariable *GV) const { const Type *Ty = C->getType(); unsigned ValSize = TD->getTypeAllocSize(Ty); - // Go through all BSS Sections and assign this variable + // Go through all UDATA Sections and assign this variable // to the first available section having enough space. - PIC16Section *FoundBSS = NULL; - for (unsigned i = 0; i < BSSSections.size(); i++) { - if (DataBankSize - BSSSections[i]->Size >= ValSize) { - FoundBSS = BSSSections[i]; + PIC16Section *Found = NULL; + for (unsigned i = 0; i < UDATASections_.size(); i++) { + if (DataBankSize - UDATASections_[i]->getSize() >= ValSize) { + Found = UDATASections_[i]; break; } } - // 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); + // 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); } - // Insert the GV into this BSS. - FoundBSS->Items.push_back(GV); - FoundBSS->Size += ValSize; - return FoundBSS->S_; + // Insert the GV into this UDATA section. + Found->Items.push_back(GV); + Found->setSize(Found->getSize() + ValSize); + return Found; } +/// allocateIDATA - allocate an initialized global into an existing +/// or new section and return that section. const MCSection * -PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{ +PIC16TargetObjectFile::allocateIDATA(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 split initialized RAM data only"); + "can allocate initialized RAM data only"); // Find how much space this global needs. const TargetData *TD = TM->getTargetData(); @@ -140,64 +172,47 @@ PIC16TargetObjectFile::getIDATASectionForGlobal(const GlobalVariable *GV) const{ // Go through all IDATA Sections and assign this variable // to the first available section having enough space. - PIC16Section *FoundIDATA = NULL; - for (unsigned i = 0; i < IDATASections.size(); i++) { - if (DataBankSize - IDATASections[i]->Size >= ValSize) { - FoundIDATA = IDATASections[i]; + PIC16Section *Found = NULL; + for (unsigned i = 0; i < IDATASections_.size(); i++) { + if (DataBankSize - IDATASections_[i]->getSize() >= ValSize) { + Found = IDATASections_[i]; break; } } // No IDATA section spacious enough was found. Crate a new one. - 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); + if (!Found) { + std::string name = PAN::getIdataSectionName(IDATASections_.size()); + Found = getPIC16DataSection(name.c_str(), IDATA); } // Insert the GV into this IDATA. - FoundIDATA->Items.push_back(GV); - FoundIDATA->Size += ValSize; - return FoundIDATA->S_; + Found->Items.push_back(GV); + Found->setSize(Found->getSize() + ValSize); + return Found; } -// Get the section for an automatic variable of a function. -// For PIC16 they are globals only with mangled names. +// Allocate a program memory variable into ROMDATA section. const MCSection * -PIC16TargetObjectFile::getSectionForAuto(const GlobalVariable *GV) const { +PIC16TargetObjectFile::allocateROMDATA(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 MCSectionPIC16 *NewSection = - getPIC16Section(name.c_str(), MCSectionPIC16::UDATA_OVR_Kind()); + std::string name = PAN::getRomdataSectionName(); + PIC16Section *S = getPIC16DataSection(name.c_str(), ROMDATA); - FoundAutoSec = new PIC16Section(NewSection); + S->Items.push_back(GV); + return S; +} - // Add this newly created autos section to the list of AutosSections. - AutosSections.push_back(FoundAutoSec); - } +// 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 { - // Insert the auto into this section. - FoundAutoSec->Items.push_back(GV); + const std::string name = PAN::getSectionNameForSym(GV->getName()); + PIC16Section *S = getPIC16AutoSection(name.c_str()); - return FoundAutoSec->S_; + S->Items.push_back(GV); + return S; } @@ -214,56 +229,50 @@ 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 getSectionForAuto(GV); - - // Record Exteranl Var Defs. - if (GV->hasExternalLinkage() || GV->hasCommonLinkage()) - ExternalVarDefs->Items.push_back(GV); + return allocateAUTO(GV); // See if this is an uninitialized global. const Constant *C = GV->getInitializer(); if (C->isNullValue()) - return getBSSSectionForGlobal(GV); + return allocateUDATA(GV); // If this is initialized data in RAM. Put it in the correct IDATA section. if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) - return getIDATASectionForGlobal(GV); + return allocateIDATA(GV); // This is initialized data in rom, put it in the readonly section. if (GV->getType()->getAddressSpace() == PIC16ISD::ROM_SPACE) - return getROSectionForGlobal(GV); + return allocateROMDATA(GV); // Else let the default implementation take care of it. return TargetLoweringObjectFile::SelectSectionForGlobal(GV, Kind, Mang,TM); } PIC16TargetObjectFile::~PIC16TargetObjectFile() { - 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; +#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 } -/// getSpecialCasedSectionGlobals - Allow the target to completely override +/// getExplicitSectionGlobal - Allow the target to completely override /// section assignment of a global. const MCSection *PIC16TargetObjectFile:: getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, @@ -274,167 +283,83 @@ 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 CreateSectionForGlobal(GVar, Mang, SectAddr); + return allocateAtGivenAddress(GVar, SectAddr); } // Create the section specified with section attribute. - return CreateSectionForGlobal(GVar, Mang); + return allocateInGivenSection(GVar); } - return getPIC16Section(GV->getSection().c_str(), Kind); + return getPIC16DataSection(GV->getSection().c_str(), UDATA); } -// Create a new section for global variable. If Addr is given then create -// section at that address else create by name. +// 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. const MCSection * -PIC16TargetObjectFile::CreateSectionForGlobal(const GlobalVariable *GV, - Mangler *Mang, - const std::string &Addr) const { +PIC16TargetObjectFile::allocateInGivenSection(const GlobalVariable *GV) const { + // Determine the type of section that we need to create. + PIC16SectionType SecTy; + // See if this is an uninitialized global. const Constant *C = GV->getInitializer(); if (C->isNullValue()) - return CreateBSSSectionForGlobal(GV, Addr); - + SecTy = UDATA; // 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); - + else if (GV->getType()->getAddressSpace() == PIC16ISD::RAM_SPACE) + SecTy = IDATA; // 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 TargetLoweringObjectFile::SectionForGlobal(GV, Mang, *TM); + 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; } -// Create uninitialized section for a variable. +// Allocate a global var in a new absolute sections at given address. const MCSection * -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); - } - - // Insert the GV into this BSS. - NewBSS->Items.push_back(GV); +PIC16TargetObjectFile::allocateAtGivenAddress(const GlobalVariable *GV, + const std::string &Addr) const { + // Determine the type of section that we need to create. + PIC16SectionType SecTy; - // 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_; + // 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; } -// 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_; -} diff --git a/lib/Target/PIC16/PIC16TargetObjectFile.h b/lib/Target/PIC16/PIC16TargetObjectFile.h index 75f6cce..6ec5512 100644 --- a/lib/Target/PIC16/PIC16TargetObjectFile.h +++ b/lib/Target/PIC16/PIC16TargetObjectFile.h @@ -10,6 +10,8 @@ #ifndef LLVM_TARGET_PIC16_TARGETOBJECTFILE_H #define LLVM_TARGET_PIC16_TARGETOBJECTFILE_H +#include "PIC16.h" +#include "PIC16ABINames.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/ADT/StringMap.h" #include <vector> @@ -19,7 +21,7 @@ namespace llvm { class GlobalVariable; class Module; class PIC16TargetMachine; - class MCSectionPIC16; + class PIC16Section; enum { DataBankSize = 80 }; @@ -29,91 +31,124 @@ namespace llvm { /// again and printing only those that match the current section. /// Keeping values inside the sections make printing a section much easier. /// - /// FIXME: MOVE ALL THIS STUFF TO MCSectionPIC16. + /// FIXME: MOVE ALL THIS STUFF TO PIC16Section. /// - struct PIC16Section { - const MCSectionPIC16 *S_; // Connection to actual Section. - unsigned Size; // Total size of the objects contained. - bool SectionPrinted; - std::vector<const GlobalVariable*> Items; - - PIC16Section(const MCSectionPIC16 *s) { - S_ = s; - Size = 0; - SectionPrinted = false; - } - bool isPrinted() const { return SectionPrinted; } - void setPrintedStatus(bool status) { SectionPrinted = status; } - }; - + + /// PIC16TargetObjectFile - PIC16 Object file. Contains data and code + /// sections. + // PIC16 Object File has two types of sections. + // 1. Standard Sections + // 1.1 un-initialized global data + // 1.2 initialized global data + // 1.3 program memory data + // 1.4 local variables of functions. + // 2. User defined sections + // 2.1 Objects placed in a specific section. (By _Section() macro) + // 2.2 Objects placed at a specific address. (By _Address() macro) class PIC16TargetObjectFile : public TargetLoweringObjectFile { /// SectionsByName - Bindings of names to allocated sections. - mutable StringMap<MCSectionPIC16*> SectionsByName; + mutable StringMap<PIC16Section*> SectionsByName; const TargetMachine *TM; - const MCSectionPIC16 *getPIC16Section(const char *Name, - SectionKind K, - int Address = -1, - int Color = -1) const; - public: - mutable std::vector<PIC16Section*> BSSSections; - mutable std::vector<PIC16Section*> IDATASections; - mutable std::vector<PIC16Section*> AutosSections; - mutable std::vector<PIC16Section*> ROSections; - mutable PIC16Section *ExternalVarDecls; - mutable PIC16Section *ExternalVarDefs; + /// Lists of sections. + /// Standard Data Sections. + mutable std::vector<PIC16Section *> UDATASections_; + mutable std::vector<PIC16Section *> IDATASections_; + mutable PIC16Section * ROMDATASection_; + + /// Standard Auto Sections. + mutable std::vector<PIC16Section *> AUTOSections_; + + /// User specified sections. + mutable std::vector<PIC16Section *> USERSections_; + + + /// Find or Create a PIC16 Section, without adding it to any + /// section list. + PIC16Section *getPIC16Section(const std::string &Name, + PIC16SectionType Ty, + const std::string &Address = "", + int Color = -1) const; + + /// Convenience functions. These wrappers also take care of adding + /// the newly created section to the appropriate sections list. + + /// Find or Create PIC16 Standard Data Section. + PIC16Section *getPIC16DataSection(const std::string &Name, + PIC16SectionType Ty, + const std::string &Address = "", + int Color = -1) const; + + /// Find or Create PIC16 Standard Auto Section. + PIC16Section *getPIC16AutoSection(const std::string &Name, + PIC16SectionType Ty = UDATA_OVR, + const std::string &Address = "", + int Color = -1) const; + + /// Find or Create PIC16 Standard Auto Section. + PIC16Section *getPIC16UserSection(const std::string &Name, + PIC16SectionType Ty, + const std::string &Address = "", + int Color = -1) const; + + /// Allocate Un-initialized data to a standard UDATA section. + const MCSection *allocateUDATA(const GlobalVariable *GV) const; + /// Allocate Initialized data to a standard IDATA section. + const MCSection *allocateIDATA(const GlobalVariable *GV) const; + + /// Allocate ROM data to the standard ROMDATA section. + const MCSection *allocateROMDATA(const GlobalVariable *GV) const; + + /// Allocate an AUTO variable to an AUTO section. + const MCSection *allocateAUTO(const GlobalVariable *GV) const; + + /// Allocate DATA in user specified section. + const MCSection *allocateInGivenSection(const GlobalVariable *GV) const; + + /// Allocate DATA at user specified address. + const MCSection *allocateAtGivenAddress(const GlobalVariable *GV, + const std::string &Addr) const; + + public: PIC16TargetObjectFile(); ~PIC16TargetObjectFile(); - void Initialize(MCContext &Ctx, const TargetMachine &TM); - + /// Override section allocations for user specified sections. virtual const MCSection * getExplicitSectionGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine &TM) const; + /// Select sections for Data and Auto variables(globals). virtual const MCSection *SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, Mangler *Mang, const TargetMachine&) const; - const MCSection *getSectionForFunction(const std::string &FnName) const; - const MCSection *getSectionForFunctionFrame(const std::string &FnName)const; - - - private: - std::string getSectionNameForSym(const std::string &Sym) const; - - const MCSection *getBSSSectionForGlobal(const GlobalVariable *GV) const; - const MCSection *getIDATASectionForGlobal(const GlobalVariable *GV) const; - const MCSection *getSectionForAuto(const GlobalVariable *GV) const; - const MCSection *CreateBSSSectionForGlobal(const GlobalVariable *GV, - std::string Addr = "") const; - const MCSection *CreateIDATASectionForGlobal(const GlobalVariable *GV, - std::string Addr = "") const; - const MCSection *getROSectionForGlobal(const GlobalVariable *GV) const; - const MCSection *CreateROSectionForGlobal(const GlobalVariable *GV, - std::string Addr = "") const; - const MCSection *CreateSectionForGlobal(const GlobalVariable *GV, - Mangler *Mang, - const std::string &Addr = "") const; - public: - void SetSectionForGVs(Module &M); - const std::vector<PIC16Section*> &getBSSSections() const { - return BSSSections; + /// Return a code section for a function. + const PIC16Section *SectionForCode (const std::string &FnName) const; + + /// Return a frame section for a function. + const PIC16Section *SectionForFrame (const std::string &FnName) const; + + /// Accessors for various section lists. + const std::vector<PIC16Section *> &UDATASections() const { + return UDATASections_; } - const std::vector<PIC16Section*> &getIDATASections() const { - return IDATASections; + const std::vector<PIC16Section *> &IDATASections() const { + return IDATASections_; } - const std::vector<PIC16Section*> &getAutosSections() const { - return AutosSections; + const PIC16Section *ROMDATASection() const { + return ROMDATASection_; } - const std::vector<PIC16Section*> &getROSections() const { - return ROSections; + const std::vector<PIC16Section *> &AUTOSections() const { + return AUTOSections_; + } + const std::vector<PIC16Section *> &USERSections() const { + return USERSections_; } - }; } // end namespace llvm diff --git a/test/CodeGen/PIC16/globals.ll b/test/CodeGen/PIC16/globals.ll index 959eb25..b8c9116 100644 --- a/test/CodeGen/PIC16/globals.ll +++ b/test/CodeGen/PIC16/globals.ll @@ -1,15 +1,15 @@ ; RUN: llc < %s -march=pic16 | FileCheck %s @G1 = global i32 4712, section "Address=412" -; CHECK: @G1.412.idata.0.# IDATA 412 +; CHECK: @G1.412..user_section.# IDATA 412 ; CHECK: @G1 dl 4712 @G2 = global i32 0, section "Address=412" -; CHECK: @G2.412.udata.0.# UDATA 412 +; CHECK: @G2.412..user_section.# UDATA 412 ; CHECK: @G2 RES 4 @G3 = addrspace(1) constant i32 4712, section "Address=412" -; CHECK: @G3.412.romdata.1.# ROMDATA 412 +; CHECK: @G3.412..user_section.# ROMDATA 412 ; CHECK: @G3 rom_dl 4712 |