Implement Thumb2 ldr.
[oota-llvm.git] / lib / Target / X86 / X86TargetAsmInfo.cpp
1 //===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the declarations of the X86TargetAsmInfo properties.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "X86TargetAsmInfo.h"
15 #include "X86TargetMachine.h"
16 #include "X86Subtarget.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/InlineAsm.h"
19 #include "llvm/Instructions.h"
20 #include "llvm/Intrinsics.h"
21 #include "llvm/Module.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Support/Dwarf.h"
24
25 using namespace llvm;
26 using namespace llvm::dwarf;
27
28 const char *const llvm::x86_asm_table[] = {
29   "{si}", "S",
30   "{di}", "D",
31   "{ax}", "a",
32   "{cx}", "c",
33   "{memory}", "memory",
34   "{flags}", "",
35   "{dirflag}", "",
36   "{fpsr}", "",
37   "{cc}", "cc",
38   0,0};
39
40 X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
41   X86TargetAsmInfo<DarwinTargetAsmInfo>(TM) {
42   const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>();
43   bool is64Bit = Subtarget->is64Bit();
44
45   AlignmentIsInBytes = false;
46   TextAlignFillValue = 0x90;
47     
48     
49   if (!is64Bit)
50     Data64bitsDirective = 0;       // we can't emit a 64-bit unit
51   ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
52   ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
53   if (TM.getRelocationModel() != Reloc::Static)
54     ConstantPoolSection = "\t.const_data";
55   else
56     ConstantPoolSection = "\t.const\n";
57   // FIXME: Why don't we always use this section?
58   if (is64Bit)
59     SixteenByteConstantSection = getUnnamedSection("\t.literal16\n",
60                                                    SectionFlags::Mergeable);
61   LCOMMDirective = "\t.lcomm\t";
62   // Leopard and above support aligned common symbols.
63   COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9);
64   HasDotTypeDotSizeDirective = false;
65   NonLocalEHFrameLabel = true;
66   if (is64Bit) {
67     PersonalityPrefix = "";
68     PersonalitySuffix = "+4@GOTPCREL";
69   } else {
70     PersonalityPrefix = "L";
71     PersonalitySuffix = "$non_lazy_ptr";
72   }
73   InlineAsmStart = "## InlineAsm Start";
74   InlineAsmEnd = "## InlineAsm End";
75   CommentString = "##";
76   SetDirective = "\t.set";
77   PCSymbol = ".";
78   UsedDirective = "\t.no_dead_strip\t";
79   ProtectedDirective = "\t.globl\t";
80
81   SupportsDebugInformation = true;
82
83   DwarfDebugInlineSection = ".section __DWARF,__debug_inlined,regular,debug";
84   DwarfUsesInlineInfoSection = true;
85
86   // Exceptions handling
87   SupportsExceptionHandling = true;
88   GlobalEHDirective = "\t.globl\t";
89   SupportsWeakOmittedEHFrame = false;
90   AbsoluteEHSectionOffsets = false;
91   DwarfEHFrameSection =
92   ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support";
93   DwarfExceptionSection = ".section __DATA,__gcc_except_tab";
94 }
95
96 unsigned
97 X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
98                                               bool Global) const {
99   if (Reason == DwarfEncoding::Functions && Global)
100     return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4);
101   else if (Reason == DwarfEncoding::CodeLabels || !Global)
102     return DW_EH_PE_pcrel;
103   else
104     return DW_EH_PE_absptr;
105 }
106
107 const char *
108 X86DarwinTargetAsmInfo::getEHGlobalPrefix() const
109 {
110   const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>();
111   if (Subtarget->getDarwinVers() > 9)
112     return PrivateGlobalPrefix;
113   else
114     return "";
115 }
116
117 X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM):
118   X86TargetAsmInfo<ELFTargetAsmInfo>(TM) {
119
120   CStringSection = ".rodata.str";
121   PrivateGlobalPrefix = ".L";
122   WeakRefDirective = "\t.weak\t";
123   SetDirective = "\t.set\t";
124   PCSymbol = ".";
125
126   // Set up DWARF directives
127   HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
128
129   // Debug Information
130   AbsoluteDebugSectionOffsets = true;
131   SupportsDebugInformation = true;
132   DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits";
133   DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits";
134   DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits";
135   DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits";
136   DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits";
137   DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits";
138   DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits";
139   DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits";
140   DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits";
141   DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits";
142   DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits";
143
144   // Exceptions handling
145   SupportsExceptionHandling = true;
146   AbsoluteEHSectionOffsets = false;
147   DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits";
148   DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits";
149
150   // On Linux we must declare when we can use a non-executable stack.
151   if (TM.getSubtarget<X86Subtarget>().isLinux())
152     NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
153 }
154
155 unsigned
156 X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
157                                            bool Global) const {
158   CodeModel::Model CM = TM.getCodeModel();
159   bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
160
161   if (TM.getRelocationModel() == Reloc::PIC_) {
162     unsigned Format = 0;
163
164     if (!is64Bit)
165       // 32 bit targets always encode pointers as 4 bytes
166       Format = DW_EH_PE_sdata4;
167     else {
168       // 64 bit targets encode pointers in 4 bytes iff:
169       // - code model is small OR
170       // - code model is medium and we're emitting externally visible symbols
171       //   or any code symbols
172       if (CM == CodeModel::Small ||
173           (CM == CodeModel::Medium && (Global ||
174                                        Reason != DwarfEncoding::Data)))
175         Format = DW_EH_PE_sdata4;
176       else
177         Format = DW_EH_PE_sdata8;
178     }
179
180     if (Global)
181       Format |= DW_EH_PE_indirect;
182
183     return (Format | DW_EH_PE_pcrel);
184   } else {
185     if (is64Bit &&
186         (CM == CodeModel::Small ||
187          (CM == CodeModel::Medium && Reason != DwarfEncoding::Data)))
188       return DW_EH_PE_udata4;
189     else
190       return DW_EH_PE_absptr;
191   }
192 }
193
194 X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM):
195   X86GenericTargetAsmInfo(TM) {
196
197   GlobalPrefix = "_";
198   LCOMMDirective = "\t.lcomm\t";
199   COMMDirectiveTakesAlignment = false;
200   HasDotTypeDotSizeDirective = false;
201   HasSingleParameterDotFile = false;
202   StaticCtorsSection = "\t.section .ctors,\"aw\"";
203   StaticDtorsSection = "\t.section .dtors,\"aw\"";
204   HiddenDirective = NULL;
205   PrivateGlobalPrefix = "L";  // Prefix for private global symbols
206   WeakRefDirective = "\t.weak\t";
207   SetDirective = "\t.set\t";
208
209   // Set up DWARF directives
210   HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
211   AbsoluteDebugSectionOffsets = true;
212   AbsoluteEHSectionOffsets = false;
213   SupportsDebugInformation = true;
214   DwarfSectionOffsetDirective = "\t.secrel32\t";
215   DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\"";
216   DwarfInfoSection =    "\t.section\t.debug_info,\"dr\"";
217   DwarfLineSection =    "\t.section\t.debug_line,\"dr\"";
218   DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\"";
219   DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\"";
220   DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\"";
221   DwarfStrSection =     "\t.section\t.debug_str,\"dr\"";
222   DwarfLocSection =     "\t.section\t.debug_loc,\"dr\"";
223   DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\"";
224   DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\"";
225   DwarfMacroInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
226 }
227
228 unsigned
229 X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
230                                             bool Global) const {
231   CodeModel::Model CM = TM.getCodeModel();
232   bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
233
234   if (TM.getRelocationModel() == Reloc::PIC_) {
235     unsigned Format = 0;
236
237     if (!is64Bit)
238       // 32 bit targets always encode pointers as 4 bytes
239       Format = DW_EH_PE_sdata4;
240     else {
241       // 64 bit targets encode pointers in 4 bytes iff:
242       // - code model is small OR
243       // - code model is medium and we're emitting externally visible symbols
244       //   or any code symbols
245       if (CM == CodeModel::Small ||
246           (CM == CodeModel::Medium && (Global ||
247                                        Reason != DwarfEncoding::Data)))
248         Format = DW_EH_PE_sdata4;
249       else
250         Format = DW_EH_PE_sdata8;
251     }
252
253     if (Global)
254       Format |= DW_EH_PE_indirect;
255
256     return (Format | DW_EH_PE_pcrel);
257   } else {
258     if (is64Bit &&
259         (CM == CodeModel::Small ||
260          (CM == CodeModel::Medium && Reason != DwarfEncoding::Data)))
261       return DW_EH_PE_udata4;
262     else
263       return DW_EH_PE_absptr;
264   }
265 }
266
267 std::string
268 X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
269                                              SectionKind::Kind kind) const {
270   switch (kind) {
271    case SectionKind::Text:
272     return ".text$linkonce" + GV->getName();
273    case SectionKind::Data:
274    case SectionKind::BSS:
275    case SectionKind::ThreadData:
276    case SectionKind::ThreadBSS:
277     return ".data$linkonce" + GV->getName();
278    case SectionKind::ROData:
279    case SectionKind::RODataMergeConst:
280    case SectionKind::RODataMergeStr:
281     return ".rdata$linkonce" + GV->getName();
282    default:
283     assert(0 && "Unknown section kind");
284   }
285   return NULL;
286 }
287
288 std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
289   std::string Flags = ",\"";
290
291   if (flags & SectionFlags::Code)
292     Flags += 'x';
293   if (flags & SectionFlags::Writeable)
294     Flags += 'w';
295
296   Flags += "\"";
297
298   return Flags;
299 }
300
301 X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
302   X86GenericTargetAsmInfo(TM) {
303   GlobalPrefix = "_";
304   CommentString = ";";
305
306   InlineAsmStart = "; InlineAsm Start";
307   InlineAsmEnd   = "; InlineAsm End";
308
309   PrivateGlobalPrefix = "$";
310   AlignDirective = "\tALIGN\t";
311   ZeroDirective = "\tdb\t";
312   ZeroDirectiveSuffix = " dup(0)";
313   AsciiDirective = "\tdb\t";
314   AscizDirective = 0;
315   Data8bitsDirective = "\tdb\t";
316   Data16bitsDirective = "\tdw\t";
317   Data32bitsDirective = "\tdd\t";
318   Data64bitsDirective = "\tdq\t";
319   HasDotTypeDotSizeDirective = false;
320   HasSingleParameterDotFile = false;
321
322   AlignmentIsInBytes = true;
323
324   TextSection = getUnnamedSection("_text", SectionFlags::Code);
325   DataSection = getUnnamedSection("_data", SectionFlags::Writeable);
326
327   JumpTableDataSection = NULL;
328   SwitchToSectionDirective = "";
329   TextSectionStartSuffix = "\tSEGMENT PARA 'CODE'";
330   DataSectionStartSuffix = "\tSEGMENT PARA 'DATA'";
331   SectionEndDirectiveSuffix = "\tends\n";
332 }
333
334 template <class BaseTAI>
335 bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const {
336   // FIXME: this should verify that we are targetting a 486 or better.  If not,
337   // we will turn this bswap into something that will be lowered to logical ops
338   // instead of emitting the bswap asm.  For now, we don't support 486 or lower
339   // so don't worry about this.
340
341   // Verify this is a simple bswap.
342   if (CI->getNumOperands() != 2 ||
343       CI->getType() != CI->getOperand(1)->getType() ||
344       !CI->getType()->isInteger())
345     return false;
346
347   const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
348   if (!Ty || Ty->getBitWidth() % 16 != 0)
349     return false;
350
351   // Okay, we can do this xform, do so now.
352   const Type *Tys[] = { Ty };
353   Module *M = CI->getParent()->getParent()->getParent();
354   Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1);
355
356   Value *Op = CI->getOperand(1);
357   Op = CallInst::Create(Int, Op, CI->getName(), CI);
358
359   CI->replaceAllUsesWith(Op);
360   CI->eraseFromParent();
361   return true;
362 }
363
364 template <class BaseTAI>
365 bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const {
366   InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
367   std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
368
369   std::string AsmStr = IA->getAsmString();
370
371   // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
372   std::vector<std::string> AsmPieces;
373   SplitString(AsmStr, AsmPieces, "\n");  // ; as separator?
374
375   switch (AsmPieces.size()) {
376   default: return false;
377   case 1:
378     AsmStr = AsmPieces[0];
379     AsmPieces.clear();
380     SplitString(AsmStr, AsmPieces, " \t");  // Split with whitespace.
381
382     // bswap $0
383     if (AsmPieces.size() == 2 &&
384         (AsmPieces[0] == "bswap" ||
385          AsmPieces[0] == "bswapq" ||
386          AsmPieces[0] == "bswapl") &&
387         (AsmPieces[1] == "$0" ||
388          AsmPieces[1] == "${0:q}")) {
389       // No need to check constraints, nothing other than the equivalent of
390       // "=r,0" would be valid here.
391       return LowerToBSwap(CI);
392     }
393     // rorw $$8, ${0:w}  -->  llvm.bswap.i16
394     if (CI->getType() == Type::Int16Ty &&
395         AsmPieces.size() == 3 &&
396         AsmPieces[0] == "rorw" &&
397         AsmPieces[1] == "$$8," &&
398         AsmPieces[2] == "${0:w}" &&
399         IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") {
400       return LowerToBSwap(CI);
401     }
402     break;
403   case 3:
404     if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 &&
405         Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
406         Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
407       // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64
408       std::vector<std::string> Words;
409       SplitString(AsmPieces[0], Words, " \t");
410       if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") {
411         Words.clear();
412         SplitString(AsmPieces[1], Words, " \t");
413         if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") {
414           Words.clear();
415           SplitString(AsmPieces[2], Words, " \t,");
416           if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" &&
417               Words[2] == "%edx") {
418             return LowerToBSwap(CI);
419           }
420         }
421       }
422     }
423     break;
424   }
425   return false;
426 }
427
428 // Instantiate default implementation.
429 TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);