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/DerivedTypes.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/Function.h"
19 #include "llvm/Module.h"
20 #include "llvm/Type.h"
21 #include "llvm/Target/TargetAsmInfo.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Target/TargetOptions.h"
24 #include "llvm/Support/Dwarf.h"
30 void TargetAsmInfo::fillDefaultValues() {
31 BSSSection
= "\t.bss";
36 SmallRODataSection
= 0;
39 ZeroFillDirective
= 0;
40 NonexecutableStackDirective
= 0;
47 PrivateGlobalPrefix
= ".";
48 LessPrivateGlobalPrefix
= "";
49 JumpTableSpecialLabelPrefix
= 0;
50 GlobalVarAddrPrefix
= "";
51 GlobalVarAddrSuffix
= "";
52 FunctionAddrPrefix
= "";
53 FunctionAddrSuffix
= "";
54 PersonalityPrefix
= "";
55 PersonalitySuffix
= "";
56 NeedsIndirectEncoding
= false;
57 InlineAsmStart
= "#APP";
58 InlineAsmEnd
= "#NO_APP";
60 StringConstantPrefix
= ".str";
61 ZeroDirective
= "\t.zero\t";
62 ZeroDirectiveSuffix
= 0;
63 AsciiDirective
= "\t.ascii\t";
64 AscizDirective
= "\t.asciz\t";
65 Data8bitsDirective
= "\t.byte\t";
66 Data16bitsDirective
= "\t.short\t";
67 Data32bitsDirective
= "\t.long\t";
68 Data64bitsDirective
= "\t.quad\t";
69 AlignDirective
= "\t.align\t";
70 AlignmentIsInBytes
= true;
71 TextAlignFillValue
= 0;
72 SwitchToSectionDirective
= "\t.section\t";
73 TextSectionStartSuffix
= "";
74 DataSectionStartSuffix
= "";
75 SectionEndDirectiveSuffix
= 0;
76 ConstantPoolSection
= "\t.section .rodata";
77 JumpTableDataSection
= "\t.section .rodata";
78 JumpTableDirective
= 0;
81 // FIXME: Flags are ELFish - replace with normal section stuff.
82 StaticCtorsSection
= "\t.section .ctors,\"aw\",@progbits";
83 StaticDtorsSection
= "\t.section .dtors,\"aw\",@progbits";
84 GlobalDirective
= "\t.globl\t";
87 COMMDirective
= "\t.comm\t";
88 COMMDirectiveTakesAlignment
= true;
89 HasDotTypeDotSizeDirective
= true;
90 HasSingleParameterDotFile
= true;
94 // FIXME: These are ELFish - move to ELFTAI.
95 HiddenDirective
= "\t.hidden\t";
96 ProtectedDirective
= "\t.protected\t";
97 AbsoluteDebugSectionOffsets
= false;
98 AbsoluteEHSectionOffsets
= false;
100 HasDotLocAndDotFile
= false;
101 SupportsDebugInformation
= false;
102 SupportsExceptionHandling
= false;
103 DwarfRequiresFrameSection
= true;
104 DwarfUsesInlineInfoSection
= false;
105 SupportsMacInfoSection
= true;
106 NonLocalEHFrameLabel
= false;
107 GlobalEHDirective
= 0;
108 SupportsWeakOmittedEHFrame
= true;
109 DwarfSectionOffsetDirective
= 0;
110 DwarfAbbrevSection
= ".debug_abbrev";
111 DwarfInfoSection
= ".debug_info";
112 DwarfLineSection
= ".debug_line";
113 DwarfFrameSection
= ".debug_frame";
114 DwarfPubNamesSection
= ".debug_pubnames";
115 DwarfPubTypesSection
= ".debug_pubtypes";
116 DwarfDebugInlineSection
= ".debug_inlined";
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("\t.text", SectionFlags::Code
);
126 DataSection
= getUnnamedSection("\t.data", SectionFlags::Writeable
);
129 TargetAsmInfo::TargetAsmInfo(const TargetMachine
&tm
)
134 TargetAsmInfo::~TargetAsmInfo() {
137 /// Measure the specified inline asm to determine an approximation of its
139 /// Comments (which run till the next SeparatorChar or newline) do not
140 /// count as an instruction.
141 /// Any other non-whitespace text is considered an instruction, with
142 /// multiple instructions separated by SeparatorChar or newlines.
143 /// Variable-length instructions are not handled here; this function
144 /// may be overloaded in the target code to do that.
145 unsigned TargetAsmInfo::getInlineAsmLength(const char *Str
) const {
146 // Count the number of instructions in the asm.
147 bool atInsnStart
= true;
149 for (; *Str
; ++Str
) {
150 if (*Str
== '\n' || *Str
== SeparatorChar
)
152 if (atInsnStart
&& !isspace(*Str
)) {
153 Length
+= MaxInstLength
;
156 if (atInsnStart
&& strncmp(Str
, CommentString
, strlen(CommentString
))==0)
163 unsigned TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason
,
165 return dwarf::DW_EH_PE_absptr
;
168 static bool isSuitableForBSS(const GlobalVariable
*GV
) {
169 if (!GV
->hasInitializer())
172 // Leave constant zeros in readonly constant sections, so they can be shared
173 Constant
*C
= GV
->getInitializer();
174 return (C
->isNullValue() && !GV
->isConstant() && !NoZerosInBSS
);
177 static bool isConstantString(const Constant
*C
) {
178 // First check: is we have constant array of i8 terminated with zero
179 const ConstantArray
*CVA
= dyn_cast
<ConstantArray
>(C
);
180 // Check, if initializer is a null-terminated string
181 if (CVA
&& CVA
->isCString())
184 // Another possibility: [1 x i8] zeroinitializer
185 if (isa
<ConstantAggregateZero
>(C
)) {
186 if (const ArrayType
*Ty
= dyn_cast
<ArrayType
>(C
->getType())) {
187 return (Ty
->getElementType() == Type::Int8Ty
&&
188 Ty
->getNumElements() == 1);
195 unsigned TargetAsmInfo::RelocBehaviour() const {
196 // By default - all relocations in PIC mode would force symbol to be
197 // placed in r/w section.
198 return (TM
.getRelocationModel() != Reloc::Static
?
199 Reloc::LocalOrGlobal
: Reloc::None
);
203 TargetAsmInfo::SectionKindForGlobal(const GlobalValue
*GV
) const {
204 // Early exit - functions should be always in text sections.
205 if (isa
<Function
>(GV
))
206 return SectionKind::Text
;
208 const GlobalVariable
* GVar
= dyn_cast
<GlobalVariable
>(GV
);
209 bool isThreadLocal
= GVar
->isThreadLocal();
210 assert(GVar
&& "Invalid global value for section selection");
212 if (isSuitableForBSS(GVar
)) {
213 // Variable can be easily put to BSS section.
214 return (isThreadLocal
? SectionKind::ThreadBSS
: SectionKind::BSS
);
215 } else if (GVar
->isConstant() && !isThreadLocal
) {
216 // Now we know, that varible has initializer and it is constant. We need to
217 // check its initializer to decide, which section to output it into. Also
218 // note, there is no thread-local r/o section.
219 Constant
*C
= GVar
->getInitializer();
220 if (C
->ContainsRelocations(Reloc::LocalOrGlobal
)) {
221 // Decide, whether it is still possible to put symbol into r/o section.
222 unsigned Reloc
= RelocBehaviour();
224 // We already did a query for 'all' relocs, thus - early exits.
225 if (Reloc
== Reloc::LocalOrGlobal
)
226 return SectionKind::Data
;
227 else if (Reloc
== Reloc::None
)
228 return SectionKind::ROData
;
230 // Ok, target wants something funny. Honour it.
231 return (C
->ContainsRelocations(Reloc
) ?
232 SectionKind::Data
: SectionKind::ROData
);
235 // Check, if initializer is a null-terminated string
236 if (isConstantString(C
))
237 return SectionKind::RODataMergeStr
;
239 return SectionKind::RODataMergeConst
;
243 // Variable either is not constant or thread-local - output to data section.
244 return (isThreadLocal
? SectionKind::ThreadData
: SectionKind::Data
);
248 TargetAsmInfo::SectionFlagsForGlobal(const GlobalValue
*GV
,
249 const char* Name
) const {
250 unsigned Flags
= SectionFlags::None
;
252 // Decode flags from global itself.
254 SectionKind::Kind Kind
= SectionKindForGlobal(GV
);
256 case SectionKind::Text
:
257 Flags
|= SectionFlags::Code
;
259 case SectionKind::ThreadData
:
260 case SectionKind::ThreadBSS
:
261 Flags
|= SectionFlags::TLS
;
263 case SectionKind::Data
:
264 case SectionKind::DataRel
:
265 case SectionKind::DataRelLocal
:
266 case SectionKind::DataRelRO
:
267 case SectionKind::DataRelROLocal
:
268 case SectionKind::BSS
:
269 Flags
|= SectionFlags::Writeable
;
271 case SectionKind::ROData
:
272 case SectionKind::RODataMergeStr
:
273 case SectionKind::RODataMergeConst
:
274 // No additional flags here
276 case SectionKind::SmallData
:
277 case SectionKind::SmallBSS
:
278 Flags
|= SectionFlags::Writeable
;
280 case SectionKind::SmallROData
:
281 Flags
|= SectionFlags::Small
;
284 assert(0 && "Unexpected section kind!");
287 if (GV
->isWeakForLinker())
288 Flags
|= SectionFlags::Linkonce
;
291 // Add flags from sections, if any.
293 Flags
|= SectionFlags::Named
;
295 // Some lame default implementation based on some magic section names.
296 if (strncmp(Name
, ".gnu.linkonce.b.", 16) == 0 ||
297 strncmp(Name
, ".llvm.linkonce.b.", 17) == 0 ||
298 strncmp(Name
, ".gnu.linkonce.sb.", 17) == 0 ||
299 strncmp(Name
, ".llvm.linkonce.sb.", 18) == 0)
300 Flags
|= SectionFlags::BSS
;
301 else if (strcmp(Name
, ".tdata") == 0 ||
302 strncmp(Name
, ".tdata.", 7) == 0 ||
303 strncmp(Name
, ".gnu.linkonce.td.", 17) == 0 ||
304 strncmp(Name
, ".llvm.linkonce.td.", 18) == 0)
305 Flags
|= SectionFlags::TLS
;
306 else if (strcmp(Name
, ".tbss") == 0 ||
307 strncmp(Name
, ".tbss.", 6) == 0 ||
308 strncmp(Name
, ".gnu.linkonce.tb.", 17) == 0 ||
309 strncmp(Name
, ".llvm.linkonce.tb.", 18) == 0)
310 Flags
|= SectionFlags::BSS
| SectionFlags::TLS
;
317 TargetAsmInfo::SectionForGlobal(const GlobalValue
*GV
) const {
319 // Select section name
320 if (GV
->hasSection()) {
321 // Honour section already set, if any
322 unsigned Flags
= SectionFlagsForGlobal(GV
,
323 GV
->getSection().c_str());
324 S
= getNamedSection(GV
->getSection().c_str(), Flags
);
326 // Use default section depending on the 'type' of global
327 S
= SelectSectionForGlobal(GV
);
333 // Lame default implementation. Calculate the section name for global.
335 TargetAsmInfo::SelectSectionForGlobal(const GlobalValue
*GV
) const {
336 SectionKind::Kind Kind
= SectionKindForGlobal(GV
);
338 if (GV
->isWeakForLinker()) {
339 std::string Name
= UniqueSectionForGlobal(GV
, Kind
);
340 unsigned Flags
= SectionFlagsForGlobal(GV
, Name
.c_str());
341 return getNamedSection(Name
.c_str(), Flags
);
343 if (Kind
== SectionKind::Text
)
344 return getTextSection();
345 else if (isBSS(Kind
) && getBSSSection_())
346 return getBSSSection_();
347 else if (getReadOnlySection() && SectionKind::isReadOnly(Kind
))
348 return getReadOnlySection();
351 return getDataSection();
354 // Lame default implementation. Calculate the section name for machine const.
356 TargetAsmInfo::SelectSectionForMachineConst(const Type
*Ty
) const {
357 // FIXME: Support data.rel stuff someday
358 return getDataSection();
362 TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue
* GV
,
363 SectionKind::Kind Kind
) const {
365 case SectionKind::Text
:
366 return ".gnu.linkonce.t." + GV
->getName();
367 case SectionKind::Data
:
368 return ".gnu.linkonce.d." + GV
->getName();
369 case SectionKind::DataRel
:
370 return ".gnu.linkonce.d.rel" + GV
->getName();
371 case SectionKind::DataRelLocal
:
372 return ".gnu.linkonce.d.rel.local" + GV
->getName();
373 case SectionKind::DataRelRO
:
374 return ".gnu.linkonce.d.rel.ro" + GV
->getName();
375 case SectionKind::DataRelROLocal
:
376 return ".gnu.linkonce.d.rel.ro.local" + GV
->getName();
377 case SectionKind::SmallData
:
378 return ".gnu.linkonce.s." + GV
->getName();
379 case SectionKind::BSS
:
380 return ".gnu.linkonce.b." + GV
->getName();
381 case SectionKind::SmallBSS
:
382 return ".gnu.linkonce.sb." + GV
->getName();
383 case SectionKind::ROData
:
384 case SectionKind::RODataMergeConst
:
385 case SectionKind::RODataMergeStr
:
386 return ".gnu.linkonce.r." + GV
->getName();
387 case SectionKind::SmallROData
:
388 return ".gnu.linkonce.s2." + GV
->getName();
389 case SectionKind::ThreadData
:
390 return ".gnu.linkonce.td." + GV
->getName();
391 case SectionKind::ThreadBSS
:
392 return ".gnu.linkonce.tb." + GV
->getName();
394 assert(0 && "Unknown section kind");
400 TargetAsmInfo::getNamedSection(const char *Name
, unsigned Flags
,
401 bool Override
) const {
402 Section
& S
= Sections
[Name
];
404 // This is newly-created section, set it up properly.
405 if (S
.Flags
== SectionFlags::Invalid
|| Override
) {
406 S
.Flags
= Flags
| SectionFlags::Named
;
414 TargetAsmInfo::getUnnamedSection(const char *Directive
, unsigned Flags
,
415 bool Override
) const {
416 Section
& S
= Sections
[Directive
];
418 // This is newly-created section, set it up properly.
419 if (S
.Flags
== SectionFlags::Invalid
|| Override
) {
420 S
.Flags
= Flags
& ~SectionFlags::Named
;
428 TargetAsmInfo::getSectionFlags(unsigned Flags
) const {
429 SectionFlags::FlagsStringsMapType::iterator I
= FlagsStrings
.find(Flags
);
431 // We didn't print these flags yet, print and save them to map. This reduces
432 // amount of heap trashing due to std::string construction / concatenation.
433 if (I
== FlagsStrings
.end())
434 I
= FlagsStrings
.insert(std::make_pair(Flags
,
435 printSectionFlags(Flags
))).first
;
440 unsigned TargetAsmInfo::getULEB128Size(unsigned Value
) {
444 Size
+= sizeof(int8_t);
449 unsigned TargetAsmInfo::getSLEB128Size(int Value
) {
451 int Sign
= Value
>> (8 * sizeof(Value
) - 1);
455 unsigned Byte
= Value
& 0x7f;
457 IsMore
= Value
!= Sign
|| ((Byte
^ Sign
) & 0x40) != 0;
458 Size
+= sizeof(int8_t);