ARMMCTargetDesc.cpp revision 4b64e8a9e13ba782da2034e1dee52f077bdb759c
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 "InstPrinter/ARMInstPrinter.h" 17#include "llvm/MC/MCInstrInfo.h" 18#include "llvm/MC/MCRegisterInfo.h" 19#include "llvm/MC/MCStreamer.h" 20#include "llvm/MC/MCSubtargetInfo.h" 21#include "llvm/Target/TargetRegistry.h" 22#include "llvm/Support/ErrorHandling.h" 23 24#define GET_REGINFO_MC_DESC 25#include "ARMGenRegisterInfo.inc" 26 27#define GET_INSTRINFO_MC_DESC 28#include "ARMGenInstrInfo.inc" 29 30#define GET_SUBTARGETINFO_MC_DESC 31#include "ARMGenSubtargetInfo.inc" 32 33using namespace llvm; 34 35std::string ARM_MC::ParseARMTriple(StringRef TT) { 36 // Set the boolean corresponding to the current target triple, or the default 37 // if one cannot be determined, to true. 38 unsigned Len = TT.size(); 39 unsigned Idx = 0; 40 41 // FIXME: Enahnce Triple helper class to extract ARM version. 42 bool isThumb = false; 43 if (Len >= 5 && TT.substr(0, 4) == "armv") 44 Idx = 4; 45 else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 46 isThumb = true; 47 if (Len >= 7 && TT[5] == 'v') 48 Idx = 6; 49 } 50 51 std::string ARMArchFeature; 52 if (Idx) { 53 unsigned SubVer = TT[Idx]; 54 if (SubVer >= '7' && SubVer <= '9') { 55 if (Len >= Idx+2 && TT[Idx+1] == 'm') { 56 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv 57 ARMArchFeature = "+v7,+noarm,+db,+hwdiv"; 58 } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 59 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 60 // FeatureT2XtPk 61 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk"; 62 } else 63 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2 64 ARMArchFeature = "+v7,+neon,+db,+t2dsp"; 65 } else if (SubVer == '6') { 66 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 67 ARMArchFeature = "+v6t2"; 68 else 69 ARMArchFeature = "+v6"; 70 } else if (SubVer == '5') { 71 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 72 ARMArchFeature = "+v5te"; 73 else 74 ARMArchFeature = "+v5t"; 75 } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 76 ARMArchFeature = "+v4t"; 77 } 78 79 if (isThumb) { 80 if (ARMArchFeature.empty()) 81 ARMArchFeature = "+thumb-mode"; 82 else 83 ARMArchFeature += ",+thumb-mode"; 84 } 85 86 return ARMArchFeature; 87} 88 89MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 90 StringRef FS) { 91 std::string ArchFS = ARM_MC::ParseARMTriple(TT); 92 if (!FS.empty()) { 93 if (!ArchFS.empty()) 94 ArchFS = ArchFS + "," + FS.str(); 95 else 96 ArchFS = FS; 97 } 98 99 MCSubtargetInfo *X = new MCSubtargetInfo(); 100 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 101 return X; 102} 103 104static MCInstrInfo *createARMMCInstrInfo() { 105 MCInstrInfo *X = new MCInstrInfo(); 106 InitARMMCInstrInfo(X); 107 return X; 108} 109 110static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 111 MCRegisterInfo *X = new MCRegisterInfo(); 112 InitARMMCRegisterInfo(X, ARM::LR); 113 return X; 114} 115 116static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { 117 Triple TheTriple(TT); 118 119 if (TheTriple.isOSDarwin()) 120 return new ARMMCAsmInfoDarwin(); 121 122 return new ARMELFMCAsmInfo(); 123} 124 125static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 126 CodeModel::Model CM) { 127 MCCodeGenInfo *X = new MCCodeGenInfo(); 128 if (RM == Reloc::Default) 129 RM = Reloc::DynamicNoPIC; 130 X->InitMCCodeGenInfo(RM, CM); 131 return X; 132} 133 134// This is duplicated code. Refactor this. 135static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, 136 MCContext &Ctx, TargetAsmBackend &TAB, 137 raw_ostream &OS, 138 MCCodeEmitter *Emitter, 139 bool RelaxAll, 140 bool NoExecStack) { 141 Triple TheTriple(TT); 142 143 if (TheTriple.isOSDarwin()) 144 return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll); 145 146 if (TheTriple.isOSWindows()) { 147 llvm_unreachable("ARM does not support Windows COFF format"); 148 return NULL; 149 } 150 151 return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack); 152} 153 154static MCInstPrinter *createARMMCInstPrinter(const Target &T, 155 unsigned SyntaxVariant, 156 const MCAsmInfo &MAI) { 157 if (SyntaxVariant == 0) 158 return new ARMInstPrinter(MAI); 159 return 0; 160} 161 162 163// Force static initialization. 164extern "C" void LLVMInitializeARMTargetMC() { 165 // Register the MC asm info. 166 RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 167 RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 168 169 // Register the MC codegen info. 170 TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 171 TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 172 173 // Register the MC instruction info. 174 TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 175 TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 176 177 // Register the MC register info. 178 TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 179 TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 180 181 // Register the MC subtarget info. 182 TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 183 ARM_MC::createARMMCSubtargetInfo); 184 TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 185 ARM_MC::createARMMCSubtargetInfo); 186 187 // Register the MC Code Emitter 188 TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 189 TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 190 191 // Register the asm backend. 192 TargetRegistry::RegisterAsmBackend(TheARMTarget, createARMAsmBackend); 193 TargetRegistry::RegisterAsmBackend(TheThumbTarget, createARMAsmBackend); 194 195 // Register the object streamer. 196 TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer); 197 TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer); 198 199 // Register the MCInstPrinter. 200 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 201 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 202} 203