1 //===-- TargetAsmInfo.cpp - Asm Info ---------------------------------------==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines target asm properties related what form asm statements
13 //===----------------------------------------------------------------------===//
15 #include "llvm/Constants.h"
16 #include "llvm/GlobalVariable.h"
17 #include "llvm/Function.h"
18 #include "llvm/Module.h"
19 #include "llvm/Type.h"
20 #include "llvm/Target/TargetAsmInfo.h"
21 #include "llvm/Target/TargetOptions.h"
22 #include "llvm/Support/Dwarf.h"
28 TargetAsmInfo::TargetAsmInfo() :
29 TextSection("\t.text"),
31 DataSection("\t.data"),
37 TLSDataSection("\t.section .tdata,\"awT\",@progbits"),
39 TLSBSSSection("\t.section .tbss,\"awT\",@nobits"),
42 NonexecutableStackDirective(0),
49 PrivateGlobalPrefix("."),
50 JumpTableSpecialLabelPrefix(0),
51 GlobalVarAddrPrefix(""),
52 GlobalVarAddrSuffix(""),
53 FunctionAddrPrefix(""),
54 FunctionAddrSuffix(""),
55 PersonalityPrefix(""),
56 PersonalitySuffix(""),
57 NeedsIndirectEncoding(false),
58 InlineAsmStart("#APP"),
59 InlineAsmEnd("#NO_APP"),
61 StringConstantPrefix(".str"),
62 ZeroDirective("\t.zero\t"),
63 ZeroDirectiveSuffix(0),
64 AsciiDirective("\t.ascii\t"),
65 AscizDirective("\t.asciz\t"),
66 Data8bitsDirective("\t.byte\t"),
67 Data16bitsDirective("\t.short\t"),
68 Data32bitsDirective("\t.long\t"),
69 Data64bitsDirective("\t.quad\t"),
70 AlignDirective("\t.align\t"),
71 AlignmentIsInBytes(true),
72 TextAlignFillValue(0),
73 SwitchToSectionDirective("\t.section\t"),
74 TextSectionStartSuffix(""),
75 DataSectionStartSuffix(""),
76 SectionEndDirectiveSuffix(0),
77 ConstantPoolSection("\t.section .rodata"),
78 JumpTableDataSection("\t.section .rodata"),
79 JumpTableDirective(0),
82 StaticCtorsSection("\t.section .ctors,\"aw\",@progbits"),
83 StaticDtorsSection("\t.section .dtors,\"aw\",@progbits"),
84 FourByteConstantSection(0),
85 FourByteConstantSection_(0),
86 EightByteConstantSection(0),
87 EightByteConstantSection_(0),
88 SixteenByteConstantSection(0),
89 SixteenByteConstantSection_(0),
90 GlobalDirective("\t.globl\t"),
93 COMMDirective("\t.comm\t"),
94 COMMDirectiveTakesAlignment(true),
95 HasDotTypeDotSizeDirective(true),
99 HiddenDirective("\t.hidden\t"),
100 ProtectedDirective("\t.protected\t"),
101 AbsoluteDebugSectionOffsets(false),
102 AbsoluteEHSectionOffsets(false),
104 HasDotLocAndDotFile(false),
105 SupportsDebugInformation(false),
106 SupportsExceptionHandling(false),
107 DwarfRequiresFrameSection(true),
108 GlobalEHDirective(0),
109 SupportsWeakOmittedEHFrame(true),
110 DwarfSectionOffsetDirective(0),
111 DwarfAbbrevSection(".debug_abbrev"),
112 DwarfInfoSection(".debug_info"),
113 DwarfLineSection(".debug_line"),
114 DwarfFrameSection(".debug_frame"),
115 DwarfPubNamesSection(".debug_pubnames"),
116 DwarfPubTypesSection(".debug_pubtypes"),
117 DwarfStrSection(".debug_str"),
118 DwarfLocSection(".debug_loc"),
119 DwarfARangesSection(".debug_aranges"),
120 DwarfRangesSection(".debug_ranges"),
121 DwarfMacInfoSection(".debug_macinfo"),
122 DwarfEHFrameSection(".eh_frame"),
123 DwarfExceptionSection(".gcc_except_table"),
125 TextSection_ = getUnnamedSection(TextSection);
126 DataSection_ = getUnnamedSection(DataSection);
129 TargetAsmInfo::~TargetAsmInfo() {
132 /// Measure the specified inline asm to determine an approximation of its
134 /// Comments (which run till the next SeparatorChar or newline) do not
135 /// count as an instruction.
136 /// Any other non-whitespace text is considered an instruction, with
137 /// multiple instructions separated by SeparatorChar or newlines.
138 /// Variable-length instructions are not handled here; this function
139 /// may be overloaded in the target code to do that.
140 unsigned TargetAsmInfo::getInlineAsmLength(const char *Str) const {
141 // Count the number of instructions in the asm.
142 bool atInsnStart = true;
144 for (; *Str; ++Str) {
145 if (*Str == '\n' || *Str == SeparatorChar)
147 if (atInsnStart && !isspace(*Str)) {
148 Length += MaxInstLength;
151 if (atInsnStart && strncmp(Str, CommentString, strlen(CommentString))==0)
158 unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
160 return dwarf::DW_EH_PE_absptr;
163 static bool isSuitableForBSS(const GlobalVariable *GV) {
164 if (!GV->hasInitializer())
167 // Leave constant zeros in readonly constant sections, so they can be shared
168 Constant *C = GV->getInitializer();
169 return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS);
173 TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
174 // Early exit - functions should be always in text sections.
175 if (isa<Function>(GV))
176 return SectionKind::Text;
178 const GlobalVariable* GVar = dyn_cast<GlobalVariable>(GV);
179 bool isThreadLocal = GVar->isThreadLocal();
180 assert(GVar && "Invalid global value for section selection");
182 if (isSuitableForBSS(GVar)) {
183 // Variable can be easily put to BSS section.
184 return (isThreadLocal ? SectionKind::ThreadBSS : SectionKind::BSS);
185 } else if (GVar->isConstant() && !isThreadLocal) {
186 // Now we know, that varible has initializer and it is constant. We need to
187 // check its initializer to decide, which section to output it into. Also
188 // note, there is no thread-local r/o section.
189 Constant *C = GVar->getInitializer();
190 if (C->ContainsRelocations())
191 return SectionKind::ROData;
193 const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
194 // Check, if initializer is a null-terminated string
195 if (CVA && CVA->isCString())
196 return SectionKind::RODataMergeStr;
198 return SectionKind::RODataMergeConst;
202 // Variable is not constant or thread-local - emit to generic data section.
203 return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data);
207 TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue *GV,
208 const char* Name) const {
209 unsigned Flags = SectionFlags::None;
211 // Decode flags from global itself.
213 SectionKind::Kind Kind = SectionKindForGlobal(GV);
215 case SectionKind::Text:
216 Flags |= SectionFlags::Code;
218 case SectionKind::ThreadData:
219 Flags |= SectionFlags::TLS;
221 case SectionKind::Data:
222 Flags |= SectionFlags::Writeable;
224 case SectionKind::ThreadBSS:
225 Flags |= SectionFlags::TLS;
227 case SectionKind::BSS:
228 Flags |= SectionFlags::BSS;
230 case SectionKind::ROData:
231 // No additional flags here
233 case SectionKind::RODataMergeStr:
234 Flags |= SectionFlags::Strings;
236 case SectionKind::RODataMergeConst:
237 Flags |= SectionFlags::Mergeable;
240 assert(0 && "Unexpected section kind!");
243 if (GV->isWeakForLinker())
244 Flags |= SectionFlags::Linkonce;
247 // Add flags from sections, if any.
249 Flags |= SectionFlags::Named;
251 // Some lame default implementation based on some magic section names.
252 if (strncmp(Name, ".gnu.linkonce.b.", 16) == 0 ||
253 strncmp(Name, ".llvm.linkonce.b.", 17) == 0)
254 Flags |= SectionFlags::BSS;
255 else if (strcmp(Name, ".tdata") == 0 ||
256 strncmp(Name, ".tdata.", 7) == 0 ||
257 strncmp(Name, ".gnu.linkonce.td.", 17) == 0 ||
258 strncmp(Name, ".llvm.linkonce.td.", 18) == 0)
259 Flags |= SectionFlags::TLS;
260 else if (strcmp(Name, ".tbss") == 0 ||
261 strncmp(Name, ".tbss.", 6) == 0 ||
262 strncmp(Name, ".gnu.linkonce.tb.", 17) == 0 ||
263 strncmp(Name, ".llvm.linkonce.tb.", 18) == 0)
264 Flags |= SectionFlags::BSS | SectionFlags::TLS;
271 TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
273 // Select section name
274 if (GV->hasSection()) {
275 // Honour section already set, if any
276 unsigned Flags = SectionFlagsForGlobal(GV,
277 GV->getSection().c_str());
278 S = getNamedSection(GV->getSection().c_str(), Flags);
280 // Use default section depending on the 'type' of global
281 S = SelectSectionForGlobal(GV);
284 std::string Name = S->Name;
286 // If section is named we need to switch into it via special '.section'
287 // directive and also append funky flags. Otherwise - section name is just
288 // some magic assembler directive.
290 Name = getSwitchToSectionDirective() + Name + PrintSectionFlags(S->Flags);
295 // Lame default implementation. Calculate the section name for global.
297 TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
298 SectionKind::Kind Kind = SectionKindForGlobal(GV);
300 if (GV->isWeakForLinker()) {
301 std::string Name = UniqueSectionForGlobal(GV, Kind);
302 unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
303 return getNamedSection(Name.c_str(), Flags);
305 if (Kind == SectionKind::Text)
306 return getTextSection_();
307 else if (Kind == SectionKind::BSS && getBSSSection_())
308 return getBSSSection_();
309 else if (getReadOnlySection_() &&
310 (Kind == SectionKind::ROData ||
311 Kind == SectionKind::RODataMergeConst ||
312 Kind == SectionKind::RODataMergeStr))
313 return getReadOnlySection_();
316 return getDataSection_();
320 TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
321 SectionKind::Kind Kind) const {
323 case SectionKind::Text:
324 return ".gnu.linkonce.t." + GV->getName();
325 case SectionKind::Data:
326 return ".gnu.linkonce.d." + GV->getName();
327 case SectionKind::BSS:
328 return ".gnu.linkonce.b." + GV->getName();
329 case SectionKind::ROData:
330 case SectionKind::RODataMergeConst:
331 case SectionKind::RODataMergeStr:
332 return ".gnu.linkonce.r." + GV->getName();
333 case SectionKind::ThreadData:
334 return ".gnu.linkonce.td." + GV->getName();
335 case SectionKind::ThreadBSS:
336 return ".gnu.linkonce.tb." + GV->getName();
338 assert(0 && "Unknown section kind");
343 TargetAsmInfo::getNamedSection(const char *Name, unsigned Flags) const {
344 Section& S = Sections[Name];
346 // This is newly-created section, set it up properly.
347 if (S.Flags == SectionFlags::Invalid) {
348 S.Flags = Flags | SectionFlags::Named;
356 TargetAsmInfo::getUnnamedSection(const char *Directive, unsigned Flags) const {
357 Section& S = Sections[Directive];
359 // This is newly-created section, set it up properly.
360 if (S.Flags == SectionFlags::Invalid) {
361 S.Flags = Flags & ~SectionFlags::Named;