X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FMCTargetDesc%2FARMMCTargetDesc.cpp;h=b858fff546e33cce745186c96479204bf371f3c7;hb=4a971705bc6030dc2e4338b3cd5cffa2e0f88b7b;hp=6c4411850e22b73147d288685e24c0a4ad180d2f;hpb=78c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5c;p=oota-llvm.git diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 6c4411850e2..b858fff546e 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -1,4 +1,4 @@ -//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions -----------*- C++ -*-===// +//===-- ARMMCTargetDesc.cpp - ARM Target Descriptions ---------------------===// // // The LLVM Compiler Infrastructure // @@ -11,15 +11,20 @@ // //===----------------------------------------------------------------------===// -#include "ARMMCTargetDesc.h" +#include "ARMBaseInfo.h" +#include "ARMELFStreamer.h" #include "ARMMCAsmInfo.h" +#include "ARMMCTargetDesc.h" #include "InstPrinter/ARMInstPrinter.h" +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Target/TargetRegistry.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TargetRegistry.h" #define GET_REGINFO_MC_DESC #include "ARMGenRegisterInfo.inc" @@ -32,13 +37,15 @@ using namespace llvm; -std::string ARM_MC::ParseARMTriple(StringRef TT) { +std::string ARM_MC::ParseARMTriple(StringRef TT, StringRef CPU) { + Triple triple(TT); + // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. unsigned Len = TT.size(); unsigned Idx = 0; - // FIXME: Enahnce Triple helper class to extract ARM version. + // FIXME: Enhance Triple helper class to extract ARM version. bool isThumb = false; if (Len >= 5 && TT.substr(0, 4) == "armv") Idx = 4; @@ -48,24 +55,56 @@ std::string ARM_MC::ParseARMTriple(StringRef TT) { Idx = 6; } + bool NoCPU = CPU == "generic" || CPU.empty(); std::string ARMArchFeature; if (Idx) { unsigned SubVer = TT[Idx]; if (SubVer >= '7' && SubVer <= '9') { if (Len >= Idx+2 && TT[Idx+1] == 'm') { - // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv - ARMArchFeature = "+v7,+noarm,+db,+hwdiv"; + if (NoCPU) + // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass + ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') { - // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, - // FeatureT2XtPk - ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk"; - } else - // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2 - ARMArchFeature = "+v7,+neon,+db,+t2dsp"; + if (NoCPU) + // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2, + // FeatureT2XtPk, FeatureMClass + ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + } else if (Len >= Idx+2 && TT[Idx+1] == 's') { + if (NoCPU) + // v7s: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk + // Swift + ARMArchFeature = "+v7,+swift,+neon,+db,+t2dsp,+t2xtpk"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + } else { + // v7 CPUs have lots of different feature sets. If no CPU is specified, + // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return + // the "minimum" feature set and use CPU string to figure out the exact + // features. + if (NoCPU) + // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk + ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; + else + // Use CPU to figure out the exact features. + ARMArchFeature = "+v7"; + } } else if (SubVer == '6') { if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') ARMArchFeature = "+v6t2"; - else + else if (Len >= Idx+2 && TT[Idx+1] == 'm') { + if (NoCPU) + // v6m: FeatureNoARM, FeatureMClass + ARMArchFeature = "+v6,+noarm,+mclass"; + else + ARMArchFeature = "+v6"; + } else ARMArchFeature = "+v6"; } else if (SubVer == '5') { if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') @@ -83,12 +122,19 @@ std::string ARM_MC::ParseARMTriple(StringRef TT) { ARMArchFeature += ",+thumb-mode"; } + if (triple.isOSNaCl()) { + if (ARMArchFeature.empty()) + ARMArchFeature = "+nacl-trap"; + else + ARMArchFeature += ",+nacl-trap"; + } + return ARMArchFeature; } MCSubtargetInfo *ARM_MC::createARMMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { - std::string ArchFS = ARM_MC::ParseARMTriple(TT); + std::string ArchFS = ARM_MC::ParseARMTriple(TT, CPU); if (!FS.empty()) { if (!ArchFS.empty()) ArchFS = ArchFS + "," + FS.str(); @@ -109,11 +155,11 @@ static MCInstrInfo *createARMMCInstrInfo() { static MCRegisterInfo *createARMMCRegisterInfo(StringRef Triple) { MCRegisterInfo *X = new MCRegisterInfo(); - InitARMMCRegisterInfo(X, ARM::LR); + InitARMMCRegisterInfo(X, ARM::LR, 0, 0, ARM::PC); return X; } -static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { +static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) { Triple TheTriple(TT); if (TheTriple.isOSDarwin()) @@ -123,16 +169,20 @@ static MCAsmInfo *createARMMCAsmInfo(const Target &T, StringRef TT) { } static MCCodeGenInfo *createARMMCCodeGenInfo(StringRef TT, Reloc::Model RM, - CodeModel::Model CM) { + CodeModel::Model CM, + CodeGenOpt::Level OL) { MCCodeGenInfo *X = new MCCodeGenInfo(); - if (RM == Reloc::Default) - RM = Reloc::DynamicNoPIC; - X->InitMCCodeGenInfo(RM, CM); + if (RM == Reloc::Default) { + Triple TheTriple(TT); + // Default relocation model on Darwin is PIC, not DynamicNoPIC. + RM = TheTriple.isOSDarwin() ? Reloc::PIC_ : Reloc::DynamicNoPIC; + } + X->InitMCCodeGenInfo(RM, CM, OL); return X; } // This is duplicated code. Refactor this. -static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, +static MCStreamer *createMCStreamer(const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &MAB, raw_ostream &OS, MCCodeEmitter *Emitter, @@ -141,24 +191,64 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, Triple TheTriple(TT); if (TheTriple.isOSDarwin()) - return createMachOStreamer(Ctx, MAB, OS, Emitter, RelaxAll); + return createMachOStreamer(Ctx, MAB, OS, Emitter, false); if (TheTriple.isOSWindows()) { llvm_unreachable("ARM does not support Windows COFF format"); - return NULL; } - return createELFStreamer(Ctx, MAB, OS, Emitter, RelaxAll, NoExecStack); + return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, + TheTriple.getArch() == Triple::thumb); } static MCInstPrinter *createARMMCInstPrinter(const Target &T, unsigned SyntaxVariant, - const MCAsmInfo &MAI) { + const MCAsmInfo &MAI, + const MCInstrInfo &MII, + const MCRegisterInfo &MRI, + const MCSubtargetInfo &STI) { if (SyntaxVariant == 0) - return new ARMInstPrinter(MAI); + return new ARMInstPrinter(MAI, MII, MRI, STI); return 0; } +namespace { + +class ARMMCInstrAnalysis : public MCInstrAnalysis { +public: + ARMMCInstrAnalysis(const MCInstrInfo *Info) : MCInstrAnalysis(Info) {} + + virtual bool isUnconditionalBranch(const MCInst &Inst) const { + // BCCs with the "always" predicate are unconditional branches. + if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) + return true; + return MCInstrAnalysis::isUnconditionalBranch(Inst); + } + + virtual bool isConditionalBranch(const MCInst &Inst) const { + // BCCs with the "always" predicate are unconditional branches. + if (Inst.getOpcode() == ARM::Bcc && Inst.getOperand(1).getImm()==ARMCC::AL) + return false; + return MCInstrAnalysis::isConditionalBranch(Inst); + } + + uint64_t evaluateBranch(const MCInst &Inst, uint64_t Addr, + uint64_t Size) const { + // We only handle PCRel branches for now. + if (Info->get(Inst.getOpcode()).OpInfo[0].OperandType!=MCOI::OPERAND_PCREL) + return -1ULL; + + int64_t Imm = Inst.getOperand(0).getImm(); + // FIXME: This is not right for thumb. + return Addr+Imm+8; // In ARM mode the PC is always off by 8 bytes. + } +}; + +} + +static MCInstrAnalysis *createARMMCInstrAnalysis(const MCInstrInfo *Info) { + return new ARMMCInstrAnalysis(Info); +} // Force static initialization. extern "C" void LLVMInitializeARMTargetMC() { @@ -184,17 +274,23 @@ extern "C" void LLVMInitializeARMTargetMC() { TargetRegistry::RegisterMCSubtargetInfo(TheThumbTarget, ARM_MC::createARMMCSubtargetInfo); + // Register the MC instruction analyzer. + TargetRegistry::RegisterMCInstrAnalysis(TheARMTarget, + createARMMCInstrAnalysis); + TargetRegistry::RegisterMCInstrAnalysis(TheThumbTarget, + createARMMCInstrAnalysis); + // Register the MC Code Emitter - TargetRegistry::RegisterCodeEmitter(TheARMTarget, createARMMCCodeEmitter); - TargetRegistry::RegisterCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheARMTarget, createARMMCCodeEmitter); + TargetRegistry::RegisterMCCodeEmitter(TheThumbTarget, createARMMCCodeEmitter); // Register the asm backend. TargetRegistry::RegisterMCAsmBackend(TheARMTarget, createARMAsmBackend); TargetRegistry::RegisterMCAsmBackend(TheThumbTarget, createARMAsmBackend); // Register the object streamer. - TargetRegistry::RegisterObjectStreamer(TheARMTarget, createMCStreamer); - TargetRegistry::RegisterObjectStreamer(TheThumbTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheARMTarget, createMCStreamer); + TargetRegistry::RegisterMCObjectStreamer(TheThumbTarget, createMCStreamer); // Register the MCInstPrinter. TargetRegistry::RegisterMCInstPrinter(TheARMTarget, createARMMCInstPrinter);