1 //===-- X86MCAsmInfo.cpp - X86 asm properties -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the declarations of the X86MCAsmInfo properties.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "X86MCAsmInfo.h"
14 #include "MCTargetDesc/X86MCExpr.h"
15 #include "llvm/MC/MCExpr.h"
16 #include "llvm/MC/MCStreamer.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/TargetParser/Triple.h"
19 using namespace llvm;
20
21 enum AsmWriterFlavorTy {
22 // Note: This numbering has to match the GCC assembler dialects for inline
23 // asm alternatives to work right.
24 ATT = 0, Intel = 1
25 };
26
27 static cl::opt<AsmWriterFlavorTy> X86AsmSyntax(
28 "x86-asm-syntax", cl::init(ATT), cl::Hidden,
29 cl::desc("Select the assembly style for input"),
30 cl::values(clEnumValN(ATT, "att", "Emit AT&T-style assembly"),
31 clEnumValN(Intel, "intel", "Emit Intel-style assembly")));
32
33 static cl::opt<bool>
34 MarkedJTDataRegions("mark-data-regions", cl::init(true),
35 cl::desc("Mark code section jump table data regions."),
36 cl::Hidden);
37
38 const MCAsmInfo::AtSpecifier atSpecifiers[] = {
39 {X86::S_ABS8, "ABS8"},
40 {X86::S_DTPOFF, "DTPOFF"},
41 {X86::S_DTPREL, "DTPREL"},
42 {X86::S_GOT, "GOT"},
43 {X86::S_GOTENT, "GOTENT"},
44 {X86::S_GOTNTPOFF, "GOTNTPOFF"},
45 {X86::S_GOTOFF, "GOTOFF"},
46 {X86::S_GOTPCREL, "GOTPCREL"},
47 {X86::S_GOTPCREL_NORELAX, "GOTPCREL_NORELAX"},
48 {X86::S_GOTREL, "GOTREL"},
49 {X86::S_GOTTPOFF, "GOTTPOFF"},
50 {X86::S_INDNTPOFF, "INDNTPOFF"},
51 {MCSymbolRefExpr::VK_COFF_IMGREL32, "IMGREL"},
52 {X86::S_NTPOFF, "NTPOFF"},
53 {X86::S_PCREL, "PCREL"},
54 {X86::S_PLT, "PLT"},
55 {X86::S_PLTOFF, "PLTOFF"},
56 {X86::S_COFF_SECREL, "SECREL32"},
57 {X86::S_SIZE, "SIZE"},
58 {X86::S_TLSCALL, "tlscall"},
59 {X86::S_TLSDESC, "tlsdesc"},
60 {X86::S_TLSGD, "TLSGD"},
61 {X86::S_TLSLD, "TLSLD"},
62 {X86::S_TLSLDM, "TLSLDM"},
63 {X86::S_TLVP, "TLVP"},
64 {X86::S_TLVPPAGE, "TLVPPAGE"},
65 {X86::S_TLVPPAGEOFF, "TLVPPAGEOFF"},
66 {X86::S_TPOFF, "TPOFF"},
67 };
68
anchor()69 void X86MCAsmInfoDarwin::anchor() { }
70
X86MCAsmInfoDarwin(const Triple & T)71 X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T) {
72 bool is64Bit = T.getArch() == Triple::x86_64;
73 if (is64Bit)
74 CodePointerSize = CalleeSaveStackSlotSize = 8;
75
76 AssemblerDialect = X86AsmSyntax;
77
78 if (!is64Bit)
79 Data64bitsDirective = nullptr; // we can't emit a 64-bit unit
80
81 // Use ## as a comment string so that .s files generated by llvm can go
82 // through the GCC preprocessor without causing an error. This is needed
83 // because "clang foo.s" runs the C preprocessor, which is usually reserved
84 // for .S files on other systems. Perhaps this is because the file system
85 // wasn't always case preserving or something.
86 CommentString = "##";
87
88 AllowDollarAtStartOfIdentifier = false;
89
90 SupportsDebugInformation = true;
91 UseDataRegionDirectives = MarkedJTDataRegions;
92
93 // Exceptions handling
94 ExceptionsType = ExceptionHandling::DwarfCFI;
95
96 // old assembler lacks some directives
97 // FIXME: this should really be a check on the assembler characteristics
98 // rather than OS version
99 if (T.isMacOSX() && T.isMacOSXVersionLT(10, 6))
100 HasWeakDefCanBeHiddenDirective = false;
101
102 // Assume ld64 is new enough that the abs-ified FDE relocs may be used
103 // (actually, must, since otherwise the non-extern relocations we produce
104 // overwhelm ld64's tiny little mind and it fails).
105 DwarfFDESymbolsUseAbsDiff = true;
106
107 initializeAtSpecifiers(atSpecifiers);
108 }
109
X86_64MCAsmInfoDarwin(const Triple & Triple)110 X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple)
111 : X86MCAsmInfoDarwin(Triple) {
112 }
113
anchor()114 void X86ELFMCAsmInfo::anchor() { }
115
X86ELFMCAsmInfo(const Triple & T)116 X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T) {
117 bool is64Bit = T.getArch() == Triple::x86_64;
118 bool isX32 = T.isX32();
119
120 // For ELF, x86-64 pointer size depends on the ABI.
121 // For x86-64 without the x32 ABI, pointer size is 8. For x86 and for x86-64
122 // with the x32 ABI, pointer size remains the default 4.
123 CodePointerSize = (is64Bit && !isX32) ? 8 : 4;
124
125 // OTOH, stack slot size is always 8 for x86-64, even with the x32 ABI.
126 CalleeSaveStackSlotSize = is64Bit ? 8 : 4;
127
128 AssemblerDialect = X86AsmSyntax;
129 AllowDollarAtStartOfIdentifier = false;
130
131 // Debug Information
132 SupportsDebugInformation = true;
133
134 // Exceptions handling
135 ExceptionsType = ExceptionHandling::DwarfCFI;
136
137 initializeAtSpecifiers(atSpecifiers);
138 }
139
140 const MCExpr *
getExprForPersonalitySymbol(const MCSymbol * Sym,unsigned Encoding,MCStreamer & Streamer) const141 X86_64MCAsmInfoDarwin::getExprForPersonalitySymbol(const MCSymbol *Sym,
142 unsigned Encoding,
143 MCStreamer &Streamer) const {
144 MCContext &Context = Streamer.getContext();
145 const MCExpr *Res = MCSymbolRefExpr::create(Sym, X86::S_GOTPCREL, Context);
146 const MCExpr *Four = MCConstantExpr::create(4, Context);
147 return MCBinaryExpr::createAdd(Res, Four, Context);
148 }
149
anchor()150 void X86MCAsmInfoMicrosoft::anchor() { }
151
X86MCAsmInfoMicrosoft(const Triple & Triple)152 X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple) {
153 if (Triple.getArch() == Triple::x86_64) {
154 PrivateGlobalPrefix = ".L";
155 PrivateLabelPrefix = ".L";
156 CodePointerSize = 8;
157 WinEHEncodingType = WinEH::EncodingType::Itanium;
158 } else {
159 // 32-bit X86 doesn't use CFI, so this isn't a real encoding type. It's just
160 // a place holder that the Windows EHStreamer looks for to suppress CFI
161 // output. In particular, usesWindowsCFI() returns false.
162 WinEHEncodingType = WinEH::EncodingType::X86;
163 }
164
165 ExceptionsType = ExceptionHandling::WinEH;
166
167 AssemblerDialect = X86AsmSyntax;
168 AllowDollarAtStartOfIdentifier = false;
169
170 AllowAtInName = true;
171
172 initializeAtSpecifiers(atSpecifiers);
173 }
174
anchor()175 void X86MCAsmInfoMicrosoftMASM::anchor() { }
176
X86MCAsmInfoMicrosoftMASM(const Triple & Triple)177 X86MCAsmInfoMicrosoftMASM::X86MCAsmInfoMicrosoftMASM(const Triple &Triple)
178 : X86MCAsmInfoMicrosoft(Triple) {
179 DollarIsPC = true;
180 SeparatorString = "\n";
181 CommentString = ";";
182 AllowAdditionalComments = false;
183 AllowQuestionAtStartOfIdentifier = true;
184 AllowDollarAtStartOfIdentifier = true;
185 AllowAtAtStartOfIdentifier = true;
186 }
187
anchor()188 void X86MCAsmInfoGNUCOFF::anchor() { }
189
X86MCAsmInfoGNUCOFF(const Triple & Triple)190 X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF(const Triple &Triple) {
191 assert((Triple.isOSWindows() || Triple.isUEFI()) &&
192 "Windows and UEFI are the only supported COFF targets");
193 if (Triple.getArch() == Triple::x86_64) {
194 PrivateGlobalPrefix = ".L";
195 PrivateLabelPrefix = ".L";
196 CodePointerSize = 8;
197 WinEHEncodingType = WinEH::EncodingType::Itanium;
198 ExceptionsType = ExceptionHandling::WinEH;
199 } else {
200 ExceptionsType = ExceptionHandling::DwarfCFI;
201 }
202
203 AssemblerDialect = X86AsmSyntax;
204
205 AllowAtInName = true;
206 AllowDollarAtStartOfIdentifier = false;
207
208 initializeAtSpecifiers(atSpecifiers);
209 }
210