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 "X86MCOptions.h"
15#include "llvm/ADT/Enum.h"
16#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCStreamer.h"
18#include "llvm/TargetParser/Triple.h"
19using namespace llvm;
20
21constexpr EnumStringDef<MCAsmInfo::AtSpecifierKind> AtSpecifierDefs[] = {
22 {.Names: {"ABS8"}, .Value: X86::S_ABS8},
23 {.Names: {"DTPOFF"}, .Value: X86::S_DTPOFF},
24 {.Names: {"DTPREL"}, .Value: X86::S_DTPREL},
25 {.Names: {"GOT"}, .Value: X86::S_GOT},
26 {.Names: {"GOTENT"}, .Value: X86::S_GOTENT},
27 {.Names: {"GOTNTPOFF"}, .Value: X86::S_GOTNTPOFF},
28 {.Names: {"GOTOFF"}, .Value: X86::S_GOTOFF},
29 {.Names: {"GOTPCREL"}, .Value: X86::S_GOTPCREL},
30 {.Names: {"GOTPCREL_NORELAX"}, .Value: X86::S_GOTPCREL_NORELAX},
31 {.Names: {"GOTREL"}, .Value: X86::S_GOTREL},
32 {.Names: {"GOTTPOFF"}, .Value: X86::S_GOTTPOFF},
33 {.Names: {"INDNTPOFF"}, .Value: X86::S_INDNTPOFF},
34 {.Names: {"IMGREL"}, .Value: MCSymbolRefExpr::VK_COFF_IMGREL32},
35 {.Names: {"NTPOFF"}, .Value: X86::S_NTPOFF},
36 {.Names: {"PCREL"}, .Value: X86::S_PCREL},
37 {.Names: {"PLT"}, .Value: X86::S_PLT},
38 {.Names: {"PLTOFF"}, .Value: X86::S_PLTOFF},
39 {.Names: {"SECREL32"}, .Value: X86::S_COFF_SECREL},
40 {.Names: {"SIZE"}, .Value: X86::S_SIZE},
41 {.Names: {"tlscall"}, .Value: X86::S_TLSCALL},
42 {.Names: {"tlsdesc"}, .Value: X86::S_TLSDESC},
43 {.Names: {"TLSGD"}, .Value: X86::S_TLSGD},
44 {.Names: {"TLSLD"}, .Value: X86::S_TLSLD},
45 {.Names: {"TLSLDM"}, .Value: X86::S_TLSLDM},
46 {.Names: {"TLVP"}, .Value: X86::S_TLVP},
47 {.Names: {"TLVPPAGE"}, .Value: X86::S_TLVPPAGE},
48 {.Names: {"TLVPPAGEOFF"}, .Value: X86::S_TLVPPAGEOFF},
49 {.Names: {"TPOFF"}, .Value: X86::S_TPOFF},
50};
51constexpr auto atSpecifiers = BUILD_ENUM_STRINGS(AtSpecifierDefs);
52
53void X86MCAsmInfoDarwin::anchor() { }
54
55X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &T,
56 const MCTargetOptions &Options)
57 : MCAsmInfoDarwin(Options) {
58 bool is64Bit = T.isX86_64();
59 if (is64Bit)
60 CodePointerSize = CalleeSaveStackSlotSize = 8;
61
62 AssemblerDialect = X86MCOptions::Global.asm_syntax;
63
64 if (!is64Bit)
65 Data64bitsDirective = nullptr; // we can't emit a 64-bit unit
66
67 // Use ## as a comment string so that .s files generated by llvm can go
68 // through the GCC preprocessor without causing an error. This is needed
69 // because "clang foo.s" runs the C preprocessor, which is usually reserved
70 // for .S files on other systems. Perhaps this is because the file system
71 // wasn't always case preserving or something.
72 CommentString = "##";
73
74 SupportsDebugInformation = true;
75 UseDataRegionDirectives = X86MCOptions::Global.mark_data_regions;
76
77 // Exceptions handling
78 ExceptionsType = ExceptionHandling::DwarfCFI;
79
80 // old assembler lacks some directives
81 // FIXME: this should really be a check on the assembler characteristics
82 // rather than OS version
83 if (T.isMacOSX() && T.isMacOSXVersionLT(Major: 10, Minor: 6))
84 HasWeakDefCanBeHiddenDirective = false;
85
86 // Assume ld64 is new enough that the abs-ified FDE relocs may be used
87 // (actually, must, since otherwise the non-extern relocations we produce
88 // overwhelm ld64's tiny little mind and it fails).
89 DwarfFDESymbolsUseAbsDiff = true;
90
91 initializeAtSpecifiers(atSpecifiers);
92}
93
94X86_64MCAsmInfoDarwin::X86_64MCAsmInfoDarwin(const Triple &Triple,
95 const MCTargetOptions &Options)
96 : X86MCAsmInfoDarwin(Triple, Options) {}
97
98void X86ELFMCAsmInfo::anchor() { }
99
100X86ELFMCAsmInfo::X86ELFMCAsmInfo(const Triple &T,
101 const MCTargetOptions &Options)
102 : MCAsmInfoELF(Options) {
103 bool is64Bit = T.isX86_64();
104 bool isX32 = T.isX32();
105
106 // For ELF, x86-64 pointer size depends on the ABI.
107 // For x86-64 without the x32 ABI, pointer size is 8. For x86 and for x86-64
108 // with the x32 ABI, pointer size remains the default 4.
109 CodePointerSize = (is64Bit && !isX32) ? 8 : 4;
110
111 // OTOH, stack slot size is always 8 for x86-64, even with the x32 ABI.
112 CalleeSaveStackSlotSize = is64Bit ? 8 : 4;
113
114 AssemblerDialect = X86MCOptions::Global.asm_syntax;
115
116 // Debug Information
117 SupportsDebugInformation = true;
118
119 // Exceptions handling
120 ExceptionsType = ExceptionHandling::DwarfCFI;
121
122 initializeAtSpecifiers(atSpecifiers);
123}
124
125const MCExpr *
126X86_64MCAsmInfoDarwin::getExprForPersonalitySymbol(const MCSymbol *Sym,
127 unsigned Encoding,
128 MCStreamer &Streamer) const {
129 MCContext &Context = Streamer.getContext();
130 const MCExpr *Res = MCSymbolRefExpr::create(Symbol: Sym, specifier: X86::S_GOTPCREL, Ctx&: Context);
131 const MCExpr *Four = MCConstantExpr::create(Value: 4, Ctx&: Context);
132 return MCBinaryExpr::createAdd(LHS: Res, RHS: Four, Ctx&: Context);
133}
134
135void X86MCAsmInfoMicrosoft::anchor() { }
136
137X86MCAsmInfoMicrosoft::X86MCAsmInfoMicrosoft(const Triple &Triple,
138 const MCTargetOptions &Options)
139 : MCAsmInfoMicrosoft(Options) {
140 if (Triple.isX86_64()) {
141 InternalSymbolPrefix = ".L";
142 CodePointerSize = 8;
143 WinEHEncodingType = WinEH::EncodingType::Itanium;
144 } else {
145 // 32-bit X86 doesn't use CFI, so this isn't a real encoding type. It's just
146 // a place holder that the Windows EHStreamer looks for to suppress CFI
147 // output. In particular, usesWindowsCFI() returns false.
148 WinEHEncodingType = WinEH::EncodingType::X86;
149 }
150
151 ExceptionsType = ExceptionHandling::WinEH;
152
153 AssemblerDialect = X86MCOptions::Global.asm_syntax;
154
155 AllowAtInName = true;
156
157 initializeAtSpecifiers(atSpecifiers);
158}
159
160void X86MCAsmInfoMicrosoftMASM::anchor() { }
161
162X86MCAsmInfoMicrosoftMASM::X86MCAsmInfoMicrosoftMASM(
163 const Triple &Triple, const MCTargetOptions &Options)
164 : X86MCAsmInfoMicrosoft(Triple, Options) {
165 DollarIsPC = true;
166 SeparatorString = "\n";
167 CommentString = ";";
168 AllowAdditionalComments = false;
169 AllowQuestionAtStartOfIdentifier = true;
170 AllowDollarAtStartOfIdentifier = true;
171 AllowAtAtStartOfIdentifier = true;
172}
173
174void X86MCAsmInfoGNUCOFF::anchor() { }
175
176X86MCAsmInfoGNUCOFF::X86MCAsmInfoGNUCOFF(const Triple &Triple,
177 const MCTargetOptions &Options)
178 : MCAsmInfoGNUCOFF(Options) {
179 assert(Triple.isOSWindowsOrUEFI() &&
180 "Windows and UEFI are the only supported COFF targets");
181 if (Triple.isX86_64()) {
182 InternalSymbolPrefix = ".L";
183 CodePointerSize = 8;
184 WinEHEncodingType = WinEH::EncodingType::Itanium;
185 ExceptionsType = ExceptionHandling::WinEH;
186 } else {
187 ExceptionsType = ExceptionHandling::DwarfCFI;
188 }
189
190 AssemblerDialect = X86MCOptions::Global.asm_syntax;
191
192 AllowAtInName = true;
193
194 initializeAtSpecifiers(atSpecifiers);
195}
196