diff options
Diffstat (limited to 'lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp')
-rw-r--r-- | lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 214 |
1 files changed, 163 insertions, 51 deletions
diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 694cf582f8d9..bb98c2bbef6d 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -22,6 +22,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCELFStreamer.h" +#include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" @@ -66,6 +67,12 @@ static cl::opt<bool> HexagonV55ArchVariant("mv55", cl::Hidden, cl::init(false), static cl::opt<bool> HexagonV60ArchVariant("mv60", cl::Hidden, cl::init(false), cl::desc("Build for Hexagon V60")); +static cl::opt<bool> HexagonV62ArchVariant("mv62", cl::Hidden, cl::init(false), + cl::desc("Build for Hexagon V62")); + +static cl::opt<bool> EnableHVX("mhvx", cl::Hidden, cl::init(false), + cl::desc("Enable Hexagon Vector Extension (HVX)")); + static StringRef DefaultArch = "hexagonv60"; static StringRef HexagonGetArchVariant() { @@ -77,6 +84,8 @@ static StringRef HexagonGetArchVariant() { return "hexagonv55"; if (HexagonV60ArchVariant) return "hexagonv60"; + if (HexagonV62ArchVariant) + return "hexagonv62"; return ""; } @@ -95,31 +104,16 @@ StringRef Hexagon_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) { return ArchV; } -MCInstrInfo *llvm::createHexagonMCInstrInfo() { - MCInstrInfo *X = new MCInstrInfo(); - InitHexagonMCInstrInfo(X); - return X; -} - -static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { - MCRegisterInfo *X = new MCRegisterInfo(); - InitHexagonMCRegisterInfo(X, Hexagon::R31); - return X; -} - -static MCSubtargetInfo * -createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { - CPU = Hexagon_MC::selectHexagonCPU(TT, CPU); - return createHexagonMCSubtargetInfoImpl(TT, CPU, FS); -} +unsigned llvm::HexagonGetLastSlot() { return HexagonItinerariesV4FU::SLOT3; } namespace { class HexagonTargetAsmStreamer : public HexagonTargetStreamer { public: HexagonTargetAsmStreamer(MCStreamer &S, - formatted_raw_ostream &, bool, - MCInstPrinter &) + formatted_raw_ostream &OS, + bool isVerboseAsm, + MCInstPrinter &IP) : HexagonTargetStreamer(S) {} void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, @@ -156,24 +150,15 @@ public: class HexagonTargetELFStreamer : public HexagonTargetStreamer { public: + MCELFStreamer &getStreamer() { + return static_cast<MCELFStreamer &>(Streamer); + } HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI) : HexagonTargetStreamer(S) { - auto Bits = STI.getFeatureBits(); - unsigned Flags = 0; - if (Bits[Hexagon::ArchV60]) - Flags = ELF::EF_HEXAGON_MACH_V60; - else if (Bits[Hexagon::ArchV55]) - Flags = ELF::EF_HEXAGON_MACH_V55; - else if (Bits[Hexagon::ArchV5]) - Flags = ELF::EF_HEXAGON_MACH_V5; - else if (Bits[Hexagon::ArchV4]) - Flags = ELF::EF_HEXAGON_MACH_V4; - getStreamer().getAssembler().setELFHeaderEFlags(Flags); + MCAssembler &MCA = getStreamer().getAssembler(); + MCA.setELFHeaderEFlags(Hexagon_MC::GetELFFlags(STI)); } - MCELFStreamer &getStreamer() { - return static_cast<MCELFStreamer &>(Streamer); - } void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, @@ -196,13 +181,26 @@ public: } // end anonymous namespace +llvm::MCInstrInfo *llvm::createHexagonMCInstrInfo() { + MCInstrInfo *X = new MCInstrInfo(); + InitHexagonMCInstrInfo(X); + return X; +} + +static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { + MCRegisterInfo *X = new MCRegisterInfo(); + InitHexagonMCRegisterInfo(X, Hexagon::R31); + return X; +} + static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, const Triple &TT) { MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); // VirtualFP = (R30 + #0). MCCFIInstruction Inst = - MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0); + MCCFIInstruction::createDefCfa(nullptr, + MRI.getDwarfRegNum(Hexagon::R30, true), 0); MAI->addInitialFrameState(Inst); return MAI; @@ -212,31 +210,138 @@ static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T, unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI) { + const MCRegisterInfo &MRI) +{ if (SyntaxVariant == 0) - return (new HexagonInstPrinter(MAI, MII, MRI)); + return new HexagonInstPrinter(MAI, MII, MRI); else return nullptr; } -static MCTargetStreamer *createMCAsmTargetStreamer(MCStreamer &S, - formatted_raw_ostream &OS, - MCInstPrinter *InstPrint, - bool IsVerboseAsm) { - return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *InstPrint); +static MCTargetStreamer * +createMCAsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, + MCInstPrinter *IP, bool IsVerboseAsm) { + return new HexagonTargetAsmStreamer(S, OS, IsVerboseAsm, *IP); } -static MCStreamer *createMCStreamer(Triple const &T, MCContext &Context, - MCAsmBackend &MAB, raw_pwrite_stream &OS, - MCCodeEmitter *Emitter, bool RelaxAll) { - return createHexagonELFStreamer(Context, MAB, OS, Emitter); +static MCStreamer *createMCStreamer(Triple const &T, + MCContext &Context, + MCAsmBackend &MAB, + raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, + bool RelaxAll) { + return createHexagonELFStreamer(T, Context, MAB, OS, Emitter); } static MCTargetStreamer * -createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) { +createHexagonObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) { return new HexagonTargetELFStreamer(S, STI); } +static void LLVM_ATTRIBUTE_UNUSED clearFeature(MCSubtargetInfo* STI, uint64_t F) { + uint64_t FB = STI->getFeatureBits().to_ullong(); + if (FB & (1ULL << F)) + STI->ToggleFeature(F); +} + +static bool LLVM_ATTRIBUTE_UNUSED checkFeature(MCSubtargetInfo* STI, uint64_t F) { + uint64_t FB = STI->getFeatureBits().to_ullong(); + return (FB & (1ULL << F)) != 0; +} + +StringRef Hexagon_MC::ParseHexagonTriple(const Triple &TT, StringRef CPU) { + StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU); + StringRef FS = ""; + if (EnableHVX) { + if (CPUName.equals_lower("hexagonv60") || + CPUName.equals_lower("hexagonv62")) + FS = "+hvx"; + } + return FS; +} + +static bool isCPUValid(std::string CPU) +{ + std::vector<std::string> table + { + "hexagonv4", + "hexagonv5", + "hexagonv55", + "hexagonv60", + "hexagonv62", + }; + + return std::find(table.begin(), table.end(), CPU) != table.end(); +} + +MCSubtargetInfo *Hexagon_MC::createHexagonMCSubtargetInfo(const Triple &TT, + StringRef CPU, + StringRef FS) { + StringRef ArchFS = (FS.size()) ? FS : Hexagon_MC::ParseHexagonTriple(TT, CPU); + StringRef CPUName = Hexagon_MC::selectHexagonCPU(TT, CPU); + if (!isCPUValid(CPUName.str())) { + errs() << "error: invalid CPU \"" << CPUName.str().c_str() + << "\" specified\n"; + return nullptr; + } + + MCSubtargetInfo *X = createHexagonMCSubtargetInfoImpl(TT, CPUName, ArchFS); + if (X->getFeatureBits()[Hexagon::ExtensionHVXDbl]) { + llvm::FeatureBitset Features = X->getFeatureBits(); + X->setFeatureBits(Features.set(Hexagon::ExtensionHVX)); + } + return X; +} + +unsigned Hexagon_MC::GetELFFlags(const MCSubtargetInfo &STI) { + static std::map<StringRef,unsigned> ElfFlags = { + {"hexagonv4", ELF::EF_HEXAGON_MACH_V4}, + {"hexagonv5", ELF::EF_HEXAGON_MACH_V5}, + {"hexagonv55", ELF::EF_HEXAGON_MACH_V55}, + {"hexagonv60", ELF::EF_HEXAGON_MACH_V60}, + {"hexagonv62", ELF::EF_HEXAGON_MACH_V62}, + }; + + auto F = ElfFlags.find(STI.getCPU()); + assert(F != ElfFlags.end() && "Unrecognized Architecture"); + return F->second; +} + +namespace { +class HexagonMCInstrAnalysis : public MCInstrAnalysis { +public: + HexagonMCInstrAnalysis(MCInstrInfo const *Info) : MCInstrAnalysis(Info) {} + + bool isUnconditionalBranch(MCInst const &Inst) const override { + //assert(!HexagonMCInstrInfo::isBundle(Inst)); + return MCInstrAnalysis::isUnconditionalBranch(Inst); + } + + bool isConditionalBranch(MCInst const &Inst) const override { + //assert(!HexagonMCInstrInfo::isBundle(Inst)); + return MCInstrAnalysis::isConditionalBranch(Inst); + } + + bool evaluateBranch(MCInst const &Inst, uint64_t Addr, + uint64_t Size, uint64_t &Target) const override { + //assert(!HexagonMCInstrInfo::isBundle(Inst)); + if(!HexagonMCInstrInfo::isExtendable(*Info, Inst)) + return false; + auto const &Extended(HexagonMCInstrInfo::getExtendableOperand(*Info, Inst)); + assert(Extended.isExpr()); + int64_t Value; + if(!Extended.getExpr()->evaluateAsAbsolute(Value)) + return false; + Target = Value; + return true; + } +}; +} + +static MCInstrAnalysis *createHexagonMCInstrAnalysis(const MCInstrInfo *Info) { + return new HexagonMCInstrAnalysis(Info); +} + // Force static initialization. extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC asm info. @@ -252,7 +357,7 @@ extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC subtarget info. TargetRegistry::RegisterMCSubtargetInfo(getTheHexagonTarget(), - createHexagonMCSubtargetInfo); + Hexagon_MC::createHexagonMCSubtargetInfo); // Register the MC Code Emitter TargetRegistry::RegisterMCCodeEmitter(getTheHexagonTarget(), @@ -262,8 +367,18 @@ extern "C" void LLVMInitializeHexagonTargetMC() { TargetRegistry::RegisterMCAsmBackend(getTheHexagonTarget(), createHexagonAsmBackend); + + // Register the MC instruction analyzer. + TargetRegistry::RegisterMCInstrAnalysis(getTheHexagonTarget(), + createHexagonMCInstrAnalysis); + // Register the obj streamer - TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), createMCStreamer); + TargetRegistry::RegisterELFStreamer(getTheHexagonTarget(), + createMCStreamer); + + // Register the obj target streamer + TargetRegistry::RegisterObjectTargetStreamer(getTheHexagonTarget(), + createHexagonObjectTargetStreamer); // Register the asm streamer TargetRegistry::RegisterAsmTargetStreamer(getTheHexagonTarget(), @@ -272,7 +387,4 @@ extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC Inst Printer TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(), createHexagonMCInstPrinter); - - TargetRegistry::RegisterObjectTargetStreamer( - getTheHexagonTarget(), createHexagonObjectTargetStreamer); } |