xref: /minix3/external/bsd/llvm/dist/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===-- X86MCTargetDesc.cpp - X86 Target Descriptions ---------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file provides X86 specific target descriptions.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc 
14f4a2713aSLionel Sambuc #include "X86MCTargetDesc.h"
15f4a2713aSLionel Sambuc #include "InstPrinter/X86ATTInstPrinter.h"
16f4a2713aSLionel Sambuc #include "InstPrinter/X86IntelInstPrinter.h"
17f4a2713aSLionel Sambuc #include "X86MCAsmInfo.h"
18f4a2713aSLionel Sambuc #include "llvm/ADT/Triple.h"
19f4a2713aSLionel Sambuc #include "llvm/MC/MCCodeGenInfo.h"
20f4a2713aSLionel Sambuc #include "llvm/MC/MCInstrAnalysis.h"
21f4a2713aSLionel Sambuc #include "llvm/MC/MCInstrInfo.h"
22f4a2713aSLionel Sambuc #include "llvm/MC/MCRegisterInfo.h"
23f4a2713aSLionel Sambuc #include "llvm/MC/MCStreamer.h"
24f4a2713aSLionel Sambuc #include "llvm/MC/MCSubtargetInfo.h"
25f4a2713aSLionel Sambuc #include "llvm/MC/MachineLocation.h"
26f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
27f4a2713aSLionel Sambuc #include "llvm/Support/Host.h"
28f4a2713aSLionel Sambuc #include "llvm/Support/TargetRegistry.h"
29f4a2713aSLionel Sambuc 
30*0a6a1f1dSLionel Sambuc #if _MSC_VER
31*0a6a1f1dSLionel Sambuc #include <intrin.h>
32*0a6a1f1dSLionel Sambuc #endif
33*0a6a1f1dSLionel Sambuc 
34*0a6a1f1dSLionel Sambuc using namespace llvm;
35*0a6a1f1dSLionel Sambuc 
36f4a2713aSLionel Sambuc #define GET_REGINFO_MC_DESC
37f4a2713aSLionel Sambuc #include "X86GenRegisterInfo.inc"
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc #define GET_INSTRINFO_MC_DESC
40f4a2713aSLionel Sambuc #include "X86GenInstrInfo.inc"
41f4a2713aSLionel Sambuc 
42f4a2713aSLionel Sambuc #define GET_SUBTARGETINFO_MC_DESC
43f4a2713aSLionel Sambuc #include "X86GenSubtargetInfo.inc"
44f4a2713aSLionel Sambuc 
ParseX86Triple(StringRef TT)45f4a2713aSLionel Sambuc std::string X86_MC::ParseX86Triple(StringRef TT) {
46f4a2713aSLionel Sambuc   Triple TheTriple(TT);
47f4a2713aSLionel Sambuc   std::string FS;
48f4a2713aSLionel Sambuc   if (TheTriple.getArch() == Triple::x86_64)
49*0a6a1f1dSLionel Sambuc     FS = "+64bit-mode,-32bit-mode,-16bit-mode";
50*0a6a1f1dSLionel Sambuc   else if (TheTriple.getEnvironment() != Triple::CODE16)
51*0a6a1f1dSLionel Sambuc     FS = "-64bit-mode,+32bit-mode,-16bit-mode";
52f4a2713aSLionel Sambuc   else
53*0a6a1f1dSLionel Sambuc     FS = "-64bit-mode,-32bit-mode,+16bit-mode";
54*0a6a1f1dSLionel Sambuc 
55f4a2713aSLionel Sambuc   return FS;
56f4a2713aSLionel Sambuc }
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc /// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
59f4a2713aSLionel Sambuc /// specified arguments.  If we can't run cpuid on the host, return true.
GetCpuIDAndInfo(unsigned value,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)60f4a2713aSLionel Sambuc bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
61f4a2713aSLionel Sambuc                              unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
62f4a2713aSLionel Sambuc #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
63f4a2713aSLionel Sambuc   #if defined(__GNUC__)
64f4a2713aSLionel Sambuc     // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
65f4a2713aSLionel Sambuc     asm ("movq\t%%rbx, %%rsi\n\t"
66f4a2713aSLionel Sambuc          "cpuid\n\t"
67f4a2713aSLionel Sambuc          "xchgq\t%%rbx, %%rsi\n\t"
68f4a2713aSLionel Sambuc          : "=a" (*rEAX),
69f4a2713aSLionel Sambuc            "=S" (*rEBX),
70f4a2713aSLionel Sambuc            "=c" (*rECX),
71f4a2713aSLionel Sambuc            "=d" (*rEDX)
72f4a2713aSLionel Sambuc          :  "a" (value));
73f4a2713aSLionel Sambuc     return false;
74f4a2713aSLionel Sambuc   #elif defined(_MSC_VER)
75f4a2713aSLionel Sambuc     int registers[4];
76f4a2713aSLionel Sambuc     __cpuid(registers, value);
77f4a2713aSLionel Sambuc     *rEAX = registers[0];
78f4a2713aSLionel Sambuc     *rEBX = registers[1];
79f4a2713aSLionel Sambuc     *rECX = registers[2];
80f4a2713aSLionel Sambuc     *rEDX = registers[3];
81f4a2713aSLionel Sambuc     return false;
82f4a2713aSLionel Sambuc   #else
83f4a2713aSLionel Sambuc     return true;
84f4a2713aSLionel Sambuc   #endif
85f4a2713aSLionel Sambuc #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
86f4a2713aSLionel Sambuc   #if defined(__GNUC__)
87f4a2713aSLionel Sambuc     asm ("movl\t%%ebx, %%esi\n\t"
88f4a2713aSLionel Sambuc          "cpuid\n\t"
89f4a2713aSLionel Sambuc          "xchgl\t%%ebx, %%esi\n\t"
90f4a2713aSLionel Sambuc          : "=a" (*rEAX),
91f4a2713aSLionel Sambuc            "=S" (*rEBX),
92f4a2713aSLionel Sambuc            "=c" (*rECX),
93f4a2713aSLionel Sambuc            "=d" (*rEDX)
94f4a2713aSLionel Sambuc          :  "a" (value));
95f4a2713aSLionel Sambuc     return false;
96f4a2713aSLionel Sambuc   #elif defined(_MSC_VER)
97f4a2713aSLionel Sambuc     __asm {
98f4a2713aSLionel Sambuc       mov   eax,value
99f4a2713aSLionel Sambuc       cpuid
100f4a2713aSLionel Sambuc       mov   esi,rEAX
101f4a2713aSLionel Sambuc       mov   dword ptr [esi],eax
102f4a2713aSLionel Sambuc       mov   esi,rEBX
103f4a2713aSLionel Sambuc       mov   dword ptr [esi],ebx
104f4a2713aSLionel Sambuc       mov   esi,rECX
105f4a2713aSLionel Sambuc       mov   dword ptr [esi],ecx
106f4a2713aSLionel Sambuc       mov   esi,rEDX
107f4a2713aSLionel Sambuc       mov   dword ptr [esi],edx
108f4a2713aSLionel Sambuc     }
109f4a2713aSLionel Sambuc     return false;
110f4a2713aSLionel Sambuc   #else
111f4a2713aSLionel Sambuc     return true;
112f4a2713aSLionel Sambuc   #endif
113f4a2713aSLionel Sambuc #else
114f4a2713aSLionel Sambuc   return true;
115f4a2713aSLionel Sambuc #endif
116f4a2713aSLionel Sambuc }
117f4a2713aSLionel Sambuc 
118f4a2713aSLionel Sambuc /// GetCpuIDAndInfoEx - Execute the specified cpuid with subleaf and return the
119f4a2713aSLionel Sambuc /// 4 values in the specified arguments.  If we can't run cpuid on the host,
120f4a2713aSLionel Sambuc /// return true.
GetCpuIDAndInfoEx(unsigned value,unsigned subleaf,unsigned * rEAX,unsigned * rEBX,unsigned * rECX,unsigned * rEDX)121f4a2713aSLionel Sambuc bool X86_MC::GetCpuIDAndInfoEx(unsigned value, unsigned subleaf, unsigned *rEAX,
122f4a2713aSLionel Sambuc                                unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
123f4a2713aSLionel Sambuc #if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
124f4a2713aSLionel Sambuc   #if defined(__GNUC__)
125f4a2713aSLionel Sambuc     // gcc desn't know cpuid would clobber ebx/rbx. Preseve it manually.
126f4a2713aSLionel Sambuc     asm ("movq\t%%rbx, %%rsi\n\t"
127f4a2713aSLionel Sambuc          "cpuid\n\t"
128f4a2713aSLionel Sambuc          "xchgq\t%%rbx, %%rsi\n\t"
129f4a2713aSLionel Sambuc          : "=a" (*rEAX),
130f4a2713aSLionel Sambuc            "=S" (*rEBX),
131f4a2713aSLionel Sambuc            "=c" (*rECX),
132f4a2713aSLionel Sambuc            "=d" (*rEDX)
133f4a2713aSLionel Sambuc          :  "a" (value),
134f4a2713aSLionel Sambuc             "c" (subleaf));
135f4a2713aSLionel Sambuc     return false;
136f4a2713aSLionel Sambuc   #elif defined(_MSC_VER)
137f4a2713aSLionel Sambuc     // __cpuidex was added in MSVC++ 9.0 SP1
138f4a2713aSLionel Sambuc     #if (_MSC_VER > 1500) || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)
139f4a2713aSLionel Sambuc       int registers[4];
140f4a2713aSLionel Sambuc       __cpuidex(registers, value, subleaf);
141f4a2713aSLionel Sambuc       *rEAX = registers[0];
142f4a2713aSLionel Sambuc       *rEBX = registers[1];
143f4a2713aSLionel Sambuc       *rECX = registers[2];
144f4a2713aSLionel Sambuc       *rEDX = registers[3];
145f4a2713aSLionel Sambuc       return false;
146f4a2713aSLionel Sambuc     #else
147f4a2713aSLionel Sambuc       return true;
148f4a2713aSLionel Sambuc     #endif
149f4a2713aSLionel Sambuc   #else
150f4a2713aSLionel Sambuc     return true;
151f4a2713aSLionel Sambuc   #endif
152f4a2713aSLionel Sambuc #elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
153f4a2713aSLionel Sambuc   #if defined(__GNUC__)
154f4a2713aSLionel Sambuc     asm ("movl\t%%ebx, %%esi\n\t"
155f4a2713aSLionel Sambuc          "cpuid\n\t"
156f4a2713aSLionel Sambuc          "xchgl\t%%ebx, %%esi\n\t"
157f4a2713aSLionel Sambuc          : "=a" (*rEAX),
158f4a2713aSLionel Sambuc            "=S" (*rEBX),
159f4a2713aSLionel Sambuc            "=c" (*rECX),
160f4a2713aSLionel Sambuc            "=d" (*rEDX)
161f4a2713aSLionel Sambuc          :  "a" (value),
162f4a2713aSLionel Sambuc             "c" (subleaf));
163f4a2713aSLionel Sambuc     return false;
164f4a2713aSLionel Sambuc   #elif defined(_MSC_VER)
165f4a2713aSLionel Sambuc     __asm {
166f4a2713aSLionel Sambuc       mov   eax,value
167f4a2713aSLionel Sambuc       mov   ecx,subleaf
168f4a2713aSLionel Sambuc       cpuid
169f4a2713aSLionel Sambuc       mov   esi,rEAX
170f4a2713aSLionel Sambuc       mov   dword ptr [esi],eax
171f4a2713aSLionel Sambuc       mov   esi,rEBX
172f4a2713aSLionel Sambuc       mov   dword ptr [esi],ebx
173f4a2713aSLionel Sambuc       mov   esi,rECX
174f4a2713aSLionel Sambuc       mov   dword ptr [esi],ecx
175f4a2713aSLionel Sambuc       mov   esi,rEDX
176f4a2713aSLionel Sambuc       mov   dword ptr [esi],edx
177f4a2713aSLionel Sambuc     }
178f4a2713aSLionel Sambuc     return false;
179f4a2713aSLionel Sambuc   #else
180f4a2713aSLionel Sambuc     return true;
181f4a2713aSLionel Sambuc   #endif
182f4a2713aSLionel Sambuc #else
183f4a2713aSLionel Sambuc   return true;
184f4a2713aSLionel Sambuc #endif
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc 
DetectFamilyModel(unsigned EAX,unsigned & Family,unsigned & Model)187f4a2713aSLionel Sambuc void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
188f4a2713aSLionel Sambuc                                unsigned &Model) {
189f4a2713aSLionel Sambuc   Family = (EAX >> 8) & 0xf; // Bits 8 - 11
190f4a2713aSLionel Sambuc   Model  = (EAX >> 4) & 0xf; // Bits 4 - 7
191f4a2713aSLionel Sambuc   if (Family == 6 || Family == 0xf) {
192f4a2713aSLionel Sambuc     if (Family == 0xf)
193f4a2713aSLionel Sambuc       // Examine extended family ID if family ID is F.
194f4a2713aSLionel Sambuc       Family += (EAX >> 20) & 0xff;    // Bits 20 - 27
195f4a2713aSLionel Sambuc     // Examine extended model ID if family ID is 6 or F.
196f4a2713aSLionel Sambuc     Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
197f4a2713aSLionel Sambuc   }
198f4a2713aSLionel Sambuc }
199f4a2713aSLionel Sambuc 
getDwarfRegFlavour(Triple TT,bool isEH)200*0a6a1f1dSLionel Sambuc unsigned X86_MC::getDwarfRegFlavour(Triple TT, bool isEH) {
201*0a6a1f1dSLionel Sambuc   if (TT.getArch() == Triple::x86_64)
202f4a2713aSLionel Sambuc     return DWARFFlavour::X86_64;
203f4a2713aSLionel Sambuc 
204*0a6a1f1dSLionel Sambuc   if (TT.isOSDarwin())
205f4a2713aSLionel Sambuc     return isEH ? DWARFFlavour::X86_32_DarwinEH : DWARFFlavour::X86_32_Generic;
206*0a6a1f1dSLionel Sambuc   if (TT.isOSCygMing())
207f4a2713aSLionel Sambuc     // Unsupported by now, just quick fallback
208f4a2713aSLionel Sambuc     return DWARFFlavour::X86_32_Generic;
209f4a2713aSLionel Sambuc   return DWARFFlavour::X86_32_Generic;
210f4a2713aSLionel Sambuc }
211f4a2713aSLionel Sambuc 
InitLLVM2SEHRegisterMapping(MCRegisterInfo * MRI)212f4a2713aSLionel Sambuc void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
213f4a2713aSLionel Sambuc   // FIXME: TableGen these.
214f4a2713aSLionel Sambuc   for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
215f4a2713aSLionel Sambuc     unsigned SEH = MRI->getEncodingValue(Reg);
216f4a2713aSLionel Sambuc     MRI->mapLLVMRegToSEHReg(Reg, SEH);
217f4a2713aSLionel Sambuc   }
218f4a2713aSLionel Sambuc }
219f4a2713aSLionel Sambuc 
createX86MCSubtargetInfo(StringRef TT,StringRef CPU,StringRef FS)220f4a2713aSLionel Sambuc MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
221f4a2713aSLionel Sambuc                                                   StringRef FS) {
222f4a2713aSLionel Sambuc   std::string ArchFS = X86_MC::ParseX86Triple(TT);
223f4a2713aSLionel Sambuc   if (!FS.empty()) {
224f4a2713aSLionel Sambuc     if (!ArchFS.empty())
225f4a2713aSLionel Sambuc       ArchFS = ArchFS + "," + FS.str();
226f4a2713aSLionel Sambuc     else
227f4a2713aSLionel Sambuc       ArchFS = FS;
228f4a2713aSLionel Sambuc   }
229f4a2713aSLionel Sambuc 
230f4a2713aSLionel Sambuc   std::string CPUName = CPU;
231*0a6a1f1dSLionel Sambuc   if (CPUName.empty())
232f4a2713aSLionel Sambuc     CPUName = "generic";
233f4a2713aSLionel Sambuc 
234f4a2713aSLionel Sambuc   MCSubtargetInfo *X = new MCSubtargetInfo();
235f4a2713aSLionel Sambuc   InitX86MCSubtargetInfo(X, TT, CPUName, ArchFS);
236f4a2713aSLionel Sambuc   return X;
237f4a2713aSLionel Sambuc }
238f4a2713aSLionel Sambuc 
createX86MCInstrInfo()239f4a2713aSLionel Sambuc static MCInstrInfo *createX86MCInstrInfo() {
240f4a2713aSLionel Sambuc   MCInstrInfo *X = new MCInstrInfo();
241f4a2713aSLionel Sambuc   InitX86MCInstrInfo(X);
242f4a2713aSLionel Sambuc   return X;
243f4a2713aSLionel Sambuc }
244f4a2713aSLionel Sambuc 
createX86MCRegisterInfo(StringRef TT)245f4a2713aSLionel Sambuc static MCRegisterInfo *createX86MCRegisterInfo(StringRef TT) {
246f4a2713aSLionel Sambuc   Triple TheTriple(TT);
247f4a2713aSLionel Sambuc   unsigned RA = (TheTriple.getArch() == Triple::x86_64)
248f4a2713aSLionel Sambuc     ? X86::RIP     // Should have dwarf #16.
249f4a2713aSLionel Sambuc     : X86::EIP;    // Should have dwarf #8.
250f4a2713aSLionel Sambuc 
251f4a2713aSLionel Sambuc   MCRegisterInfo *X = new MCRegisterInfo();
252f4a2713aSLionel Sambuc   InitX86MCRegisterInfo(X, RA,
253*0a6a1f1dSLionel Sambuc                         X86_MC::getDwarfRegFlavour(TheTriple, false),
254*0a6a1f1dSLionel Sambuc                         X86_MC::getDwarfRegFlavour(TheTriple, true),
255f4a2713aSLionel Sambuc                         RA);
256f4a2713aSLionel Sambuc   X86_MC::InitLLVM2SEHRegisterMapping(X);
257f4a2713aSLionel Sambuc   return X;
258f4a2713aSLionel Sambuc }
259f4a2713aSLionel Sambuc 
createX86MCAsmInfo(const MCRegisterInfo & MRI,StringRef TT)260f4a2713aSLionel Sambuc static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
261f4a2713aSLionel Sambuc   Triple TheTriple(TT);
262f4a2713aSLionel Sambuc   bool is64Bit = TheTriple.getArch() == Triple::x86_64;
263f4a2713aSLionel Sambuc 
264f4a2713aSLionel Sambuc   MCAsmInfo *MAI;
265*0a6a1f1dSLionel Sambuc   if (TheTriple.isOSBinFormatMachO()) {
266f4a2713aSLionel Sambuc     if (is64Bit)
267f4a2713aSLionel Sambuc       MAI = new X86_64MCAsmInfoDarwin(TheTriple);
268f4a2713aSLionel Sambuc     else
269f4a2713aSLionel Sambuc       MAI = new X86MCAsmInfoDarwin(TheTriple);
270*0a6a1f1dSLionel Sambuc   } else if (TheTriple.isOSBinFormatELF()) {
271f4a2713aSLionel Sambuc     // Force the use of an ELF container.
272f4a2713aSLionel Sambuc     MAI = new X86ELFMCAsmInfo(TheTriple);
273*0a6a1f1dSLionel Sambuc   } else if (TheTriple.isWindowsMSVCEnvironment()) {
274f4a2713aSLionel Sambuc     MAI = new X86MCAsmInfoMicrosoft(TheTriple);
275*0a6a1f1dSLionel Sambuc   } else if (TheTriple.isOSCygMing() ||
276*0a6a1f1dSLionel Sambuc              TheTriple.isWindowsItaniumEnvironment()) {
277f4a2713aSLionel Sambuc     MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
278f4a2713aSLionel Sambuc   } else {
279f4a2713aSLionel Sambuc     // The default is ELF.
280f4a2713aSLionel Sambuc     MAI = new X86ELFMCAsmInfo(TheTriple);
281f4a2713aSLionel Sambuc   }
282f4a2713aSLionel Sambuc 
283f4a2713aSLionel Sambuc   // Initialize initial frame state.
284f4a2713aSLionel Sambuc   // Calculate amount of bytes used for return address storing
285f4a2713aSLionel Sambuc   int stackGrowth = is64Bit ? -8 : -4;
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc   // Initial state of the frame pointer is esp+stackGrowth.
288f4a2713aSLionel Sambuc   unsigned StackPtr = is64Bit ? X86::RSP : X86::ESP;
289f4a2713aSLionel Sambuc   MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
290*0a6a1f1dSLionel Sambuc       nullptr, MRI.getDwarfRegNum(StackPtr, true), -stackGrowth);
291f4a2713aSLionel Sambuc   MAI->addInitialFrameState(Inst);
292f4a2713aSLionel Sambuc 
293f4a2713aSLionel Sambuc   // Add return address to move list
294f4a2713aSLionel Sambuc   unsigned InstPtr = is64Bit ? X86::RIP : X86::EIP;
295f4a2713aSLionel Sambuc   MCCFIInstruction Inst2 = MCCFIInstruction::createOffset(
296*0a6a1f1dSLionel Sambuc       nullptr, MRI.getDwarfRegNum(InstPtr, true), stackGrowth);
297f4a2713aSLionel Sambuc   MAI->addInitialFrameState(Inst2);
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc   return MAI;
300f4a2713aSLionel Sambuc }
301f4a2713aSLionel Sambuc 
createX86MCCodeGenInfo(StringRef TT,Reloc::Model RM,CodeModel::Model CM,CodeGenOpt::Level OL)302f4a2713aSLionel Sambuc static MCCodeGenInfo *createX86MCCodeGenInfo(StringRef TT, Reloc::Model RM,
303f4a2713aSLionel Sambuc                                              CodeModel::Model CM,
304f4a2713aSLionel Sambuc                                              CodeGenOpt::Level OL) {
305f4a2713aSLionel Sambuc   MCCodeGenInfo *X = new MCCodeGenInfo();
306f4a2713aSLionel Sambuc 
307f4a2713aSLionel Sambuc   Triple T(TT);
308f4a2713aSLionel Sambuc   bool is64Bit = T.getArch() == Triple::x86_64;
309f4a2713aSLionel Sambuc 
310f4a2713aSLionel Sambuc   if (RM == Reloc::Default) {
311f4a2713aSLionel Sambuc     // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
312f4a2713aSLionel Sambuc     // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
313f4a2713aSLionel Sambuc     // use static relocation model by default.
314f4a2713aSLionel Sambuc     if (T.isOSDarwin()) {
315f4a2713aSLionel Sambuc       if (is64Bit)
316f4a2713aSLionel Sambuc         RM = Reloc::PIC_;
317f4a2713aSLionel Sambuc       else
318f4a2713aSLionel Sambuc         RM = Reloc::DynamicNoPIC;
319f4a2713aSLionel Sambuc     } else if (T.isOSWindows() && is64Bit)
320f4a2713aSLionel Sambuc       RM = Reloc::PIC_;
321f4a2713aSLionel Sambuc     else
322f4a2713aSLionel Sambuc       RM = Reloc::Static;
323f4a2713aSLionel Sambuc   }
324f4a2713aSLionel Sambuc 
325f4a2713aSLionel Sambuc   // ELF and X86-64 don't have a distinct DynamicNoPIC model.  DynamicNoPIC
326f4a2713aSLionel Sambuc   // is defined as a model for code which may be used in static or dynamic
327f4a2713aSLionel Sambuc   // executables but not necessarily a shared library. On X86-32 we just
328f4a2713aSLionel Sambuc   // compile in -static mode, in x86-64 we use PIC.
329f4a2713aSLionel Sambuc   if (RM == Reloc::DynamicNoPIC) {
330f4a2713aSLionel Sambuc     if (is64Bit)
331f4a2713aSLionel Sambuc       RM = Reloc::PIC_;
332f4a2713aSLionel Sambuc     else if (!T.isOSDarwin())
333f4a2713aSLionel Sambuc       RM = Reloc::Static;
334f4a2713aSLionel Sambuc   }
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc   // If we are on Darwin, disallow static relocation model in X86-64 mode, since
337f4a2713aSLionel Sambuc   // the Mach-O file format doesn't support it.
338f4a2713aSLionel Sambuc   if (RM == Reloc::Static && T.isOSDarwin() && is64Bit)
339f4a2713aSLionel Sambuc     RM = Reloc::PIC_;
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc   // For static codegen, if we're not already set, use Small codegen.
342f4a2713aSLionel Sambuc   if (CM == CodeModel::Default)
343f4a2713aSLionel Sambuc     CM = CodeModel::Small;
344f4a2713aSLionel Sambuc   else if (CM == CodeModel::JITDefault)
345f4a2713aSLionel Sambuc     // 64-bit JIT places everything in the same buffer except external funcs.
346f4a2713aSLionel Sambuc     CM = is64Bit ? CodeModel::Large : CodeModel::Small;
347f4a2713aSLionel Sambuc 
348f4a2713aSLionel Sambuc   X->InitMCCodeGenInfo(RM, CM, OL);
349f4a2713aSLionel Sambuc   return X;
350f4a2713aSLionel Sambuc }
351f4a2713aSLionel Sambuc 
createMCStreamer(const Target & T,StringRef TT,MCContext & Ctx,MCAsmBackend & MAB,raw_ostream & _OS,MCCodeEmitter * _Emitter,const MCSubtargetInfo & STI,bool RelaxAll)352f4a2713aSLionel Sambuc static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
353f4a2713aSLionel Sambuc                                     MCContext &Ctx, MCAsmBackend &MAB,
354*0a6a1f1dSLionel Sambuc                                     raw_ostream &_OS, MCCodeEmitter *_Emitter,
355*0a6a1f1dSLionel Sambuc                                     const MCSubtargetInfo &STI, bool RelaxAll) {
356f4a2713aSLionel Sambuc   Triple TheTriple(TT);
357f4a2713aSLionel Sambuc 
358*0a6a1f1dSLionel Sambuc   switch (TheTriple.getObjectFormat()) {
359*0a6a1f1dSLionel Sambuc   default: llvm_unreachable("unsupported object format");
360*0a6a1f1dSLionel Sambuc   case Triple::MachO:
361f4a2713aSLionel Sambuc     return createMachOStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
362*0a6a1f1dSLionel Sambuc   case Triple::COFF:
363*0a6a1f1dSLionel Sambuc     assert(TheTriple.isOSWindows() && "only Windows COFF is supported");
364*0a6a1f1dSLionel Sambuc     return createX86WinCOFFStreamer(Ctx, MAB, _Emitter, _OS, RelaxAll);
365*0a6a1f1dSLionel Sambuc   case Triple::ELF:
366*0a6a1f1dSLionel Sambuc     return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll);
367*0a6a1f1dSLionel Sambuc   }
368f4a2713aSLionel Sambuc }
369f4a2713aSLionel Sambuc 
createX86MCInstPrinter(const Target & T,unsigned SyntaxVariant,const MCAsmInfo & MAI,const MCInstrInfo & MII,const MCRegisterInfo & MRI,const MCSubtargetInfo & STI)370f4a2713aSLionel Sambuc static MCInstPrinter *createX86MCInstPrinter(const Target &T,
371f4a2713aSLionel Sambuc                                              unsigned SyntaxVariant,
372f4a2713aSLionel Sambuc                                              const MCAsmInfo &MAI,
373f4a2713aSLionel Sambuc                                              const MCInstrInfo &MII,
374f4a2713aSLionel Sambuc                                              const MCRegisterInfo &MRI,
375f4a2713aSLionel Sambuc                                              const MCSubtargetInfo &STI) {
376f4a2713aSLionel Sambuc   if (SyntaxVariant == 0)
377*0a6a1f1dSLionel Sambuc     return new X86ATTInstPrinter(MAI, MII, MRI, STI);
378f4a2713aSLionel Sambuc   if (SyntaxVariant == 1)
379f4a2713aSLionel Sambuc     return new X86IntelInstPrinter(MAI, MII, MRI);
380*0a6a1f1dSLionel Sambuc   return nullptr;
381f4a2713aSLionel Sambuc }
382f4a2713aSLionel Sambuc 
createX86MCRelocationInfo(StringRef TT,MCContext & Ctx)383f4a2713aSLionel Sambuc static MCRelocationInfo *createX86MCRelocationInfo(StringRef TT,
384f4a2713aSLionel Sambuc                                                    MCContext &Ctx) {
385f4a2713aSLionel Sambuc   Triple TheTriple(TT);
386*0a6a1f1dSLionel Sambuc   if (TheTriple.isOSBinFormatMachO() && TheTriple.getArch() == Triple::x86_64)
387f4a2713aSLionel Sambuc     return createX86_64MachORelocationInfo(Ctx);
388f4a2713aSLionel Sambuc   else if (TheTriple.isOSBinFormatELF())
389f4a2713aSLionel Sambuc     return createX86_64ELFRelocationInfo(Ctx);
390f4a2713aSLionel Sambuc   // Default to the stock relocation info.
391f4a2713aSLionel Sambuc   return llvm::createMCRelocationInfo(TT, Ctx);
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc 
createX86MCInstrAnalysis(const MCInstrInfo * Info)394f4a2713aSLionel Sambuc static MCInstrAnalysis *createX86MCInstrAnalysis(const MCInstrInfo *Info) {
395f4a2713aSLionel Sambuc   return new MCInstrAnalysis(Info);
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc 
398f4a2713aSLionel Sambuc // Force static initialization.
LLVMInitializeX86TargetMC()399f4a2713aSLionel Sambuc extern "C" void LLVMInitializeX86TargetMC() {
400f4a2713aSLionel Sambuc   // Register the MC asm info.
401f4a2713aSLionel Sambuc   RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo);
402f4a2713aSLionel Sambuc   RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo);
403f4a2713aSLionel Sambuc 
404f4a2713aSLionel Sambuc   // Register the MC codegen info.
405f4a2713aSLionel Sambuc   RegisterMCCodeGenInfoFn C(TheX86_32Target, createX86MCCodeGenInfo);
406f4a2713aSLionel Sambuc   RegisterMCCodeGenInfoFn D(TheX86_64Target, createX86MCCodeGenInfo);
407f4a2713aSLionel Sambuc 
408f4a2713aSLionel Sambuc   // Register the MC instruction info.
409f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
410f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
411f4a2713aSLionel Sambuc 
412f4a2713aSLionel Sambuc   // Register the MC register info.
413f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
414f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);
415f4a2713aSLionel Sambuc 
416f4a2713aSLionel Sambuc   // Register the MC subtarget info.
417f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target,
418f4a2713aSLionel Sambuc                                           X86_MC::createX86MCSubtargetInfo);
419f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target,
420f4a2713aSLionel Sambuc                                           X86_MC::createX86MCSubtargetInfo);
421f4a2713aSLionel Sambuc 
422f4a2713aSLionel Sambuc   // Register the MC instruction analyzer.
423f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstrAnalysis(TheX86_32Target,
424f4a2713aSLionel Sambuc                                           createX86MCInstrAnalysis);
425f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstrAnalysis(TheX86_64Target,
426f4a2713aSLionel Sambuc                                           createX86MCInstrAnalysis);
427f4a2713aSLionel Sambuc 
428f4a2713aSLionel Sambuc   // Register the code emitter.
429f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCCodeEmitter(TheX86_32Target,
430f4a2713aSLionel Sambuc                                         createX86MCCodeEmitter);
431f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCCodeEmitter(TheX86_64Target,
432f4a2713aSLionel Sambuc                                         createX86MCCodeEmitter);
433f4a2713aSLionel Sambuc 
434f4a2713aSLionel Sambuc   // Register the asm backend.
435f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCAsmBackend(TheX86_32Target,
436f4a2713aSLionel Sambuc                                        createX86_32AsmBackend);
437f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCAsmBackend(TheX86_64Target,
438f4a2713aSLionel Sambuc                                        createX86_64AsmBackend);
439f4a2713aSLionel Sambuc 
440f4a2713aSLionel Sambuc   // Register the object streamer.
441f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCObjectStreamer(TheX86_32Target,
442f4a2713aSLionel Sambuc                                            createMCStreamer);
443f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCObjectStreamer(TheX86_64Target,
444f4a2713aSLionel Sambuc                                            createMCStreamer);
445f4a2713aSLionel Sambuc 
446f4a2713aSLionel Sambuc   // Register the MCInstPrinter.
447f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstPrinter(TheX86_32Target,
448f4a2713aSLionel Sambuc                                         createX86MCInstPrinter);
449f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCInstPrinter(TheX86_64Target,
450f4a2713aSLionel Sambuc                                         createX86MCInstPrinter);
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc   // Register the MC relocation info.
453f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCRelocationInfo(TheX86_32Target,
454f4a2713aSLionel Sambuc                                            createX86MCRelocationInfo);
455f4a2713aSLionel Sambuc   TargetRegistry::RegisterMCRelocationInfo(TheX86_64Target,
456f4a2713aSLionel Sambuc                                            createX86MCRelocationInfo);
457f4a2713aSLionel Sambuc }
458