1 //===-- X86MCTargetDesc.cpp - X86 Target Descriptions ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides X86 specific target descriptions.
12 //===----------------------------------------------------------------------===//
14 #include "X86MCTargetDesc.h"
15 #include "InstPrinter/X86ATTInstPrinter.h"
16 #include "InstPrinter/X86IntelInstPrinter.h"
17 #include "X86MCAsmInfo.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/MC/MCCodeGenInfo.h"
20 #include "llvm/MC/MCInstrAnalysis.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MachineLocation.h"
26 #include "llvm/Support/ErrorHandling.h"
27 #include "llvm/Support/Host.h"
28 #include "llvm/Support/TargetRegistry.h"
36 #define GET_REGINFO_MC_DESC
37 #include "X86GenRegisterInfo.inc"
39 #define GET_INSTRINFO_MC_DESC
40 #include "X86GenInstrInfo.inc"
42 #define GET_SUBTARGETINFO_MC_DESC
43 #include "X86GenSubtargetInfo.inc"
45 std::string
X86_MC::ParseX86Triple(StringRef TT
) {
48 if (TheTriple
.getArch() == Triple::x86_64
)
49 FS
= "+64bit-mode,-32bit-mode,-16bit-mode";
50 else if (TheTriple
.getEnvironment() != Triple::CODE16
)
51 FS
= "-64bit-mode,+32bit-mode,-16bit-mode";
53 FS
= "-64bit-mode,-32bit-mode,+16bit-mode";
58 /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
59 /// specified arguments. If we can't run cpuid on the host, return true.
60 bool X86_MC::GetCpuIDAndInfo(unsigned value
, unsigned *rEAX
,
61 unsigned *rEBX
, unsigned *rECX
, unsigned *rEDX
) {
62 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
64 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
65 asm ("movq\t%%rbx, %%rsi\n\t"
67 "xchgq\t%%rbx, %%rsi\n\t"
74 #elif defined(_MSC_VER)
76 __cpuid(registers
, value
);
85 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
87 asm ("movl\t%%ebx, %%esi\n\t"
89 "xchgl\t%%ebx, %%esi\n\t"
96 #elif defined(_MSC_VER)
101 mov dword ptr
[esi
],eax
103 mov dword ptr
[esi
],ebx
105 mov dword ptr
[esi
],ecx
107 mov dword ptr
[esi
],edx
118 /// GetCpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the
119 /// 4 values in the specified arguments. If we can't run cpuid on the host,
121 bool X86_MC::GetCpuIDAndInfoEx(unsigned value
, unsigned subleaf
, unsigned *rEAX
,
122 unsigned *rEBX
, unsigned *rECX
, unsigned *rEDX
) {
123 #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
124 #if defined(__GNUC__)
125 // gcc desn't know cpuid would clobber ebx/rbx. Preseve it manually.
126 asm ("movq\t%%rbx, %%rsi\n\t"
128 "xchgq\t%%rbx, %%rsi\n\t"
136 #elif defined(_MSC_VER)
137 // __cpuidex was added in MSVC++ 9.0 SP1
138 #if (_MSC_VER > 1500) || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)
140 __cpuidex(registers
, value
, subleaf
);
141 *rEAX
= registers
[0];
142 *rEBX
= registers
[1];
143 *rECX
= registers
[2];
144 *rEDX
= registers
[3];
152 #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
153 #if defined(__GNUC__)
154 asm ("movl\t%%ebx, %%esi\n\t"
156 "xchgl\t%%ebx, %%esi\n\t"
164 #elif defined(_MSC_VER)
170 mov dword ptr
[esi
],eax
172 mov dword ptr
[esi
],ebx
174 mov dword ptr
[esi
],ecx
176 mov dword ptr
[esi
],edx
187 void X86_MC::DetectFamilyModel(unsigned EAX
, unsigned &Family
,
189 Family
= (EAX
>> 8) & 0xf; // Bits 8 - 11
190 Model
= (EAX
>> 4) & 0xf; // Bits 4 - 7
191 if (Family
== 6 || Family
== 0xf) {
193 // Examine extended family ID if family ID is F.
194 Family
+= (EAX
>> 20) & 0xff; // Bits 20 - 27
195 // Examine extended model ID if family ID is 6 or F.
196 Model
+= ((EAX
>> 16) & 0xf) << 4; // Bits 16 - 19
200 unsigned X86_MC::getDwarfRegFlavour(Triple TT
, bool isEH
) {
201 if (TT
.getArch() == Triple::x86_64
)
202 return DWARFFlavour::X86_64
;
205 return isEH
? DWARFFlavour::X86_32_DarwinEH
: DWARFFlavour::X86_32_Generic
;
206 if (TT
.isOSCygMing())
207 // Unsupported by now, just quick fallback
208 return DWARFFlavour::X86_32_Generic
;
209 return DWARFFlavour::X86_32_Generic
;
212 void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo
*MRI
) {
213 // FIXME: TableGen these.
214 for (unsigned Reg
= X86::NoRegister
+1; Reg
< X86::NUM_TARGET_REGS
; ++Reg
) {
215 unsigned SEH
= MRI
->getEncodingValue(Reg
);
216 MRI
->mapLLVMRegToSEHReg(Reg
, SEH
);
220 MCSubtargetInfo
*X86_MC::createX86MCSubtargetInfo(StringRef TT
, StringRef CPU
,
222 std::string ArchFS
= X86_MC::ParseX86Triple(TT
);
225 ArchFS
= ArchFS
+ "," + FS
.str();
230 std::string CPUName
= CPU
;
234 MCSubtargetInfo
*X
= new MCSubtargetInfo();
235 InitX86MCSubtargetInfo(X
, TT
, CPUName
, ArchFS
);
239 static MCInstrInfo
*createX86MCInstrInfo() {
240 MCInstrInfo
*X
= new MCInstrInfo();
241 InitX86MCInstrInfo(X
);
245 static MCRegisterInfo
*createX86MCRegisterInfo(StringRef TT
) {
246 Triple
TheTriple(TT
);
247 unsigned RA
= (TheTriple
.getArch() == Triple::x86_64
)
248 ? X86::RIP
// Should have dwarf #16.
249 : X86::EIP
; // Should have dwarf #8.
251 MCRegisterInfo
*X
= new MCRegisterInfo();
252 InitX86MCRegisterInfo(X
, RA
,
253 X86_MC::getDwarfRegFlavour(TheTriple
, false),
254 X86_MC::getDwarfRegFlavour(TheTriple
, true),
256 X86_MC::InitLLVM2SEHRegisterMapping(X
);
260 static MCAsmInfo
*createX86MCAsmInfo(const MCRegisterInfo
&MRI
, StringRef TT
) {
261 Triple
TheTriple(TT
);
262 bool is64Bit
= TheTriple
.getArch() == Triple::x86_64
;
265 if (TheTriple
.isOSBinFormatMachO()) {
267 MAI
= new X86_64MCAsmInfoDarwin(TheTriple
);
269 MAI
= new X86MCAsmInfoDarwin(TheTriple
);
270 } else if (TheTriple
.isOSBinFormatELF()) {
271 // Force the use of an ELF container.
272 MAI
= new X86ELFMCAsmInfo(TheTriple
);
273 } else if (TheTriple
.isWindowsMSVCEnvironment()) {
274 MAI
= new X86MCAsmInfoMicrosoft(TheTriple
);
275 } else if (TheTriple
.isOSCygMing() ||
276 TheTriple
.isWindowsItaniumEnvironment()) {
277 MAI
= new X86MCAsmInfoGNUCOFF(TheTriple
);
279 // The default is ELF.
280 MAI
= new X86ELFMCAsmInfo(TheTriple
);
283 // Initialize initial frame state.
284 // Calculate amount of bytes used for return address storing
285 int stackGrowth
= is64Bit
? -8 : -4;
287 // Initial state of the frame pointer is esp+stackGrowth.
288 unsigned StackPtr
= is64Bit
? X86::RSP
: X86::ESP
;
289 MCCFIInstruction Inst
= MCCFIInstruction::createDefCfa(
290 nullptr, MRI
.getDwarfRegNum(StackPtr
, true), -stackGrowth
);
291 MAI
->addInitialFrameState(Inst
);
293 // Add return address to move list
294 unsigned InstPtr
= is64Bit
? X86::RIP
: X86::EIP
;
295 MCCFIInstruction Inst2
= MCCFIInstruction::createOffset(
296 nullptr, MRI
.getDwarfRegNum(InstPtr
, true), stackGrowth
);
297 MAI
->addInitialFrameState(Inst2
);
302 static MCCodeGenInfo
*createX86MCCodeGenInfo(StringRef TT
, Reloc::Model RM
,
304 CodeGenOpt::Level OL
) {
305 MCCodeGenInfo
*X
= new MCCodeGenInfo();
308 bool is64Bit
= T
.getArch() == Triple::x86_64
;
310 if (RM
== Reloc::Default
) {
311 // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
312 // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
313 // use static relocation model by default.
314 if (T
.isOSDarwin()) {
318 RM
= Reloc::DynamicNoPIC
;
319 } else if (T
.isOSWindows() && is64Bit
)
325 // ELF and X86-64 don't have a distinct DynamicNoPIC model. DynamicNoPIC
326 // is defined as a model for code which may be used in static or dynamic
327 // executables but not necessarily a shared library. On X86-32 we just
328 // compile in -static mode, in x86-64 we use PIC.
329 if (RM
== Reloc::DynamicNoPIC
) {
332 else if (!T
.isOSDarwin())
336 // If we are on Darwin, disallow static relocation model in X86-64 mode, since
337 // the Mach-O file format doesn't support it.
338 if (RM
== Reloc::Static
&& T
.isOSDarwin() && is64Bit
)
341 // For static codegen, if we're not already set, use Small codegen.
342 if (CM
== CodeModel::Default
)
343 CM
= CodeModel::Small
;
344 else if (CM
== CodeModel::JITDefault
)
345 // 64-bit JIT places everything in the same buffer except external funcs.
346 CM
= is64Bit
? CodeModel::Large
: CodeModel::Small
;
348 X
->InitMCCodeGenInfo(RM
, CM
, OL
);
352 static MCStreamer
*createMCStreamer(const Target
&T
, StringRef TT
,
353 MCContext
&Ctx
, MCAsmBackend
&MAB
,
354 raw_ostream
&_OS
, MCCodeEmitter
*_Emitter
,
355 const MCSubtargetInfo
&STI
, bool RelaxAll
) {
356 Triple
TheTriple(TT
);
358 switch (TheTriple
.getObjectFormat()) {
359 default: llvm_unreachable("unsupported object format");
361 return createMachOStreamer(Ctx
, MAB
, _OS
, _Emitter
, RelaxAll
);
363 assert(TheTriple
.isOSWindows() && "only Windows COFF is supported");
364 return createX86WinCOFFStreamer(Ctx
, MAB
, _Emitter
, _OS
, RelaxAll
);
366 return createELFStreamer(Ctx
, MAB
, _OS
, _Emitter
, RelaxAll
);
370 static MCInstPrinter
*createX86MCInstPrinter(const Target
&T
,
371 unsigned SyntaxVariant
,
372 const MCAsmInfo
&MAI
,
373 const MCInstrInfo
&MII
,
374 const MCRegisterInfo
&MRI
,
375 const MCSubtargetInfo
&STI
) {
376 if (SyntaxVariant
== 0)
377 return new X86ATTInstPrinter(MAI
, MII
, MRI
, STI
);
378 if (SyntaxVariant
== 1)
379 return new X86IntelInstPrinter(MAI
, MII
, MRI
);
383 static MCRelocationInfo
*createX86MCRelocationInfo(StringRef TT
,
385 Triple
TheTriple(TT
);
386 if (TheTriple
.isOSBinFormatMachO() && TheTriple
.getArch() == Triple::x86_64
)
387 return createX86_64MachORelocationInfo(Ctx
);
388 else if (TheTriple
.isOSBinFormatELF())
389 return createX86_64ELFRelocationInfo(Ctx
);
390 // Default to the stock relocation info.
391 return llvm::createMCRelocationInfo(TT
, Ctx
);
394 static MCInstrAnalysis
*createX86MCInstrAnalysis(const MCInstrInfo
*Info
) {
395 return new MCInstrAnalysis(Info
);
398 // Force static initialization.
399 extern "C" void LLVMInitializeX86TargetMC() {
400 // Register the MC asm info.
401 RegisterMCAsmInfoFn
A(TheX86_32Target
, createX86MCAsmInfo
);
402 RegisterMCAsmInfoFn
B(TheX86_64Target
, createX86MCAsmInfo
);
404 // Register the MC codegen info.
405 RegisterMCCodeGenInfoFn
C(TheX86_32Target
, createX86MCCodeGenInfo
);
406 RegisterMCCodeGenInfoFn
D(TheX86_64Target
, createX86MCCodeGenInfo
);
408 // Register the MC instruction info.
409 TargetRegistry::RegisterMCInstrInfo(TheX86_32Target
, createX86MCInstrInfo
);
410 TargetRegistry::RegisterMCInstrInfo(TheX86_64Target
, createX86MCInstrInfo
);
412 // Register the MC register info.
413 TargetRegistry::RegisterMCRegInfo(TheX86_32Target
, createX86MCRegisterInfo
);
414 TargetRegistry::RegisterMCRegInfo(TheX86_64Target
, createX86MCRegisterInfo
);
416 // Register the MC subtarget info.
417 TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target
,
418 X86_MC::createX86MCSubtargetInfo
);
419 TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target
,
420 X86_MC::createX86MCSubtargetInfo
);
422 // Register the MC instruction analyzer.
423 TargetRegistry::RegisterMCInstrAnalysis(TheX86_32Target
,
424 createX86MCInstrAnalysis
);
425 TargetRegistry::RegisterMCInstrAnalysis(TheX86_64Target
,
426 createX86MCInstrAnalysis
);
428 // Register the code emitter.
429 TargetRegistry::RegisterMCCodeEmitter(TheX86_32Target
,
430 createX86MCCodeEmitter
);
431 TargetRegistry::RegisterMCCodeEmitter(TheX86_64Target
,
432 createX86MCCodeEmitter
);
434 // Register the asm backend.
435 TargetRegistry::RegisterMCAsmBackend(TheX86_32Target
,
436 createX86_32AsmBackend
);
437 TargetRegistry::RegisterMCAsmBackend(TheX86_64Target
,
438 createX86_64AsmBackend
);
440 // Register the object streamer.
441 TargetRegistry::RegisterMCObjectStreamer(TheX86_32Target
,
443 TargetRegistry::RegisterMCObjectStreamer(TheX86_64Target
,
446 // Register the MCInstPrinter.
447 TargetRegistry::RegisterMCInstPrinter(TheX86_32Target
,
448 createX86MCInstPrinter
);
449 TargetRegistry::RegisterMCInstPrinter(TheX86_64Target
,
450 createX86MCInstPrinter
);
452 // Register the MC relocation info.
453 TargetRegistry::RegisterMCRelocationInfo(TheX86_32Target
,
454 createX86MCRelocationInfo
);
455 TargetRegistry::RegisterMCRelocationInfo(TheX86_64Target
,
456 createX86MCRelocationInfo
);