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