1 //===-- X86TargetAsmInfo.cpp - X86 asm properties ---------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by James M. Laskey and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the declarations of the X86TargetAsmInfo properties.
12 //===----------------------------------------------------------------------===//
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"
25 static const char* x86_asm_table
[] = {"{si}", "S",
36 X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine
&TM
) {
37 const X86Subtarget
*Subtarget
= &TM
.getSubtarget
<X86Subtarget
>();
39 // FIXME - Should be simplified.
41 AsmTransCBE
= x86_asm_table
;
43 switch (Subtarget
->TargetType
) {
44 case X86Subtarget::isDarwin
:
45 AlignmentIsInBytes
= false;
47 if (!Subtarget
->is64Bit())
48 Data64bitsDirective
= 0; // we can't emit a 64-bit unit
49 ZeroDirective
= "\t.space\t"; // ".space N" emits N zeros.
50 PrivateGlobalPrefix
= "L"; // Marker for constant pool idxs
51 BSSSection
= 0; // no BSS section.
52 ZeroFillDirective
= "\t.zerofill\t"; // Uses .zerofill
53 ConstantPoolSection
= "\t.const\n";
54 JumpTableDataSection
= "\t.const\n";
55 CStringSection
= "\t.cstring";
56 FourByteConstantSection
= "\t.literal4\n";
57 EightByteConstantSection
= "\t.literal8\n";
58 if (Subtarget
->is64Bit())
59 SixteenByteConstantSection
= "\t.literal16\n";
60 ReadOnlySection
= "\t.const\n";
61 LCOMMDirective
= "\t.lcomm\t";
62 COMMDirectiveTakesAlignment
= false;
63 HasDotTypeDotSizeDirective
= false;
64 if (TM
.getRelocationModel() == Reloc::Static
) {
65 StaticCtorsSection
= ".constructor";
66 StaticDtorsSection
= ".destructor";
68 StaticCtorsSection
= ".mod_init_func";
69 StaticDtorsSection
= ".mod_term_func";
71 PersonalityPrefix
= "L";
72 PersonalitySuffix
= "$non_lazy_ptr";
73 NeedsIndirectEncoding
= true;
74 InlineAsmStart
= "# InlineAsm Start";
75 InlineAsmEnd
= "# InlineAsm End";
76 SetDirective
= "\t.set";
78 UsedDirective
= "\t.no_dead_strip\t";
79 WeakRefDirective
= "\t.weak_reference\t";
80 HiddenDirective
= "\t.private_extern\t";
82 // In non-PIC modes, emit a special label before jump tables so that the
83 // linker can perform more accurate dead code stripping.
84 if (TM
.getRelocationModel() != Reloc::PIC_
) {
85 // Emit a local label that is preserved until the linker runs.
86 JumpTableSpecialLabelPrefix
= "l";
89 SupportsDebugInformation
= true;
91 DwarfAbbrevSection
= ".section __DWARF,__debug_abbrev,regular,debug";
92 DwarfInfoSection
= ".section __DWARF,__debug_info,regular,debug";
93 DwarfLineSection
= ".section __DWARF,__debug_line,regular,debug";
94 DwarfFrameSection
= ".section __DWARF,__debug_frame,regular,debug";
95 DwarfPubNamesSection
= ".section __DWARF,__debug_pubnames,regular,debug";
96 DwarfPubTypesSection
= ".section __DWARF,__debug_pubtypes,regular,debug";
97 DwarfStrSection
= ".section __DWARF,__debug_str,regular,debug";
98 DwarfLocSection
= ".section __DWARF,__debug_loc,regular,debug";
99 DwarfARangesSection
= ".section __DWARF,__debug_aranges,regular,debug";
100 DwarfRangesSection
= ".section __DWARF,__debug_ranges,regular,debug";
101 DwarfMacInfoSection
= ".section __DWARF,__debug_macinfo,regular,debug";
103 // Exceptions handling
104 if (!Subtarget
->is64Bit())
105 SupportsExceptionHandling
= true;
106 AbsoluteEHSectionOffsets
= false;
107 DwarfEHFrameSection
=
108 ".section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support";
109 DwarfExceptionSection
= ".section __DATA,__gcc_except_tab";
112 case X86Subtarget::isELF
:
113 ReadOnlySection
= "\t.section\t.rodata";
114 FourByteConstantSection
= "\t.section\t.rodata.cst4,\"aM\",@progbits,4";
115 EightByteConstantSection
= "\t.section\t.rodata.cst8,\"aM\",@progbits,8";
116 SixteenByteConstantSection
= "\t.section\t.rodata.cst16,\"aM\",@progbits,16";
117 CStringSection
= "\t.section\t.rodata.str1.1,\"aMS\",@progbits,1";
118 PrivateGlobalPrefix
= ".L";
119 WeakRefDirective
= "\t.weak\t";
120 SetDirective
= "\t.set\t";
123 // Set up DWARF directives
124 HasLEB128
= true; // Target asm supports leb128 directives (little-endian)
127 AbsoluteDebugSectionOffsets
= true;
128 SupportsDebugInformation
= true;
129 DwarfAbbrevSection
= "\t.section\t.debug_abbrev,\"\",@progbits";
130 DwarfInfoSection
= "\t.section\t.debug_info,\"\",@progbits";
131 DwarfLineSection
= "\t.section\t.debug_line,\"\",@progbits";
132 DwarfFrameSection
= "\t.section\t.debug_frame,\"\",@progbits";
133 DwarfPubNamesSection
="\t.section\t.debug_pubnames,\"\",@progbits";
134 DwarfPubTypesSection
="\t.section\t.debug_pubtypes,\"\",@progbits";
135 DwarfStrSection
= "\t.section\t.debug_str,\"\",@progbits";
136 DwarfLocSection
= "\t.section\t.debug_loc,\"\",@progbits";
137 DwarfARangesSection
= "\t.section\t.debug_aranges,\"\",@progbits";
138 DwarfRangesSection
= "\t.section\t.debug_ranges,\"\",@progbits";
139 DwarfMacInfoSection
= "\t.section\t.debug_macinfo,\"\",@progbits";
141 // Exceptions handling
142 if (!Subtarget
->is64Bit())
143 SupportsExceptionHandling
= true;
144 AbsoluteEHSectionOffsets
= false;
145 DwarfEHFrameSection
= "\t.section\t.eh_frame,\"aw\",@progbits";
146 DwarfExceptionSection
= "\t.section\t.gcc_except_table,\"a\",@progbits";
149 case X86Subtarget::isCygwin
:
150 case X86Subtarget::isMingw
:
152 LCOMMDirective
= "\t.lcomm\t";
153 COMMDirectiveTakesAlignment
= false;
154 HasDotTypeDotSizeDirective
= false;
155 StaticCtorsSection
= "\t.section .ctors,\"aw\"";
156 StaticDtorsSection
= "\t.section .dtors,\"aw\"";
157 HiddenDirective
= NULL
;
158 PrivateGlobalPrefix
= "L"; // Prefix for private global symbols
159 WeakRefDirective
= "\t.weak\t";
160 SetDirective
= "\t.set\t";
162 // Set up DWARF directives
163 HasLEB128
= true; // Target asm supports leb128 directives (little-endian)
164 AbsoluteDebugSectionOffsets
= true;
165 AbsoluteEHSectionOffsets
= false;
166 SupportsDebugInformation
= true;
167 DwarfSectionOffsetDirective
= "\t.secrel32\t";
168 DwarfAbbrevSection
= "\t.section\t.debug_abbrev,\"dr\"";
169 DwarfInfoSection
= "\t.section\t.debug_info,\"dr\"";
170 DwarfLineSection
= "\t.section\t.debug_line,\"dr\"";
171 DwarfFrameSection
= "\t.section\t.debug_frame,\"dr\"";
172 DwarfPubNamesSection
="\t.section\t.debug_pubnames,\"dr\"";
173 DwarfPubTypesSection
="\t.section\t.debug_pubtypes,\"dr\"";
174 DwarfStrSection
= "\t.section\t.debug_str,\"dr\"";
175 DwarfLocSection
= "\t.section\t.debug_loc,\"dr\"";
176 DwarfARangesSection
= "\t.section\t.debug_aranges,\"dr\"";
177 DwarfRangesSection
= "\t.section\t.debug_ranges,\"dr\"";
178 DwarfMacInfoSection
= "\t.section\t.debug_macinfo,\"dr\"";
181 case X86Subtarget::isWindows
:
183 HasDotTypeDotSizeDirective
= false;
189 if (Subtarget
->isFlavorIntel()) {
193 PrivateGlobalPrefix
= "$";
194 AlignDirective
= "\talign\t";
195 ZeroDirective
= "\tdb\t";
196 ZeroDirectiveSuffix
= " dup(0)";
197 AsciiDirective
= "\tdb\t";
199 Data8bitsDirective
= "\tdb\t";
200 Data16bitsDirective
= "\tdw\t";
201 Data32bitsDirective
= "\tdd\t";
202 Data64bitsDirective
= "\tdq\t";
203 HasDotTypeDotSizeDirective
= false;
205 TextSection
= "_text";
206 DataSection
= "_data";
207 JumpTableDataSection
= NULL
;
208 SwitchToSectionDirective
= "";
209 TextSectionStartSuffix
= "\tsegment 'CODE'";
210 DataSectionStartSuffix
= "\tsegment 'DATA'";
211 SectionEndDirectiveSuffix
= "\tends\n";
214 AssemblerDialect
= Subtarget
->getAsmFlavor();
217 bool X86TargetAsmInfo::LowerToBSwap(CallInst
*CI
) const {
218 // FIXME: this should verify that we are targetting a 486 or better. If not,
219 // we will turn this bswap into something that will be lowered to logical ops
220 // instead of emitting the bswap asm. For now, we don't support 486 or lower
221 // so don't worry about this.
223 // Verify this is a simple bswap.
224 if (CI
->getNumOperands() != 2 ||
225 CI
->getType() != CI
->getOperand(1)->getType() ||
226 !CI
->getType()->isInteger())
229 const IntegerType
*Ty
= dyn_cast
<IntegerType
>(CI
->getType());
230 if (!Ty
|| Ty
->getBitWidth() % 16 != 0)
233 // Okay, we can do this xform, do so now.
234 const Type
*Tys
[] = { Ty
};
235 Module
*M
= CI
->getParent()->getParent()->getParent();
236 Constant
*Int
= Intrinsic::getDeclaration(M
, Intrinsic::bswap
, Tys
, 1);
238 Value
*Op
= CI
->getOperand(1);
239 Op
= new CallInst(Int
, Op
, CI
->getName(), CI
);
241 CI
->replaceAllUsesWith(Op
);
242 CI
->eraseFromParent();
247 bool X86TargetAsmInfo::ExpandInlineAsm(CallInst
*CI
) const {
248 InlineAsm
*IA
= cast
<InlineAsm
>(CI
->getCalledValue());
249 std::vector
<InlineAsm::ConstraintInfo
> Constraints
= IA
->ParseConstraints();
251 std::string AsmStr
= IA
->getAsmString();
253 // TODO: should remove alternatives from the asmstring: "foo {a|b}" -> "foo a"
254 std::vector
<std::string
> AsmPieces
;
255 SplitString(AsmStr
, AsmPieces
, "\n"); // ; as separator?
257 switch (AsmPieces
.size()) {
258 default: return false;
260 AsmStr
= AsmPieces
[0];
262 SplitString(AsmStr
, AsmPieces
, " \t"); // Split with whitespace.
265 if (AsmPieces
.size() == 2 &&
266 AsmPieces
[0] == "bswap" && AsmPieces
[1] == "$0") {
267 // No need to check constraints, nothing other than the equivalent of
268 // "=r,0" would be valid here.
269 return LowerToBSwap(CI
);
273 if (CI
->getType() == Type::Int64Ty
&& Constraints
.size() >= 2 &&
274 Constraints
[0].Codes
.size() == 1 && Constraints
[0].Codes
[0] == "A" &&
275 Constraints
[1].Codes
.size() == 1 && Constraints
[1].Codes
[0] == "0") {
276 // bswap %eax / bswap %edx / xchgl %eax, %edx -> llvm.bswap.i64
277 std::vector
<std::string
> Words
;
278 SplitString(AsmPieces
[0], Words
, " \t");
279 if (Words
.size() == 2 && Words
[0] == "bswap" && Words
[1] == "%eax") {
281 SplitString(AsmPieces
[1], Words
, " \t");
282 if (Words
.size() == 2 && Words
[0] == "bswap" && Words
[1] == "%edx") {
284 SplitString(AsmPieces
[2], Words
, " \t,");
285 if (Words
.size() == 3 && Words
[0] == "xchgl" && Words
[1] == "%eax" &&
286 Words
[2] == "%edx") {
287 return LowerToBSwap(CI
);