LLVM API Documentation
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>);