PageRenderTime 45ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp

https://gitlab.com/Birhetia/platform_external_llvm
C++ | 270 lines | 182 code | 44 blank | 44 comment | 56 complexity | 8e1653a5a3c38b9ac0a901c38b29d233 MD5 | raw file
  1. //===-- X86MCTargetDesc.cpp - X86 Target Descriptions ---------------------===//
  2. //
  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. #include "X86MCTargetDesc.h"
  14. #include "InstPrinter/X86ATTInstPrinter.h"
  15. #include "InstPrinter/X86IntelInstPrinter.h"
  16. #include "X86MCAsmInfo.h"
  17. #include "llvm/ADT/Triple.h"
  18. #include "llvm/MC/MCCodeGenInfo.h"
  19. #include "llvm/MC/MCInstrAnalysis.h"
  20. #include "llvm/MC/MCInstrInfo.h"
  21. #include "llvm/MC/MCRegisterInfo.h"
  22. #include "llvm/MC/MCStreamer.h"
  23. #include "llvm/MC/MCSubtargetInfo.h"
  24. #include "llvm/MC/MachineLocation.h"
  25. #include "llvm/Support/ErrorHandling.h"
  26. #include "llvm/Support/Host.h"
  27. #include "llvm/Support/TargetRegistry.h"
  28. #if _MSC_VER
  29. #include <intrin.h>
  30. #endif
  31. using namespace llvm;
  32. #define GET_REGINFO_MC_DESC
  33. #include "X86GenRegisterInfo.inc"
  34. #define GET_INSTRINFO_MC_DESC
  35. #include "X86GenInstrInfo.inc"
  36. #define GET_SUBTARGETINFO_MC_DESC
  37. #include "X86GenSubtargetInfo.inc"
  38. std::string X86_MC::ParseX86Triple(const Triple &TT) {
  39. std::string FS;
  40. if (TT.getArch() == Triple::x86_64)
  41. FS = "+64bit-mode,-32bit-mode,-16bit-mode";
  42. else if (TT.getEnvironment() != Triple::CODE16)
  43. FS = "-64bit-mode,+32bit-mode,-16bit-mode";
  44. else
  45. FS = "-64bit-mode,-32bit-mode,+16bit-mode";
  46. return FS;
  47. }
  48. unsigned X86_MC::getDwarfRegFlavour(const Triple &TT, bool isEH) {
  49. if (TT.getArch() == Triple::x86_64)
  50. return DWARFFlavour::X86_64;
  51. if (TT.isOSDarwin())
  52. return isEH ? DWARFFlavour::X86_32_DarwinEH : DWARFFlavour::X86_32_Generic;
  53. if (TT.isOSCygMing())
  54. // Unsupported by now, just quick fallback
  55. return DWARFFlavour::X86_32_Generic;
  56. return DWARFFlavour::X86_32_Generic;
  57. }
  58. void X86_MC::InitLLVM2SEHRegisterMapping(MCRegisterInfo *MRI) {
  59. // FIXME: TableGen these.
  60. for (unsigned Reg = X86::NoRegister+1; Reg < X86::NUM_TARGET_REGS; ++Reg) {
  61. unsigned SEH = MRI->getEncodingValue(Reg);
  62. MRI->mapLLVMRegToSEHReg(Reg, SEH);
  63. }
  64. }
  65. MCSubtargetInfo *X86_MC::createX86MCSubtargetInfo(const Triple &TT,
  66. StringRef CPU, StringRef FS) {
  67. std::string ArchFS = X86_MC::ParseX86Triple(TT);
  68. if (!FS.empty()) {
  69. if (!ArchFS.empty())
  70. ArchFS = (Twine(ArchFS) + "," + FS).str();
  71. else
  72. ArchFS = FS;
  73. }
  74. std::string CPUName = CPU;
  75. if (CPUName.empty())
  76. CPUName = "generic";
  77. return createX86MCSubtargetInfoImpl(TT, CPUName, ArchFS);
  78. }
  79. static MCInstrInfo *createX86MCInstrInfo() {
  80. MCInstrInfo *X = new MCInstrInfo();
  81. InitX86MCInstrInfo(X);
  82. return X;
  83. }
  84. static MCRegisterInfo *createX86MCRegisterInfo(const Triple &TT) {
  85. unsigned RA = (TT.getArch() == Triple::x86_64)
  86. ? X86::RIP // Should have dwarf #16.
  87. : X86::EIP; // Should have dwarf #8.
  88. MCRegisterInfo *X = new MCRegisterInfo();
  89. InitX86MCRegisterInfo(X, RA, X86_MC::getDwarfRegFlavour(TT, false),
  90. X86_MC::getDwarfRegFlavour(TT, true), RA);
  91. X86_MC::InitLLVM2SEHRegisterMapping(X);
  92. return X;
  93. }
  94. static MCAsmInfo *createX86MCAsmInfo(const MCRegisterInfo &MRI,
  95. const Triple &TheTriple) {
  96. bool is64Bit = TheTriple.getArch() == Triple::x86_64;
  97. MCAsmInfo *MAI;
  98. if (TheTriple.isOSBinFormatMachO()) {
  99. if (is64Bit)
  100. MAI = new X86_64MCAsmInfoDarwin(TheTriple);
  101. else
  102. MAI = new X86MCAsmInfoDarwin(TheTriple);
  103. } else if (TheTriple.isOSBinFormatELF()) {
  104. // Force the use of an ELF container.
  105. MAI = new X86ELFMCAsmInfo(TheTriple);
  106. } else if (TheTriple.isWindowsMSVCEnvironment() ||
  107. TheTriple.isWindowsCoreCLREnvironment()) {
  108. MAI = new X86MCAsmInfoMicrosoft(TheTriple);
  109. } else if (TheTriple.isOSCygMing() ||
  110. TheTriple.isWindowsItaniumEnvironment()) {
  111. MAI = new X86MCAsmInfoGNUCOFF(TheTriple);
  112. } else {
  113. // The default is ELF.
  114. MAI = new X86ELFMCAsmInfo(TheTriple);
  115. }
  116. // Initialize initial frame state.
  117. // Calculate amount of bytes used for return address storing
  118. int stackGrowth = is64Bit ? -8 : -4;
  119. // Initial state of the frame pointer is esp+stackGrowth.
  120. unsigned StackPtr = is64Bit ? X86::RSP : X86::ESP;
  121. MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
  122. nullptr, MRI.getDwarfRegNum(StackPtr, true), -stackGrowth);
  123. MAI->addInitialFrameState(Inst);
  124. // Add return address to move list
  125. unsigned InstPtr = is64Bit ? X86::RIP : X86::EIP;
  126. MCCFIInstruction Inst2 = MCCFIInstruction::createOffset(
  127. nullptr, MRI.getDwarfRegNum(InstPtr, true), stackGrowth);
  128. MAI->addInitialFrameState(Inst2);
  129. return MAI;
  130. }
  131. static MCCodeGenInfo *createX86MCCodeGenInfo(const Triple &TT, Reloc::Model RM,
  132. CodeModel::Model CM,
  133. CodeGenOpt::Level OL) {
  134. MCCodeGenInfo *X = new MCCodeGenInfo();
  135. bool is64Bit = TT.getArch() == Triple::x86_64;
  136. if (RM == Reloc::Default) {
  137. // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode.
  138. // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we
  139. // use static relocation model by default.
  140. if (TT.isOSDarwin()) {
  141. if (is64Bit)
  142. RM = Reloc::PIC_;
  143. else
  144. RM = Reloc::DynamicNoPIC;
  145. } else if (TT.isOSWindows() && is64Bit)
  146. RM = Reloc::PIC_;
  147. else
  148. RM = Reloc::Static;
  149. }
  150. // ELF and X86-64 don't have a distinct DynamicNoPIC model. DynamicNoPIC
  151. // is defined as a model for code which may be used in static or dynamic
  152. // executables but not necessarily a shared library. On X86-32 we just
  153. // compile in -static mode, in x86-64 we use PIC.
  154. if (RM == Reloc::DynamicNoPIC) {
  155. if (is64Bit)
  156. RM = Reloc::PIC_;
  157. else if (!TT.isOSDarwin())
  158. RM = Reloc::Static;
  159. }
  160. // If we are on Darwin, disallow static relocation model in X86-64 mode, since
  161. // the Mach-O file format doesn't support it.
  162. if (RM == Reloc::Static && TT.isOSDarwin() && is64Bit)
  163. RM = Reloc::PIC_;
  164. // For static codegen, if we're not already set, use Small codegen.
  165. if (CM == CodeModel::Default)
  166. CM = CodeModel::Small;
  167. else if (CM == CodeModel::JITDefault)
  168. // 64-bit JIT places everything in the same buffer except external funcs.
  169. CM = is64Bit ? CodeModel::Large : CodeModel::Small;
  170. X->initMCCodeGenInfo(RM, CM, OL);
  171. return X;
  172. }
  173. static MCInstPrinter *createX86MCInstPrinter(const Triple &T,
  174. unsigned SyntaxVariant,
  175. const MCAsmInfo &MAI,
  176. const MCInstrInfo &MII,
  177. const MCRegisterInfo &MRI) {
  178. if (SyntaxVariant == 0)
  179. return new X86ATTInstPrinter(MAI, MII, MRI);
  180. if (SyntaxVariant == 1)
  181. return new X86IntelInstPrinter(MAI, MII, MRI);
  182. return nullptr;
  183. }
  184. static MCRelocationInfo *createX86MCRelocationInfo(const Triple &TheTriple,
  185. MCContext &Ctx) {
  186. if (TheTriple.isOSBinFormatMachO() && TheTriple.getArch() == Triple::x86_64)
  187. return createX86_64MachORelocationInfo(Ctx);
  188. else if (TheTriple.isOSBinFormatELF())
  189. return createX86_64ELFRelocationInfo(Ctx);
  190. // Default to the stock relocation info.
  191. return llvm::createMCRelocationInfo(TheTriple, Ctx);
  192. }
  193. static MCInstrAnalysis *createX86MCInstrAnalysis(const MCInstrInfo *Info) {
  194. return new MCInstrAnalysis(Info);
  195. }
  196. // Force static initialization.
  197. extern "C" void LLVMInitializeX86TargetMC() {
  198. for (Target *T : {&TheX86_32Target, &TheX86_64Target}) {
  199. // Register the MC asm info.
  200. RegisterMCAsmInfoFn X(*T, createX86MCAsmInfo);
  201. // Register the MC codegen info.
  202. RegisterMCCodeGenInfoFn Y(*T, createX86MCCodeGenInfo);
  203. // Register the MC instruction info.
  204. TargetRegistry::RegisterMCInstrInfo(*T, createX86MCInstrInfo);
  205. // Register the MC register info.
  206. TargetRegistry::RegisterMCRegInfo(*T, createX86MCRegisterInfo);
  207. // Register the MC subtarget info.
  208. TargetRegistry::RegisterMCSubtargetInfo(*T,
  209. X86_MC::createX86MCSubtargetInfo);
  210. // Register the MC instruction analyzer.
  211. TargetRegistry::RegisterMCInstrAnalysis(*T, createX86MCInstrAnalysis);
  212. // Register the code emitter.
  213. TargetRegistry::RegisterMCCodeEmitter(*T, createX86MCCodeEmitter);
  214. // Register the object streamer.
  215. TargetRegistry::RegisterCOFFStreamer(*T, createX86WinCOFFStreamer);
  216. // Register the MCInstPrinter.
  217. TargetRegistry::RegisterMCInstPrinter(*T, createX86MCInstPrinter);
  218. // Register the MC relocation info.
  219. TargetRegistry::RegisterMCRelocationInfo(*T, createX86MCRelocationInfo);
  220. }
  221. // Register the asm backend.
  222. TargetRegistry::RegisterMCAsmBackend(TheX86_32Target,
  223. createX86_32AsmBackend);
  224. TargetRegistry::RegisterMCAsmBackend(TheX86_64Target,
  225. createX86_64AsmBackend);
  226. }