131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// 278a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// 378a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// The LLVM Compiler Infrastructure 478a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// 578a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// This file is distributed under the University of Illinois Open Source 678a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// License. See LICENSE.TXT for details. 778a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// 878a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng//===----------------------------------------------------------------------===// 978a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// 1078a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// This file provides ARM specific target descriptions. 1178a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng// 1278a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng//===----------------------------------------------------------------------===// 1378a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 1458a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "ARMBaseInfo.h" 156eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "ARMELFStreamer.h" 166eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "ARMMCAsmInfo.h" 170f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky#include "ARMMCTargetDesc.h" 184b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng#include "InstPrinter/ARMInstPrinter.h" 190f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky#include "llvm/ADT/Triple.h" 207801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCCodeGenInfo.h" 217801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng#include "llvm/MC/MCInstrAnalysis.h" 2278a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCInstrInfo.h" 2378a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 24be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCStreamer.h" 2578a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 26be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/Support/ErrorHandling.h" 273e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 2878a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 2978a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_REGINFO_MC_DESC 3078a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenRegisterInfo.inc" 3178a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 3278a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_INSTRINFO_MC_DESC 3378a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenInstrInfo.inc" 3478a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 3578a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_SUBTARGETINFO_MC_DESC 3678a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenSubtargetInfo.inc" 3778a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 3878a9f138ae95458bf6d922f38706eed045691d5aEvan Chengusing namespace llvm; 3978a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 40e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Chengstd::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { 410f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky Triple triple(TT); 420f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky 4394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // Set the boolean corresponding to the current target triple, or the default 4494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // if one cannot be determined, to true. 4594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned Len = TT.size(); 4694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned Idx = 0; 4794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 487442a03dcc2ac7850a77ec7c639973d8dc6034aeNick Lewycky // FIXME: Enhance Triple helper class to extract ARM version. 49db068738e806753bc5735434cab9b9f930840c7aEvan Cheng bool isThumb = false; 5094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= 5 && TT.substr(0, 4) == "armv") 5194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng Idx = 4; 5294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 53db068738e806753bc5735434cab9b9f930840c7aEvan Cheng isThumb = true; 5494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= 7 && TT[5] == 'v') 5594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng Idx = 6; 5694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 5794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 5897a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng bool NoCPU = CPU == "generic" || CPU.empty(); 5994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng std::string ARMArchFeature; 6094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Idx) { 6194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned SubVer = TT[Idx]; 62849eedce9921eb8f285cd0df0ad69ee5133459d1Joey Gouly if (SubVer == '8') { 63849eedce9921eb8f285cd0df0ad69ee5133459d1Joey Gouly // FIXME: Parse v8 features 64849eedce9921eb8f285cd0df0ad69ee5133459d1Joey Gouly ARMArchFeature = "+v8"; 65849eedce9921eb8f285cd0df0ad69ee5133459d1Joey Gouly } else if (SubVer == '7') { 6694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= Idx+2 && TT[Idx+1] == 'm') { 679bdd78501484a1add2d8a757fd29960dd9fc9de7Tim Northover isThumb = true; 6897a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 6997a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass 7097a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; 7197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 7297a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // Use CPU to figure out the exact features. 7397a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7"; 7494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 7597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 7697a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 7797a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // FeatureT2XtPk, FeatureMClass 7897a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; 7997a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 8097a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // Use CPU to figure out the exact features. 8197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7"; 82eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson } else if (Len >= Idx+2 && TT[Idx+1] == 's') { 83eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson if (NoCPU) 84eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 85eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // Swift 86eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+t2xtpk"; 87eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson else 88eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // Use CPU to figure out the exact features. 89eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson ARMArchFeature = "+v7"; 90e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng } else { 91e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // v7 CPUs have lots of different feature sets. If no CPU is specified, 92e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return 93e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // the "minimum" feature set and use CPU string to figure out the exact 94e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // features. 9597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 96e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 97e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; 98e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng else 99e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // Use CPU to figure out the exact features. 100e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng ARMArchFeature = "+v7"; 101e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng } 10294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '6') { 103f06dfa786064edc3bb6de92bb3783d0c23f4d34aJim Grosbach if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 10494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v6t2"; 10597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else if (Len >= Idx+2 && TT[Idx+1] == 'm') { 1069bdd78501484a1add2d8a757fd29960dd9fc9de7Tim Northover isThumb = true; 10797a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 10897a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v6m: FeatureNoARM, FeatureMClass 10997a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v6,+noarm,+mclass"; 11097a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 11197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v6"; 11297a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng } else 11339dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v6"; 11494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '5') { 11539dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 11694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v5te"; 11739dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng else 11839dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v5t"; 11939dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 12039dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v4t"; 12194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 12294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 123db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (isThumb) { 124db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (ARMArchFeature.empty()) 125963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature = "+thumb-mode"; 126db068738e806753bc5735434cab9b9f930840c7aEvan Cheng else 127963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature += ",+thumb-mode"; 128db068738e806753bc5735434cab9b9f930840c7aEvan Cheng } 129db068738e806753bc5735434cab9b9f930840c7aEvan Cheng 1300f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky if (triple.isOSNaCl()) { 1310f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky if (ARMArchFeature.empty()) 1320f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky ARMArchFeature = "+nacl-trap"; 1330f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky else 1340f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky ARMArchFeature += ",+nacl-trap"; 1350f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky } 1360f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky 13794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng return ARMArchFeature; 13894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng} 139ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan ChengMCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 141ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef FS) { 142e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!FS.empty()) { 144ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!ArchFS.empty()) 145ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = ArchFS + "," + FS.str(); 146ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng else 147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = FS; 148ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 149ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 150ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCSubtargetInfo *X = new MCSubtargetInfo(); 15159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 152ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 153ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 154ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1551abf2cb59b8d63415780a03329307c0997b2670cEvan Chengstatic MCInstrInfo *createARMMCInstrInfo() { 1561abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCInstrInfo *X = new MCInstrInfo(); 1571abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng InitARMMCInstrInfo(X); 158ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 159ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 160ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1610e6a052331f674dd70e28af41f654a7874405eabEvan Chengstatic MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 1621abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCRegisterInfo *X = new MCRegisterInfo(); 163fbf3b4a07690751f72302757058ab0298dfb832eJim Grosbach InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 1641abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return X; 1651abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1661abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1674a971705bc6030dc2e4338b3cd5cffa2e0f88b7bRafael Espindolastatic MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { 1681abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng Triple TheTriple(TT); 1691abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1701abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng if (TheTriple.isOSDarwin()) 1711abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMMCAsmInfoDarwin(); 1721abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1731abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMELFMCAsmInfo(); 1741abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1751abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 176be74029f44c32efc09274a16cbff588ad10dc5eaEvan Chengstatic MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 177b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng CodeModel::Model CM, 178b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng CodeGenOpt::Level OL) { 179439661395fd2a2a832dba01c65bc88718528313cEvan Cheng MCCodeGenInfo *X = new MCCodeGenInfo(); 1806f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach if (RM == Reloc::Default) { 1816f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach Triple TheTriple(TT); 1826f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach // Default relocation model on Darwin is PIC, not DynamicNoPIC. 1836f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 1846f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach } 185b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng X->InitMCCodeGenInfo(RM, CM, OL); 186439661395fd2a2a832dba01c65bc88718528313cEvan Cheng return X; 187439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 188439661395fd2a2a832dba01c65bc88718528313cEvan Cheng 189be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng// This is duplicated code. Refactor this. 19028c85a81a17dd719a254dc00cbeb484774893197Evan Chengstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT, 19178c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng MCContext &Ctx, MCAsmBackend &MAB, 192be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng raw_ostream &OS, 193be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng MCCodeEmitter *Emitter, 194be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool RelaxAll, 195be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool NoExecStack) { 196be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng Triple TheTriple(TT); 197be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 198be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSDarwin()) 199fd03ccddedce13a216c9b6e04e9d0ca6b163170eJim Grosbach return createMachOStreamer(Ctx, MAB, OS, Emitter, false); 200be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 201be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSWindows()) { 202be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng llvm_unreachable("ARM does not support Windows COFF format"); 203be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng } 204be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2056eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, 2066eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover TheTriple.getArch() == Triple::thumb); 207be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng} 208be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2094b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Chengstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 2104b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng unsigned SyntaxVariant, 211b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const MCAsmInfo &MAI, 21217463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper const MCInstrInfo &MII, 213c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach const MCRegisterInfo &MRI, 214b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const MCSubtargetInfo &STI) { 2154b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng if (SyntaxVariant == 0) 21617463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper return new ARMInstPrinter(MAI, MII, MRI, STI); 2174b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng return 0; 2184b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng} 2194b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 220de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombetstatic MCRelocationInfo *createARMMCRelocationInfo(StringRef TT, 221de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet MCContext &Ctx) { 2222c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha Triple TheTriple(TT); 2232c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha if (TheTriple.isEnvironmentMachO()) 2242c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha return createARMMachORelocationInfo(Ctx); 2252c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // Default to the stock relocation info. 226de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet return llvm::createMCRelocationInfo(TT, Ctx); 2272c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha} 2282c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 22941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramernamespace { 23041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 23141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerclass ARMMCInstrAnalysis : public MCInstrAnalysis { 23241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerpublic: 23341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 23441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 23541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer virtual bool isUnconditionalBranch(const MCInst &Inst) const { 23641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // BCCs with the "always" predicate are unconditional branches. 23741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 23841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return true; 23941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return MCInstrAnalysis::isUnconditionalBranch(Inst); 24041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 24141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 24241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer virtual bool isConditionalBranch(const MCInst &Inst) const { 24341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // BCCs with the "always" predicate are unconditional branches. 24441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 24541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return false; 24641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return MCInstrAnalysis::isConditionalBranch(Inst); 24741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 24841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 249ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha bool evaluateBranch(const MCInst &Inst, uint64_t Addr, 250ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha uint64_t Size, uint64_t &Target) const { 25141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // We only handle PCRel branches for now. 25241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 253ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha return false; 25441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 25541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer int64_t Imm = Inst.getOperand(0).getImm(); 25641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // FIXME: This is not right for thumb. 257ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha Target = Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 258ef99356dfebb96f6f90efb912c2877214bad060eAhmed Bougacha return true; 25941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 26041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer}; 26141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 26241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer} 26341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 26441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerstatic MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 26541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return new ARMMCInstrAnalysis(Info); 26641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer} 267be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 268e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng// Force static initialization. 269e78085a3c03de648a481e9751c3094c517bd7123Evan Chengextern "C" void LLVMInitializeARMTargetMC() { 270e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC asm info. 271e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 272e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 273e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 274e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC codegen info. 275439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 276439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 277e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 278e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC instruction info. 279e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 280e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 281e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 282e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC register info. 283e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 284e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 285e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 286e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC subtarget info. 287e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 288e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 289e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 290e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 291be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2927801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng // Register the MC instruction analyzer. 2937801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng TargetRegistry::RegisterMCInstrAnalysis(TheARMTarget, 2947801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng createARMMCInstrAnalysis); 2957801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget, 2967801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng createARMMCInstrAnalysis); 2977801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng 298be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the MC Code Emitter 29928c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 30028c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 301be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 302be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the asm backend. 30378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); 30478c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); 305be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 306be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the object streamer. 30728c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); 30828c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); 3094b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 3104b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng // Register the MCInstPrinter. 3114b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 3124b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 3132c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha 3142c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha // Register the MC relocation info. 3152c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha TargetRegistry::RegisterMCRelocationInfo(TheARMTarget, 316de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet createARMMCRelocationInfo); 3172c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha TargetRegistry::RegisterMCRelocationInfo(TheThumbTarget, 318de7cbbfcce5c068f0699bdcb6dac093c0c91ba6fQuentin Colombet createARMMCRelocationInfo); 319439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 320