X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FHexagon%2FMCTargetDesc%2FHexagonMCTargetDesc.cpp;h=9a292577a8f3d83cadccbf4f1cd4afa7988b9c05;hb=311fb07b3bb96292c8d0cc2d0d49576e1321e420;hp=a78c7f992009b7d4e0278b1d49824e78e9e487dd;hpb=1c60a4e36b77d5d08c747c21def9b59d909237a1;p=oota-llvm.git diff --git a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp index a78c7f99200..9a292577a8f 100644 --- a/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp +++ b/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp @@ -12,15 +12,20 @@ //===----------------------------------------------------------------------===// #include "HexagonMCTargetDesc.h" +#include "Hexagon.h" #include "HexagonMCAsmInfo.h" +#include "HexagonMCELFStreamer.h" #include "MCTargetDesc/HexagonInstPrinter.h" #include "llvm/MC/MCCodeGenInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MachineLocation.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" @@ -35,27 +40,115 @@ using namespace llvm; #define GET_REGINFO_MC_DESC #include "HexagonGenRegisterInfo.inc" +cl::opt llvm::HexagonDisableCompound + ("mno-compound", + cl::desc("Disable looking for compound instructions for Hexagon")); + +cl::opt llvm::HexagonDisableDuplex + ("mno-pairing", + cl::desc("Disable looking for duplex instructions for Hexagon")); + +StringRef HEXAGON_MC::selectHexagonCPU(const Triple &TT, StringRef CPU) { + if (CPU.empty()) + CPU = "hexagonv60"; + return CPU; +} + MCInstrInfo *llvm::createHexagonMCInstrInfo() { MCInstrInfo *X = new MCInstrInfo(); InitHexagonMCInstrInfo(X); return X; } -static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) { +static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { MCRegisterInfo *X = new MCRegisterInfo(); InitHexagonMCRegisterInfo(X, Hexagon::R0); return X; } static MCSubtargetInfo * -createHexagonMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) { - MCSubtargetInfo *X = new MCSubtargetInfo(); - InitHexagonMCSubtargetInfo(X, TT, CPU, FS); - return X; +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 &) + : HexagonTargetStreamer(S) {} + void prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, + const MCInst &Inst, const MCSubtargetInfo &STI) override { + assert(HexagonMCInstrInfo::isBundle(Inst)); + assert(HexagonMCInstrInfo::bundleSize(Inst) <= HEXAGON_PACKET_SIZE); + std::string Buffer; + { + raw_string_ostream TempStream(Buffer); + InstPrinter.printInst(&Inst, TempStream, "", STI); + } + StringRef Contents(Buffer); + auto PacketBundle = Contents.rsplit('\n'); + auto HeadTail = PacketBundle.first.split('\n'); + StringRef Separator = "\n"; + StringRef Indent = "\t\t"; + OS << "\t{\n"; + while (!HeadTail.first.empty()) { + StringRef InstTxt; + auto Duplex = HeadTail.first.split('\v'); + if (!Duplex.second.empty()) { + OS << Indent << Duplex.first << Separator; + InstTxt = Duplex.second; + } else if (!HeadTail.first.trim().startswith("immext")) { + InstTxt = Duplex.first; + } + if (!InstTxt.empty()) + OS << Indent << InstTxt << Separator; + HeadTail = HeadTail.second.split('\n'); + } + OS << "\t}" << PacketBundle.second; + } +}; +} + +namespace { +class HexagonTargetELFStreamer : public HexagonTargetStreamer { +public: + MCELFStreamer &getStreamer() { + return static_cast(Streamer); + } + HexagonTargetELFStreamer(MCStreamer &S, MCSubtargetInfo const &STI) + : HexagonTargetStreamer(S) { + auto Bits = STI.getFeatureBits(); + unsigned Flags; + if (Bits.to_ullong() & llvm::Hexagon::ArchV5) + Flags = ELF::EF_HEXAGON_MACH_V5; + else + Flags = ELF::EF_HEXAGON_MACH_V4; + getStreamer().getAssembler().setELFHeaderEFlags(Flags); + } + void EmitCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment, + unsigned AccessSize) override { + HexagonMCELFStreamer &HexagonELFStreamer = + static_cast(getStreamer()); + HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, + AccessSize); + } + void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, + unsigned ByteAlignment, + unsigned AccessSize) override { + HexagonMCELFStreamer &HexagonELFStreamer = + static_cast(getStreamer()); + HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol( + Symbol, Size, ByteAlignment, AccessSize); + } +}; } static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, - StringRef TT) { + const Triple &TT) { MCAsmInfo *MAI = new HexagonMCAsmInfo(TT); // VirtualFP = (R30 + #0). @@ -66,21 +159,44 @@ static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI, return MAI; } -static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM, +static MCCodeGenInfo *createHexagonMCCodeGenInfo(const Triple &TT, + Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) { MCCodeGenInfo *X = new MCCodeGenInfo(); - // For the time being, use static relocations, since there's really no - // support for PIC yet. - X->InitMCCodeGenInfo(Reloc::Static, CM, OL); + if (RM == Reloc::Default) + RM = Reloc::Static; + X->initMCCodeGenInfo(RM, CM, OL); return X; } -static MCInstPrinter *createHexagonMCInstPrinter(unsigned SyntaxVariant, + +static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T, + unsigned SyntaxVariant, const MCAsmInfo &MAI, const MCInstrInfo &MII, - const MCRegisterInfo &MRI, - const MCSubtargetInfo &STI) { - return new HexagonInstPrinter(MAI, MII, MRI); + const MCRegisterInfo &MRI) { + if (SyntaxVariant == 0) + 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 MCStreamer *createMCStreamer(Triple const &T, MCContext &Context, + MCAsmBackend &MAB, raw_pwrite_stream &OS, + MCCodeEmitter *Emitter, bool RelaxAll) { + return createHexagonELFStreamer(Context, MAB, OS, Emitter); +} + +static MCTargetStreamer * +createHexagonObjectTargetStreamer(MCStreamer &S, MCSubtargetInfo const &STI) { + return new HexagonTargetELFStreamer(S, STI); } // Force static initialization. @@ -108,11 +224,21 @@ extern "C" void LLVMInitializeHexagonTargetMC() { TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget, createHexagonMCCodeEmitter); + // Register the asm backend + TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget, + createHexagonAsmBackend); + + // Register the obj streamer + TargetRegistry::RegisterELFStreamer(TheHexagonTarget, createMCStreamer); + + // Register the asm streamer + TargetRegistry::RegisterAsmTargetStreamer(TheHexagonTarget, + createMCAsmTargetStreamer); + // Register the MC Inst Printer TargetRegistry::RegisterMCInstPrinter(TheHexagonTarget, createHexagonMCInstPrinter); - // Register the asm backend - TargetRegistry::RegisterMCAsmBackend(TheHexagonTarget, - createHexagonAsmBackend); + TargetRegistry::RegisterObjectTargetStreamer( + TheHexagonTarget, createHexagonObjectTargetStreamer); }