| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 1 | //===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
| Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 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" | 
| Reid Spencer | 7aa8a45 | 2007-01-12 23:22:14 +0000 | [diff] [blame] | 17 | #include "llvm/DerivedTypes.h" | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 18 | #include "llvm/InlineAsm.h" | 
|  | 19 | #include "llvm/Instructions.h" | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 20 | #include "llvm/Intrinsics.h" | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 21 | #include "llvm/Module.h" | 
|  | 22 | #include "llvm/ADT/StringExtras.h" | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 23 | #include "llvm/Support/Dwarf.h" | 
|  | 24 |  | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 25 | using namespace llvm; | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 26 | using namespace llvm::dwarf; | 
| Jim Laskey | 8e8de8f | 2006-09-07 22:05:02 +0000 | [diff] [blame] | 27 |  | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 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}; | 
| Andrew Lenharth | 6c0695f | 2006-11-28 19:52:49 +0000 | [diff] [blame] | 39 |  | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 40 | TEMPLATE_INSTANTIATION(class X86TargetAsmInfo<TargetAsmInfo>); | 
|  | 41 | TEMPLATE_INSTANTIATION( | 
|  | 42 | bool X86TargetAsmInfo<TargetAsmInfo>::ExpandInlineAsm(CallInst*) const); | 
|  | 43 | TEMPLATE_INSTANTIATION( | 
|  | 44 | bool X86TargetAsmInfo<TargetAsmInfo>::LowerToBSwap(CallInst*) const); | 
| Anton Korobeynikov | 742fd19 | 2008-09-24 22:22:54 +0000 | [diff] [blame] | 45 |  | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 46 | template <class BaseTAI> | 
|  | 47 | bool X86TargetAsmInfo<BaseTAI>::LowerToBSwap(CallInst *CI) const { | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 48 | // FIXME: this should verify that we are targetting a 486 or better.  If not, | 
|  | 49 | // we will turn this bswap into something that will be lowered to logical ops | 
|  | 50 | // instead of emitting the bswap asm.  For now, we don't support 486 or lower | 
|  | 51 | // so don't worry about this. | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 52 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 53 | // Verify this is a simple bswap. | 
|  | 54 | if (CI->getNumOperands() != 2 || | 
|  | 55 | CI->getType() != CI->getOperand(1)->getType() || | 
| Chris Lattner | 42a7551 | 2007-01-15 02:27:26 +0000 | [diff] [blame] | 56 | !CI->getType()->isInteger()) | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 57 | return false; | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 58 |  | 
| Chris Lattner | 3e9f1d0 | 2007-04-01 20:49:36 +0000 | [diff] [blame] | 59 | const IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); | 
|  | 60 | if (!Ty || Ty->getBitWidth() % 16 != 0) | 
| Reid Spencer | a54b7cb | 2007-01-12 07:05:14 +0000 | [diff] [blame] | 61 | return false; | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 62 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 63 | // Okay, we can do this xform, do so now. | 
| Chandler Carruth | 6994040 | 2007-08-04 01:51:18 +0000 | [diff] [blame] | 64 | const Type *Tys[] = { Ty }; | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 65 | Module *M = CI->getParent()->getParent()->getParent(); | 
| Chandler Carruth | 6994040 | 2007-08-04 01:51:18 +0000 | [diff] [blame] | 66 | Constant *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Tys, 1); | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 67 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 68 | Value *Op = CI->getOperand(1); | 
| Gabor Greif | 051a950 | 2008-04-06 20:25:17 +0000 | [diff] [blame] | 69 | Op = CallInst::Create(Int, Op, CI->getName(), CI); | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 70 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 71 | CI->replaceAllUsesWith(Op); | 
|  | 72 | CI->eraseFromParent(); | 
|  | 73 | return true; | 
|  | 74 | } | 
|  | 75 |  | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 76 | template <class BaseTAI> | 
|  | 77 | bool X86TargetAsmInfo<BaseTAI>::ExpandInlineAsm(CallInst *CI) const { | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 78 | InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue()); | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 79 | std::vector<InlineAsm::ConstraintInfo> Constraints = IA->ParseConstraints(); | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 80 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 81 | std::string AsmStr = IA->getAsmString(); | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 82 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 83 | // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a" | 
|  | 84 | std::vector<std::string> AsmPieces; | 
|  | 85 | SplitString(AsmStr, AsmPieces, "\n");  // ; as separator? | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 86 |  | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 87 | switch (AsmPieces.size()) { | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 88 | default: return false; | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 89 | case 1: | 
|  | 90 | AsmStr = AsmPieces[0]; | 
|  | 91 | AsmPieces.clear(); | 
|  | 92 | SplitString(AsmStr, AsmPieces, " \t");  // Split with whitespace. | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 93 |  | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 94 | // bswap $0 | 
| Anton Korobeynikov | 8210045 | 2008-07-09 13:20:27 +0000 | [diff] [blame] | 95 | if (AsmPieces.size() == 2 && | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 96 | AsmPieces[0] == "bswap" && AsmPieces[1] == "$0") { | 
|  | 97 | // No need to check constraints, nothing other than the equivalent of | 
|  | 98 | // "=r,0" would be valid here. | 
|  | 99 | return LowerToBSwap(CI); | 
|  | 100 | } | 
|  | 101 | break; | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 102 | case 3: | 
| Reid Spencer | 4785781 | 2006-12-31 05:55:36 +0000 | [diff] [blame] | 103 | if (CI->getType() == Type::Int64Ty && Constraints.size() >= 2 && | 
| Chris Lattner | 5d52135 | 2006-11-29 01:48:01 +0000 | [diff] [blame] | 104 | Constraints[0].Codes.size() == 1 && Constraints[0].Codes[0] == "A" && | 
|  | 105 | Constraints[1].Codes.size() == 1 && Constraints[1].Codes[0] == "0") { | 
|  | 106 | // bswap %eax / bswap %edx / xchgl %eax, %edx  -> llvm.bswap.i64 | 
|  | 107 | std::vector<std::string> Words; | 
|  | 108 | SplitString(AsmPieces[0], Words, " \t"); | 
|  | 109 | if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%eax") { | 
|  | 110 | Words.clear(); | 
|  | 111 | SplitString(AsmPieces[1], Words, " \t"); | 
|  | 112 | if (Words.size() == 2 && Words[0] == "bswap" && Words[1] == "%edx") { | 
|  | 113 | Words.clear(); | 
|  | 114 | SplitString(AsmPieces[2], Words, " \t,"); | 
|  | 115 | if (Words.size() == 3 && Words[0] == "xchgl" && Words[1] == "%eax" && | 
|  | 116 | Words[2] == "%edx") { | 
|  | 117 | return LowerToBSwap(CI); | 
|  | 118 | } | 
|  | 119 | } | 
|  | 120 | } | 
|  | 121 | } | 
|  | 122 | break; | 
| Chris Lattner | 625bd05 | 2006-11-29 01:14:06 +0000 | [diff] [blame] | 123 | } | 
|  | 124 | return false; | 
|  | 125 | } | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 126 |  | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 127 | X86DarwinTargetAsmInfo::X86DarwinTargetAsmInfo(const X86TargetMachine &TM): | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 128 | X86TargetAsmInfo<DarwinTargetAsmInfo>(TM) { | 
| Anton Korobeynikov | 16b7f51 | 2008-08-08 18:25:52 +0000 | [diff] [blame] | 129 | const X86Subtarget* Subtarget = &DTM->getSubtarget<X86Subtarget>(); | 
|  | 130 | bool is64Bit = Subtarget->is64Bit(); | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 131 |  | 
|  | 132 | AlignmentIsInBytes = false; | 
|  | 133 | TextAlignFillValue = 0x90; | 
|  | 134 | GlobalPrefix = "_"; | 
|  | 135 | if (!is64Bit) | 
|  | 136 | Data64bitsDirective = 0;       // we can't emit a 64-bit unit | 
|  | 137 | ZeroDirective = "\t.space\t";  // ".space N" emits N zeros. | 
|  | 138 | PrivateGlobalPrefix = "L";     // Marker for constant pool idxs | 
| Dale Johannesen | b2dfb89 | 2008-09-09 01:21:22 +0000 | [diff] [blame] | 139 | LessPrivateGlobalPrefix = "l";  // Marker for some ObjC metadata | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 140 | BSSSection = 0;                       // no BSS section. | 
|  | 141 | ZeroFillDirective = "\t.zerofill\t";  // Uses .zerofill | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 142 | if (DTM->getRelocationModel() != Reloc::Static) | 
| Anton Korobeynikov | 7705ea3 | 2008-07-09 21:54:26 +0000 | [diff] [blame] | 143 | ConstantPoolSection = "\t.const_data"; | 
|  | 144 | else | 
|  | 145 | ConstantPoolSection = "\t.const\n"; | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 146 | JumpTableDataSection = "\t.const\n"; | 
|  | 147 | CStringSection = "\t.cstring"; | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 148 | // FIXME: Why don't always use this section? | 
| Anton Korobeynikov | 0d44ba8 | 2008-07-09 13:28:49 +0000 | [diff] [blame] | 149 | if (is64Bit) { | 
| Anton Korobeynikov | 6481873 | 2008-09-24 22:18:54 +0000 | [diff] [blame] | 150 | SixteenByteConstantSection = getUnnamedSection("\t.literal16\n", | 
|  | 151 | SectionFlags::Mergeable); | 
| Anton Korobeynikov | 0d44ba8 | 2008-07-09 13:28:49 +0000 | [diff] [blame] | 152 | } | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 153 | LCOMMDirective = "\t.lcomm\t"; | 
|  | 154 | SwitchToSectionDirective = "\t.section "; | 
|  | 155 | StringConstantPrefix = "\1LC"; | 
| Anton Korobeynikov | 16b7f51 | 2008-08-08 18:25:52 +0000 | [diff] [blame] | 156 | // Leopard and above support aligned common symbols. | 
|  | 157 | COMMDirectiveTakesAlignment = (Subtarget->getDarwinVers() >= 9); | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 158 | HasDotTypeDotSizeDirective = false; | 
|  | 159 | if (TM.getRelocationModel() == Reloc::Static) { | 
|  | 160 | StaticCtorsSection = ".constructor"; | 
|  | 161 | StaticDtorsSection = ".destructor"; | 
|  | 162 | } else { | 
|  | 163 | StaticCtorsSection = ".mod_init_func"; | 
|  | 164 | StaticDtorsSection = ".mod_term_func"; | 
|  | 165 | } | 
|  | 166 | if (is64Bit) { | 
|  | 167 | PersonalityPrefix = ""; | 
|  | 168 | PersonalitySuffix = "+4@GOTPCREL"; | 
|  | 169 | } else { | 
|  | 170 | PersonalityPrefix = "L"; | 
|  | 171 | PersonalitySuffix = "$non_lazy_ptr"; | 
|  | 172 | } | 
|  | 173 | NeedsIndirectEncoding = true; | 
|  | 174 | InlineAsmStart = "## InlineAsm Start"; | 
|  | 175 | InlineAsmEnd = "## InlineAsm End"; | 
|  | 176 | CommentString = "##"; | 
|  | 177 | SetDirective = "\t.set"; | 
|  | 178 | PCSymbol = "."; | 
|  | 179 | UsedDirective = "\t.no_dead_strip\t"; | 
|  | 180 | WeakDefDirective = "\t.weak_definition "; | 
|  | 181 | WeakRefDirective = "\t.weak_reference "; | 
|  | 182 | HiddenDirective = "\t.private_extern "; | 
|  | 183 | ProtectedDirective = "\t.globl\t"; | 
|  | 184 |  | 
|  | 185 | // In non-PIC modes, emit a special label before jump tables so that the | 
|  | 186 | // linker can perform more accurate dead code stripping. | 
|  | 187 | if (TM.getRelocationModel() != Reloc::PIC_) { | 
|  | 188 | // Emit a local label that is preserved until the linker runs. | 
|  | 189 | JumpTableSpecialLabelPrefix = "l"; | 
|  | 190 | } | 
|  | 191 |  | 
|  | 192 | SupportsDebugInformation = true; | 
|  | 193 | NeedsSet = true; | 
|  | 194 | DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug"; | 
|  | 195 | DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug"; | 
|  | 196 | DwarfLineSection = ".section __DWARF,__debug_line,regular,debug"; | 
|  | 197 | DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug"; | 
|  | 198 | DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug"; | 
|  | 199 | DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug"; | 
|  | 200 | DwarfStrSection = ".section __DWARF,__debug_str,regular,debug"; | 
|  | 201 | DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug"; | 
|  | 202 | DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug"; | 
|  | 203 | DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug"; | 
|  | 204 | DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug"; | 
|  | 205 |  | 
|  | 206 | // Exceptions handling | 
|  | 207 | SupportsExceptionHandling = true; | 
|  | 208 | GlobalEHDirective = "\t.globl\t"; | 
|  | 209 | SupportsWeakOmittedEHFrame = false; | 
|  | 210 | AbsoluteEHSectionOffsets = false; | 
|  | 211 | DwarfEHFrameSection = | 
|  | 212 | ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support"; | 
|  | 213 | DwarfExceptionSection = ".section __DATA,__gcc_except_tab"; | 
|  | 214 | } | 
|  | 215 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 216 | unsigned | 
|  | 217 | X86DarwinTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, | 
|  | 218 | bool Global) const { | 
|  | 219 | if (Reason == DwarfEncoding::Functions && Global) | 
|  | 220 | return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4); | 
|  | 221 | else if (Reason == DwarfEncoding::CodeLabels || !Global) | 
|  | 222 | return DW_EH_PE_pcrel; | 
|  | 223 | else | 
|  | 224 | return DW_EH_PE_absptr; | 
|  | 225 | } | 
|  | 226 |  | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 227 | X86ELFTargetAsmInfo::X86ELFTargetAsmInfo(const X86TargetMachine &TM): | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 228 | X86TargetAsmInfo<ELFTargetAsmInfo>(TM) { | 
| Anton Korobeynikov | 0d44ba8 | 2008-07-09 13:28:49 +0000 | [diff] [blame] | 229 |  | 
| Anton Korobeynikov | b20015b | 2008-07-09 13:25:26 +0000 | [diff] [blame] | 230 | CStringSection = ".rodata.str"; | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 231 | PrivateGlobalPrefix = ".L"; | 
|  | 232 | WeakRefDirective = "\t.weak\t"; | 
|  | 233 | SetDirective = "\t.set\t"; | 
|  | 234 | PCSymbol = "."; | 
|  | 235 |  | 
|  | 236 | // Set up DWARF directives | 
|  | 237 | HasLEB128 = true;  // Target asm supports leb128 directives (little-endian) | 
|  | 238 |  | 
|  | 239 | // Debug Information | 
|  | 240 | AbsoluteDebugSectionOffsets = true; | 
|  | 241 | SupportsDebugInformation = true; | 
|  | 242 | DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"\",@progbits"; | 
|  | 243 | DwarfInfoSection =    "\t.section\t.debug_info,\"\",@progbits"; | 
|  | 244 | DwarfLineSection =    "\t.section\t.debug_line,\"\",@progbits"; | 
|  | 245 | DwarfFrameSection =   "\t.section\t.debug_frame,\"\",@progbits"; | 
|  | 246 | DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"\",@progbits"; | 
|  | 247 | DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"\",@progbits"; | 
|  | 248 | DwarfStrSection =     "\t.section\t.debug_str,\"\",@progbits"; | 
|  | 249 | DwarfLocSection =     "\t.section\t.debug_loc,\"\",@progbits"; | 
|  | 250 | DwarfARangesSection = "\t.section\t.debug_aranges,\"\",@progbits"; | 
|  | 251 | DwarfRangesSection =  "\t.section\t.debug_ranges,\"\",@progbits"; | 
|  | 252 | DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"\",@progbits"; | 
|  | 253 |  | 
|  | 254 | // Exceptions handling | 
| Anton Korobeynikov | c4da15a | 2008-09-08 21:13:08 +0000 | [diff] [blame] | 255 | SupportsExceptionHandling = true; | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 256 | AbsoluteEHSectionOffsets = false; | 
|  | 257 | DwarfEHFrameSection = "\t.section\t.eh_frame,\"aw\",@progbits"; | 
|  | 258 | DwarfExceptionSection = "\t.section\t.gcc_except_table,\"a\",@progbits"; | 
|  | 259 |  | 
|  | 260 | // On Linux we must declare when we can use a non-executable stack. | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 261 | if (ETM->getSubtarget<X86Subtarget>().isLinux()) | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 262 | NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits"; | 
|  | 263 | } | 
|  | 264 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 265 | unsigned | 
|  | 266 | X86ELFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, | 
|  | 267 | bool Global) const { | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 268 | CodeModel::Model CM = ETM->getCodeModel(); | 
|  | 269 | bool is64Bit = ETM->getSubtarget<X86Subtarget>().is64Bit(); | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 270 |  | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 271 | if (ETM->getRelocationModel() == Reloc::PIC_) { | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 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 |  | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 304 | X86COFFTargetAsmInfo::X86COFFTargetAsmInfo(const X86TargetMachine &TM): | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 305 | X86GenericTargetAsmInfo(TM) { | 
| Anton Korobeynikov | 18f6ed9 | 2008-07-19 13:15:21 +0000 | [diff] [blame] | 306 | X86TM = &TM; | 
|  | 307 |  | 
| Anton Korobeynikov | 4468b7a | 2008-07-09 13:20:48 +0000 | [diff] [blame] | 308 | GlobalPrefix = "_"; | 
|  | 309 | LCOMMDirective = "\t.lcomm\t"; | 
|  | 310 | COMMDirectiveTakesAlignment = false; | 
|  | 311 | HasDotTypeDotSizeDirective = false; | 
|  | 312 | StaticCtorsSection = "\t.section .ctors,\"aw\""; | 
|  | 313 | StaticDtorsSection = "\t.section .dtors,\"aw\""; | 
|  | 314 | HiddenDirective = NULL; | 
|  | 315 | PrivateGlobalPrefix = "L";  // Prefix for private global symbols | 
|  | 316 | WeakRefDirective = "\t.weak\t"; | 
|  | 317 | SetDirective = "\t.set\t"; | 
|  | 318 |  | 
|  | 319 | // Set up DWARF directives | 
|  | 320 | HasLEB128 = true;  // Target asm supports leb128 directives (little-endian) | 
|  | 321 | AbsoluteDebugSectionOffsets = true; | 
|  | 322 | AbsoluteEHSectionOffsets = false; | 
|  | 323 | SupportsDebugInformation = true; | 
|  | 324 | DwarfSectionOffsetDirective = "\t.secrel32\t"; | 
|  | 325 | DwarfAbbrevSection =  "\t.section\t.debug_abbrev,\"dr\""; | 
|  | 326 | DwarfInfoSection =    "\t.section\t.debug_info,\"dr\""; | 
|  | 327 | DwarfLineSection =    "\t.section\t.debug_line,\"dr\""; | 
|  | 328 | DwarfFrameSection =   "\t.section\t.debug_frame,\"dr\""; | 
|  | 329 | DwarfPubNamesSection ="\t.section\t.debug_pubnames,\"dr\""; | 
|  | 330 | DwarfPubTypesSection ="\t.section\t.debug_pubtypes,\"dr\""; | 
|  | 331 | DwarfStrSection =     "\t.section\t.debug_str,\"dr\""; | 
|  | 332 | DwarfLocSection =     "\t.section\t.debug_loc,\"dr\""; | 
|  | 333 | DwarfARangesSection = "\t.section\t.debug_aranges,\"dr\""; | 
|  | 334 | DwarfRangesSection =  "\t.section\t.debug_ranges,\"dr\""; | 
|  | 335 | DwarfMacInfoSection = "\t.section\t.debug_macinfo,\"dr\""; | 
|  | 336 | } | 
|  | 337 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 338 | unsigned | 
|  | 339 | X86COFFTargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason, | 
|  | 340 | bool Global) const { | 
|  | 341 | CodeModel::Model CM = X86TM->getCodeModel(); | 
|  | 342 | bool is64Bit = X86TM->getSubtarget<X86Subtarget>().is64Bit(); | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 343 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 344 | if (X86TM->getRelocationModel() == Reloc::PIC_) { | 
|  | 345 | unsigned Format = 0; | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 346 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 347 | if (!is64Bit) | 
|  | 348 | // 32 bit targets always encode pointers as 4 bytes | 
|  | 349 | Format = DW_EH_PE_sdata4; | 
|  | 350 | else { | 
|  | 351 | // 64 bit targets encode pointers in 4 bytes iff: | 
|  | 352 | // - code model is small OR | 
|  | 353 | // - code model is medium and we're emitting externally visible symbols | 
|  | 354 | //   or any code symbols | 
|  | 355 | if (CM == CodeModel::Small || | 
|  | 356 | (CM == CodeModel::Medium && (Global || | 
|  | 357 | Reason != DwarfEncoding::Data))) | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 358 | Format = DW_EH_PE_sdata4; | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 359 | else | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 360 | Format = DW_EH_PE_sdata8; | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 361 | } | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 362 |  | 
| Anton Korobeynikov | b9e58ef | 2008-07-09 13:21:08 +0000 | [diff] [blame] | 363 | if (Global) | 
|  | 364 | Format |= DW_EH_PE_indirect; | 
|  | 365 |  | 
|  | 366 | return (Format | DW_EH_PE_pcrel); | 
|  | 367 | } else { | 
|  | 368 | if (is64Bit && | 
|  | 369 | (CM == CodeModel::Small || | 
|  | 370 | (CM == CodeModel::Medium && Reason != DwarfEncoding::Data))) | 
|  | 371 | return DW_EH_PE_udata4; | 
|  | 372 | else | 
|  | 373 | return DW_EH_PE_absptr; | 
| Anton Korobeynikov | cee750f | 2008-02-27 23:33:50 +0000 | [diff] [blame] | 374 | } | 
|  | 375 | } | 
|  | 376 |  | 
| Anton Korobeynikov | b9a02fc | 2008-07-09 13:21:29 +0000 | [diff] [blame] | 377 | std::string | 
|  | 378 | X86COFFTargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV, | 
|  | 379 | SectionKind::Kind kind) const { | 
|  | 380 | switch (kind) { | 
|  | 381 | case SectionKind::Text: | 
|  | 382 | return ".text$linkonce" + GV->getName(); | 
|  | 383 | case SectionKind::Data: | 
|  | 384 | case SectionKind::BSS: | 
|  | 385 | case SectionKind::ThreadData: | 
|  | 386 | case SectionKind::ThreadBSS: | 
|  | 387 | return ".data$linkonce" + GV->getName(); | 
|  | 388 | case SectionKind::ROData: | 
|  | 389 | case SectionKind::RODataMergeConst: | 
|  | 390 | case SectionKind::RODataMergeStr: | 
|  | 391 | return ".rdata$linkonce" + GV->getName(); | 
| Anton Korobeynikov | 29b03f7 | 2008-07-09 13:19:38 +0000 | [diff] [blame] | 392 | default: | 
| Anton Korobeynikov | b9a02fc | 2008-07-09 13:21:29 +0000 | [diff] [blame] | 393 | assert(0 && "Unknown section kind"); | 
| Anton Korobeynikov | 29b03f7 | 2008-07-09 13:19:38 +0000 | [diff] [blame] | 394 | } | 
|  | 395 | } | 
|  | 396 |  | 
| Anton Korobeynikov | d0c1e29 | 2008-08-16 12:57:07 +0000 | [diff] [blame] | 397 | std::string X86COFFTargetAsmInfo::printSectionFlags(unsigned flags) const { | 
| Anton Korobeynikov | f447e3d | 2008-07-09 13:21:49 +0000 | [diff] [blame] | 398 | std::string Flags = ",\""; | 
|  | 399 |  | 
|  | 400 | if (flags & SectionFlags::Code) | 
|  | 401 | Flags += 'x'; | 
|  | 402 | if (flags & SectionFlags::Writeable) | 
|  | 403 | Flags += 'w'; | 
|  | 404 |  | 
|  | 405 | Flags += "\""; | 
|  | 406 |  | 
|  | 407 | return Flags; | 
|  | 408 | } | 
|  | 409 |  | 
|  | 410 | X86WinTargetAsmInfo::X86WinTargetAsmInfo(const X86TargetMachine &TM): | 
| Anton Korobeynikov | 32b952a | 2008-09-25 21:00:33 +0000 | [diff] [blame] | 411 | X86GenericTargetAsmInfo(TM) { | 
| Anton Korobeynikov | f447e3d | 2008-07-09 13:21:49 +0000 | [diff] [blame] | 412 | GlobalPrefix = "_"; | 
|  | 413 | CommentString = ";"; | 
|  | 414 |  | 
|  | 415 | PrivateGlobalPrefix = "$"; | 
|  | 416 | AlignDirective = "\talign\t"; | 
|  | 417 | ZeroDirective = "\tdb\t"; | 
|  | 418 | ZeroDirectiveSuffix = " dup(0)"; | 
|  | 419 | AsciiDirective = "\tdb\t"; | 
|  | 420 | AscizDirective = 0; | 
|  | 421 | Data8bitsDirective = "\tdb\t"; | 
|  | 422 | Data16bitsDirective = "\tdw\t"; | 
|  | 423 | Data32bitsDirective = "\tdd\t"; | 
|  | 424 | Data64bitsDirective = "\tdq\t"; | 
|  | 425 | HasDotTypeDotSizeDirective = false; | 
|  | 426 |  | 
| Anton Korobeynikov | d7ca416 | 2008-09-24 22:15:21 +0000 | [diff] [blame] | 427 | TextSection = getUnnamedSection("_text", SectionFlags::Code); | 
| Anton Korobeynikov | 315690e | 2008-09-24 22:16:16 +0000 | [diff] [blame] | 428 | DataSection = getUnnamedSection("_data", SectionFlags::Writeable); | 
|  | 429 |  | 
| Anton Korobeynikov | f447e3d | 2008-07-09 13:21:49 +0000 | [diff] [blame] | 430 | JumpTableDataSection = NULL; | 
|  | 431 | SwitchToSectionDirective = ""; | 
|  | 432 | TextSectionStartSuffix = "\tsegment 'CODE'"; | 
|  | 433 | DataSectionStartSuffix = "\tsegment 'DATA'"; | 
|  | 434 | SectionEndDirectiveSuffix = "\tends\n"; | 
|  | 435 | } |