mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	Add TargetAsmInfo for all ELF-based targets
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53786 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		
							
								
								
									
										38
									
								
								include/llvm/Target/ELFTargetAsmInfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								include/llvm/Target/ELFTargetAsmInfo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | //===---- ELFTargetAsmInfo.h - ELF asm properties ---------------*- C++ -*-===// | ||||||
|  | // | ||||||
|  | //                     The LLVM Compiler Infrastructure | ||||||
|  | // | ||||||
|  | // This file is distributed under the University of Illinois Open Source | ||||||
|  | // License. See LICENSE.TXT for details. | ||||||
|  | // | ||||||
|  | //===----------------------------------------------------------------------===// | ||||||
|  | // | ||||||
|  | // This file defines target asm properties related what form asm statements | ||||||
|  | // should take in general on ELF-based targets | ||||||
|  | // | ||||||
|  | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #ifndef LLVM_ELF_TARGET_ASM_INFO_H | ||||||
|  | #define LLVM_ELF_TARGET_ASM_INFO_H | ||||||
|  |  | ||||||
|  | #include "llvm/Target/TargetAsmInfo.h" | ||||||
|  | #include "llvm/Target/TargetMachine.h" | ||||||
|  |  | ||||||
|  | namespace llvm { | ||||||
|  |   class GlobalValue; | ||||||
|  |   class GlobalVariable; | ||||||
|  |  | ||||||
|  |   class ELFTargetAsmInfo: public TargetAsmInfo { | ||||||
|  |     explicit ELFTargetAsmInfo(const TargetMachine &TM); | ||||||
|  |  | ||||||
|  |     virtual const Section* SelectSectionForGlobal(const GlobalValue *GV) const; | ||||||
|  |     virtual std::string PrintSectionFlags(unsigned flags) const; | ||||||
|  |     const Section* MergeableConstSection(const GlobalVariable *GV) const; | ||||||
|  |     const Section* MergeableStringSection(const GlobalVariable *GV) const; | ||||||
|  |   protected: | ||||||
|  |     const TargetMachine* ETM; | ||||||
|  |   }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #endif // LLVM_ELF_TARGET_ASM_INFO_H | ||||||
							
								
								
									
										164
									
								
								lib/Target/ELFTargetAsmInfo.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								lib/Target/ELFTargetAsmInfo.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | |||||||
|  | //===-- ELFTargetAsmInfo.cpp - ELF asm properties ---------------*- C++ -*-===// | ||||||
|  | // | ||||||
|  | //                     The LLVM Compiler Infrastructure | ||||||
|  | // | ||||||
|  | // This file is distributed under the University of Illinois Open Source | ||||||
|  | // License. See LICENSE.TXT for details. | ||||||
|  | // | ||||||
|  | //===----------------------------------------------------------------------===// | ||||||
|  | // | ||||||
|  | // This file defines target asm properties related what form asm statements | ||||||
|  | // should take in general on ELF-based targets | ||||||
|  | // | ||||||
|  | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
|  | #include "llvm/Constants.h" | ||||||
|  | #include "llvm/DerivedTypes.h" | ||||||
|  | #include "llvm/Function.h" | ||||||
|  | #include "llvm/GlobalVariable.h" | ||||||
|  | #include "llvm/ADT/StringExtras.h" | ||||||
|  | #include "llvm/Target/ELFTargetAsmInfo.h" | ||||||
|  | #include "llvm/Target/TargetMachine.h" | ||||||
|  | #include "llvm/Target/TargetData.h" | ||||||
|  |  | ||||||
|  | using namespace llvm; | ||||||
|  |  | ||||||
|  | ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) { | ||||||
|  |   ETM = &TM; | ||||||
|  |  | ||||||
|  |   TextSection_ = getUnnamedSection("\t.text", SectionFlags::Code); | ||||||
|  |   DataSection_ = getUnnamedSection("\t.data", SectionFlags::Writeable); | ||||||
|  |   BSSSection_  = getUnnamedSection("\t.bss", | ||||||
|  |                                    SectionFlags::Writeable | SectionFlags::BSS); | ||||||
|  |   ReadOnlySection_ = getNamedSection("\t.rodata", SectionFlags::None); | ||||||
|  |   TLSDataSection_ = getNamedSection("\t.tdata", | ||||||
|  |                                     SectionFlags::Writeable | SectionFlags::TLS); | ||||||
|  |   TLSBSSSection_ = getNamedSection("\t.tbss", | ||||||
|  |                 SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS); | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const Section* | ||||||
|  | ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { | ||||||
|  |   SectionKind::Kind Kind = SectionKindForGlobal(GV); | ||||||
|  |  | ||||||
|  |   if (const Function *F = dyn_cast<Function>(GV)) { | ||||||
|  |     switch (F->getLinkage()) { | ||||||
|  |      default: assert(0 && "Unknown linkage type!"); | ||||||
|  |      case Function::InternalLinkage: | ||||||
|  |      case Function::DLLExportLinkage: | ||||||
|  |      case Function::ExternalLinkage: | ||||||
|  |       return getTextSection_(); | ||||||
|  |      case Function::WeakLinkage: | ||||||
|  |      case Function::LinkOnceLinkage: | ||||||
|  |       std::string Name = UniqueSectionForGlobal(GV, Kind); | ||||||
|  |       unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); | ||||||
|  |       return getNamedSection(Name.c_str(), Flags); | ||||||
|  |     } | ||||||
|  |   } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) { | ||||||
|  |     if (GVar->isWeakForLinker()) { | ||||||
|  |       std::string Name = UniqueSectionForGlobal(GVar, Kind); | ||||||
|  |       unsigned Flags = SectionFlagsForGlobal(GVar, Name.c_str()); | ||||||
|  |       return getNamedSection(Name.c_str(), Flags); | ||||||
|  |     } else { | ||||||
|  |       switch (Kind) { | ||||||
|  |        case SectionKind::Data: | ||||||
|  |         return getDataSection_(); | ||||||
|  |        case SectionKind::BSS: | ||||||
|  |         // ELF targets usually have BSS sections | ||||||
|  |         return getBSSSection_(); | ||||||
|  |        case SectionKind::ROData: | ||||||
|  |         return getReadOnlySection_(); | ||||||
|  |        case SectionKind::RODataMergeStr: | ||||||
|  |         return MergeableStringSection(GVar); | ||||||
|  |        case SectionKind::RODataMergeConst: | ||||||
|  |         return MergeableConstSection(GVar); | ||||||
|  |        case SectionKind::ThreadData: | ||||||
|  |         // ELF targets usually support TLS stuff | ||||||
|  |         return getTLSDataSection_(); | ||||||
|  |        case SectionKind::ThreadBSS: | ||||||
|  |         return getTLSBSSSection_(); | ||||||
|  |        default: | ||||||
|  |         assert(0 && "Unsuported section kind for global"); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } else | ||||||
|  |     assert(0 && "Unsupported global"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const Section* | ||||||
|  | ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { | ||||||
|  |   const TargetData *TD = ETM->getTargetData(); | ||||||
|  |   Constant *C = cast<GlobalVariable>(GV)->getInitializer(); | ||||||
|  |   const Type *Type = C->getType(); | ||||||
|  |  | ||||||
|  |   // FIXME: string here is temporary, until stuff will fully land in. | ||||||
|  |   // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's | ||||||
|  |   // currently directly used by asmprinter. | ||||||
|  |   unsigned Size = TD->getABITypeSize(Type); | ||||||
|  |   if (Size == 4 || Size == 8 || Size == 16) { | ||||||
|  |     std::string Name =  ".rodata.cst" + utostr(Size); | ||||||
|  |  | ||||||
|  |     return getNamedSection(Name.c_str(), | ||||||
|  |                            SectionFlags::setEntitySize(SectionFlags::Mergeable, | ||||||
|  |                                                        Size)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return getReadOnlySection_(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const Section* | ||||||
|  | ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { | ||||||
|  |   const TargetData *TD = ETM->getTargetData(); | ||||||
|  |   Constant *C = cast<GlobalVariable>(GV)->getInitializer(); | ||||||
|  |   const ConstantArray *CVA = cast<ConstantArray>(C); | ||||||
|  |   const Type *Type = CVA->getType()->getElementType(); | ||||||
|  |  | ||||||
|  |   unsigned Size = TD->getABITypeSize(Type); | ||||||
|  |   if (Size <= 16) { | ||||||
|  |     // We also need alignment here | ||||||
|  |     const TargetData *TD = ETM->getTargetData(); | ||||||
|  |     unsigned Align = TD->getPreferredAlignment(GV); | ||||||
|  |     if (Align < Size) | ||||||
|  |       Align = Size; | ||||||
|  |  | ||||||
|  |     std::string Name = getCStringSection() + utostr(Size) + '.' + utostr(Align); | ||||||
|  |     unsigned Flags = SectionFlags::setEntitySize(SectionFlags::Mergeable | | ||||||
|  |                                                  SectionFlags::Strings, | ||||||
|  |                                                  Size); | ||||||
|  |     return getNamedSection(Name.c_str(), Flags); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return getReadOnlySection_(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | std::string ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { | ||||||
|  |   std::string Flags = ",\""; | ||||||
|  |  | ||||||
|  |   if (!(flags & SectionFlags::Debug)) | ||||||
|  |     Flags += 'a'; | ||||||
|  |   if (flags & SectionFlags::Code) | ||||||
|  |     Flags += 'x'; | ||||||
|  |   if (flags & SectionFlags::Writeable) | ||||||
|  |     Flags += 'w'; | ||||||
|  |   if (flags & SectionFlags::Mergeable) | ||||||
|  |     Flags += 'M'; | ||||||
|  |   if (flags & SectionFlags::Strings) | ||||||
|  |     Flags += 'S'; | ||||||
|  |   if (flags & SectionFlags::TLS) | ||||||
|  |     Flags += 'T'; | ||||||
|  |  | ||||||
|  |   Flags += "\""; | ||||||
|  |  | ||||||
|  |   // FIXME: There can be exceptions here | ||||||
|  |   if (flags & SectionFlags::BSS) | ||||||
|  |     Flags += ",@nobits"; | ||||||
|  |   else | ||||||
|  |     Flags += ",@progbits"; | ||||||
|  |  | ||||||
|  |   if (unsigned entitySize = SectionFlags::getEntitySize(flags)) | ||||||
|  |     Flags += "," + utostr(entitySize); | ||||||
|  |  | ||||||
|  |   return Flags; | ||||||
|  | } | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user