ARMMCTargetDesc.cpp revision fbf3b4a07690751f72302757058ab0298dfb832e
1//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// 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 "ARMELFStreamer.h" 16#include "ARMMCAsmInfo.h" 17#include "ARMBaseInfo.h" 18#include "ARMMCAsmInfo.h" 19#include "InstPrinter/ARMInstPrinter.h" 20#include "llvm/MC/MCCodeGenInfo.h" 21#include "llvm/MC/MCInstrAnalysis.h" 22#include "llvm/MC/MCInstrInfo.h" 23#include "llvm/MC/MCRegisterInfo.h" 24#include "llvm/MC/MCStreamer.h" 25#include "llvm/MC/MCSubtargetInfo.h" 26#include "llvm/Support/ErrorHandling.h" 27#include "llvm/Support/TargetRegistry.h" 28 29#define GET_REGINFO_MC_DESC 30#include "ARMGenRegisterInfo.inc" 31 32#define GET_INSTRINFO_MC_DESC 33#include "ARMGenInstrInfo.inc" 34 35#define GET_SUBTARGETINFO_MC_DESC 36#include "ARMGenSubtargetInfo.inc" 37 38using namespace llvm; 39 40std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { 41 // Set the boolean corresponding to the current target triple, or the default 42 // if one cannot be determined, to true. 43 unsigned Len = TT.size(); 44 unsigned Idx = 0; 45 46 // FIXME: Enhance Triple helper class to extract ARM version. 47 bool isThumb = false; 48 if (Len >= 5 && TT.substr(0, 4) == "armv") 49 Idx = 4; 50 else if (Len >= 6 && TT.substr(0, 5) == "thumb") { 51 isThumb = true; 52 if (Len >= 7 && TT[5] == 'v') 53 Idx = 6; 54 } 55 56 bool NoCPU = CPU == "generic" || CPU.empty(); 57 std::string ARMArchFeature; 58 if (Idx) { 59 unsigned SubVer = TT[Idx]; 60 if (SubVer >= '7' && SubVer <= '9') { 61 if (Len >= Idx+2 && TT[Idx+1] == 'm') { 62 if (NoCPU) 63 // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass 64 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; 65 else 66 // Use CPU to figure out the exact features. 67 ARMArchFeature = "+v7"; 68 } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { 69 if (NoCPU) 70 // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, 71 // FeatureT2XtPk, FeatureMClass 72 ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; 73 else 74 // Use CPU to figure out the exact features. 75 ARMArchFeature = "+v7"; 76 } else if (Len >= Idx+2 && TT[Idx+1] == 's') { 77 if (NoCPU) 78 // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 79 // Swift 80 ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+t2xtpk"; 81 else 82 // Use CPU to figure out the exact features. 83 ARMArchFeature = "+v7"; 84 } else { 85 // v7 CPUs have lots of different feature sets. If no CPU is specified, 86 // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return 87 // the "minimum" feature set and use CPU string to figure out the exact 88 // features. 89 if (NoCPU) 90 // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk 91 ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; 92 else 93 // Use CPU to figure out the exact features. 94 ARMArchFeature = "+v7"; 95 } 96 } else if (SubVer == '6') { 97 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') 98 ARMArchFeature = "+v6t2"; 99 else if (Len >= Idx+2 && TT[Idx+1] == 'm') { 100 if (NoCPU) 101 // v6m: FeatureNoARM, FeatureMClass 102 ARMArchFeature = "+v6,+noarm,+mclass"; 103 else 104 ARMArchFeature = "+v6"; 105 } else 106 ARMArchFeature = "+v6"; 107 } else if (SubVer == '5') { 108 if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') 109 ARMArchFeature = "+v5te"; 110 else 111 ARMArchFeature = "+v5t"; 112 } else if (SubVer == '4' && Len >= Idx+2 && TT[Idx+1] == 't') 113 ARMArchFeature = "+v4t"; 114 } 115 116 if (isThumb) { 117 if (ARMArchFeature.empty()) 118 ARMArchFeature = "+thumb-mode"; 119 else 120 ARMArchFeature += ",+thumb-mode"; 121 } 122 123 return ARMArchFeature; 124} 125 126MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, 127 StringRef FS) { 128 std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); 129 if (!FS.empty()) { 130 if (!ArchFS.empty()) 131 ArchFS = ArchFS + "," + FS.str(); 132 else 133 ArchFS = FS; 134 } 135 136 MCSubtargetInfo *X = new MCSubtargetInfo(); 137 InitARMMCSubtargetInfo(X, TT, CPU, ArchFS); 138 return X; 139} 140 141static MCInstrInfo *createARMMCInstrInfo() { 142 MCInstrInfo *X = new MCInstrInfo(); 143 InitARMMCInstrInfo(X); 144 return X; 145} 146 147static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { 148 MCRegisterInfo *X = new MCRegisterInfo(); 149 InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); 150 return X; 151} 152 153static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { 154 Triple TheTriple(TT); 155 156 if (TheTriple.isOSDarwin()) 157 return new ARMMCAsmInfoDarwin(); 158 159 return new ARMELFMCAsmInfo(); 160} 161 162static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, 163 CodeModel::Model CM, 164 CodeGenOpt::Level OL) { 165 MCCodeGenInfo *X = new MCCodeGenInfo(); 166 if (RM == Reloc::Default) { 167 Triple TheTriple(TT); 168 // Default relocation model on Darwin is PIC, not DynamicNoPIC. 169 RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; 170 } 171 X->InitMCCodeGenInfo(RM, CM, OL); 172 return X; 173} 174 175// This is duplicated code. Refactor this. 176static MCStreamer *createMCStreamer(const Target &T, StringRef TT, 177 MCContext &Ctx, MCAsmBackend &MAB, 178 raw_ostream &OS, 179 MCCodeEmitter *Emitter, 180 bool RelaxAll, 181 bool NoExecStack) { 182 Triple TheTriple(TT); 183 184 if (TheTriple.isOSDarwin()) 185 return createMachOStreamer(Ctx, MAB, OS, Emitter, false); 186 187 if (TheTriple.isOSWindows()) { 188 llvm_unreachable("ARM does not support Windows COFF format"); 189 } 190 191 return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, 192 TheTriple.getArch() == Triple::thumb); 193} 194 195static MCInstPrinter *createARMMCInstPrinter(const Target &T, 196 unsigned SyntaxVariant, 197 const MCAsmInfo &MAI, 198 const MCInstrInfo &MII, 199 const MCRegisterInfo &MRI, 200 const MCSubtargetInfo &STI) { 201 if (SyntaxVariant == 0) 202 return new ARMInstPrinter(MAI, MII, MRI, STI); 203 return 0; 204} 205 206namespace { 207 208class ARMMCInstrAnalysis : public MCInstrAnalysis { 209public: 210 ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} 211 212 virtual bool isUnconditionalBranch(const MCInst &Inst) const { 213 // BCCs with the "always" predicate are unconditional branches. 214 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 215 return true; 216 return MCInstrAnalysis::isUnconditionalBranch(Inst); 217 } 218 219 virtual bool isConditionalBranch(const MCInst &Inst) const { 220 // BCCs with the "always" predicate are unconditional branches. 221 if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) 222 return false; 223 return MCInstrAnalysis::isConditionalBranch(Inst); 224 } 225 226 uint64_t evaluateBranch(const MCInst &Inst, uint64_t Addr, 227 uint64_t Size) const { 228 // We only handle PCRel branches for now. 229 if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) 230 return -1ULL; 231 232 int64_t Imm = Inst.getOperand(0).getImm(); 233 // FIXME: This is not right for thumb. 234 return Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. 235 } 236}; 237 238} 239 240static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { 241 return new ARMMCInstrAnalysis(Info); 242} 243 244// Force static initialization. 245extern "C" void LLVMInitializeARMTargetMC() { 246 // Register the MC asm info. 247 RegisterMCAsmInfoFn A(TheARMTarget, createARMMCAsmInfo); 248 RegisterMCAsmInfoFn B(TheThumbTarget, createARMMCAsmInfo); 249 250 // Register the MC codegen info. 251 TargetRegistry::RegisterMCCodeGenInfo(TheARMTarget, createARMMCCodeGenInfo); 252 TargetRegistry::RegisterMCCodeGenInfo(TheThumbTarget, createARMMCCodeGenInfo); 253 254 // Register the MC instruction info. 255 TargetRegistry::RegisterMCInstrInfo(TheARMTarget, createARMMCInstrInfo); 256 TargetRegistry::RegisterMCInstrInfo(TheThumbTarget, createARMMCInstrInfo); 257 258 // Register the MC register info. 259 TargetRegistry::RegisterMCRegInfo(TheARMTarget, createARMMCRegisterInfo); 260 TargetRegistry::RegisterMCRegInfo(TheThumbTarget, createARMMCRegisterInfo); 261 262 // Register the MC subtarget info. 263 TargetRegistry::RegisterMCSubtargetInfo(TheARMTarget, 264 ARM_MC::createARMMCSubtargetInfo); 265 TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, 266 ARM_MC::createARMMCSubtargetInfo); 267 268 // Register the MC instruction analyzer. 269 TargetRegistry::RegisterMCInstrAnalysis(TheARMTarget, 270 createARMMCInstrAnalysis); 271 TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget, 272 createARMMCInstrAnalysis); 273 274 // Register the MC Code Emitter 275 TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); 276 TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); 277 278 // Register the asm backend. 279 TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); 280 TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); 281 282 // Register the object streamer. 283 TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); 284 TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); 285 286 // Register the MCInstPrinter. 287 TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter); 288 TargetRegistry::RegisterMCInstPrinter(TheThumbTarget, createARMMCInstPrinter); 289} 290