|  | //===-- HexagonMCTargetDesc.cpp - Hexagon Target Descriptions -------------===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file provides Hexagon specific target descriptions. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #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" | 
|  |  | 
|  | using namespace llvm; | 
|  |  | 
|  | #define GET_INSTRINFO_MC_DESC | 
|  | #include "HexagonGenInstrInfo.inc" | 
|  |  | 
|  | #define GET_SUBTARGETINFO_MC_DESC | 
|  | #include "HexagonGenSubtargetInfo.inc" | 
|  |  | 
|  | #define GET_REGINFO_MC_DESC | 
|  | #include "HexagonGenRegisterInfo.inc" | 
|  |  | 
|  | MCInstrInfo *llvm::createHexagonMCInstrInfo() { | 
|  | MCInstrInfo *X = new MCInstrInfo(); | 
|  | InitHexagonMCInstrInfo(X); | 
|  | return X; | 
|  | } | 
|  |  | 
|  | static MCRegisterInfo *createHexagonMCRegisterInfo(const Triple &TT) { | 
|  | MCRegisterInfo *X = new MCRegisterInfo(); | 
|  | InitHexagonMCRegisterInfo(X, Hexagon::R0); | 
|  | return X; | 
|  | } | 
|  |  | 
|  | static MCSubtargetInfo * | 
|  | createHexagonMCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS) { | 
|  | 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'); | 
|  | auto Preamble = "\t{\n\t\t"; | 
|  | auto Separator = ""; | 
|  | while(!HeadTail.first.empty()) { | 
|  | OS << Separator; | 
|  | StringRef Inst; | 
|  | auto Duplex = HeadTail.first.split('\v'); | 
|  | if(!Duplex.second.empty()){ | 
|  | OS << Duplex.first << "\n"; | 
|  | Inst = Duplex.second; | 
|  | } | 
|  | else { | 
|  | if(!HeadTail.first.startswith("immext")) | 
|  | Inst = Duplex.first; | 
|  | } | 
|  | OS << Preamble; | 
|  | OS << Inst; | 
|  | HeadTail = HeadTail.second.split('\n'); | 
|  | Preamble = ""; | 
|  | Separator = "\n\t\t"; | 
|  | } | 
|  | if(HexagonMCInstrInfo::bundleSize(Inst) != 0) | 
|  | OS << "\n\t}" << PacketBundle.second; | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | namespace { | 
|  | 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; | 
|  | 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<HexagonMCELFStreamer &>(getStreamer()); | 
|  | HexagonELFStreamer.HexagonMCEmitCommonSymbol(Symbol, Size, ByteAlignment, | 
|  | AccessSize); | 
|  | } | 
|  | void EmitLocalCommonSymbolSorted(MCSymbol *Symbol, uint64_t Size, | 
|  | unsigned ByteAlignment, | 
|  | unsigned AccessSize) override { | 
|  | HexagonMCELFStreamer &HexagonELFStreamer = | 
|  | static_cast<HexagonMCELFStreamer &>(getStreamer()); | 
|  | HexagonELFStreamer.HexagonMCEmitLocalCommonSymbol( | 
|  | Symbol, Size, ByteAlignment, AccessSize); | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | 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); | 
|  | MAI->addInitialFrameState(Inst); | 
|  |  | 
|  | return MAI; | 
|  | } | 
|  |  | 
|  | 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); | 
|  | return X; | 
|  | } | 
|  |  | 
|  | static MCInstPrinter *createHexagonMCInstPrinter(const Triple &T, | 
|  | unsigned SyntaxVariant, | 
|  | const MCAsmInfo &MAI, | 
|  | const MCInstrInfo &MII, | 
|  | 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. | 
|  | extern "C" void LLVMInitializeHexagonTargetMC() { | 
|  | // Register the MC asm info. | 
|  | RegisterMCAsmInfoFn X(TheHexagonTarget, createHexagonMCAsmInfo); | 
|  |  | 
|  | // Register the MC codegen info. | 
|  | TargetRegistry::RegisterMCCodeGenInfo(TheHexagonTarget, | 
|  | createHexagonMCCodeGenInfo); | 
|  |  | 
|  | // Register the MC instruction info. | 
|  | TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget, | 
|  | createHexagonMCInstrInfo); | 
|  |  | 
|  | // Register the MC register info. | 
|  | TargetRegistry::RegisterMCRegInfo(TheHexagonTarget, | 
|  | createHexagonMCRegisterInfo); | 
|  |  | 
|  | // Register the MC subtarget info. | 
|  | TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget, | 
|  | createHexagonMCSubtargetInfo); | 
|  |  | 
|  | // Register the MC Code Emitter | 
|  | 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); | 
|  |  | 
|  | TargetRegistry::RegisterObjectTargetStreamer( | 
|  | TheHexagonTarget, createHexagonObjectTargetStreamer); | 
|  | } |