diff options
Diffstat (limited to 'llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp')
| -rw-r--r-- | llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp | 200 |
1 files changed, 151 insertions, 49 deletions
diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index 694cf582f8d..52c61eb6e5d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/llvm/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" @@ -95,31 +96,19 @@ 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; +unsigned HexagonGetLastSlot() { + return HexagonItinerariesV4FU::SLOT3; } -static MCSubtargetInfo * -createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { - CPU = Hexagon_MC::selectHexagonCPU(TT, CPU); - return createHexagonMCSubtargetInfoImpl(TT, CPU, FS); -} 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 +145,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 +176,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 +205,133 @@ 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 (CPUName.equals_lower("hexagonv60")) + FS = "+hvx"; + return FS; +} + +static bool isCPUValid(std::string CPU) +{ + std::vector<std::string> table + { + "hexagonv4", + "hexagonv5", + "hexagonv55", + "hexagonv60", + }; + + 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}, + }; + + 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 +347,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 +357,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 +377,4 @@ extern "C" void LLVMInitializeHexagonTargetMC() { // Register the MC Inst Printer TargetRegistry::RegisterMCInstPrinter(getTheHexagonTarget(), createHexagonMCInstPrinter); - - TargetRegistry::RegisterObjectTargetStreamer( - getTheHexagonTarget(), createHexagonObjectTargetStreamer); } |

