ARMMCTargetDesc.cpp revision 28c85a81a17dd719a254dc00cbeb484774893197
178a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions -----------*- C++ -*-===// 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 1478a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMMCTargetDesc.h" 151abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng#include "ARMMCAsmInfo.h" 164b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng#include "InstPrinter/ARMInstPrinter.h" 1778a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCInstrInfo.h" 1878a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 19be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/MC/MCStreamer.h" 2078a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/MC/MCSubtargetInfo.h" 2178a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "llvm/Target/TargetRegistry.h" 22be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "llvm/Support/ErrorHandling.h" 2378a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 2478a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_REGINFO_MC_DESC 2578a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenRegisterInfo.inc" 2678a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 2778a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_INSTRINFO_MC_DESC 2878a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenInstrInfo.inc" 2978a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 3078a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#define GET_SUBTARGETINFO_MC_DESC 3178a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng#include "ARMGenSubtargetInfo.inc" 3278a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 3378a9f138ae95458bf6d922f38706eed045691d5aEvan Chengusing namespace llvm; 3478a9f138ae95458bf6d922f38706eed045691d5aEvan Cheng 35db068738e806753bc5735434cab9b9f930840c7aEvan Chengstd::string ARM_MC::ParseARMTriple(StringRef TT) { 3694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // Set the boolean corresponding to the current target triple, or the default 3794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng // if one cannot be determined, to true. 3894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned Len = TT.size(); 3994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned Idx = 0; 4094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 41963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng // FIXME: Enahnce Triple helper class to extract ARM version. 42db068738e806753bc5735434cab9b9f930840c7aEvan Cheng bool isThumb = false; 4394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= 5 && TT.substr(0, 4) == "armv") 4494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng Idx = 4; 4594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 46db068738e806753bc5735434cab9b9f930840c7aEvan Cheng isThumb = true; 4794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= 7 && TT[5] == 'v') 4894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng Idx = 6; 4994ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 5094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 5194ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng std::string ARMArchFeature; 5294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Idx) { 5394ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng unsigned SubVer = TT[Idx]; 5494ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (SubVer >= '7' && SubVer <= '9') { 5594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng if (Len >= Idx+2 && TT[Idx+1] == 'm') { 5639dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv 5739dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv"; 5894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 5939dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 6039dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng // FeatureT2XtPk 6139dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk"; 6239dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng } else 6339dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2 6439dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v7,+neon,+db,+t2dsp"; 6594ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '6') { 6639dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 6794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v6t2"; 6839dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng else 6939dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v6"; 7094ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } else if (SubVer == '5') { 7139dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 7294ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng ARMArchFeature = "+v5te"; 7339dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng else 7439dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v5t"; 7539dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 7639dfb0ff848be6b380ca81ff95d4ca4e0ae09c76Evan Cheng ARMArchFeature = "+v4t"; 7794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng } 7894ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng 79db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (isThumb) { 80db068738e806753bc5735434cab9b9f930840c7aEvan Cheng if (ARMArchFeature.empty()) 81963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature = "+thumb-mode"; 82db068738e806753bc5735434cab9b9f930840c7aEvan Cheng else 83963b03c1a9f6a9742671459f103ee9a566c6de58Evan Cheng ARMArchFeature += ",+thumb-mode"; 84db068738e806753bc5735434cab9b9f930840c7aEvan Cheng } 85db068738e806753bc5735434cab9b9f930840c7aEvan Cheng 8694ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng return ARMArchFeature; 8794ca42ff0407d71bacc41de4032d8dbe6358d33dEvan Cheng} 88ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 89ebdeeab812beec0385b445f3d4c41a114e0d972fEvan ChengMCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 90ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng StringRef FS) { 91ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng std::string ArchFS = ARM_MC::ParseARMTriple(TT); 92ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!FS.empty()) { 93ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng if (!ArchFS.empty()) 94ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = ArchFS + "," + FS.str(); 95ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng else 96ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng ArchFS = FS; 97ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng } 98ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 99ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng MCSubtargetInfo *X = new MCSubtargetInfo(); 10059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 101ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 102ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 103ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1041abf2cb59b8d63415780a03329307c0997b2670cEvan Chengstatic MCInstrInfo *createARMMCInstrInfo() { 1051abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCInstrInfo *X = new MCInstrInfo(); 1061abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng InitARMMCInstrInfo(X); 107ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng return X; 108ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng} 109ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng 1100e6a052331f674dd70e28af41f654a7874405eabEvan Chengstatic MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 1111abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng MCRegisterInfo *X = new MCRegisterInfo(); 1120e6a052331f674dd70e28af41f654a7874405eabEvan Cheng InitARMMCRegisterInfo(X, ARM::LR); 1131abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return X; 1141abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1151abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1161be0e271a07925b928ba89848934f1ea6f1854e2Evan Chengstatic MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { 1171abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng Triple TheTriple(TT); 1181abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1191abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng if (TheTriple.isOSDarwin()) 1201abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMMCAsmInfoDarwin(); 1211abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 1221abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng return new ARMELFMCAsmInfo(); 1231abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng} 1241abf2cb59b8d63415780a03329307c0997b2670cEvan Cheng 125be74029f44c32efc09274a16cbff588ad10dc5eaEvan Chengstatic MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 126be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng CodeModel::Model CM) { 127439661395fd2a2a832dba01c65bc88718528313cEvan Cheng MCCodeGenInfo *X = new MCCodeGenInfo(); 128439661395fd2a2a832dba01c65bc88718528313cEvan Cheng if (RM == Reloc::Default) 129439661395fd2a2a832dba01c65bc88718528313cEvan Cheng RM = Reloc::DynamicNoPIC; 13034ad6db8b958fdc0d38e122edf753b5326e69b03Evan Cheng X->InitMCCodeGenInfo(RM, CM); 131439661395fd2a2a832dba01c65bc88718528313cEvan Cheng return X; 132439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 133439661395fd2a2a832dba01c65bc88718528313cEvan Cheng 134be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng// This is duplicated code. Refactor this. 13528c85a81a17dd719a254dc00cbeb484774893197Evan Chengstatic MCStreamer *createMCStreamer(const Target &T, StringRef TT, 13678c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng MCContext &Ctx, MCAsmBackend &MAB, 137be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng raw_ostream &OS, 138be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng MCCodeEmitter *Emitter, 139be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool RelaxAll, 140be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng bool NoExecStack) { 141be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng Triple TheTriple(TT); 142be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 143be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSDarwin()) 14478c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll); 145be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 146be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng if (TheTriple.isOSWindows()) { 147be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng llvm_unreachable("ARM does not support Windows COFF format"); 148be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng return NULL; 149be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng } 150be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 15178c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); 152be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng} 153be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 1544b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Chengstatic MCInstPrinter *createARMMCInstPrinter(const Target &T, 1554b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng unsigned SyntaxVariant, 1564b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng const MCAsmInfo &MAI) { 1574b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng if (SyntaxVariant == 0) 1584b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng return new ARMInstPrinter(MAI); 1594b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng return 0; 1604b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng} 1614b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 162be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 163e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng// Force static initialization. 164e78085a3c03de648a481e9751c3094c517bd7123Evan Chengextern "C" void LLVMInitializeARMTargetMC() { 165e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC asm info. 166e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 167e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 168e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 169e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC codegen info. 170439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 171439661395fd2a2a832dba01c65bc88718528313cEvan Cheng TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 172e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 173e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC instruction info. 174e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 175e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 176e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 177e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC register info. 178e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 179e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 180e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng 181e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng // Register the MC subtarget info. 182e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 183e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 184e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 185e78085a3c03de648a481e9751c3094c517bd7123Evan Cheng ARM_MC::createARMMCSubtargetInfo); 186be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 187be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the MC Code Emitter 18828c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 18928c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 190be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 191be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the asm backend. 19278c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); 19378c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); 194be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng 195be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng // Register the object streamer. 19628c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); 19728c85a81a17dd719a254dc00cbeb484774893197Evan Cheng TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); 1984b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng 1994b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng // Register the MCInstPrinter. 2004b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 2014b64e8a9e13ba782da2034e1dee52f077bdb759cEvan Cheng TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 202439661395fd2a2a832dba01c65bc88718528313cEvan Cheng} 203