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