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]; 6294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (SubVer >= '7' && SubVer <= '9') { 6394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= Idx+2 && TT[Idx+1] == 'm') { 6497a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 6597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass 6697a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; 6797a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 6897a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // Use CPU to figure out the exact features. 6997a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7"; 7094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 7197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 7297a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 7397a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // FeatureT2XtPk, FeatureMClass 7497a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; 7597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 7697a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // Use CPU to figure out the exact features. 7797a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v7"; 78eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson } else if (Len >= Idx+2 && TT[Idx+1] == 's') { 79eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson if (NoCPU) 80eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 81eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // Swift 82eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+t2xtpk"; 83eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson else 84eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson // Use CPU to figure out the exact features. 85eb1641d54a7eda7717304bc4d55d059208d8ebedBob Wilson ARMArchFeature = "+v7"; 86e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng } else { 87e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // v7 CPUs have lots of different feature sets. If no CPU is specified, 88e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return 89e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // the "minimum" feature set and use CPU string to figure out the exact 90e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // features. 9197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 92e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 93e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; 94e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng else 95e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng // Use CPU to figure out the exact features. 96e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng ARMArchFeature = "+v7"; 97e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng } 9894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '6') { 99f06dfa786064edc3bb6de92bb3783d0c23f4d34aJim Grosbach if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 10094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v6t2"; 10197a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else if (Len >= Idx+2 && TT[Idx+1] == 'm') { 10297a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng if (NoCPU) 10397a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng // v6m: FeatureNoARM, FeatureMClass 10497a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v6,+noarm,+mclass"; 10597a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng else 10697a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng ARMArchFeature = "+v6"; 10797a454317af1903b269d42d368d2263ab79b6ed1Evan Cheng } else 10839dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v6"; 10994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '5') { 11039dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 11194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v5te"; 11239dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng else 11339dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v5t"; 11439dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 11539dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v4t"; 11694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 11794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 118db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (isThumb) { 119db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (ARMArchFeature.empty()) 120963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature = "+thumb-mode"; 121db068738e806753bc5735434cab9b9f930840c7aEvan Cheng else 122963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature += ",+thumb-mode"; 123db068738e806753bc5735434cab9b9f930840c7aEvan Cheng } 124db068738e806753bc5735434cab9b9f930840c7aEvan Cheng 1250f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky if (triple.isOSNaCl()) { 1260f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky if (ARMArchFeature.empty()) 1270f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky ARMArchFeature = "+nacl-trap"; 1280f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky else 1290f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky ARMArchFeature += ",+nacl-trap"; 1300f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky } 1310f156af8312a0f3ce88e5c006bf2a52691039cebEli Bendersky 13294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng return ARMArchFeature; 13394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng} 134ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 135ebdeeab812beec0385b445f3d4c41a114e0d972fEvan ChengMCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 136ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef FS) { 137e67a4163f5d2ad8e42a3aa0ccdaa27d85f6d5be4Evan Cheng std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 138ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!FS.empty()) { 139ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!ArchFS.empty()) 140ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = ArchFS + "," + FS.str(); 141ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng else 142ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = FS; 143ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 144ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 145ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCSubtargetInfo *X = new MCSubtargetInfo(); 14659ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 147ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 148ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 149ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1501abf2cb59b8d63415780a03329307c0997b2670cEvan Chengstatic MCInstrInfo *createARMMCInstrInfo() { 1511abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCInstrInfo *X = new MCInstrInfo(); 1521abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng InitARMMCInstrInfo(X); 153ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 154ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 155ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1560e6a052331f674dd70e28af41f654a7874405eabEvan Chengstatic MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 1571abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCRegisterInfo *X = new MCRegisterInfo(); 158fbf3b4a07690751f72302757058ab0298dfb832eJim Grosbach InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 1591abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return X; 1601abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1611abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1621be0e271a07925b928ba89848934f1ea6f1854e2Evan Chengstatic MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { 1631abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng Triple TheTriple(TT); 1641abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1651abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng if (TheTriple.isOSDarwin()) 1661abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMMCAsmInfoDarwin(); 1671abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1681abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMELFMCAsmInfo(); 1691abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1701abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 171be74029f44c32efc09274a16cbff588ad10dc5eaEvan Chengstatic MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 172b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng CodeModel::Model CM, 173b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng CodeGenOpt::Level OL) { 174439661395fd2a2a832dba01c65bc88718528313cEvan Cheng MCCodeGenInfo *X = new MCCodeGenInfo(); 1756f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach if (RM == Reloc::Default) { 1766f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach Triple TheTriple(TT); 1776f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach // Default relocation model on Darwin is PIC, not DynamicNoPIC. 1786f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 1796f09fcf5dae14d68ec9f8731b8c91c04868532e2Jim Grosbach } 180b95fc31aa2e5a0a0b9ee1909d1cb949577c5aa16Evan Cheng X->InitMCCodeGenInfo(RM, CM, OL); 181439661395fd2a2a832dba01c65bc88718528313cEvan Cheng return X; 182439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 183439661395fd2a2a832dba01c65bc88718528313cEvan Cheng 184be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng// This is duplicated code. Refactor this. 18528c85a81a17dd719a254dc00cbeb484774893197Evan Chengstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT, 18678c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng MCContext &Ctx, MCAsmBackend &MAB, 187be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng raw_ostream &OS, 188be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng MCCodeEmitter *Emitter, 189be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool RelaxAll, 190be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool NoExecStack) { 191be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng Triple TheTriple(TT); 192be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 193be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSDarwin()) 194fd03ccddedce13a216c9b6e04e9d0ca6b163170eJim Grosbach return createMachOStreamer(Ctx, MAB, OS, Emitter, false); 195be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 196be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSWindows()) { 197be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng llvm_unreachable("ARM does not support Windows COFF format"); 198be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng } 199be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2006eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, 2016eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover TheTriple.getArch() == Triple::thumb); 202be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng} 203be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2044b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Chengstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 2054b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng unsigned SyntaxVariant, 206b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const MCAsmInfo &MAI, 20717463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper const MCInstrInfo &MII, 208c6449b636f4984be88f128d0375c056ad05e7e8fJim Grosbach const MCRegisterInfo &MRI, 209b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy const MCSubtargetInfo &STI) { 2104b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng if (SyntaxVariant == 0) 21117463b3ef1a3d39b10619254f12e806c8c43f9e7Craig Topper return new ARMInstPrinter(MAI, MII, MRI, STI); 2124b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng return 0; 2134b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng} 2144b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 21541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramernamespace { 21641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 21741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerclass ARMMCInstrAnalysis : public MCInstrAnalysis { 21841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerpublic: 21941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 22041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 22141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer virtual bool isUnconditionalBranch(const MCInst &Inst) const { 22241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // BCCs with the "always" predicate are unconditional branches. 22341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 22441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return true; 22541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return MCInstrAnalysis::isUnconditionalBranch(Inst); 22641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 22741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 22841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer virtual bool isConditionalBranch(const MCInst &Inst) const { 22941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // BCCs with the "always" predicate are unconditional branches. 23041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 23141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return false; 23241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return MCInstrAnalysis::isConditionalBranch(Inst); 23341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 23441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 23541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer uint64_t evaluateBranch(const MCInst &Inst, uint64_t Addr, 23641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer uint64_t Size) const { 23741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // We only handle PCRel branches for now. 23841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 23941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return -1ULL; 24041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 24141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer int64_t Imm = Inst.getOperand(0).getImm(); 24241ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer // FIXME: This is not right for thumb. 24341ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 24441ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer } 24541ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer}; 24641ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 24741ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer} 24841ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer 24941ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramerstatic MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 25041ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer return new ARMMCInstrAnalysis(Info); 25141ab14b725c8f2bb3e54553d0d7d96ff184786b1Benjamin Kramer} 252be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 253e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng// Force static initialization. 254e78085a3c03de648a481e9751c3094c517bd7123Evan Chengextern "C" void LLVMInitializeARMTargetMC() { 255e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC asm info. 256e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 257e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 258e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 259e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC codegen info. 260439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 261439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 262e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 263e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC instruction info. 264e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 265e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 266e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 267e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC register info. 268e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 269e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 270e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 271e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC subtarget info. 272e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 273e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 274e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 275e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 276be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 2777801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng // Register the MC instruction analyzer. 2787801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng TargetRegistry::RegisterMCInstrAnalysis(TheARMTarget, 2797801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng createARMMCInstrAnalysis); 2807801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget, 2817801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng createARMMCInstrAnalysis); 2827801136b95d1fbe515b9655b73ada39b05a33559Evan Cheng 283be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the MC Code Emitter 28428c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 28528c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 286be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 287be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the asm backend. 28878c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); 28978c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); 290be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 291be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the object streamer. 29228c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); 29328c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); 2944b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 2954b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng // Register the MCInstPrinter. 2964b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 2974b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 298439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 299