LLVM API Documentation

X86TargetAsmInfo.cpp

Go to the documentation of this file.
00001 //===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the declarations of the X86TargetAsmInfo properties.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "X86TargetAsmInfo.h"
00015 #include "X86TargetMachine.h"
00016 #include "X86Subtarget.h"
00017 #include "llvm/DerivedTypes.h"
00018 #include "llvm/InlineAsm.h"
00019 #include "llvm/Instructions.h"
00020 #include "llvm/Intrinsics.h"
00021 #include "llvm/Module.h"
00022 #include "llvm/ADT/StringExtras.h"
00023 #include "llvm/Support/Dwarf.h"
00024 
00025 using namespace llvm;
00026 using namespace llvm::dwarf;
00027 
00028 const char *const llvm::x86_asm_table[] = {
00029   "{si}", "S",
00030   "{di}", "D",
00031   "{ax}", "a",
00032   "{cx}", "c",
00033   "{memory}", "memory",
00034   "{flags}", "",
00035   "{dirflag}", "",
00036   "{fpsr}", "",
00037   "{cc}", "cc",
00038   0,0};
00039 
00040 X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM):
00041   X86TargetAsmInfo<DarwinTargetAsmInfo>(TM) {
00042   const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>();
00043   bool is64Bit = Subtarget->is64Bit();
00044 
00045   AlignmentIsInBytes = false;
00046   TextAlignFillValue = 0x90;
00047   GlobalPrefix = "_";
00048   if (!is64Bit)
00049     Data64bitsDirective = 0;       // we can't emit a 64-bit unit
00050   ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
00051   PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
00052   LessPrivateGlobalPrefix = "l";  // Marker for some ObjC metadata
00053   BSSSection = 0;                       // no BSS section.
00054   ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill
00055   if (TM.getRelocationModel() != Reloc::Static)
00056     ConstantPoolSection = "\t.const_data";
00057   else
00058     ConstantPoolSection = "\t.const\n";
00059   JumpTableDataSection = "\t.const\n";
00060   CStringSection = "\t.cstring";
00061   // FIXME: Why don't always use this section?
00062   if (is64Bit) {
00063     SixteenByteConstantSection = getUnnamedSection("\t.literal16\n",
00064                                                    SectionFlags::Mergeable);
00065   }
00066   LCOMMDirective = "\t.lcomm\t";
00067   SwitchToSectionDirective = "\t.section ";
00068   StringConstantPrefix = "\1LC";
00069   // Leopard and above support aligned common symbols.
00070   COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9);
00071   HasDotTypeDotSizeDirective = false;
00072   HasSingleParameterDotFile = false;
00073   NonLocalEHFrameLabel = true;
00074   if (TM.getRelocationModel() == Reloc::Static) {
00075     StaticCtorsSection = ".constructor";
00076     StaticDtorsSection = ".destructor";
00077   } else {
00078     StaticCtorsSection = ".mod_init_func";
00079     StaticDtorsSection = ".mod_term_func";
00080   }
00081   if (is64Bit) {
00082     PersonalityPrefix = "";
00083     PersonalitySuffix = "+4@GOTPCREL";
00084   } else {
00085     PersonalityPrefix = "L";
00086     PersonalitySuffix = "$non_lazy_ptr";
00087   }
00088   NeedsIndirectEncoding = true;
00089   InlineAsmStart = "## InlineAsm Start";
00090   InlineAsmEnd = "## InlineAsm End";
00091   CommentString = "##";
00092   SetDirective = "\t.set";
00093   PCSymbol = ".";
00094   UsedDirective = "\t.no_dead_strip\t";
00095   WeakDefDirective = "\t.weak_definition ";
00096   WeakRefDirective = "\t.weak_reference ";
00097   HiddenDirective = "\t.private_extern ";
00098   ProtectedDirective = "\t.globl\t";
00099 
00100   // In non-PIC modes, emit a special label before jump tables so that the
00101   // linker can perform more accurate dead code stripping.
00102   if (TM.getRelocationModel() != Reloc::PIC_) {
00103     // Emit a local label that is preserved until the linker runs.
00104     JumpTableSpecialLabelPrefix = "l";
00105   }
00106 
00107   SupportsDebugInformation = true;
00108   NeedsSet = true;
00109   DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
00110   DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
00111   DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
00112   DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
00113   DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
00114   DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
00115   DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
00116   DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
00117   DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
00118   DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
00119   DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
00120 
00121   // Exceptions handling
00122   SupportsExceptionHandling = true;
00123   GlobalEHDirective = "\t.globl\t";
00124   SupportsWeakOmittedEHFrame = false;
00125   AbsoluteEHSectionOffsets = false;
00126   DwarfEHFrameSection =
00127   ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support";
00128   DwarfExceptionSection = ".section __DATA,__gcc_except_tab";
00129 }
00130 
00131 unsigned
00132 X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
00133                                               bool Global) const {
00134   if (Reason == DwarfEncoding::Functions && Global)
00135     return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4);
00136   else if (Reason == DwarfEncoding::CodeLabels || !Global)
00137     return DW_EH_PE_pcrel;
00138   else
00139     return DW_EH_PE_absptr;
00140 }
00141 
00142 const char *
00143 X86DarwinTargetAsmInfo::getEHGlobalPrefix() const
00144 {
00145   const X86Subtarget* Subtarget = &TM.getSubtarget<X86Subtarget>();
00146   if (Subtarget->getDarwinVers() > 9)
00147     return PrivateGlobalPrefix;
00148   else
00149     return "";
00150 }
00151 
00152 X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM):
00153   X86TargetAsmInfo<ELFTargetAsmInfo>(TM) {
00154 
00155   CStringSection = ".rodata.str";
00156   PrivateGlobalPrefix = ".L";
00157   WeakRefDirective = "\t.weak\t";
00158   SetDirective = "\t.set\t";
00159   PCSymbol = ".";
00160 
00161   // Set up DWARF directives
00162   HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
00163 
00164   // Debug Information
00165   AbsoluteDebugSectionOffsets = true;
00166   SupportsDebugInformation = true;
00167   DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits";
00168   DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits";
00169   DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits";
00170   DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits";
00171   DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits";
00172   DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits";
00173   DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits";
00174   DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits";
00175   DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits";
00176   DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits";
00177   DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits";
00178 
00179   // Exceptions handling
00180   SupportsExceptionHandling = true;
00181   AbsoluteEHSectionOffsets = false;
00182   DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits";
00183   DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits";
00184 
00185   // On Linux we must declare when we can use a non-executable stack.
00186   if (TM.getSubtarget<X86Subtarget>().isLinux())
00187     NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits";
00188 }
00189 
00190 unsigned
00191 X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
00192                                            bool Global) const {
00193   CodeModel::Model CM = TM.getCodeModel();
00194   bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
00195 
00196   if (TM.getRelocationModel() == Reloc::PIC_) {
00197     unsigned Format = 0;
00198 
00199     if (!is64Bit)
00200       // 32 bit targets always encode pointers as 4 bytes
00201       Format = DW_EH_PE_sdata4;
00202     else {
00203       // 64 bit targets encode pointers in 4 bytes iff:
00204       // - code model is small OR
00205       // - code model is medium and we're emitting externally visible symbols
00206       //   or any code symbols
00207       if (CM == CodeModel::Small ||
00208           (CM == CodeModel::Medium && (Global ||
00209                                        Reason != DwarfEncoding::Data)))
00210         Format = DW_EH_PE_sdata4;
00211       else
00212         Format = DW_EH_PE_sdata8;
00213     }
00214 
00215     if (Global)
00216       Format |= DW_EH_PE_indirect;
00217 
00218     return (Format | DW_EH_PE_pcrel);
00219   } else {
00220     if (is64Bit &&
00221         (CM == CodeModel::Small ||
00222          (CM == CodeModel::Medium && Reason != DwarfEncoding::Data)))
00223       return DW_EH_PE_udata4;
00224     else
00225       return DW_EH_PE_absptr;
00226   }
00227 }
00228 
00229 X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM):
00230   X86GenericTargetAsmInfo(TM) {
00231 
00232   GlobalPrefix = "_";
00233   LCOMMDirective = "\t.lcomm\t";
00234   COMMDirectiveTakesAlignment = false;
00235   HasDotTypeDotSizeDirective = false;
00236   HasSingleParameterDotFile = false;
00237   StaticCtorsSection = "\t.section .ctors,\"aw\"";
00238   StaticDtorsSection = "\t.section .dtors,\"aw\"";
00239   HiddenDirective = NULL;
00240   PrivateGlobalPrefix = "L";  // Prefix for private global symbols
00241   WeakRefDirective = "\t.weak\t";
00242   SetDirective = "\t.set\t";
00243 
00244   // Set up DWARF directives
00245   HasLEB128 = true;  // Target asm supports leb128 directives (little-endian)
00246   AbsoluteDebugSectionOffsets = true;
00247   AbsoluteEHSectionOffsets = false;
00248   SupportsDebugInformation = true;
00249   DwarfSectionOffsetDirective = "\t.secrel32\t";
00250   DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\"";
00251   DwarfInfoSection =    "\t.section\t.debug_info,\"dr\"";
00252   DwarfLineSection =    "\t.section\t.debug_line,\"dr\"";
00253   DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\"";
00254   DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\"";
00255   DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\"";
00256   DwarfStrSection =     "\t.section\t.debug_str,\"dr\"";
00257   DwarfLocSection =     "\t.section\t.debug_loc,\"dr\"";
00258   DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\"";
00259   DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\"";
00260   DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\"";
00261 }
00262 
00263 unsigned
00264 X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
00265                                             bool Global) const {
00266   CodeModel::Model CM = TM.getCodeModel();
00267   bool is64Bit = TM.getSubtarget<X86Subtarget>().is64Bit();
00268 
00269   if (TM.getRelocationModel() == Reloc::PIC_) {
00270     unsigned Format = 0;
00271 
00272     if (!is64Bit)
00273       // 32 bit targets always encode pointers as 4 bytes
00274       Format = DW_EH_PE_sdata4;
00275     else {
00276       // 64 bit targets encode pointers in 4 bytes iff:
00277       // - code model is small OR
00278       // - code model is medium and we're emitting externally visible symbols
00279       //   or any code symbols
00280       if (CM == CodeModel::Small ||
00281           (CM == CodeModel::Medium && (Global ||
00282                                        Reason != DwarfEncoding::Data)))
00283         Format = DW_EH_PE_sdata4;
00284       else
00285         Format = DW_EH_PE_sdata8;
00286     }
00287 
00288     if (Global)
00289       Format |= DW_EH_PE_indirect;
00290 
00291     return (Format | DW_EH_PE_pcrel);
00292   } else {
00293     if (is64Bit &&
00294         (CM == CodeModel::Small ||
00295          (CM == CodeModel::Medium && Reason != DwarfEncoding::Data)))
00296       return DW_EH_PE_udata4;
00297     else
00298       return DW_EH_PE_absptr;
00299   }
00300 }
00301 
00302 std::string
00303 X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
00304                                              SectionKind::Kind kind) const {
00305   switch (kind) {
00306    case SectionKind::Text:
00307     return ".text$linkonce" + GV->getName();
00308    case SectionKind::Data:
00309    case SectionKind::BSS:
00310    case SectionKind::ThreadData:
00311    case SectionKind::ThreadBSS:
00312     return ".data$linkonce" + GV->getName();
00313    case SectionKind::ROData:
00314    case SectionKind::RODataMergeConst:
00315    case SectionKind::RODataMergeStr:
00316     return ".rdata$linkonce" + GV->getName();
00317    default:
00318     assert(0 && "Unknown section kind");
00319   }
00320   return NULL;
00321 }
00322 
00323 std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const {
00324   std::string Flags = ",\"";
00325 
00326   if (flags & SectionFlags::Code)
00327     Flags += 'x';
00328   if (flags & SectionFlags::Writeable)
00329     Flags += 'w';
00330 
00331   Flags += "\"";
00332 
00333   return Flags;
00334 }
00335 
00336 X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM):
00337   X86GenericTargetAsmInfo(TM) {
00338   GlobalPrefix = "_";
00339   CommentString = ";";
00340 
00341   PrivateGlobalPrefix = "$";
00342   AlignDirective = "\talign\t";
00343   ZeroDirective = "\tdb\t";
00344   ZeroDirectiveSuffix = " dup(0)";
00345   AsciiDirective = "\tdb\t";
00346   AscizDirective = 0;
00347   Data8bitsDirective = "\tdb\t";
00348   Data16bitsDirective = "\tdw\t";
00349   Data32bitsDirective = "\tdd\t";
00350   Data64bitsDirective = "\tdq\t";
00351   HasDotTypeDotSizeDirective = false;
00352   HasSingleParameterDotFile = false;
00353 
00354   TextSection = getUnnamedSection("_text", SectionFlags::Code);
00355   DataSection = getUnnamedSection("_data", SectionFlags::Writeable);
00356 
00357   JumpTableDataSection = NULL;
00358   SwitchToSectionDirective = "";
00359   TextSectionStartSuffix = "\tsegment 'CODE'";
00360   DataSectionStartSuffix = "\tsegment 'DATA'";
00361   SectionEndDirectiveSuffix = "\tends\n";
00362 }
00363 
00364 template <class BaseTAI>
00365 bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const {
00366   // FIXME: this should verify that we are targetting a 486 or better.  If not,
00367   // we will turn this bswap into something that will be lowered to logical ops
00368   // instead of emitting the bswap asm.  For now, we don't support 486 or lower
00369   // so don't worry about this.
00370 
00371   // Verify this is a simple bswap.
00372   if (CI->getNumOperands() != 2 ||
00373       CI->getType() != CI->getOperand(1)->getType() ||
00374       !CI->getType()->isInteger())
00375     return false;
00376 
00377   const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType());
00378   if (!Ty || Ty->getBitWidth() % 16 != 0)
00379     return false;
00380 
00381   // Okay, we can do this xform, do so now.
00382   const Type *Tys[] = { Ty };
00383   Module *M = CI->getParent()->getParent()->getParent();
00384   Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1);
00385 
00386   Value *Op = CI->getOperand(1);
00387   Op = CallInst::Create(Int, Op, CI->getName(), CI);
00388 
00389   CI->replaceAllUsesWith(Op);
00390   CI->eraseFromParent();
00391   return true;
00392 }
00393 
00394 template <class BaseTAI>
00395 bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const {
00396   InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
00397   std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints();
00398 
00399   std::string AsmStr = IA->getAsmString();
00400 
00401   // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
00402   std::vector<std::string> AsmPieces;
00403   SplitString(AsmStr, AsmPieces, "\n");  // ; as separator?
00404 
00405   switch (AsmPieces.size()) {
00406   default: return false;
00407   case 1:
00408     AsmStr = AsmPieces[0];
00409     AsmPieces.clear();
00410     SplitString(AsmStr, AsmPieces, " \t");  // Split with whitespace.
00411 
00412     // bswap $0
00413     if (AsmPieces.size() == 2 &&
00414         AsmPieces[0] == "bswap" && (AsmPieces[1] == "$0" ||
00415                                     AsmPieces[1] == "${0:q}")) {
00416       // No need to check constraints, nothing other than the equivalent of
00417       // "=r,0" would be valid here.
00418       return LowerToBSwap(CI);
00419     }
00420     // rorw $$8, ${0:w}  -->  llvm.bswap.i16
00421     if (CI->getType() == Type::Int16Ty &&
00422         AsmPieces.size() == 3 &&
00423         AsmPieces[0] == "rorw" &&
00424         AsmPieces[1] == "$$8," &&
00425         AsmPieces[2] == "${0:w}" &&
00426         IA->getConstraintString() == "=r,0,~{dirflag},~{fpsr},~{flags},~{cc}") {
00427       return LowerToBSwap(CI);
00428     }
00429     break;
00430   case 3:
00431     if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 &&
00432         Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" &&
00433         Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") {
00434       // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64
00435       std::vector<std::string> Words;
00436       SplitString(AsmPieces[0], Words, " \t");
00437       if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") {
00438         Words.clear();
00439         SplitString(AsmPieces[1], Words, " \t");
00440         if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") {
00441           Words.clear();
00442           SplitString(AsmPieces[2], Words, " \t,");
00443           if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" &&
00444               Words[2] == "%edx") {
00445             return LowerToBSwap(CI);
00446           }
00447         }
00448       }
00449     }
00450     break;
00451   }
00452   return false;
00453 }
00454 
00455 // Instantiate default implementation.
00456 TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>);