blob: d46f7e28bcee3842fa122e44022006c595b6ab4f [file] [log] [blame]
Evan Chenged5e3552011-07-06 22:01:53 +00001//===-- X86MCTargetDesc.cpp - X86 Target Descriptions -----------*- C++ -*-===//
Evan Chenga347f852011-06-24 01:44:41 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides X86 specific target descriptions.
11//
12//===----------------------------------------------------------------------===//
13
Evan Chenged5e3552011-07-06 22:01:53 +000014#include "X86MCTargetDesc.h"
Evan Cheng1abf2cb2011-07-14 23:50:31 +000015#include "X86MCAsmInfo.h"
Evan Cheng22fee2d2011-06-28 20:07:07 +000016#include "llvm/MC/MCInstrInfo.h"
Evan Chenga347f852011-06-24 01:44:41 +000017#include "llvm/MC/MCRegisterInfo.h"
Evan Chengce795dc2011-07-01 22:25:04 +000018#include "llvm/MC/MCSubtargetInfo.h"
Evan Chengf5fa52e2011-06-24 20:42:09 +000019#include "llvm/Target/TargetRegistry.h"
Evan Cheng18fb1d32011-07-07 21:06:52 +000020#include "llvm/ADT/Triple.h"
21#include "llvm/Support/Host.h"
Evan Cheng73f50d92011-06-27 18:32:37 +000022
23#define GET_REGINFO_MC_DESC
24#include "X86GenRegisterInfo.inc"
Evan Cheng22fee2d2011-06-28 20:07:07 +000025
26#define GET_INSTRINFO_MC_DESC
27#include "X86GenInstrInfo.inc"
28
Evan Chengce795dc2011-07-01 22:25:04 +000029#define GET_SUBTARGETINFO_MC_DESC
Evan Cheng385e9302011-07-01 22:36:09 +000030#include "X86GenSubtargetInfo.inc"
Evan Chengce795dc2011-07-01 22:25:04 +000031
Evan Chenga347f852011-06-24 01:44:41 +000032using namespace llvm;
33
Evan Cheng18fb1d32011-07-07 21:06:52 +000034
35std::string X86_MC::ParseX86Triple(StringRef TT) {
36 Triple TheTriple(TT);
37 if (TheTriple.getArch() == Triple::x86_64)
Eli Friedman6dfef662011-07-08 23:07:42 +000038 return "+64bit-mode";
Evan Chengebdeeab2011-07-08 01:53:10 +000039 return "-64bit-mode";
Evan Cheng18fb1d32011-07-07 21:06:52 +000040}
41
42/// GetCpuIDAndInfo - Execute the specified cpuid and return the 4 values in the
43/// specified arguments. If we can't run cpuid on the host, return true.
44bool X86_MC::GetCpuIDAndInfo(unsigned value, unsigned *rEAX,
45 unsigned *rEBX, unsigned *rECX, unsigned *rEDX) {
46#if defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
47 #if defined(__GNUC__)
48 // gcc doesn't know cpuid would clobber ebx/rbx. Preseve it manually.
49 asm ("movq\t%%rbx, %%rsi\n\t"
50 "cpuid\n\t"
51 "xchgq\t%%rbx, %%rsi\n\t"
52 : "=a" (*rEAX),
53 "=S" (*rEBX),
54 "=c" (*rECX),
55 "=d" (*rEDX)
56 : "a" (value));
57 return false;
58 #elif defined(_MSC_VER)
59 int registers[4];
60 __cpuid(registers, value);
61 *rEAX = registers[0];
62 *rEBX = registers[1];
63 *rECX = registers[2];
64 *rEDX = registers[3];
65 return false;
66 #endif
67#elif defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)
68 #if defined(__GNUC__)
69 asm ("movl\t%%ebx, %%esi\n\t"
70 "cpuid\n\t"
71 "xchgl\t%%ebx, %%esi\n\t"
72 : "=a" (*rEAX),
73 "=S" (*rEBX),
74 "=c" (*rECX),
75 "=d" (*rEDX)
76 : "a" (value));
77 return false;
78 #elif defined(_MSC_VER)
79 __asm {
80 mov eax,value
81 cpuid
82 mov esi,rEAX
83 mov dword ptr [esi],eax
84 mov esi,rEBX
85 mov dword ptr [esi],ebx
86 mov esi,rECX
87 mov dword ptr [esi],ecx
88 mov esi,rEDX
89 mov dword ptr [esi],edx
90 }
91 return false;
92 #endif
93#endif
94 return true;
95}
96
97void X86_MC::DetectFamilyModel(unsigned EAX, unsigned &Family,
98 unsigned &Model) {
99 Family = (EAX >> 8) & 0xf; // Bits 8 - 11
100 Model = (EAX >> 4) & 0xf; // Bits 4 - 7
101 if (Family == 6 || Family == 0xf) {
102 if (Family == 0xf)
103 // Examine extended family ID if family ID is F.
104 Family += (EAX >> 20) & 0xff; // Bits 20 - 27
105 // Examine extended model ID if family ID is 6 or F.
106 Model += ((EAX >> 16) & 0xf) << 4; // Bits 16 - 19
107 }
108}
109
Evan Cheng0e6a0522011-07-18 20:57:22 +0000110unsigned X86_MC::getDwarfRegFlavour(StringRef TT, bool isEH) {
111 Triple TheTriple(TT);
112 if (TheTriple.getArch() == Triple::x86_64)
113 return DWARFFlavour::X86_64;
114
115 if (TheTriple.isOSDarwin())
116 return isEH ? DWARFFlavour::X86_32_DarwinEH : DWARFFlavour::X86_32_Generic;
117 if (TheTriple.getOS() == Triple::MinGW32 ||
118 TheTriple.getOS() == Triple::Cygwin)
119 // Unsupported by now, just quick fallback
120 return DWARFFlavour::X86_32_Generic;
121 return DWARFFlavour::X86_32_Generic;
122}
123
124/// getX86RegNum - This function maps LLVM register identifiers to their X86
125/// specific numbering, which is used in various places encoding instructions.
126unsigned X86_MC::getX86RegNum(unsigned RegNo) {
127 switch(RegNo) {
128 case X86::RAX: case X86::EAX: case X86::AX: case X86::AL: return N86::EAX;
129 case X86::RCX: case X86::ECX: case X86::CX: case X86::CL: return N86::ECX;
130 case X86::RDX: case X86::EDX: case X86::DX: case X86::DL: return N86::EDX;
131 case X86::RBX: case X86::EBX: case X86::BX: case X86::BL: return N86::EBX;
132 case X86::RSP: case X86::ESP: case X86::SP: case X86::SPL: case X86::AH:
133 return N86::ESP;
134 case X86::RBP: case X86::EBP: case X86::BP: case X86::BPL: case X86::CH:
135 return N86::EBP;
136 case X86::RSI: case X86::ESI: case X86::SI: case X86::SIL: case X86::DH:
137 return N86::ESI;
138 case X86::RDI: case X86::EDI: case X86::DI: case X86::DIL: case X86::BH:
139 return N86::EDI;
140
141 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
142 return N86::EAX;
143 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
144 return N86::ECX;
145 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
146 return N86::EDX;
147 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
148 return N86::EBX;
149 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
150 return N86::ESP;
151 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
152 return N86::EBP;
153 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
154 return N86::ESI;
155 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
156 return N86::EDI;
157
158 case X86::ST0: case X86::ST1: case X86::ST2: case X86::ST3:
159 case X86::ST4: case X86::ST5: case X86::ST6: case X86::ST7:
160 return RegNo-X86::ST0;
161
162 case X86::XMM0: case X86::XMM8:
163 case X86::YMM0: case X86::YMM8: case X86::MM0:
164 return 0;
165 case X86::XMM1: case X86::XMM9:
166 case X86::YMM1: case X86::YMM9: case X86::MM1:
167 return 1;
168 case X86::XMM2: case X86::XMM10:
169 case X86::YMM2: case X86::YMM10: case X86::MM2:
170 return 2;
171 case X86::XMM3: case X86::XMM11:
172 case X86::YMM3: case X86::YMM11: case X86::MM3:
173 return 3;
174 case X86::XMM4: case X86::XMM12:
175 case X86::YMM4: case X86::YMM12: case X86::MM4:
176 return 4;
177 case X86::XMM5: case X86::XMM13:
178 case X86::YMM5: case X86::YMM13: case X86::MM5:
179 return 5;
180 case X86::XMM6: case X86::XMM14:
181 case X86::YMM6: case X86::YMM14: case X86::MM6:
182 return 6;
183 case X86::XMM7: case X86::XMM15:
184 case X86::YMM7: case X86::YMM15: case X86::MM7:
185 return 7;
186
187 case X86::ES: return 0;
188 case X86::CS: return 1;
189 case X86::SS: return 2;
190 case X86::DS: return 3;
191 case X86::FS: return 4;
192 case X86::GS: return 5;
193
194 case X86::CR0: case X86::CR8 : case X86::DR0: return 0;
195 case X86::CR1: case X86::CR9 : case X86::DR1: return 1;
196 case X86::CR2: case X86::CR10: case X86::DR2: return 2;
197 case X86::CR3: case X86::CR11: case X86::DR3: return 3;
198 case X86::CR4: case X86::CR12: case X86::DR4: return 4;
199 case X86::CR5: case X86::CR13: case X86::DR5: return 5;
200 case X86::CR6: case X86::CR14: case X86::DR6: return 6;
201 case X86::CR7: case X86::CR15: case X86::DR7: return 7;
202
203 // Pseudo index registers are equivalent to a "none"
204 // scaled index (See Intel Manual 2A, table 2-3)
205 case X86::EIZ:
206 case X86::RIZ:
207 return 4;
208
209 default:
210 assert((int(RegNo) > 0) && "Unknown physical register!");
211 return 0;
212 }
213}
214
215void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
216 // FIXME: TableGen these.
217 for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
218 int SEH = X86_MC::getX86RegNum(Reg);
219 switch (Reg) {
220 case X86::R8: case X86::R8D: case X86::R8W: case X86::R8B:
221 case X86::R9: case X86::R9D: case X86::R9W: case X86::R9B:
222 case X86::R10: case X86::R10D: case X86::R10W: case X86::R10B:
223 case X86::R11: case X86::R11D: case X86::R11W: case X86::R11B:
224 case X86::R12: case X86::R12D: case X86::R12W: case X86::R12B:
225 case X86::R13: case X86::R13D: case X86::R13W: case X86::R13B:
226 case X86::R14: case X86::R14D: case X86::R14W: case X86::R14B:
227 case X86::R15: case X86::R15D: case X86::R15W: case X86::R15B:
228 case X86::XMM8: case X86::XMM9: case X86::XMM10: case X86::XMM11:
229 case X86::XMM12: case X86::XMM13: case X86::XMM14: case X86::XMM15:
230 case X86::YMM8: case X86::YMM9: case X86::YMM10: case X86::YMM11:
231 case X86::YMM12: case X86::YMM13: case X86::YMM14: case X86::YMM15:
232 SEH += 8;
233 break;
234 }
235 MRI->mapLLVMRegToSEHReg(Reg, SEH);
236 }
237}
238
Evan Chengebdeeab2011-07-08 01:53:10 +0000239MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(StringRef TT, StringRef CPU,
240 StringRef FS) {
Evan Cheng18fb1d32011-07-07 21:06:52 +0000241 std::string ArchFS = X86_MC::ParseX86Triple(TT);
242 if (!FS.empty()) {
243 if (!ArchFS.empty())
244 ArchFS = ArchFS + "," + FS.str();
245 else
246 ArchFS = FS;
247 }
248
249 std::string CPUName = CPU;
Evan Chengcc0ddc72011-07-08 21:14:14 +0000250 if (CPUName.empty()) {
251#if defined (__x86_64__) || defined(__i386__)
Evan Cheng18fb1d32011-07-07 21:06:52 +0000252 CPUName = sys::getHostCPUName();
Evan Chengcc0ddc72011-07-08 21:14:14 +0000253#else
254 CPUName = "generic";
255#endif
256 }
Evan Cheng18fb1d32011-07-07 21:06:52 +0000257
Evan Chengce795dc2011-07-01 22:25:04 +0000258 MCSubtargetInfo *X = new MCSubtargetInfo();
Evan Cheng59ee62d2011-07-11 03:57:24 +0000259 InitX86MCSubtargetInfo(X, TT, CPUName, ArchFS);
Evan Chengebdeeab2011-07-08 01:53:10 +0000260 return X;
261}
262
Evan Cheng1abf2cb2011-07-14 23:50:31 +0000263// Force static initialization.
264extern "C" void LLVMInitializeX86MCSubtargetInfo() {
265 TargetRegistry::RegisterMCSubtargetInfo(TheX86_32Target,
266 X86_MC::createX86MCSubtargetInfo);
267 TargetRegistry::RegisterMCSubtargetInfo(TheX86_64Target,
268 X86_MC::createX86MCSubtargetInfo);
269}
270
271static MCInstrInfo *createX86MCInstrInfo() {
Evan Chengebdeeab2011-07-08 01:53:10 +0000272 MCInstrInfo *X = new MCInstrInfo();
273 InitX86MCInstrInfo(X);
274 return X;
275}
276
Evan Chengce795dc2011-07-01 22:25:04 +0000277extern "C" void LLVMInitializeX86MCInstrInfo() {
Evan Chengce795dc2011-07-01 22:25:04 +0000278 TargetRegistry::RegisterMCInstrInfo(TheX86_32Target, createX86MCInstrInfo);
279 TargetRegistry::RegisterMCInstrInfo(TheX86_64Target, createX86MCInstrInfo);
280}
281
Evan Cheng0e6a0522011-07-18 20:57:22 +0000282static MCRegisterInfo *createX86MCRegisterInfo(StringRef TT) {
283 Triple TheTriple(TT);
284 unsigned RA = (TheTriple.getArch() == Triple::x86_64)
285 ? X86::RIP // Should have dwarf #16.
286 : X86::EIP; // Should have dwarf #8.
287
Evan Cheng1abf2cb2011-07-14 23:50:31 +0000288 MCRegisterInfo *X = new MCRegisterInfo();
Evan Cheng0e6a0522011-07-18 20:57:22 +0000289 InitX86MCRegisterInfo(X, RA,
290 X86_MC::getDwarfRegFlavour(TT, false),
291 X86_MC::getDwarfRegFlavour(TT, true));
292 X86_MC::InitLLVM2SEHRegisterMapping(X);
Evan Cheng1abf2cb2011-07-14 23:50:31 +0000293 return X;
294}
295
Evan Cheng0e6a0522011-07-18 20:57:22 +0000296extern "C" void LLVMInitializeX86MCRegisterInfo() {
Evan Chengf5fa52e2011-06-24 20:42:09 +0000297 TargetRegistry::RegisterMCRegInfo(TheX86_32Target, createX86MCRegisterInfo);
298 TargetRegistry::RegisterMCRegInfo(TheX86_64Target, createX86MCRegisterInfo);
299}
Evan Chengffc0e732011-07-09 05:47:46 +0000300
301
Evan Cheng1be0e272011-07-15 02:09:41 +0000302static MCAsmInfo *createX86MCAsmInfo(const Target &T, StringRef TT) {
Evan Cheng1abf2cb2011-07-14 23:50:31 +0000303 Triple TheTriple(TT);
304
305 if (TheTriple.isOSDarwin() || TheTriple.getEnvironment() == Triple::MachO) {
306 if (TheTriple.getArch() == Triple::x86_64)
307 return new X86_64MCAsmInfoDarwin(TheTriple);
308 else
309 return new X86MCAsmInfoDarwin(TheTriple);
310 }
311
312 if (TheTriple.isOSWindows())
313 return new X86MCAsmInfoCOFF(TheTriple);
314
315 return new X86ELFMCAsmInfo(TheTriple);
316}
317
318extern "C" void LLVMInitializeX86MCAsmInfo() {
319 // Register the target asm info.
Evan Cheng1be0e272011-07-15 02:09:41 +0000320 RegisterMCAsmInfoFn A(TheX86_32Target, createX86MCAsmInfo);
321 RegisterMCAsmInfoFn B(TheX86_64Target, createX86MCAsmInfo);
Evan Chengffc0e732011-07-09 05:47:46 +0000322}