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