1 //===-- ARMMCTargetDesc.cpp - ARM Target Descriptions -----------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides ARM specific target descriptions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMMCTargetDesc.h" 15 #include "ARMMCAsmInfo.h" 16 #include "llvm/MC/MCInstrInfo.h" 17 #include "llvm/MC/MCRegisterInfo.h" 18 #include "llvm/MC/MCSubtargetInfo.h" 19 #include "llvm/Target/TargetRegistry.h" 20 21 #define GET_REGINFO_MC_DESC 22 #include "ARMGenRegisterInfo.inc" 23 24 #define GET_INSTRINFO_MC_DESC 25 #include "ARMGenInstrInfo.inc" 26 27 #define GET_SUBTARGETINFO_MC_DESC 28 #include "ARMGenSubtargetInfo.inc" 29 30 using namespace llvm; 31 32 std::string ARM_MC::ParseARMTriple(StringRef TT) { 33 // Set the boolean corresponding to the current target triple, or the default 34 // if one cannot be determined, to true. 35 unsigned Len = TT.size(); 36 unsigned Idx = 0; 37 38 // FIXME: Enahnce Triple helper class to extract ARM version. 39 bool isThumb = false; 40 if (Len >= 5 && TT.substr(0, 4) == "armv") 41 Idx = 4; 42 else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 43 isThumb = true; 44 if (Len >= 7 && TT[5] == 'v') 45 Idx = 6; 46 } 47 48 std::string ARMArchFeature; 49 if (Idx) { 50 unsigned SubVer = TT[Idx]; 51 if (SubVer >= '7' && SubVer <= '9') { 52 if (Len >= Idx+2 && TT[Idx+1] == 'm') { 53 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv 54 ARMArchFeature = "+v7,+noarm,+db,+hwdiv"; 55 } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 56 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 57 // FeatureT2XtPk 58 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk"; 59 } else 60 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2 61 ARMArchFeature = "+v7,+neon,+db,+t2dsp"; 62 } else if (SubVer == '6') { 63 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 64 ARMArchFeature = "+v6t2"; 65 else 66 ARMArchFeature = "+v6"; 67 } else if (SubVer == '5') { 68 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 69 ARMArchFeature = "+v5te"; 70 else 71 ARMArchFeature = "+v5t"; 72 } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 73 ARMArchFeature = "+v4t"; 74 } 75 76 if (isThumb) { 77 if (ARMArchFeature.empty()) 78 ARMArchFeature = "+thumb-mode"; 79 else 80 ARMArchFeature += ",+thumb-mode"; 81 } 82 83 return ARMArchFeature; 84 } 85 86 MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 87 StringRef FS) { 88 std::string ArchFS = ARM_MC::ParseARMTriple(TT); 89 if (!FS.empty()) { 90 if (!ArchFS.empty()) 91 ArchFS = ArchFS + "," + FS.str(); 92 else 93 ArchFS = FS; 94 } 95 96 MCSubtargetInfo *X = new MCSubtargetInfo(); 97 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 98 return X; 99 } 100 101 // Force static initialization. 102 extern "C" void LLVMInitializeARMMCSubtargetInfo() { 103 TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 104 ARM_MC::createARMMCSubtargetInfo); 105 TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 106 ARM_MC::createARMMCSubtargetInfo); 107 } 108 109 static MCInstrInfo *createARMMCInstrInfo() { 110 MCInstrInfo *X = new MCInstrInfo(); 111 InitARMMCInstrInfo(X); 112 return X; 113 } 114 115 extern "C" void LLVMInitializeARMMCInstrInfo() { 116 TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 117 TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 118 } 119 120 static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 121 MCRegisterInfo *X = new MCRegisterInfo(); 122 InitARMMCRegisterInfo(X, ARM::LR); 123 return X; 124 } 125 126 extern "C" void LLVMInitializeARMMCRegisterInfo() { 127 TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 128 TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 129 } 130 131 static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { 132 Triple TheTriple(TT); 133 134 if (TheTriple.isOSDarwin()) 135 return new ARMMCAsmInfoDarwin(); 136 137 return new ARMELFMCAsmInfo(); 138 } 139 140 extern "C" void LLVMInitializeARMMCAsmInfo() { 141 // Register the target asm info. 142 RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 143 RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 144 } 145 146 MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM) { 147 MCCodeGenInfo *X = new MCCodeGenInfo(); 148 if (RM == Reloc::Default) 149 RM = Reloc::DynamicNoPIC; 150 X->InitMCCodeGenInfo(RM); 151 return X; 152 } 153 154 extern "C" void LLVMInitializeARMMCCodeGenInfo() { 155 TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 156 TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 157 } 158