LLVM API Documentation
00001 //===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines target asm properties related what form asm statements 00011 // should take. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Constants.h" 00016 #include "llvm/DerivedTypes.h" 00017 #include "llvm/GlobalVariable.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Module.h" 00020 #include "llvm/Type.h" 00021 #include "llvm/Target/TargetAsmInfo.h" 00022 #include "llvm/Target/TargetOptions.h" 00023 #include "llvm/Support/Dwarf.h" 00024 #include <cctype> 00025 #include <cstring> 00026 00027 using namespace llvm; 00028 00029 void TargetAsmInfo::fillDefaultValues() { 00030 BSSSection = "\t.bss"; 00031 BSSSection_ = 0; 00032 ReadOnlySection = 0; 00033 SmallDataSection = 0; 00034 SmallBSSSection = 0; 00035 SmallRODataSection = 0; 00036 TLSDataSection = 0; 00037 TLSBSSSection = 0; 00038 ZeroFillDirective = 0; 00039 NonexecutableStackDirective = 0; 00040 NeedsSet = false; 00041 MaxInstLength = 4; 00042 PCSymbol = "$"; 00043 SeparatorChar = ';'; 00044 CommentString = "#"; 00045 GlobalPrefix = ""; 00046 PrivateGlobalPrefix = "."; 00047 LessPrivateGlobalPrefix = ""; 00048 JumpTableSpecialLabelPrefix = 0; 00049 GlobalVarAddrPrefix = ""; 00050 GlobalVarAddrSuffix = ""; 00051 FunctionAddrPrefix = ""; 00052 FunctionAddrSuffix = ""; 00053 PersonalityPrefix = ""; 00054 PersonalitySuffix = ""; 00055 NeedsIndirectEncoding = false; 00056 InlineAsmStart = "#APP"; 00057 InlineAsmEnd = "#NO_APP"; 00058 AssemblerDialect = 0; 00059 StringConstantPrefix = ".str"; 00060 ZeroDirective = "\t.zero\t"; 00061 ZeroDirectiveSuffix = 0; 00062 AsciiDirective = "\t.ascii\t"; 00063 AscizDirective = "\t.asciz\t"; 00064 Data8bitsDirective = "\t.byte\t"; 00065 Data16bitsDirective = "\t.short\t"; 00066 Data32bitsDirective = "\t.long\t"; 00067 Data64bitsDirective = "\t.quad\t"; 00068 AlignDirective = "\t.align\t"; 00069 AlignmentIsInBytes = true; 00070 TextAlignFillValue = 0; 00071 SwitchToSectionDirective = "\t.section\t"; 00072 TextSectionStartSuffix = ""; 00073 DataSectionStartSuffix = ""; 00074 SectionEndDirectiveSuffix = 0; 00075 ConstantPoolSection = "\t.section .rodata"; 00076 JumpTableDataSection = "\t.section .rodata"; 00077 JumpTableDirective = 0; 00078 CStringSection = 0; 00079 CStringSection_ = 0; 00080 // FIXME: Flags are ELFish - replace with normal section stuff. 00081 StaticCtorsSection = "\t.section .ctors,\"aw\",@progbits"; 00082 StaticDtorsSection = "\t.section .dtors,\"aw\",@progbits"; 00083 GlobalDirective = "\t.globl\t"; 00084 SetDirective = 0; 00085 LCOMMDirective = 0; 00086 COMMDirective = "\t.comm\t"; 00087 COMMDirectiveTakesAlignment = true; 00088 HasDotTypeDotSizeDirective = true; 00089 HasSingleParameterDotFile = true; 00090 UsedDirective = 0; 00091 WeakRefDirective = 0; 00092 WeakDefDirective = 0; 00093 // FIXME: These are ELFish - move to ELFTAI. 00094 HiddenDirective = "\t.hidden\t"; 00095 ProtectedDirective = "\t.protected\t"; 00096 AbsoluteDebugSectionOffsets = false; 00097 AbsoluteEHSectionOffsets = false; 00098 HasLEB128 = false; 00099 HasDotLocAndDotFile = false; 00100 SupportsDebugInformation = false; 00101 SupportsExceptionHandling = false; 00102 DwarfRequiresFrameSection = true; 00103 SupportsMacInfoSection = true; 00104 NonLocalEHFrameLabel = false; 00105 GlobalEHDirective = 0; 00106 SupportsWeakOmittedEHFrame = true; 00107 DwarfSectionOffsetDirective = 0; 00108 DwarfAbbrevSection = ".debug_abbrev"; 00109 DwarfInfoSection = ".debug_info"; 00110 DwarfLineSection = ".debug_line"; 00111 DwarfFrameSection = ".debug_frame"; 00112 DwarfPubNamesSection = ".debug_pubnames"; 00113 DwarfPubTypesSection = ".debug_pubtypes"; 00114 DwarfStrSection = ".debug_str"; 00115 DwarfLocSection = ".debug_loc"; 00116 DwarfARangesSection = ".debug_aranges"; 00117 DwarfRangesSection = ".debug_ranges"; 00118 DwarfMacInfoSection = ".debug_macinfo"; 00119 DwarfEHFrameSection = ".eh_frame"; 00120 DwarfExceptionSection = ".gcc_except_table"; 00121 AsmTransCBE = 0; 00122 TextSection = getUnnamedSection("\t.text", SectionFlags::Code); 00123 DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable); 00124 } 00125 00126 TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm) 00127 : TM(tm) { 00128 fillDefaultValues(); 00129 } 00130 00131 TargetAsmInfo::~TargetAsmInfo() { 00132 } 00133 00134 /// Measure the specified inline asm to determine an approximation of its 00135 /// length. 00136 /// Comments (which run till the next SeparatorChar or newline) do not 00137 /// count as an instruction. 00138 /// Any other non-whitespace text is considered an instruction, with 00139 /// multiple instructions separated by SeparatorChar or newlines. 00140 /// Variable-length instructions are not handled here; this function 00141 /// may be overloaded in the target code to do that. 00142 unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const { 00143 // Count the number of instructions in the asm. 00144 bool atInsnStart = true; 00145 unsigned Length = 0; 00146 for (; *Str; ++Str) { 00147 if (*Str == '\n' || *Str == SeparatorChar) 00148 atInsnStart = true; 00149 if (atInsnStart && !isspace(*Str)) { 00150 Length += MaxInstLength; 00151 atInsnStart = false; 00152 } 00153 if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0) 00154 atInsnStart = false; 00155 } 00156 00157 return Length; 00158 } 00159 00160 unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, 00161 bool Global) const { 00162 return dwarf::DW_EH_PE_absptr; 00163 } 00164 00165 static bool isSuitableForBSS(const GlobalVariable *GV) { 00166 if (!GV->hasInitializer()) 00167 return true; 00168 00169 // Leave constant zeros in readonly constant sections, so they can be shared 00170 Constant *C = GV->getInitializer(); 00171 return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS); 00172 } 00173 00174 static bool isConstantString(const Constant *C) { 00175 // First check: is we have constant array of i8 terminated with zero 00176 const ConstantArray *CVA = dyn_cast<ConstantArray>(C); 00177 // Check, if initializer is a null-terminated string 00178 if (CVA && CVA->isCString()) 00179 return true; 00180 00181 // Another possibility: [1 x i8] zeroinitializer 00182 if (isa<ConstantAggregateZero>(C)) { 00183 if (const ArrayType *Ty = dyn_cast<ArrayType>(C->getType())) { 00184 return (Ty->getElementType() == Type::Int8Ty && 00185 Ty->getNumElements() == 1); 00186 } 00187 } 00188 00189 return false; 00190 } 00191 00192 00193 SectionKind::Kind 00194 TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { 00195 // Early exit - functions should be always in text sections. 00196 if (isa<Function>(GV)) 00197 return SectionKind::Text; 00198 00199 const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV); 00200 bool isThreadLocal = GVar->isThreadLocal(); 00201 assert(GVar && "Invalid global value for section selection"); 00202 00203 if (isSuitableForBSS(GVar)) { 00204 // Variable can be easily put to BSS section. 00205 return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS); 00206 } else if (GVar->isConstant() && !isThreadLocal) { 00207 // Now we know, that varible has initializer and it is constant. We need to 00208 // check its initializer to decide, which section to output it into. Also 00209 // note, there is no thread-local r/o section. 00210 Constant *C = GVar->getInitializer(); 00211 if (C->ContainsRelocations()) 00212 return SectionKind::ROData; 00213 else { 00214 // Check, if initializer is a null-terminated string 00215 if (isConstantString(C)) 00216 return SectionKind::RODataMergeStr; 00217 else 00218 return SectionKind::RODataMergeConst; 00219 } 00220 } 00221 00222 // Variable is not constant or thread-local - emit to generic data section. 00223 return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data); 00224 } 00225 00226 unsigned 00227 TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV, 00228 const char* Name) const { 00229 unsigned Flags = SectionFlags::None; 00230 00231 // Decode flags from global itself. 00232 if (GV) { 00233 SectionKind::Kind Kind = SectionKindForGlobal(GV); 00234 switch (Kind) { 00235 case SectionKind::Text: 00236 Flags |= SectionFlags::Code; 00237 break; 00238 case SectionKind::ThreadData: 00239 case SectionKind::ThreadBSS: 00240 Flags |= SectionFlags::TLS; 00241 // FALLS THROUGH 00242 case SectionKind::Data: 00243 case SectionKind::BSS: 00244 Flags |= SectionFlags::Writeable; 00245 break; 00246 case SectionKind::ROData: 00247 case SectionKind::RODataMergeStr: 00248 case SectionKind::RODataMergeConst: 00249 // No additional flags here 00250 break; 00251 case SectionKind::SmallData: 00252 case SectionKind::SmallBSS: 00253 Flags |= SectionFlags::Writeable; 00254 // FALLS THROUGH 00255 case SectionKind::SmallROData: 00256 Flags |= SectionFlags::Small; 00257 break; 00258 default: 00259 assert(0 && "Unexpected section kind!"); 00260 } 00261 00262 if (GV->mayBeOverridden()) 00263 Flags |= SectionFlags::Linkonce; 00264 } 00265 00266 // Add flags from sections, if any. 00267 if (Name && *Name) { 00268 Flags |= SectionFlags::Named; 00269 00270 // Some lame default implementation based on some magic section names. 00271 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 || 00272 strncmp(Name, ".llvm.linkonce.b.", 17) == 0 || 00273 strncmp(Name, ".gnu.linkonce.sb.", 17) == 0 || 00274 strncmp(Name, ".llvm.linkonce.sb.", 18) == 0) 00275 Flags |= SectionFlags::BSS; 00276 else if (strcmp(Name, ".tdata") == 0 || 00277 strncmp(Name, ".tdata.", 7) == 0 || 00278 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 || 00279 strncmp(Name, ".llvm.linkonce.td.", 18) == 0) 00280 Flags |= SectionFlags::TLS; 00281 else if (strcmp(Name, ".tbss") == 0 || 00282 strncmp(Name, ".tbss.", 6) == 0 || 00283 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 || 00284 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0) 00285 Flags |= SectionFlags::BSS | SectionFlags::TLS; 00286 } 00287 00288 return Flags; 00289 } 00290 00291 const Section* 00292 TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const { 00293 const Section* S; 00294 // Select section name 00295 if (GV->hasSection()) { 00296 // Honour section already set, if any 00297 unsigned Flags = SectionFlagsForGlobal(GV, 00298 GV->getSection().c_str()); 00299 S = getNamedSection(GV->getSection().c_str(), Flags); 00300 } else { 00301 // Use default section depending on the 'type' of global 00302 S = SelectSectionForGlobal(GV); 00303 } 00304 00305 return S; 00306 } 00307 00308 // Lame default implementation. Calculate the section name for global. 00309 const Section* 00310 TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { 00311 SectionKind::Kind Kind = SectionKindForGlobal(GV); 00312 00313 if (GV->mayBeOverridden()) { 00314 std::string Name = UniqueSectionForGlobal(GV, Kind); 00315 unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); 00316 return getNamedSection(Name.c_str(), Flags); 00317 } else { 00318 if (Kind == SectionKind::Text) 00319 return getTextSection(); 00320 else if (isBSS(Kind) && getBSSSection_()) 00321 return getBSSSection_(); 00322 else if (getReadOnlySection() && SectionKind::isReadOnly(Kind)) 00323 return getReadOnlySection(); 00324 } 00325 00326 return getDataSection(); 00327 } 00328 00329 // Lame default implementation. Calculate the section name for machine const. 00330 const Section* 00331 TargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { 00332 // FIXME: Support data.rel stuff someday 00333 return getDataSection(); 00334 } 00335 00336 std::string 00337 TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, 00338 SectionKind::Kind Kind) const { 00339 switch (Kind) { 00340 case SectionKind::Text: 00341 return ".gnu.linkonce.t." + GV->getName(); 00342 case SectionKind::Data: 00343 return ".gnu.linkonce.d." + GV->getName(); 00344 case SectionKind::SmallData: 00345 return ".gnu.linkonce.s." + GV->getName(); 00346 case SectionKind::BSS: 00347 return ".gnu.linkonce.b." + GV->getName(); 00348 case SectionKind::SmallBSS: 00349 return ".gnu.linkonce.sb." + GV->getName(); 00350 case SectionKind::ROData: 00351 case SectionKind::RODataMergeConst: 00352 case SectionKind::RODataMergeStr: 00353 return ".gnu.linkonce.r." + GV->getName(); 00354 case SectionKind::SmallROData: 00355 return ".gnu.linkonce.s2." + GV->getName(); 00356 case SectionKind::ThreadData: 00357 return ".gnu.linkonce.td." + GV->getName(); 00358 case SectionKind::ThreadBSS: 00359 return ".gnu.linkonce.tb." + GV->getName(); 00360 default: 00361 assert(0 && "Unknown section kind"); 00362 } 00363 return NULL; 00364 } 00365 00366 const Section* 00367 TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags, 00368 bool Override) const { 00369 Section& S = Sections[Name]; 00370 00371 // This is newly-created section, set it up properly. 00372 if (S.Flags == SectionFlags::Invalid || Override) { 00373 S.Flags = Flags | SectionFlags::Named; 00374 S.Name = Name; 00375 } 00376 00377 return &S; 00378 } 00379 00380 const Section* 00381 TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags, 00382 bool Override) const { 00383 Section& S = Sections[Directive]; 00384 00385 // This is newly-created section, set it up properly. 00386 if (S.Flags == SectionFlags::Invalid || Override) { 00387 S.Flags = Flags & ~SectionFlags::Named; 00388 S.Name = Directive; 00389 } 00390 00391 return &S; 00392 } 00393 00394 const std::string& 00395 TargetAsmInfo::getSectionFlags(unsigned Flags) const { 00396 SectionFlags::FlagsStringsMapType::iterator I = FlagsStrings.find(Flags); 00397 00398 // We didn't print these flags yet, print and save them to map. This reduces 00399 // amount of heap trashing due to std::string construction / concatenation. 00400 if (I == FlagsStrings.end()) 00401 I = FlagsStrings.insert(std::make_pair(Flags, 00402 printSectionFlags(Flags))).first; 00403 00404 return I->second; 00405 } 00406 00407 unsigned TargetAsmInfo::getULEB128Size(unsigned Value) { 00408 unsigned Size = 0; 00409 do { 00410 Value >>= 7; 00411 Size += sizeof(int8_t); 00412 } while (Value); 00413 return Size; 00414 } 00415 00416 unsigned TargetAsmInfo::getSLEB128Size(int Value) { 00417 unsigned Size = 0; 00418 int Sign = Value >> (8 * sizeof(Value) - 1); 00419 bool IsMore; 00420 00421 do { 00422 unsigned Byte = Value & 0x7f; 00423 Value >>= 7; 00424 IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; 00425 Size += sizeof(int8_t); 00426 } while (IsMore); 00427 return Size; 00428 }