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