1349cc55cSDimitry Andric //===- MC/TargetRegistry.h - Target Registration ----------------*- C++ -*-===// 2349cc55cSDimitry Andric // 3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6349cc55cSDimitry Andric // 7349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8349cc55cSDimitry Andric // 9349cc55cSDimitry Andric // This file exposes the TargetRegistry interface, which tools can use to access 10349cc55cSDimitry Andric // the appropriate target specific classes (TargetMachine, AsmPrinter, etc.) 11349cc55cSDimitry Andric // which have been registered. 12349cc55cSDimitry Andric // 13349cc55cSDimitry Andric // Target specific class implementations should register themselves using the 14349cc55cSDimitry Andric // appropriate TargetRegistry interfaces. 15349cc55cSDimitry Andric // 16349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 17349cc55cSDimitry Andric 18349cc55cSDimitry Andric #ifndef LLVM_MC_TARGETREGISTRY_H 19349cc55cSDimitry Andric #define LLVM_MC_TARGETREGISTRY_H 20349cc55cSDimitry Andric 21349cc55cSDimitry Andric #include "llvm-c/DisassemblerTypes.h" 22349cc55cSDimitry Andric #include "llvm/ADT/StringRef.h" 23349cc55cSDimitry Andric #include "llvm/ADT/Triple.h" 24349cc55cSDimitry Andric #include "llvm/ADT/iterator_range.h" 25349cc55cSDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 26349cc55cSDimitry Andric #include "llvm/Support/CodeGen.h" 27349cc55cSDimitry Andric #include "llvm/Support/ErrorHandling.h" 28349cc55cSDimitry Andric #include "llvm/Support/FormattedStream.h" 29349cc55cSDimitry Andric #include <cassert> 30349cc55cSDimitry Andric #include <cstddef> 31349cc55cSDimitry Andric #include <iterator> 32349cc55cSDimitry Andric #include <memory> 33*bdd1243dSDimitry Andric #include <optional> 34349cc55cSDimitry Andric #include <string> 35349cc55cSDimitry Andric 36349cc55cSDimitry Andric namespace llvm { 37349cc55cSDimitry Andric 38349cc55cSDimitry Andric class AsmPrinter; 39349cc55cSDimitry Andric class MCAsmBackend; 40349cc55cSDimitry Andric class MCAsmInfo; 41349cc55cSDimitry Andric class MCAsmParser; 42349cc55cSDimitry Andric class MCCodeEmitter; 43349cc55cSDimitry Andric class MCContext; 44349cc55cSDimitry Andric class MCDisassembler; 45349cc55cSDimitry Andric class MCInstPrinter; 46349cc55cSDimitry Andric class MCInstrAnalysis; 47349cc55cSDimitry Andric class MCInstrInfo; 48349cc55cSDimitry Andric class MCObjectWriter; 49349cc55cSDimitry Andric class MCRegisterInfo; 50349cc55cSDimitry Andric class MCRelocationInfo; 51349cc55cSDimitry Andric class MCStreamer; 52349cc55cSDimitry Andric class MCSubtargetInfo; 53349cc55cSDimitry Andric class MCSymbolizer; 54349cc55cSDimitry Andric class MCTargetAsmParser; 55349cc55cSDimitry Andric class MCTargetOptions; 56349cc55cSDimitry Andric class MCTargetStreamer; 57349cc55cSDimitry Andric class raw_ostream; 58349cc55cSDimitry Andric class TargetMachine; 59349cc55cSDimitry Andric class TargetOptions; 60349cc55cSDimitry Andric namespace mca { 61349cc55cSDimitry Andric class CustomBehaviour; 62349cc55cSDimitry Andric class InstrPostProcess; 63*bdd1243dSDimitry Andric class InstrumentManager; 6481ad6265SDimitry Andric struct SourceMgr; 65349cc55cSDimitry Andric } // namespace mca 66349cc55cSDimitry Andric 67349cc55cSDimitry Andric MCStreamer *createNullStreamer(MCContext &Ctx); 68349cc55cSDimitry Andric // Takes ownership of \p TAB and \p CE. 69349cc55cSDimitry Andric 70349cc55cSDimitry Andric /// Create a machine code streamer which will print out assembly for the native 71349cc55cSDimitry Andric /// target, suitable for compiling with a native assembler. 72349cc55cSDimitry Andric /// 73349cc55cSDimitry Andric /// \param InstPrint - If given, the instruction printer to use. If not given 74349cc55cSDimitry Andric /// the MCInst representation will be printed. This method takes ownership of 75349cc55cSDimitry Andric /// InstPrint. 76349cc55cSDimitry Andric /// 77349cc55cSDimitry Andric /// \param CE - If given, a code emitter to use to show the instruction 78349cc55cSDimitry Andric /// encoding inline with the assembly. This method takes ownership of \p CE. 79349cc55cSDimitry Andric /// 80349cc55cSDimitry Andric /// \param TAB - If given, a target asm backend to use to show the fixup 81349cc55cSDimitry Andric /// information in conjunction with encoding information. This method takes 82349cc55cSDimitry Andric /// ownership of \p TAB. 83349cc55cSDimitry Andric /// 84349cc55cSDimitry Andric /// \param ShowInst - Whether to show the MCInst representation inline with 85349cc55cSDimitry Andric /// the assembly. 86349cc55cSDimitry Andric MCStreamer * 87349cc55cSDimitry Andric createAsmStreamer(MCContext &Ctx, std::unique_ptr<formatted_raw_ostream> OS, 88349cc55cSDimitry Andric bool isVerboseAsm, bool useDwarfDirectory, 89349cc55cSDimitry Andric MCInstPrinter *InstPrint, std::unique_ptr<MCCodeEmitter> &&CE, 90349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, bool ShowInst); 91349cc55cSDimitry Andric 92349cc55cSDimitry Andric MCStreamer *createELFStreamer(MCContext &Ctx, 93349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 94349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 95349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 96349cc55cSDimitry Andric bool RelaxAll); 97349cc55cSDimitry Andric MCStreamer *createMachOStreamer(MCContext &Ctx, 98349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 99349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 100349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 101349cc55cSDimitry Andric bool RelaxAll, bool DWARFMustBeAtTheEnd, 102349cc55cSDimitry Andric bool LabelSections = false); 103349cc55cSDimitry Andric MCStreamer *createWasmStreamer(MCContext &Ctx, 104349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 105349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 106349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 107349cc55cSDimitry Andric bool RelaxAll); 108349cc55cSDimitry Andric MCStreamer *createXCOFFStreamer(MCContext &Ctx, 109349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 110349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 111349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 112349cc55cSDimitry Andric bool RelaxAll); 11381ad6265SDimitry Andric MCStreamer *createSPIRVStreamer(MCContext &Ctx, 11481ad6265SDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 11581ad6265SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 11681ad6265SDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 11781ad6265SDimitry Andric bool RelaxAll); 11881ad6265SDimitry Andric MCStreamer *createDXContainerStreamer(MCContext &Ctx, 11981ad6265SDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 12081ad6265SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 12181ad6265SDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 12281ad6265SDimitry Andric bool RelaxAll); 123349cc55cSDimitry Andric 124349cc55cSDimitry Andric MCRelocationInfo *createMCRelocationInfo(const Triple &TT, MCContext &Ctx); 125349cc55cSDimitry Andric 126349cc55cSDimitry Andric MCSymbolizer *createMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo, 127349cc55cSDimitry Andric LLVMSymbolLookupCallback SymbolLookUp, 128349cc55cSDimitry Andric void *DisInfo, MCContext *Ctx, 129349cc55cSDimitry Andric std::unique_ptr<MCRelocationInfo> &&RelInfo); 130349cc55cSDimitry Andric 131349cc55cSDimitry Andric mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI, 132349cc55cSDimitry Andric const mca::SourceMgr &SrcMgr, 133349cc55cSDimitry Andric const MCInstrInfo &MCII); 134349cc55cSDimitry Andric 135349cc55cSDimitry Andric mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI, 136349cc55cSDimitry Andric const MCInstrInfo &MCII); 137349cc55cSDimitry Andric 138*bdd1243dSDimitry Andric mca::InstrumentManager *createInstrumentManager(const MCSubtargetInfo &STI, 139*bdd1243dSDimitry Andric const MCInstrInfo &MCII); 140*bdd1243dSDimitry Andric 141349cc55cSDimitry Andric /// Target - Wrapper for Target specific information. 142349cc55cSDimitry Andric /// 143349cc55cSDimitry Andric /// For registration purposes, this is a POD type so that targets can be 144349cc55cSDimitry Andric /// registered without the use of static constructors. 145349cc55cSDimitry Andric /// 146349cc55cSDimitry Andric /// Targets should implement a single global instance of this class (which 147349cc55cSDimitry Andric /// will be zero initialized), and pass that instance to the TargetRegistry as 148349cc55cSDimitry Andric /// part of their initialization. 149349cc55cSDimitry Andric class Target { 150349cc55cSDimitry Andric public: 151349cc55cSDimitry Andric friend struct TargetRegistry; 152349cc55cSDimitry Andric 153349cc55cSDimitry Andric using ArchMatchFnTy = bool (*)(Triple::ArchType Arch); 154349cc55cSDimitry Andric 155349cc55cSDimitry Andric using MCAsmInfoCtorFnTy = MCAsmInfo *(*)(const MCRegisterInfo &MRI, 156349cc55cSDimitry Andric const Triple &TT, 157349cc55cSDimitry Andric const MCTargetOptions &Options); 158349cc55cSDimitry Andric using MCObjectFileInfoCtorFnTy = MCObjectFileInfo *(*)(MCContext &Ctx, 159349cc55cSDimitry Andric bool PIC, 160349cc55cSDimitry Andric bool LargeCodeModel); 161349cc55cSDimitry Andric using MCInstrInfoCtorFnTy = MCInstrInfo *(*)(); 162349cc55cSDimitry Andric using MCInstrAnalysisCtorFnTy = MCInstrAnalysis *(*)(const MCInstrInfo *Info); 163349cc55cSDimitry Andric using MCRegInfoCtorFnTy = MCRegisterInfo *(*)(const Triple &TT); 164349cc55cSDimitry Andric using MCSubtargetInfoCtorFnTy = MCSubtargetInfo *(*)(const Triple &TT, 165349cc55cSDimitry Andric StringRef CPU, 166349cc55cSDimitry Andric StringRef Features); 167349cc55cSDimitry Andric using TargetMachineCtorTy = TargetMachine 168349cc55cSDimitry Andric *(*)(const Target &T, const Triple &TT, StringRef CPU, StringRef Features, 169*bdd1243dSDimitry Andric const TargetOptions &Options, std::optional<Reloc::Model> RM, 170*bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, CodeGenOpt::Level OL, bool JIT); 171349cc55cSDimitry Andric // If it weren't for layering issues (this header is in llvm/Support, but 172349cc55cSDimitry Andric // depends on MC?) this should take the Streamer by value rather than rvalue 173349cc55cSDimitry Andric // reference. 174349cc55cSDimitry Andric using AsmPrinterCtorTy = AsmPrinter *(*)( 175349cc55cSDimitry Andric TargetMachine &TM, std::unique_ptr<MCStreamer> &&Streamer); 176349cc55cSDimitry Andric using MCAsmBackendCtorTy = MCAsmBackend *(*)(const Target &T, 177349cc55cSDimitry Andric const MCSubtargetInfo &STI, 178349cc55cSDimitry Andric const MCRegisterInfo &MRI, 179349cc55cSDimitry Andric const MCTargetOptions &Options); 180349cc55cSDimitry Andric using MCAsmParserCtorTy = MCTargetAsmParser *(*)( 181349cc55cSDimitry Andric const MCSubtargetInfo &STI, MCAsmParser &P, const MCInstrInfo &MII, 182349cc55cSDimitry Andric const MCTargetOptions &Options); 183349cc55cSDimitry Andric using MCDisassemblerCtorTy = MCDisassembler *(*)(const Target &T, 184349cc55cSDimitry Andric const MCSubtargetInfo &STI, 185349cc55cSDimitry Andric MCContext &Ctx); 186349cc55cSDimitry Andric using MCInstPrinterCtorTy = MCInstPrinter *(*)(const Triple &T, 187349cc55cSDimitry Andric unsigned SyntaxVariant, 188349cc55cSDimitry Andric const MCAsmInfo &MAI, 189349cc55cSDimitry Andric const MCInstrInfo &MII, 190349cc55cSDimitry Andric const MCRegisterInfo &MRI); 191349cc55cSDimitry Andric using MCCodeEmitterCtorTy = MCCodeEmitter *(*)(const MCInstrInfo &II, 192349cc55cSDimitry Andric MCContext &Ctx); 193349cc55cSDimitry Andric using ELFStreamerCtorTy = 194349cc55cSDimitry Andric MCStreamer *(*)(const Triple &T, MCContext &Ctx, 195349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 196349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 197349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); 198349cc55cSDimitry Andric using MachOStreamerCtorTy = 199349cc55cSDimitry Andric MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, 200349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 201349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, 202349cc55cSDimitry Andric bool DWARFMustBeAtTheEnd); 203349cc55cSDimitry Andric using COFFStreamerCtorTy = 204349cc55cSDimitry Andric MCStreamer *(*)(MCContext &Ctx, std::unique_ptr<MCAsmBackend> &&TAB, 205349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 206349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll, 207349cc55cSDimitry Andric bool IncrementalLinkerCompatible); 208349cc55cSDimitry Andric using WasmStreamerCtorTy = 209349cc55cSDimitry Andric MCStreamer *(*)(const Triple &T, MCContext &Ctx, 210349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 211349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 212349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); 213349cc55cSDimitry Andric using XCOFFStreamerCtorTy = 214349cc55cSDimitry Andric MCStreamer *(*)(const Triple &T, MCContext &Ctx, 215349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 216349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 217349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); 21881ad6265SDimitry Andric using SPIRVStreamerCtorTy = 21981ad6265SDimitry Andric MCStreamer *(*)(const Triple &T, MCContext &Ctx, 22081ad6265SDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 22181ad6265SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 22281ad6265SDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); 22381ad6265SDimitry Andric 22481ad6265SDimitry Andric using DXContainerStreamerCtorTy = 22581ad6265SDimitry Andric MCStreamer *(*)(const Triple &T, MCContext &Ctx, 22681ad6265SDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 22781ad6265SDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 22881ad6265SDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, bool RelaxAll); 229349cc55cSDimitry Andric 230349cc55cSDimitry Andric using NullTargetStreamerCtorTy = MCTargetStreamer *(*)(MCStreamer &S); 231349cc55cSDimitry Andric using AsmTargetStreamerCtorTy = MCTargetStreamer *(*)( 232349cc55cSDimitry Andric MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint, 233349cc55cSDimitry Andric bool IsVerboseAsm); 234349cc55cSDimitry Andric using ObjectTargetStreamerCtorTy = MCTargetStreamer *(*)( 235349cc55cSDimitry Andric MCStreamer &S, const MCSubtargetInfo &STI); 236349cc55cSDimitry Andric using MCRelocationInfoCtorTy = MCRelocationInfo *(*)(const Triple &TT, 237349cc55cSDimitry Andric MCContext &Ctx); 238349cc55cSDimitry Andric using MCSymbolizerCtorTy = MCSymbolizer *(*)( 239349cc55cSDimitry Andric const Triple &TT, LLVMOpInfoCallback GetOpInfo, 240349cc55cSDimitry Andric LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, MCContext *Ctx, 241349cc55cSDimitry Andric std::unique_ptr<MCRelocationInfo> &&RelInfo); 242349cc55cSDimitry Andric 243349cc55cSDimitry Andric using CustomBehaviourCtorTy = 244349cc55cSDimitry Andric mca::CustomBehaviour *(*)(const MCSubtargetInfo &STI, 245349cc55cSDimitry Andric const mca::SourceMgr &SrcMgr, 246349cc55cSDimitry Andric const MCInstrInfo &MCII); 247349cc55cSDimitry Andric 248349cc55cSDimitry Andric using InstrPostProcessCtorTy = 249349cc55cSDimitry Andric mca::InstrPostProcess *(*)(const MCSubtargetInfo &STI, 250349cc55cSDimitry Andric const MCInstrInfo &MCII); 251349cc55cSDimitry Andric 252*bdd1243dSDimitry Andric using InstrumentManagerCtorTy = 253*bdd1243dSDimitry Andric mca::InstrumentManager *(*)(const MCSubtargetInfo &STI, 254*bdd1243dSDimitry Andric const MCInstrInfo &MCII); 255*bdd1243dSDimitry Andric 256349cc55cSDimitry Andric private: 257349cc55cSDimitry Andric /// Next - The next registered target in the linked list, maintained by the 258349cc55cSDimitry Andric /// TargetRegistry. 259349cc55cSDimitry Andric Target *Next; 260349cc55cSDimitry Andric 261349cc55cSDimitry Andric /// The target function for checking if an architecture is supported. 262349cc55cSDimitry Andric ArchMatchFnTy ArchMatchFn; 263349cc55cSDimitry Andric 264349cc55cSDimitry Andric /// Name - The target name. 265349cc55cSDimitry Andric const char *Name; 266349cc55cSDimitry Andric 267349cc55cSDimitry Andric /// ShortDesc - A short description of the target. 268349cc55cSDimitry Andric const char *ShortDesc; 269349cc55cSDimitry Andric 270349cc55cSDimitry Andric /// BackendName - The name of the backend implementation. This must match the 271349cc55cSDimitry Andric /// name of the 'def X : Target ...' in TableGen. 272349cc55cSDimitry Andric const char *BackendName; 273349cc55cSDimitry Andric 274349cc55cSDimitry Andric /// HasJIT - Whether this target supports the JIT. 275349cc55cSDimitry Andric bool HasJIT; 276349cc55cSDimitry Andric 277349cc55cSDimitry Andric /// MCAsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if 278349cc55cSDimitry Andric /// registered. 279349cc55cSDimitry Andric MCAsmInfoCtorFnTy MCAsmInfoCtorFn; 280349cc55cSDimitry Andric 281349cc55cSDimitry Andric /// Constructor function for this target's MCObjectFileInfo, if registered. 282349cc55cSDimitry Andric MCObjectFileInfoCtorFnTy MCObjectFileInfoCtorFn; 283349cc55cSDimitry Andric 284349cc55cSDimitry Andric /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo, 285349cc55cSDimitry Andric /// if registered. 286349cc55cSDimitry Andric MCInstrInfoCtorFnTy MCInstrInfoCtorFn; 287349cc55cSDimitry Andric 288349cc55cSDimitry Andric /// MCInstrAnalysisCtorFn - Constructor function for this target's 289349cc55cSDimitry Andric /// MCInstrAnalysis, if registered. 290349cc55cSDimitry Andric MCInstrAnalysisCtorFnTy MCInstrAnalysisCtorFn; 291349cc55cSDimitry Andric 292349cc55cSDimitry Andric /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo, 293349cc55cSDimitry Andric /// if registered. 294349cc55cSDimitry Andric MCRegInfoCtorFnTy MCRegInfoCtorFn; 295349cc55cSDimitry Andric 296349cc55cSDimitry Andric /// MCSubtargetInfoCtorFn - Constructor function for this target's 297349cc55cSDimitry Andric /// MCSubtargetInfo, if registered. 298349cc55cSDimitry Andric MCSubtargetInfoCtorFnTy MCSubtargetInfoCtorFn; 299349cc55cSDimitry Andric 300349cc55cSDimitry Andric /// TargetMachineCtorFn - Construction function for this target's 301349cc55cSDimitry Andric /// TargetMachine, if registered. 302349cc55cSDimitry Andric TargetMachineCtorTy TargetMachineCtorFn; 303349cc55cSDimitry Andric 304349cc55cSDimitry Andric /// MCAsmBackendCtorFn - Construction function for this target's 305349cc55cSDimitry Andric /// MCAsmBackend, if registered. 306349cc55cSDimitry Andric MCAsmBackendCtorTy MCAsmBackendCtorFn; 307349cc55cSDimitry Andric 308349cc55cSDimitry Andric /// MCAsmParserCtorFn - Construction function for this target's 309349cc55cSDimitry Andric /// MCTargetAsmParser, if registered. 310349cc55cSDimitry Andric MCAsmParserCtorTy MCAsmParserCtorFn; 311349cc55cSDimitry Andric 312349cc55cSDimitry Andric /// AsmPrinterCtorFn - Construction function for this target's AsmPrinter, 313349cc55cSDimitry Andric /// if registered. 314349cc55cSDimitry Andric AsmPrinterCtorTy AsmPrinterCtorFn; 315349cc55cSDimitry Andric 316349cc55cSDimitry Andric /// MCDisassemblerCtorFn - Construction function for this target's 317349cc55cSDimitry Andric /// MCDisassembler, if registered. 318349cc55cSDimitry Andric MCDisassemblerCtorTy MCDisassemblerCtorFn; 319349cc55cSDimitry Andric 320349cc55cSDimitry Andric /// MCInstPrinterCtorFn - Construction function for this target's 321349cc55cSDimitry Andric /// MCInstPrinter, if registered. 322349cc55cSDimitry Andric MCInstPrinterCtorTy MCInstPrinterCtorFn; 323349cc55cSDimitry Andric 324349cc55cSDimitry Andric /// MCCodeEmitterCtorFn - Construction function for this target's 325349cc55cSDimitry Andric /// CodeEmitter, if registered. 326349cc55cSDimitry Andric MCCodeEmitterCtorTy MCCodeEmitterCtorFn; 327349cc55cSDimitry Andric 328349cc55cSDimitry Andric // Construction functions for the various object formats, if registered. 329349cc55cSDimitry Andric COFFStreamerCtorTy COFFStreamerCtorFn = nullptr; 330349cc55cSDimitry Andric MachOStreamerCtorTy MachOStreamerCtorFn = nullptr; 331349cc55cSDimitry Andric ELFStreamerCtorTy ELFStreamerCtorFn = nullptr; 332349cc55cSDimitry Andric WasmStreamerCtorTy WasmStreamerCtorFn = nullptr; 333349cc55cSDimitry Andric XCOFFStreamerCtorTy XCOFFStreamerCtorFn = nullptr; 33481ad6265SDimitry Andric SPIRVStreamerCtorTy SPIRVStreamerCtorFn = nullptr; 33581ad6265SDimitry Andric DXContainerStreamerCtorTy DXContainerStreamerCtorFn = nullptr; 336349cc55cSDimitry Andric 337349cc55cSDimitry Andric /// Construction function for this target's null TargetStreamer, if 338349cc55cSDimitry Andric /// registered (default = nullptr). 339349cc55cSDimitry Andric NullTargetStreamerCtorTy NullTargetStreamerCtorFn = nullptr; 340349cc55cSDimitry Andric 341349cc55cSDimitry Andric /// Construction function for this target's asm TargetStreamer, if 342349cc55cSDimitry Andric /// registered (default = nullptr). 343349cc55cSDimitry Andric AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn = nullptr; 344349cc55cSDimitry Andric 345349cc55cSDimitry Andric /// Construction function for this target's obj TargetStreamer, if 346349cc55cSDimitry Andric /// registered (default = nullptr). 347349cc55cSDimitry Andric ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn = nullptr; 348349cc55cSDimitry Andric 349349cc55cSDimitry Andric /// MCRelocationInfoCtorFn - Construction function for this target's 350349cc55cSDimitry Andric /// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo) 351349cc55cSDimitry Andric MCRelocationInfoCtorTy MCRelocationInfoCtorFn = nullptr; 352349cc55cSDimitry Andric 353349cc55cSDimitry Andric /// MCSymbolizerCtorFn - Construction function for this target's 354349cc55cSDimitry Andric /// MCSymbolizer, if registered (default = llvm::createMCSymbolizer) 355349cc55cSDimitry Andric MCSymbolizerCtorTy MCSymbolizerCtorFn = nullptr; 356349cc55cSDimitry Andric 357349cc55cSDimitry Andric /// CustomBehaviourCtorFn - Construction function for this target's 358349cc55cSDimitry Andric /// CustomBehaviour, if registered (default = nullptr). 359349cc55cSDimitry Andric CustomBehaviourCtorTy CustomBehaviourCtorFn = nullptr; 360349cc55cSDimitry Andric 361349cc55cSDimitry Andric /// InstrPostProcessCtorFn - Construction function for this target's 362349cc55cSDimitry Andric /// InstrPostProcess, if registered (default = nullptr). 363349cc55cSDimitry Andric InstrPostProcessCtorTy InstrPostProcessCtorFn = nullptr; 364349cc55cSDimitry Andric 365*bdd1243dSDimitry Andric /// InstrumentManagerCtorFn - Construction function for this target's 366*bdd1243dSDimitry Andric /// InstrumentManager, if registered (default = nullptr). 367*bdd1243dSDimitry Andric InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr; 368*bdd1243dSDimitry Andric 369349cc55cSDimitry Andric public: 370349cc55cSDimitry Andric Target() = default; 371349cc55cSDimitry Andric 372349cc55cSDimitry Andric /// @name Target Information 373349cc55cSDimitry Andric /// @{ 374349cc55cSDimitry Andric 375349cc55cSDimitry Andric // getNext - Return the next registered target. 376349cc55cSDimitry Andric const Target *getNext() const { return Next; } 377349cc55cSDimitry Andric 378349cc55cSDimitry Andric /// getName - Get the target name. 379349cc55cSDimitry Andric const char *getName() const { return Name; } 380349cc55cSDimitry Andric 381349cc55cSDimitry Andric /// getShortDescription - Get a short description of the target. 382349cc55cSDimitry Andric const char *getShortDescription() const { return ShortDesc; } 383349cc55cSDimitry Andric 384349cc55cSDimitry Andric /// getBackendName - Get the backend name. 385349cc55cSDimitry Andric const char *getBackendName() const { return BackendName; } 386349cc55cSDimitry Andric 387349cc55cSDimitry Andric /// @} 388349cc55cSDimitry Andric /// @name Feature Predicates 389349cc55cSDimitry Andric /// @{ 390349cc55cSDimitry Andric 391349cc55cSDimitry Andric /// hasJIT - Check if this targets supports the just-in-time compilation. 392349cc55cSDimitry Andric bool hasJIT() const { return HasJIT; } 393349cc55cSDimitry Andric 394349cc55cSDimitry Andric /// hasTargetMachine - Check if this target supports code generation. 395349cc55cSDimitry Andric bool hasTargetMachine() const { return TargetMachineCtorFn != nullptr; } 396349cc55cSDimitry Andric 397349cc55cSDimitry Andric /// hasMCAsmBackend - Check if this target supports .o generation. 398349cc55cSDimitry Andric bool hasMCAsmBackend() const { return MCAsmBackendCtorFn != nullptr; } 399349cc55cSDimitry Andric 400349cc55cSDimitry Andric /// hasMCAsmParser - Check if this target supports assembly parsing. 401349cc55cSDimitry Andric bool hasMCAsmParser() const { return MCAsmParserCtorFn != nullptr; } 402349cc55cSDimitry Andric 403349cc55cSDimitry Andric /// @} 404349cc55cSDimitry Andric /// @name Feature Constructors 405349cc55cSDimitry Andric /// @{ 406349cc55cSDimitry Andric 407349cc55cSDimitry Andric /// createMCAsmInfo - Create a MCAsmInfo implementation for the specified 408349cc55cSDimitry Andric /// target triple. 409349cc55cSDimitry Andric /// 410349cc55cSDimitry Andric /// \param TheTriple This argument is used to determine the target machine 411349cc55cSDimitry Andric /// feature set; it should always be provided. Generally this should be 412349cc55cSDimitry Andric /// either the target triple from the module, or the target triple of the 413349cc55cSDimitry Andric /// host if that does not exist. 414349cc55cSDimitry Andric MCAsmInfo *createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, 415349cc55cSDimitry Andric const MCTargetOptions &Options) const { 416349cc55cSDimitry Andric if (!MCAsmInfoCtorFn) 417349cc55cSDimitry Andric return nullptr; 418349cc55cSDimitry Andric return MCAsmInfoCtorFn(MRI, Triple(TheTriple), Options); 419349cc55cSDimitry Andric } 420349cc55cSDimitry Andric 421349cc55cSDimitry Andric /// Create a MCObjectFileInfo implementation for the specified target 422349cc55cSDimitry Andric /// triple. 423349cc55cSDimitry Andric /// 424349cc55cSDimitry Andric MCObjectFileInfo *createMCObjectFileInfo(MCContext &Ctx, bool PIC, 425349cc55cSDimitry Andric bool LargeCodeModel = false) const { 426349cc55cSDimitry Andric if (!MCObjectFileInfoCtorFn) { 427349cc55cSDimitry Andric MCObjectFileInfo *MOFI = new MCObjectFileInfo(); 428349cc55cSDimitry Andric MOFI->initMCObjectFileInfo(Ctx, PIC, LargeCodeModel); 429349cc55cSDimitry Andric return MOFI; 430349cc55cSDimitry Andric } 431349cc55cSDimitry Andric return MCObjectFileInfoCtorFn(Ctx, PIC, LargeCodeModel); 432349cc55cSDimitry Andric } 433349cc55cSDimitry Andric 434349cc55cSDimitry Andric /// createMCInstrInfo - Create a MCInstrInfo implementation. 435349cc55cSDimitry Andric /// 436349cc55cSDimitry Andric MCInstrInfo *createMCInstrInfo() const { 437349cc55cSDimitry Andric if (!MCInstrInfoCtorFn) 438349cc55cSDimitry Andric return nullptr; 439349cc55cSDimitry Andric return MCInstrInfoCtorFn(); 440349cc55cSDimitry Andric } 441349cc55cSDimitry Andric 442349cc55cSDimitry Andric /// createMCInstrAnalysis - Create a MCInstrAnalysis implementation. 443349cc55cSDimitry Andric /// 444349cc55cSDimitry Andric MCInstrAnalysis *createMCInstrAnalysis(const MCInstrInfo *Info) const { 445349cc55cSDimitry Andric if (!MCInstrAnalysisCtorFn) 446349cc55cSDimitry Andric return nullptr; 447349cc55cSDimitry Andric return MCInstrAnalysisCtorFn(Info); 448349cc55cSDimitry Andric } 449349cc55cSDimitry Andric 450349cc55cSDimitry Andric /// createMCRegInfo - Create a MCRegisterInfo implementation. 451349cc55cSDimitry Andric /// 452349cc55cSDimitry Andric MCRegisterInfo *createMCRegInfo(StringRef TT) const { 453349cc55cSDimitry Andric if (!MCRegInfoCtorFn) 454349cc55cSDimitry Andric return nullptr; 455349cc55cSDimitry Andric return MCRegInfoCtorFn(Triple(TT)); 456349cc55cSDimitry Andric } 457349cc55cSDimitry Andric 458349cc55cSDimitry Andric /// createMCSubtargetInfo - Create a MCSubtargetInfo implementation. 459349cc55cSDimitry Andric /// 460349cc55cSDimitry Andric /// \param TheTriple This argument is used to determine the target machine 461349cc55cSDimitry Andric /// feature set; it should always be provided. Generally this should be 462349cc55cSDimitry Andric /// either the target triple from the module, or the target triple of the 463349cc55cSDimitry Andric /// host if that does not exist. 464349cc55cSDimitry Andric /// \param CPU This specifies the name of the target CPU. 465349cc55cSDimitry Andric /// \param Features This specifies the string representation of the 466349cc55cSDimitry Andric /// additional target features. 467349cc55cSDimitry Andric MCSubtargetInfo *createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, 468349cc55cSDimitry Andric StringRef Features) const { 469349cc55cSDimitry Andric if (!MCSubtargetInfoCtorFn) 470349cc55cSDimitry Andric return nullptr; 471349cc55cSDimitry Andric return MCSubtargetInfoCtorFn(Triple(TheTriple), CPU, Features); 472349cc55cSDimitry Andric } 473349cc55cSDimitry Andric 474349cc55cSDimitry Andric /// createTargetMachine - Create a target specific machine implementation 475349cc55cSDimitry Andric /// for the specified \p Triple. 476349cc55cSDimitry Andric /// 477349cc55cSDimitry Andric /// \param TT This argument is used to determine the target machine 478349cc55cSDimitry Andric /// feature set; it should always be provided. Generally this should be 479349cc55cSDimitry Andric /// either the target triple from the module, or the target triple of the 480349cc55cSDimitry Andric /// host if that does not exist. 481*bdd1243dSDimitry Andric TargetMachine *createTargetMachine( 482*bdd1243dSDimitry Andric StringRef TT, StringRef CPU, StringRef Features, 483*bdd1243dSDimitry Andric const TargetOptions &Options, std::optional<Reloc::Model> RM, 484*bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM = std::nullopt, 485*bdd1243dSDimitry Andric CodeGenOpt::Level OL = CodeGenOpt::Default, bool JIT = false) const { 486349cc55cSDimitry Andric if (!TargetMachineCtorFn) 487349cc55cSDimitry Andric return nullptr; 488349cc55cSDimitry Andric return TargetMachineCtorFn(*this, Triple(TT), CPU, Features, Options, RM, 489349cc55cSDimitry Andric CM, OL, JIT); 490349cc55cSDimitry Andric } 491349cc55cSDimitry Andric 492349cc55cSDimitry Andric /// createMCAsmBackend - Create a target specific assembly parser. 493349cc55cSDimitry Andric MCAsmBackend *createMCAsmBackend(const MCSubtargetInfo &STI, 494349cc55cSDimitry Andric const MCRegisterInfo &MRI, 495349cc55cSDimitry Andric const MCTargetOptions &Options) const { 496349cc55cSDimitry Andric if (!MCAsmBackendCtorFn) 497349cc55cSDimitry Andric return nullptr; 498349cc55cSDimitry Andric return MCAsmBackendCtorFn(*this, STI, MRI, Options); 499349cc55cSDimitry Andric } 500349cc55cSDimitry Andric 501349cc55cSDimitry Andric /// createMCAsmParser - Create a target specific assembly parser. 502349cc55cSDimitry Andric /// 503349cc55cSDimitry Andric /// \param Parser The target independent parser implementation to use for 504349cc55cSDimitry Andric /// parsing and lexing. 505349cc55cSDimitry Andric MCTargetAsmParser *createMCAsmParser(const MCSubtargetInfo &STI, 506349cc55cSDimitry Andric MCAsmParser &Parser, 507349cc55cSDimitry Andric const MCInstrInfo &MII, 508349cc55cSDimitry Andric const MCTargetOptions &Options) const { 509349cc55cSDimitry Andric if (!MCAsmParserCtorFn) 510349cc55cSDimitry Andric return nullptr; 511349cc55cSDimitry Andric return MCAsmParserCtorFn(STI, Parser, MII, Options); 512349cc55cSDimitry Andric } 513349cc55cSDimitry Andric 514349cc55cSDimitry Andric /// createAsmPrinter - Create a target specific assembly printer pass. This 515349cc55cSDimitry Andric /// takes ownership of the MCStreamer object. 516349cc55cSDimitry Andric AsmPrinter *createAsmPrinter(TargetMachine &TM, 517349cc55cSDimitry Andric std::unique_ptr<MCStreamer> &&Streamer) const { 518349cc55cSDimitry Andric if (!AsmPrinterCtorFn) 519349cc55cSDimitry Andric return nullptr; 520349cc55cSDimitry Andric return AsmPrinterCtorFn(TM, std::move(Streamer)); 521349cc55cSDimitry Andric } 522349cc55cSDimitry Andric 523349cc55cSDimitry Andric MCDisassembler *createMCDisassembler(const MCSubtargetInfo &STI, 524349cc55cSDimitry Andric MCContext &Ctx) const { 525349cc55cSDimitry Andric if (!MCDisassemblerCtorFn) 526349cc55cSDimitry Andric return nullptr; 527349cc55cSDimitry Andric return MCDisassemblerCtorFn(*this, STI, Ctx); 528349cc55cSDimitry Andric } 529349cc55cSDimitry Andric 530349cc55cSDimitry Andric MCInstPrinter *createMCInstPrinter(const Triple &T, unsigned SyntaxVariant, 531349cc55cSDimitry Andric const MCAsmInfo &MAI, 532349cc55cSDimitry Andric const MCInstrInfo &MII, 533349cc55cSDimitry Andric const MCRegisterInfo &MRI) const { 534349cc55cSDimitry Andric if (!MCInstPrinterCtorFn) 535349cc55cSDimitry Andric return nullptr; 536349cc55cSDimitry Andric return MCInstPrinterCtorFn(T, SyntaxVariant, MAI, MII, MRI); 537349cc55cSDimitry Andric } 538349cc55cSDimitry Andric 539349cc55cSDimitry Andric /// createMCCodeEmitter - Create a target specific code emitter. 540349cc55cSDimitry Andric MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II, 541349cc55cSDimitry Andric MCContext &Ctx) const { 542349cc55cSDimitry Andric if (!MCCodeEmitterCtorFn) 543349cc55cSDimitry Andric return nullptr; 54481ad6265SDimitry Andric return MCCodeEmitterCtorFn(II, Ctx); 545349cc55cSDimitry Andric } 546349cc55cSDimitry Andric 547349cc55cSDimitry Andric /// Create a target specific MCStreamer. 548349cc55cSDimitry Andric /// 549349cc55cSDimitry Andric /// \param T The target triple. 550349cc55cSDimitry Andric /// \param Ctx The target context. 551349cc55cSDimitry Andric /// \param TAB The target assembler backend object. Takes ownership. 552349cc55cSDimitry Andric /// \param OW The stream object. 553349cc55cSDimitry Andric /// \param Emitter The target independent assembler object.Takes ownership. 554349cc55cSDimitry Andric /// \param RelaxAll Relax all fixups? 555349cc55cSDimitry Andric MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx, 556349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 557349cc55cSDimitry Andric std::unique_ptr<MCObjectWriter> &&OW, 558349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&Emitter, 559349cc55cSDimitry Andric const MCSubtargetInfo &STI, bool RelaxAll, 560349cc55cSDimitry Andric bool IncrementalLinkerCompatible, 561349cc55cSDimitry Andric bool DWARFMustBeAtTheEnd) const { 562349cc55cSDimitry Andric MCStreamer *S = nullptr; 563349cc55cSDimitry Andric switch (T.getObjectFormat()) { 564349cc55cSDimitry Andric case Triple::UnknownObjectFormat: 565349cc55cSDimitry Andric llvm_unreachable("Unknown object format"); 566349cc55cSDimitry Andric case Triple::COFF: 567349cc55cSDimitry Andric assert(T.isOSWindows() && "only Windows COFF is supported"); 568349cc55cSDimitry Andric S = COFFStreamerCtorFn(Ctx, std::move(TAB), std::move(OW), 569349cc55cSDimitry Andric std::move(Emitter), RelaxAll, 570349cc55cSDimitry Andric IncrementalLinkerCompatible); 571349cc55cSDimitry Andric break; 572349cc55cSDimitry Andric case Triple::MachO: 573349cc55cSDimitry Andric if (MachOStreamerCtorFn) 574349cc55cSDimitry Andric S = MachOStreamerCtorFn(Ctx, std::move(TAB), std::move(OW), 575349cc55cSDimitry Andric std::move(Emitter), RelaxAll, 576349cc55cSDimitry Andric DWARFMustBeAtTheEnd); 577349cc55cSDimitry Andric else 578349cc55cSDimitry Andric S = createMachOStreamer(Ctx, std::move(TAB), std::move(OW), 579349cc55cSDimitry Andric std::move(Emitter), RelaxAll, 580349cc55cSDimitry Andric DWARFMustBeAtTheEnd); 581349cc55cSDimitry Andric break; 582349cc55cSDimitry Andric case Triple::ELF: 583349cc55cSDimitry Andric if (ELFStreamerCtorFn) 584349cc55cSDimitry Andric S = ELFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), 585349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 586349cc55cSDimitry Andric else 587349cc55cSDimitry Andric S = createELFStreamer(Ctx, std::move(TAB), std::move(OW), 588349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 589349cc55cSDimitry Andric break; 590349cc55cSDimitry Andric case Triple::Wasm: 591349cc55cSDimitry Andric if (WasmStreamerCtorFn) 592349cc55cSDimitry Andric S = WasmStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), 593349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 594349cc55cSDimitry Andric else 595349cc55cSDimitry Andric S = createWasmStreamer(Ctx, std::move(TAB), std::move(OW), 596349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 597349cc55cSDimitry Andric break; 598349cc55cSDimitry Andric case Triple::GOFF: 599349cc55cSDimitry Andric report_fatal_error("GOFF MCObjectStreamer not implemented yet"); 600349cc55cSDimitry Andric case Triple::XCOFF: 601349cc55cSDimitry Andric if (XCOFFStreamerCtorFn) 602349cc55cSDimitry Andric S = XCOFFStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), 603349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 604349cc55cSDimitry Andric else 605349cc55cSDimitry Andric S = createXCOFFStreamer(Ctx, std::move(TAB), std::move(OW), 606349cc55cSDimitry Andric std::move(Emitter), RelaxAll); 607349cc55cSDimitry Andric break; 60881ad6265SDimitry Andric case Triple::SPIRV: 60981ad6265SDimitry Andric if (SPIRVStreamerCtorFn) 61081ad6265SDimitry Andric S = SPIRVStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), 61181ad6265SDimitry Andric std::move(Emitter), RelaxAll); 61281ad6265SDimitry Andric else 61381ad6265SDimitry Andric S = createSPIRVStreamer(Ctx, std::move(TAB), std::move(OW), 61481ad6265SDimitry Andric std::move(Emitter), RelaxAll); 61581ad6265SDimitry Andric break; 61681ad6265SDimitry Andric case Triple::DXContainer: 61781ad6265SDimitry Andric if (DXContainerStreamerCtorFn) 61881ad6265SDimitry Andric S = DXContainerStreamerCtorFn(T, Ctx, std::move(TAB), std::move(OW), 61981ad6265SDimitry Andric std::move(Emitter), RelaxAll); 62081ad6265SDimitry Andric else 62181ad6265SDimitry Andric S = createDXContainerStreamer(Ctx, std::move(TAB), std::move(OW), 62281ad6265SDimitry Andric std::move(Emitter), RelaxAll); 62381ad6265SDimitry Andric break; 624349cc55cSDimitry Andric } 625349cc55cSDimitry Andric if (ObjectTargetStreamerCtorFn) 626349cc55cSDimitry Andric ObjectTargetStreamerCtorFn(*S, STI); 627349cc55cSDimitry Andric return S; 628349cc55cSDimitry Andric } 629349cc55cSDimitry Andric 630349cc55cSDimitry Andric MCStreamer *createAsmStreamer(MCContext &Ctx, 631349cc55cSDimitry Andric std::unique_ptr<formatted_raw_ostream> OS, 632349cc55cSDimitry Andric bool IsVerboseAsm, bool UseDwarfDirectory, 633349cc55cSDimitry Andric MCInstPrinter *InstPrint, 634349cc55cSDimitry Andric std::unique_ptr<MCCodeEmitter> &&CE, 635349cc55cSDimitry Andric std::unique_ptr<MCAsmBackend> &&TAB, 636349cc55cSDimitry Andric bool ShowInst) const { 637349cc55cSDimitry Andric formatted_raw_ostream &OSRef = *OS; 638349cc55cSDimitry Andric MCStreamer *S = llvm::createAsmStreamer( 639349cc55cSDimitry Andric Ctx, std::move(OS), IsVerboseAsm, UseDwarfDirectory, InstPrint, 640349cc55cSDimitry Andric std::move(CE), std::move(TAB), ShowInst); 641349cc55cSDimitry Andric createAsmTargetStreamer(*S, OSRef, InstPrint, IsVerboseAsm); 642349cc55cSDimitry Andric return S; 643349cc55cSDimitry Andric } 644349cc55cSDimitry Andric 645349cc55cSDimitry Andric MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S, 646349cc55cSDimitry Andric formatted_raw_ostream &OS, 647349cc55cSDimitry Andric MCInstPrinter *InstPrint, 648349cc55cSDimitry Andric bool IsVerboseAsm) const { 649349cc55cSDimitry Andric if (AsmTargetStreamerCtorFn) 650349cc55cSDimitry Andric return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm); 651349cc55cSDimitry Andric return nullptr; 652349cc55cSDimitry Andric } 653349cc55cSDimitry Andric 654349cc55cSDimitry Andric MCStreamer *createNullStreamer(MCContext &Ctx) const { 655349cc55cSDimitry Andric MCStreamer *S = llvm::createNullStreamer(Ctx); 656349cc55cSDimitry Andric createNullTargetStreamer(*S); 657349cc55cSDimitry Andric return S; 658349cc55cSDimitry Andric } 659349cc55cSDimitry Andric 660349cc55cSDimitry Andric MCTargetStreamer *createNullTargetStreamer(MCStreamer &S) const { 661349cc55cSDimitry Andric if (NullTargetStreamerCtorFn) 662349cc55cSDimitry Andric return NullTargetStreamerCtorFn(S); 663349cc55cSDimitry Andric return nullptr; 664349cc55cSDimitry Andric } 665349cc55cSDimitry Andric 666349cc55cSDimitry Andric /// createMCRelocationInfo - Create a target specific MCRelocationInfo. 667349cc55cSDimitry Andric /// 668349cc55cSDimitry Andric /// \param TT The target triple. 669349cc55cSDimitry Andric /// \param Ctx The target context. 670349cc55cSDimitry Andric MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const { 671349cc55cSDimitry Andric MCRelocationInfoCtorTy Fn = MCRelocationInfoCtorFn 672349cc55cSDimitry Andric ? MCRelocationInfoCtorFn 673349cc55cSDimitry Andric : llvm::createMCRelocationInfo; 674349cc55cSDimitry Andric return Fn(Triple(TT), Ctx); 675349cc55cSDimitry Andric } 676349cc55cSDimitry Andric 677349cc55cSDimitry Andric /// createMCSymbolizer - Create a target specific MCSymbolizer. 678349cc55cSDimitry Andric /// 679349cc55cSDimitry Andric /// \param TT The target triple. 680349cc55cSDimitry Andric /// \param GetOpInfo The function to get the symbolic information for 681349cc55cSDimitry Andric /// operands. 682349cc55cSDimitry Andric /// \param SymbolLookUp The function to lookup a symbol name. 683349cc55cSDimitry Andric /// \param DisInfo The pointer to the block of symbolic information for above 684349cc55cSDimitry Andric /// call 685349cc55cSDimitry Andric /// back. 686349cc55cSDimitry Andric /// \param Ctx The target context. 687349cc55cSDimitry Andric /// \param RelInfo The relocation information for this target. Takes 688349cc55cSDimitry Andric /// ownership. 689349cc55cSDimitry Andric MCSymbolizer * 690349cc55cSDimitry Andric createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo, 691349cc55cSDimitry Andric LLVMSymbolLookupCallback SymbolLookUp, void *DisInfo, 692349cc55cSDimitry Andric MCContext *Ctx, 693349cc55cSDimitry Andric std::unique_ptr<MCRelocationInfo> &&RelInfo) const { 694349cc55cSDimitry Andric MCSymbolizerCtorTy Fn = 695349cc55cSDimitry Andric MCSymbolizerCtorFn ? MCSymbolizerCtorFn : llvm::createMCSymbolizer; 696349cc55cSDimitry Andric return Fn(Triple(TT), GetOpInfo, SymbolLookUp, DisInfo, Ctx, 697349cc55cSDimitry Andric std::move(RelInfo)); 698349cc55cSDimitry Andric } 699349cc55cSDimitry Andric 700349cc55cSDimitry Andric /// createCustomBehaviour - Create a target specific CustomBehaviour. 701349cc55cSDimitry Andric /// This class is used by llvm-mca and requires backend functionality. 702349cc55cSDimitry Andric mca::CustomBehaviour *createCustomBehaviour(const MCSubtargetInfo &STI, 703349cc55cSDimitry Andric const mca::SourceMgr &SrcMgr, 704349cc55cSDimitry Andric const MCInstrInfo &MCII) const { 705349cc55cSDimitry Andric if (CustomBehaviourCtorFn) 706349cc55cSDimitry Andric return CustomBehaviourCtorFn(STI, SrcMgr, MCII); 707349cc55cSDimitry Andric return nullptr; 708349cc55cSDimitry Andric } 709349cc55cSDimitry Andric 710349cc55cSDimitry Andric /// createInstrPostProcess - Create a target specific InstrPostProcess. 711349cc55cSDimitry Andric /// This class is used by llvm-mca and requires backend functionality. 712349cc55cSDimitry Andric mca::InstrPostProcess *createInstrPostProcess(const MCSubtargetInfo &STI, 713349cc55cSDimitry Andric const MCInstrInfo &MCII) const { 714349cc55cSDimitry Andric if (InstrPostProcessCtorFn) 715349cc55cSDimitry Andric return InstrPostProcessCtorFn(STI, MCII); 716349cc55cSDimitry Andric return nullptr; 717349cc55cSDimitry Andric } 718349cc55cSDimitry Andric 719*bdd1243dSDimitry Andric /// createInstrumentManager - Create a target specific 720*bdd1243dSDimitry Andric /// InstrumentManager. This class is used by llvm-mca and requires 721*bdd1243dSDimitry Andric /// backend functionality. 722*bdd1243dSDimitry Andric mca::InstrumentManager * 723*bdd1243dSDimitry Andric createInstrumentManager(const MCSubtargetInfo &STI, 724*bdd1243dSDimitry Andric const MCInstrInfo &MCII) const { 725*bdd1243dSDimitry Andric if (InstrumentManagerCtorFn) 726*bdd1243dSDimitry Andric return InstrumentManagerCtorFn(STI, MCII); 727*bdd1243dSDimitry Andric return nullptr; 728*bdd1243dSDimitry Andric } 729*bdd1243dSDimitry Andric 730349cc55cSDimitry Andric /// @} 731349cc55cSDimitry Andric }; 732349cc55cSDimitry Andric 733349cc55cSDimitry Andric /// TargetRegistry - Generic interface to target specific features. 734349cc55cSDimitry Andric struct TargetRegistry { 735349cc55cSDimitry Andric // FIXME: Make this a namespace, probably just move all the Register* 736349cc55cSDimitry Andric // functions into Target (currently they all just set members on the Target 737349cc55cSDimitry Andric // anyway, and Target friends this class so those functions can... 738349cc55cSDimitry Andric // function). 739349cc55cSDimitry Andric TargetRegistry() = delete; 740349cc55cSDimitry Andric 741349cc55cSDimitry Andric class iterator { 742349cc55cSDimitry Andric friend struct TargetRegistry; 743349cc55cSDimitry Andric 744349cc55cSDimitry Andric const Target *Current = nullptr; 745349cc55cSDimitry Andric 746349cc55cSDimitry Andric explicit iterator(Target *T) : Current(T) {} 747349cc55cSDimitry Andric 748349cc55cSDimitry Andric public: 749349cc55cSDimitry Andric using iterator_category = std::forward_iterator_tag; 750349cc55cSDimitry Andric using value_type = Target; 751349cc55cSDimitry Andric using difference_type = std::ptrdiff_t; 752349cc55cSDimitry Andric using pointer = value_type *; 753349cc55cSDimitry Andric using reference = value_type &; 754349cc55cSDimitry Andric 755349cc55cSDimitry Andric iterator() = default; 756349cc55cSDimitry Andric 757349cc55cSDimitry Andric bool operator==(const iterator &x) const { return Current == x.Current; } 758349cc55cSDimitry Andric bool operator!=(const iterator &x) const { return !operator==(x); } 759349cc55cSDimitry Andric 760349cc55cSDimitry Andric // Iterator traversal: forward iteration only 761349cc55cSDimitry Andric iterator &operator++() { // Preincrement 762349cc55cSDimitry Andric assert(Current && "Cannot increment end iterator!"); 763349cc55cSDimitry Andric Current = Current->getNext(); 764349cc55cSDimitry Andric return *this; 765349cc55cSDimitry Andric } 766349cc55cSDimitry Andric iterator operator++(int) { // Postincrement 767349cc55cSDimitry Andric iterator tmp = *this; 768349cc55cSDimitry Andric ++*this; 769349cc55cSDimitry Andric return tmp; 770349cc55cSDimitry Andric } 771349cc55cSDimitry Andric 772349cc55cSDimitry Andric const Target &operator*() const { 773349cc55cSDimitry Andric assert(Current && "Cannot dereference end iterator!"); 774349cc55cSDimitry Andric return *Current; 775349cc55cSDimitry Andric } 776349cc55cSDimitry Andric 777349cc55cSDimitry Andric const Target *operator->() const { return &operator*(); } 778349cc55cSDimitry Andric }; 779349cc55cSDimitry Andric 780349cc55cSDimitry Andric /// printRegisteredTargetsForVersion - Print the registered targets 781349cc55cSDimitry Andric /// appropriately for inclusion in a tool's version output. 782349cc55cSDimitry Andric static void printRegisteredTargetsForVersion(raw_ostream &OS); 783349cc55cSDimitry Andric 784349cc55cSDimitry Andric /// @name Registry Access 785349cc55cSDimitry Andric /// @{ 786349cc55cSDimitry Andric 787349cc55cSDimitry Andric static iterator_range<iterator> targets(); 788349cc55cSDimitry Andric 789349cc55cSDimitry Andric /// lookupTarget - Lookup a target based on a target triple. 790349cc55cSDimitry Andric /// 791349cc55cSDimitry Andric /// \param Triple - The triple to use for finding a target. 792349cc55cSDimitry Andric /// \param Error - On failure, an error string describing why no target was 793349cc55cSDimitry Andric /// found. 794349cc55cSDimitry Andric static const Target *lookupTarget(const std::string &Triple, 795349cc55cSDimitry Andric std::string &Error); 796349cc55cSDimitry Andric 797349cc55cSDimitry Andric /// lookupTarget - Lookup a target based on an architecture name 798349cc55cSDimitry Andric /// and a target triple. If the architecture name is non-empty, 799349cc55cSDimitry Andric /// then the lookup is done by architecture. Otherwise, the target 800349cc55cSDimitry Andric /// triple is used. 801349cc55cSDimitry Andric /// 802349cc55cSDimitry Andric /// \param ArchName - The architecture to use for finding a target. 803349cc55cSDimitry Andric /// \param TheTriple - The triple to use for finding a target. The 804349cc55cSDimitry Andric /// triple is updated with canonical architecture name if a lookup 805349cc55cSDimitry Andric /// by architecture is done. 806349cc55cSDimitry Andric /// \param Error - On failure, an error string describing why no target was 807349cc55cSDimitry Andric /// found. 808349cc55cSDimitry Andric static const Target *lookupTarget(const std::string &ArchName, 809349cc55cSDimitry Andric Triple &TheTriple, std::string &Error); 810349cc55cSDimitry Andric 811349cc55cSDimitry Andric /// @} 812349cc55cSDimitry Andric /// @name Target Registration 813349cc55cSDimitry Andric /// @{ 814349cc55cSDimitry Andric 815349cc55cSDimitry Andric /// RegisterTarget - Register the given target. Attempts to register a 816349cc55cSDimitry Andric /// target which has already been registered will be ignored. 817349cc55cSDimitry Andric /// 818349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 819349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 820349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 821349cc55cSDimitry Andric /// 822349cc55cSDimitry Andric /// @param T - The target being registered. 823349cc55cSDimitry Andric /// @param Name - The target name. This should be a static string. 824349cc55cSDimitry Andric /// @param ShortDesc - A short target description. This should be a static 825349cc55cSDimitry Andric /// string. 826349cc55cSDimitry Andric /// @param BackendName - The name of the backend. This should be a static 827349cc55cSDimitry Andric /// string that is the same for all targets that share a backend 828349cc55cSDimitry Andric /// implementation and must match the name used in the 'def X : Target ...' in 829349cc55cSDimitry Andric /// TableGen. 830349cc55cSDimitry Andric /// @param ArchMatchFn - The arch match checking function for this target. 831349cc55cSDimitry Andric /// @param HasJIT - Whether the target supports JIT code 832349cc55cSDimitry Andric /// generation. 833349cc55cSDimitry Andric static void RegisterTarget(Target &T, const char *Name, const char *ShortDesc, 834349cc55cSDimitry Andric const char *BackendName, 835349cc55cSDimitry Andric Target::ArchMatchFnTy ArchMatchFn, 836349cc55cSDimitry Andric bool HasJIT = false); 837349cc55cSDimitry Andric 838349cc55cSDimitry Andric /// RegisterMCAsmInfo - Register a MCAsmInfo implementation for the 839349cc55cSDimitry Andric /// given target. 840349cc55cSDimitry Andric /// 841349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 842349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 843349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 844349cc55cSDimitry Andric /// 845349cc55cSDimitry Andric /// @param T - The target being registered. 846349cc55cSDimitry Andric /// @param Fn - A function to construct a MCAsmInfo for the target. 847349cc55cSDimitry Andric static void RegisterMCAsmInfo(Target &T, Target::MCAsmInfoCtorFnTy Fn) { 848349cc55cSDimitry Andric T.MCAsmInfoCtorFn = Fn; 849349cc55cSDimitry Andric } 850349cc55cSDimitry Andric 851349cc55cSDimitry Andric /// Register a MCObjectFileInfo implementation for the given target. 852349cc55cSDimitry Andric /// 853349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 854349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 855349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 856349cc55cSDimitry Andric /// 857349cc55cSDimitry Andric /// @param T - The target being registered. 858349cc55cSDimitry Andric /// @param Fn - A function to construct a MCObjectFileInfo for the target. 859349cc55cSDimitry Andric static void RegisterMCObjectFileInfo(Target &T, 860349cc55cSDimitry Andric Target::MCObjectFileInfoCtorFnTy Fn) { 861349cc55cSDimitry Andric T.MCObjectFileInfoCtorFn = Fn; 862349cc55cSDimitry Andric } 863349cc55cSDimitry Andric 864349cc55cSDimitry Andric /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the 865349cc55cSDimitry Andric /// given target. 866349cc55cSDimitry Andric /// 867349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 868349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 869349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 870349cc55cSDimitry Andric /// 871349cc55cSDimitry Andric /// @param T - The target being registered. 872349cc55cSDimitry Andric /// @param Fn - A function to construct a MCInstrInfo for the target. 873349cc55cSDimitry Andric static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) { 874349cc55cSDimitry Andric T.MCInstrInfoCtorFn = Fn; 875349cc55cSDimitry Andric } 876349cc55cSDimitry Andric 877349cc55cSDimitry Andric /// RegisterMCInstrAnalysis - Register a MCInstrAnalysis implementation for 878349cc55cSDimitry Andric /// the given target. 879349cc55cSDimitry Andric static void RegisterMCInstrAnalysis(Target &T, 880349cc55cSDimitry Andric Target::MCInstrAnalysisCtorFnTy Fn) { 881349cc55cSDimitry Andric T.MCInstrAnalysisCtorFn = Fn; 882349cc55cSDimitry Andric } 883349cc55cSDimitry Andric 884349cc55cSDimitry Andric /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the 885349cc55cSDimitry Andric /// given target. 886349cc55cSDimitry Andric /// 887349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 888349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 889349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 890349cc55cSDimitry Andric /// 891349cc55cSDimitry Andric /// @param T - The target being registered. 892349cc55cSDimitry Andric /// @param Fn - A function to construct a MCRegisterInfo for the target. 893349cc55cSDimitry Andric static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) { 894349cc55cSDimitry Andric T.MCRegInfoCtorFn = Fn; 895349cc55cSDimitry Andric } 896349cc55cSDimitry Andric 897349cc55cSDimitry Andric /// RegisterMCSubtargetInfo - Register a MCSubtargetInfo implementation for 898349cc55cSDimitry Andric /// the given target. 899349cc55cSDimitry Andric /// 900349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 901349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 902349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 903349cc55cSDimitry Andric /// 904349cc55cSDimitry Andric /// @param T - The target being registered. 905349cc55cSDimitry Andric /// @param Fn - A function to construct a MCSubtargetInfo for the target. 906349cc55cSDimitry Andric static void RegisterMCSubtargetInfo(Target &T, 907349cc55cSDimitry Andric Target::MCSubtargetInfoCtorFnTy Fn) { 908349cc55cSDimitry Andric T.MCSubtargetInfoCtorFn = Fn; 909349cc55cSDimitry Andric } 910349cc55cSDimitry Andric 911349cc55cSDimitry Andric /// RegisterTargetMachine - Register a TargetMachine implementation for the 912349cc55cSDimitry Andric /// given target. 913349cc55cSDimitry Andric /// 914349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 915349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 916349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 917349cc55cSDimitry Andric /// 918349cc55cSDimitry Andric /// @param T - The target being registered. 919349cc55cSDimitry Andric /// @param Fn - A function to construct a TargetMachine for the target. 920349cc55cSDimitry Andric static void RegisterTargetMachine(Target &T, Target::TargetMachineCtorTy Fn) { 921349cc55cSDimitry Andric T.TargetMachineCtorFn = Fn; 922349cc55cSDimitry Andric } 923349cc55cSDimitry Andric 924349cc55cSDimitry Andric /// RegisterMCAsmBackend - Register a MCAsmBackend implementation for the 925349cc55cSDimitry Andric /// given target. 926349cc55cSDimitry Andric /// 927349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 928349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 929349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 930349cc55cSDimitry Andric /// 931349cc55cSDimitry Andric /// @param T - The target being registered. 932349cc55cSDimitry Andric /// @param Fn - A function to construct an AsmBackend for the target. 933349cc55cSDimitry Andric static void RegisterMCAsmBackend(Target &T, Target::MCAsmBackendCtorTy Fn) { 934349cc55cSDimitry Andric T.MCAsmBackendCtorFn = Fn; 935349cc55cSDimitry Andric } 936349cc55cSDimitry Andric 937349cc55cSDimitry Andric /// RegisterMCAsmParser - Register a MCTargetAsmParser implementation for 938349cc55cSDimitry Andric /// the given target. 939349cc55cSDimitry Andric /// 940349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 941349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 942349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 943349cc55cSDimitry Andric /// 944349cc55cSDimitry Andric /// @param T - The target being registered. 945349cc55cSDimitry Andric /// @param Fn - A function to construct an MCTargetAsmParser for the target. 946349cc55cSDimitry Andric static void RegisterMCAsmParser(Target &T, Target::MCAsmParserCtorTy Fn) { 947349cc55cSDimitry Andric T.MCAsmParserCtorFn = Fn; 948349cc55cSDimitry Andric } 949349cc55cSDimitry Andric 950349cc55cSDimitry Andric /// RegisterAsmPrinter - Register an AsmPrinter implementation for the given 951349cc55cSDimitry Andric /// target. 952349cc55cSDimitry Andric /// 953349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 954349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 955349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 956349cc55cSDimitry Andric /// 957349cc55cSDimitry Andric /// @param T - The target being registered. 958349cc55cSDimitry Andric /// @param Fn - A function to construct an AsmPrinter for the target. 959349cc55cSDimitry Andric static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn) { 960349cc55cSDimitry Andric T.AsmPrinterCtorFn = Fn; 961349cc55cSDimitry Andric } 962349cc55cSDimitry Andric 963349cc55cSDimitry Andric /// RegisterMCDisassembler - Register a MCDisassembler implementation for 964349cc55cSDimitry Andric /// the given target. 965349cc55cSDimitry Andric /// 966349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 967349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 968349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 969349cc55cSDimitry Andric /// 970349cc55cSDimitry Andric /// @param T - The target being registered. 971349cc55cSDimitry Andric /// @param Fn - A function to construct an MCDisassembler for the target. 972349cc55cSDimitry Andric static void RegisterMCDisassembler(Target &T, 973349cc55cSDimitry Andric Target::MCDisassemblerCtorTy Fn) { 974349cc55cSDimitry Andric T.MCDisassemblerCtorFn = Fn; 975349cc55cSDimitry Andric } 976349cc55cSDimitry Andric 977349cc55cSDimitry Andric /// RegisterMCInstPrinter - Register a MCInstPrinter implementation for the 978349cc55cSDimitry Andric /// given target. 979349cc55cSDimitry Andric /// 980349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 981349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 982349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 983349cc55cSDimitry Andric /// 984349cc55cSDimitry Andric /// @param T - The target being registered. 985349cc55cSDimitry Andric /// @param Fn - A function to construct an MCInstPrinter for the target. 986349cc55cSDimitry Andric static void RegisterMCInstPrinter(Target &T, Target::MCInstPrinterCtorTy Fn) { 987349cc55cSDimitry Andric T.MCInstPrinterCtorFn = Fn; 988349cc55cSDimitry Andric } 989349cc55cSDimitry Andric 990349cc55cSDimitry Andric /// RegisterMCCodeEmitter - Register a MCCodeEmitter implementation for the 991349cc55cSDimitry Andric /// given target. 992349cc55cSDimitry Andric /// 993349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 994349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 995349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 996349cc55cSDimitry Andric /// 997349cc55cSDimitry Andric /// @param T - The target being registered. 998349cc55cSDimitry Andric /// @param Fn - A function to construct an MCCodeEmitter for the target. 999349cc55cSDimitry Andric static void RegisterMCCodeEmitter(Target &T, Target::MCCodeEmitterCtorTy Fn) { 1000349cc55cSDimitry Andric T.MCCodeEmitterCtorFn = Fn; 1001349cc55cSDimitry Andric } 1002349cc55cSDimitry Andric 1003349cc55cSDimitry Andric static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) { 1004349cc55cSDimitry Andric T.COFFStreamerCtorFn = Fn; 1005349cc55cSDimitry Andric } 1006349cc55cSDimitry Andric 1007349cc55cSDimitry Andric static void RegisterMachOStreamer(Target &T, Target::MachOStreamerCtorTy Fn) { 1008349cc55cSDimitry Andric T.MachOStreamerCtorFn = Fn; 1009349cc55cSDimitry Andric } 1010349cc55cSDimitry Andric 1011349cc55cSDimitry Andric static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) { 1012349cc55cSDimitry Andric T.ELFStreamerCtorFn = Fn; 1013349cc55cSDimitry Andric } 1014349cc55cSDimitry Andric 101581ad6265SDimitry Andric static void RegisterSPIRVStreamer(Target &T, Target::SPIRVStreamerCtorTy Fn) { 101681ad6265SDimitry Andric T.SPIRVStreamerCtorFn = Fn; 101781ad6265SDimitry Andric } 101881ad6265SDimitry Andric 101981ad6265SDimitry Andric static void RegisterDXContainerStreamer(Target &T, Target::DXContainerStreamerCtorTy Fn) { 102081ad6265SDimitry Andric T.DXContainerStreamerCtorFn = Fn; 102181ad6265SDimitry Andric } 102281ad6265SDimitry Andric 1023349cc55cSDimitry Andric static void RegisterWasmStreamer(Target &T, Target::WasmStreamerCtorTy Fn) { 1024349cc55cSDimitry Andric T.WasmStreamerCtorFn = Fn; 1025349cc55cSDimitry Andric } 1026349cc55cSDimitry Andric 1027349cc55cSDimitry Andric static void RegisterXCOFFStreamer(Target &T, Target::XCOFFStreamerCtorTy Fn) { 1028349cc55cSDimitry Andric T.XCOFFStreamerCtorFn = Fn; 1029349cc55cSDimitry Andric } 1030349cc55cSDimitry Andric 1031349cc55cSDimitry Andric static void RegisterNullTargetStreamer(Target &T, 1032349cc55cSDimitry Andric Target::NullTargetStreamerCtorTy Fn) { 1033349cc55cSDimitry Andric T.NullTargetStreamerCtorFn = Fn; 1034349cc55cSDimitry Andric } 1035349cc55cSDimitry Andric 1036349cc55cSDimitry Andric static void RegisterAsmTargetStreamer(Target &T, 1037349cc55cSDimitry Andric Target::AsmTargetStreamerCtorTy Fn) { 1038349cc55cSDimitry Andric T.AsmTargetStreamerCtorFn = Fn; 1039349cc55cSDimitry Andric } 1040349cc55cSDimitry Andric 1041349cc55cSDimitry Andric static void 1042349cc55cSDimitry Andric RegisterObjectTargetStreamer(Target &T, 1043349cc55cSDimitry Andric Target::ObjectTargetStreamerCtorTy Fn) { 1044349cc55cSDimitry Andric T.ObjectTargetStreamerCtorFn = Fn; 1045349cc55cSDimitry Andric } 1046349cc55cSDimitry Andric 1047349cc55cSDimitry Andric /// RegisterMCRelocationInfo - Register an MCRelocationInfo 1048349cc55cSDimitry Andric /// implementation for the given target. 1049349cc55cSDimitry Andric /// 1050349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 1051349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 1052349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 1053349cc55cSDimitry Andric /// 1054349cc55cSDimitry Andric /// @param T - The target being registered. 1055349cc55cSDimitry Andric /// @param Fn - A function to construct an MCRelocationInfo for the target. 1056349cc55cSDimitry Andric static void RegisterMCRelocationInfo(Target &T, 1057349cc55cSDimitry Andric Target::MCRelocationInfoCtorTy Fn) { 1058349cc55cSDimitry Andric T.MCRelocationInfoCtorFn = Fn; 1059349cc55cSDimitry Andric } 1060349cc55cSDimitry Andric 1061349cc55cSDimitry Andric /// RegisterMCSymbolizer - Register an MCSymbolizer 1062349cc55cSDimitry Andric /// implementation for the given target. 1063349cc55cSDimitry Andric /// 1064349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 1065349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 1066349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 1067349cc55cSDimitry Andric /// 1068349cc55cSDimitry Andric /// @param T - The target being registered. 1069349cc55cSDimitry Andric /// @param Fn - A function to construct an MCSymbolizer for the target. 1070349cc55cSDimitry Andric static void RegisterMCSymbolizer(Target &T, Target::MCSymbolizerCtorTy Fn) { 1071349cc55cSDimitry Andric T.MCSymbolizerCtorFn = Fn; 1072349cc55cSDimitry Andric } 1073349cc55cSDimitry Andric 1074349cc55cSDimitry Andric /// RegisterCustomBehaviour - Register a CustomBehaviour 1075349cc55cSDimitry Andric /// implementation for the given target. 1076349cc55cSDimitry Andric /// 1077349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 1078349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 1079349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 1080349cc55cSDimitry Andric /// 1081349cc55cSDimitry Andric /// @param T - The target being registered. 1082349cc55cSDimitry Andric /// @param Fn - A function to construct a CustomBehaviour for the target. 1083349cc55cSDimitry Andric static void RegisterCustomBehaviour(Target &T, 1084349cc55cSDimitry Andric Target::CustomBehaviourCtorTy Fn) { 1085349cc55cSDimitry Andric T.CustomBehaviourCtorFn = Fn; 1086349cc55cSDimitry Andric } 1087349cc55cSDimitry Andric 1088349cc55cSDimitry Andric /// RegisterInstrPostProcess - Register an InstrPostProcess 1089349cc55cSDimitry Andric /// implementation for the given target. 1090349cc55cSDimitry Andric /// 1091349cc55cSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 1092349cc55cSDimitry Andric /// while another thread is attempting to access the registry. Typically 1093349cc55cSDimitry Andric /// this is done by initializing all targets at program startup. 1094349cc55cSDimitry Andric /// 1095349cc55cSDimitry Andric /// @param T - The target being registered. 1096349cc55cSDimitry Andric /// @param Fn - A function to construct an InstrPostProcess for the target. 1097349cc55cSDimitry Andric static void RegisterInstrPostProcess(Target &T, 1098349cc55cSDimitry Andric Target::InstrPostProcessCtorTy Fn) { 1099349cc55cSDimitry Andric T.InstrPostProcessCtorFn = Fn; 1100349cc55cSDimitry Andric } 1101349cc55cSDimitry Andric 1102*bdd1243dSDimitry Andric /// RegisterInstrumentManager - Register an InstrumentManager 1103*bdd1243dSDimitry Andric /// implementation for the given target. 1104*bdd1243dSDimitry Andric /// 1105*bdd1243dSDimitry Andric /// Clients are responsible for ensuring that registration doesn't occur 1106*bdd1243dSDimitry Andric /// while another thread is attempting to access the registry. Typically 1107*bdd1243dSDimitry Andric /// this is done by initializing all targets at program startup. 1108*bdd1243dSDimitry Andric /// 1109*bdd1243dSDimitry Andric /// @param T - The target being registered. 1110*bdd1243dSDimitry Andric /// @param Fn - A function to construct an InstrumentManager for the 1111*bdd1243dSDimitry Andric /// target. 1112*bdd1243dSDimitry Andric static void RegisterInstrumentManager(Target &T, 1113*bdd1243dSDimitry Andric Target::InstrumentManagerCtorTy Fn) { 1114*bdd1243dSDimitry Andric T.InstrumentManagerCtorFn = Fn; 1115*bdd1243dSDimitry Andric } 1116*bdd1243dSDimitry Andric 1117349cc55cSDimitry Andric /// @} 1118349cc55cSDimitry Andric }; 1119349cc55cSDimitry Andric 1120349cc55cSDimitry Andric //===--------------------------------------------------------------------===// 1121349cc55cSDimitry Andric 1122349cc55cSDimitry Andric /// RegisterTarget - Helper template for registering a target, for use in the 1123349cc55cSDimitry Andric /// target's initialization function. Usage: 1124349cc55cSDimitry Andric /// 1125349cc55cSDimitry Andric /// 1126349cc55cSDimitry Andric /// Target &getTheFooTarget() { // The global target instance. 1127349cc55cSDimitry Andric /// static Target TheFooTarget; 1128349cc55cSDimitry Andric /// return TheFooTarget; 1129349cc55cSDimitry Andric /// } 1130349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTargetInfo() { 1131349cc55cSDimitry Andric /// RegisterTarget<Triple::foo> X(getTheFooTarget(), "foo", "Foo 1132349cc55cSDimitry Andric /// description", "Foo" /* Backend Name */); 1133349cc55cSDimitry Andric /// } 1134349cc55cSDimitry Andric template <Triple::ArchType TargetArchType = Triple::UnknownArch, 1135349cc55cSDimitry Andric bool HasJIT = false> 1136349cc55cSDimitry Andric struct RegisterTarget { 1137349cc55cSDimitry Andric RegisterTarget(Target &T, const char *Name, const char *Desc, 1138349cc55cSDimitry Andric const char *BackendName) { 1139349cc55cSDimitry Andric TargetRegistry::RegisterTarget(T, Name, Desc, BackendName, &getArchMatch, 1140349cc55cSDimitry Andric HasJIT); 1141349cc55cSDimitry Andric } 1142349cc55cSDimitry Andric 1143349cc55cSDimitry Andric static bool getArchMatch(Triple::ArchType Arch) { 1144349cc55cSDimitry Andric return Arch == TargetArchType; 1145349cc55cSDimitry Andric } 1146349cc55cSDimitry Andric }; 1147349cc55cSDimitry Andric 1148349cc55cSDimitry Andric /// RegisterMCAsmInfo - Helper template for registering a target assembly info 1149349cc55cSDimitry Andric /// implementation. This invokes the static "Create" method on the class to 1150349cc55cSDimitry Andric /// actually do the construction. Usage: 1151349cc55cSDimitry Andric /// 1152349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1153349cc55cSDimitry Andric /// extern Target TheFooTarget; 1154349cc55cSDimitry Andric /// RegisterMCAsmInfo<FooMCAsmInfo> X(TheFooTarget); 1155349cc55cSDimitry Andric /// } 1156349cc55cSDimitry Andric template <class MCAsmInfoImpl> struct RegisterMCAsmInfo { 1157349cc55cSDimitry Andric RegisterMCAsmInfo(Target &T) { 1158349cc55cSDimitry Andric TargetRegistry::RegisterMCAsmInfo(T, &Allocator); 1159349cc55cSDimitry Andric } 1160349cc55cSDimitry Andric 1161349cc55cSDimitry Andric private: 1162349cc55cSDimitry Andric static MCAsmInfo *Allocator(const MCRegisterInfo & /*MRI*/, const Triple &TT, 1163349cc55cSDimitry Andric const MCTargetOptions &Options) { 1164349cc55cSDimitry Andric return new MCAsmInfoImpl(TT, Options); 1165349cc55cSDimitry Andric } 1166349cc55cSDimitry Andric }; 1167349cc55cSDimitry Andric 1168349cc55cSDimitry Andric /// RegisterMCAsmInfoFn - Helper template for registering a target assembly info 1169349cc55cSDimitry Andric /// implementation. This invokes the specified function to do the 1170349cc55cSDimitry Andric /// construction. Usage: 1171349cc55cSDimitry Andric /// 1172349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1173349cc55cSDimitry Andric /// extern Target TheFooTarget; 1174349cc55cSDimitry Andric /// RegisterMCAsmInfoFn X(TheFooTarget, TheFunction); 1175349cc55cSDimitry Andric /// } 1176349cc55cSDimitry Andric struct RegisterMCAsmInfoFn { 1177349cc55cSDimitry Andric RegisterMCAsmInfoFn(Target &T, Target::MCAsmInfoCtorFnTy Fn) { 1178349cc55cSDimitry Andric TargetRegistry::RegisterMCAsmInfo(T, Fn); 1179349cc55cSDimitry Andric } 1180349cc55cSDimitry Andric }; 1181349cc55cSDimitry Andric 1182349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation. 1183349cc55cSDimitry Andric /// This invokes the static "Create" method on the class to actually do the 1184349cc55cSDimitry Andric /// construction. Usage: 1185349cc55cSDimitry Andric /// 1186349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1187349cc55cSDimitry Andric /// extern Target TheFooTarget; 1188349cc55cSDimitry Andric /// RegisterMCObjectFileInfo<FooMCObjectFileInfo> X(TheFooTarget); 1189349cc55cSDimitry Andric /// } 1190349cc55cSDimitry Andric template <class MCObjectFileInfoImpl> struct RegisterMCObjectFileInfo { 1191349cc55cSDimitry Andric RegisterMCObjectFileInfo(Target &T) { 1192349cc55cSDimitry Andric TargetRegistry::RegisterMCObjectFileInfo(T, &Allocator); 1193349cc55cSDimitry Andric } 1194349cc55cSDimitry Andric 1195349cc55cSDimitry Andric private: 1196349cc55cSDimitry Andric static MCObjectFileInfo *Allocator(MCContext &Ctx, bool PIC, 1197349cc55cSDimitry Andric bool LargeCodeModel = false) { 1198349cc55cSDimitry Andric return new MCObjectFileInfoImpl(Ctx, PIC, LargeCodeModel); 1199349cc55cSDimitry Andric } 1200349cc55cSDimitry Andric }; 1201349cc55cSDimitry Andric 1202349cc55cSDimitry Andric /// Helper template for registering a target object file info implementation. 1203349cc55cSDimitry Andric /// This invokes the specified function to do the construction. Usage: 1204349cc55cSDimitry Andric /// 1205349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1206349cc55cSDimitry Andric /// extern Target TheFooTarget; 1207349cc55cSDimitry Andric /// RegisterMCObjectFileInfoFn X(TheFooTarget, TheFunction); 1208349cc55cSDimitry Andric /// } 1209349cc55cSDimitry Andric struct RegisterMCObjectFileInfoFn { 1210349cc55cSDimitry Andric RegisterMCObjectFileInfoFn(Target &T, Target::MCObjectFileInfoCtorFnTy Fn) { 1211349cc55cSDimitry Andric TargetRegistry::RegisterMCObjectFileInfo(T, Fn); 1212349cc55cSDimitry Andric } 1213349cc55cSDimitry Andric }; 1214349cc55cSDimitry Andric 1215349cc55cSDimitry Andric /// RegisterMCInstrInfo - Helper template for registering a target instruction 1216349cc55cSDimitry Andric /// info implementation. This invokes the static "Create" method on the class 1217349cc55cSDimitry Andric /// to actually do the construction. Usage: 1218349cc55cSDimitry Andric /// 1219349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1220349cc55cSDimitry Andric /// extern Target TheFooTarget; 1221349cc55cSDimitry Andric /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget); 1222349cc55cSDimitry Andric /// } 1223349cc55cSDimitry Andric template <class MCInstrInfoImpl> struct RegisterMCInstrInfo { 1224349cc55cSDimitry Andric RegisterMCInstrInfo(Target &T) { 1225349cc55cSDimitry Andric TargetRegistry::RegisterMCInstrInfo(T, &Allocator); 1226349cc55cSDimitry Andric } 1227349cc55cSDimitry Andric 1228349cc55cSDimitry Andric private: 1229349cc55cSDimitry Andric static MCInstrInfo *Allocator() { return new MCInstrInfoImpl(); } 1230349cc55cSDimitry Andric }; 1231349cc55cSDimitry Andric 1232349cc55cSDimitry Andric /// RegisterMCInstrInfoFn - Helper template for registering a target 1233349cc55cSDimitry Andric /// instruction info implementation. This invokes the specified function to 1234349cc55cSDimitry Andric /// do the construction. Usage: 1235349cc55cSDimitry Andric /// 1236349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1237349cc55cSDimitry Andric /// extern Target TheFooTarget; 1238349cc55cSDimitry Andric /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction); 1239349cc55cSDimitry Andric /// } 1240349cc55cSDimitry Andric struct RegisterMCInstrInfoFn { 1241349cc55cSDimitry Andric RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) { 1242349cc55cSDimitry Andric TargetRegistry::RegisterMCInstrInfo(T, Fn); 1243349cc55cSDimitry Andric } 1244349cc55cSDimitry Andric }; 1245349cc55cSDimitry Andric 1246349cc55cSDimitry Andric /// RegisterMCInstrAnalysis - Helper template for registering a target 1247349cc55cSDimitry Andric /// instruction analyzer implementation. This invokes the static "Create" 1248349cc55cSDimitry Andric /// method on the class to actually do the construction. Usage: 1249349cc55cSDimitry Andric /// 1250349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1251349cc55cSDimitry Andric /// extern Target TheFooTarget; 1252349cc55cSDimitry Andric /// RegisterMCInstrAnalysis<FooMCInstrAnalysis> X(TheFooTarget); 1253349cc55cSDimitry Andric /// } 1254349cc55cSDimitry Andric template <class MCInstrAnalysisImpl> struct RegisterMCInstrAnalysis { 1255349cc55cSDimitry Andric RegisterMCInstrAnalysis(Target &T) { 1256349cc55cSDimitry Andric TargetRegistry::RegisterMCInstrAnalysis(T, &Allocator); 1257349cc55cSDimitry Andric } 1258349cc55cSDimitry Andric 1259349cc55cSDimitry Andric private: 1260349cc55cSDimitry Andric static MCInstrAnalysis *Allocator(const MCInstrInfo *Info) { 1261349cc55cSDimitry Andric return new MCInstrAnalysisImpl(Info); 1262349cc55cSDimitry Andric } 1263349cc55cSDimitry Andric }; 1264349cc55cSDimitry Andric 1265349cc55cSDimitry Andric /// RegisterMCInstrAnalysisFn - Helper template for registering a target 1266349cc55cSDimitry Andric /// instruction analyzer implementation. This invokes the specified function 1267349cc55cSDimitry Andric /// to do the construction. Usage: 1268349cc55cSDimitry Andric /// 1269349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1270349cc55cSDimitry Andric /// extern Target TheFooTarget; 1271349cc55cSDimitry Andric /// RegisterMCInstrAnalysisFn X(TheFooTarget, TheFunction); 1272349cc55cSDimitry Andric /// } 1273349cc55cSDimitry Andric struct RegisterMCInstrAnalysisFn { 1274349cc55cSDimitry Andric RegisterMCInstrAnalysisFn(Target &T, Target::MCInstrAnalysisCtorFnTy Fn) { 1275349cc55cSDimitry Andric TargetRegistry::RegisterMCInstrAnalysis(T, Fn); 1276349cc55cSDimitry Andric } 1277349cc55cSDimitry Andric }; 1278349cc55cSDimitry Andric 1279349cc55cSDimitry Andric /// RegisterMCRegInfo - Helper template for registering a target register info 1280349cc55cSDimitry Andric /// implementation. This invokes the static "Create" method on the class to 1281349cc55cSDimitry Andric /// actually do the construction. Usage: 1282349cc55cSDimitry Andric /// 1283349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1284349cc55cSDimitry Andric /// extern Target TheFooTarget; 1285349cc55cSDimitry Andric /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget); 1286349cc55cSDimitry Andric /// } 1287349cc55cSDimitry Andric template <class MCRegisterInfoImpl> struct RegisterMCRegInfo { 1288349cc55cSDimitry Andric RegisterMCRegInfo(Target &T) { 1289349cc55cSDimitry Andric TargetRegistry::RegisterMCRegInfo(T, &Allocator); 1290349cc55cSDimitry Andric } 1291349cc55cSDimitry Andric 1292349cc55cSDimitry Andric private: 1293349cc55cSDimitry Andric static MCRegisterInfo *Allocator(const Triple & /*TT*/) { 1294349cc55cSDimitry Andric return new MCRegisterInfoImpl(); 1295349cc55cSDimitry Andric } 1296349cc55cSDimitry Andric }; 1297349cc55cSDimitry Andric 1298349cc55cSDimitry Andric /// RegisterMCRegInfoFn - Helper template for registering a target register 1299349cc55cSDimitry Andric /// info implementation. This invokes the specified function to do the 1300349cc55cSDimitry Andric /// construction. Usage: 1301349cc55cSDimitry Andric /// 1302349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1303349cc55cSDimitry Andric /// extern Target TheFooTarget; 1304349cc55cSDimitry Andric /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction); 1305349cc55cSDimitry Andric /// } 1306349cc55cSDimitry Andric struct RegisterMCRegInfoFn { 1307349cc55cSDimitry Andric RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) { 1308349cc55cSDimitry Andric TargetRegistry::RegisterMCRegInfo(T, Fn); 1309349cc55cSDimitry Andric } 1310349cc55cSDimitry Andric }; 1311349cc55cSDimitry Andric 1312349cc55cSDimitry Andric /// RegisterMCSubtargetInfo - Helper template for registering a target 1313349cc55cSDimitry Andric /// subtarget info implementation. This invokes the static "Create" method 1314349cc55cSDimitry Andric /// on the class to actually do the construction. Usage: 1315349cc55cSDimitry Andric /// 1316349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1317349cc55cSDimitry Andric /// extern Target TheFooTarget; 1318349cc55cSDimitry Andric /// RegisterMCSubtargetInfo<FooMCSubtargetInfo> X(TheFooTarget); 1319349cc55cSDimitry Andric /// } 1320349cc55cSDimitry Andric template <class MCSubtargetInfoImpl> struct RegisterMCSubtargetInfo { 1321349cc55cSDimitry Andric RegisterMCSubtargetInfo(Target &T) { 1322349cc55cSDimitry Andric TargetRegistry::RegisterMCSubtargetInfo(T, &Allocator); 1323349cc55cSDimitry Andric } 1324349cc55cSDimitry Andric 1325349cc55cSDimitry Andric private: 1326349cc55cSDimitry Andric static MCSubtargetInfo *Allocator(const Triple & /*TT*/, StringRef /*CPU*/, 1327349cc55cSDimitry Andric StringRef /*FS*/) { 1328349cc55cSDimitry Andric return new MCSubtargetInfoImpl(); 1329349cc55cSDimitry Andric } 1330349cc55cSDimitry Andric }; 1331349cc55cSDimitry Andric 1332349cc55cSDimitry Andric /// RegisterMCSubtargetInfoFn - Helper template for registering a target 1333349cc55cSDimitry Andric /// subtarget info implementation. This invokes the specified function to 1334349cc55cSDimitry Andric /// do the construction. Usage: 1335349cc55cSDimitry Andric /// 1336349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1337349cc55cSDimitry Andric /// extern Target TheFooTarget; 1338349cc55cSDimitry Andric /// RegisterMCSubtargetInfoFn X(TheFooTarget, TheFunction); 1339349cc55cSDimitry Andric /// } 1340349cc55cSDimitry Andric struct RegisterMCSubtargetInfoFn { 1341349cc55cSDimitry Andric RegisterMCSubtargetInfoFn(Target &T, Target::MCSubtargetInfoCtorFnTy Fn) { 1342349cc55cSDimitry Andric TargetRegistry::RegisterMCSubtargetInfo(T, Fn); 1343349cc55cSDimitry Andric } 1344349cc55cSDimitry Andric }; 1345349cc55cSDimitry Andric 1346349cc55cSDimitry Andric /// RegisterTargetMachine - Helper template for registering a target machine 1347349cc55cSDimitry Andric /// implementation, for use in the target machine initialization 1348349cc55cSDimitry Andric /// function. Usage: 1349349cc55cSDimitry Andric /// 1350349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooTarget() { 1351349cc55cSDimitry Andric /// extern Target TheFooTarget; 1352349cc55cSDimitry Andric /// RegisterTargetMachine<FooTargetMachine> X(TheFooTarget); 1353349cc55cSDimitry Andric /// } 1354349cc55cSDimitry Andric template <class TargetMachineImpl> struct RegisterTargetMachine { 1355349cc55cSDimitry Andric RegisterTargetMachine(Target &T) { 1356349cc55cSDimitry Andric TargetRegistry::RegisterTargetMachine(T, &Allocator); 1357349cc55cSDimitry Andric } 1358349cc55cSDimitry Andric 1359349cc55cSDimitry Andric private: 1360*bdd1243dSDimitry Andric static TargetMachine *Allocator(const Target &T, const Triple &TT, 1361*bdd1243dSDimitry Andric StringRef CPU, StringRef FS, 1362*bdd1243dSDimitry Andric const TargetOptions &Options, 1363*bdd1243dSDimitry Andric std::optional<Reloc::Model> RM, 1364*bdd1243dSDimitry Andric std::optional<CodeModel::Model> CM, 1365*bdd1243dSDimitry Andric CodeGenOpt::Level OL, bool JIT) { 1366349cc55cSDimitry Andric return new TargetMachineImpl(T, TT, CPU, FS, Options, RM, CM, OL, JIT); 1367349cc55cSDimitry Andric } 1368349cc55cSDimitry Andric }; 1369349cc55cSDimitry Andric 1370349cc55cSDimitry Andric /// RegisterMCAsmBackend - Helper template for registering a target specific 1371349cc55cSDimitry Andric /// assembler backend. Usage: 1372349cc55cSDimitry Andric /// 1373349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmBackend() { 1374349cc55cSDimitry Andric /// extern Target TheFooTarget; 1375349cc55cSDimitry Andric /// RegisterMCAsmBackend<FooAsmLexer> X(TheFooTarget); 1376349cc55cSDimitry Andric /// } 1377349cc55cSDimitry Andric template <class MCAsmBackendImpl> struct RegisterMCAsmBackend { 1378349cc55cSDimitry Andric RegisterMCAsmBackend(Target &T) { 1379349cc55cSDimitry Andric TargetRegistry::RegisterMCAsmBackend(T, &Allocator); 1380349cc55cSDimitry Andric } 1381349cc55cSDimitry Andric 1382349cc55cSDimitry Andric private: 1383349cc55cSDimitry Andric static MCAsmBackend *Allocator(const Target &T, const MCSubtargetInfo &STI, 1384349cc55cSDimitry Andric const MCRegisterInfo &MRI, 1385349cc55cSDimitry Andric const MCTargetOptions &Options) { 1386349cc55cSDimitry Andric return new MCAsmBackendImpl(T, STI, MRI); 1387349cc55cSDimitry Andric } 1388349cc55cSDimitry Andric }; 1389349cc55cSDimitry Andric 1390349cc55cSDimitry Andric /// RegisterMCAsmParser - Helper template for registering a target specific 1391349cc55cSDimitry Andric /// assembly parser, for use in the target machine initialization 1392349cc55cSDimitry Andric /// function. Usage: 1393349cc55cSDimitry Andric /// 1394349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCAsmParser() { 1395349cc55cSDimitry Andric /// extern Target TheFooTarget; 1396349cc55cSDimitry Andric /// RegisterMCAsmParser<FooAsmParser> X(TheFooTarget); 1397349cc55cSDimitry Andric /// } 1398349cc55cSDimitry Andric template <class MCAsmParserImpl> struct RegisterMCAsmParser { 1399349cc55cSDimitry Andric RegisterMCAsmParser(Target &T) { 1400349cc55cSDimitry Andric TargetRegistry::RegisterMCAsmParser(T, &Allocator); 1401349cc55cSDimitry Andric } 1402349cc55cSDimitry Andric 1403349cc55cSDimitry Andric private: 1404349cc55cSDimitry Andric static MCTargetAsmParser *Allocator(const MCSubtargetInfo &STI, 1405349cc55cSDimitry Andric MCAsmParser &P, const MCInstrInfo &MII, 1406349cc55cSDimitry Andric const MCTargetOptions &Options) { 1407349cc55cSDimitry Andric return new MCAsmParserImpl(STI, P, MII, Options); 1408349cc55cSDimitry Andric } 1409349cc55cSDimitry Andric }; 1410349cc55cSDimitry Andric 1411349cc55cSDimitry Andric /// RegisterAsmPrinter - Helper template for registering a target specific 1412349cc55cSDimitry Andric /// assembly printer, for use in the target machine initialization 1413349cc55cSDimitry Andric /// function. Usage: 1414349cc55cSDimitry Andric /// 1415349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooAsmPrinter() { 1416349cc55cSDimitry Andric /// extern Target TheFooTarget; 1417349cc55cSDimitry Andric /// RegisterAsmPrinter<FooAsmPrinter> X(TheFooTarget); 1418349cc55cSDimitry Andric /// } 1419349cc55cSDimitry Andric template <class AsmPrinterImpl> struct RegisterAsmPrinter { 1420349cc55cSDimitry Andric RegisterAsmPrinter(Target &T) { 1421349cc55cSDimitry Andric TargetRegistry::RegisterAsmPrinter(T, &Allocator); 1422349cc55cSDimitry Andric } 1423349cc55cSDimitry Andric 1424349cc55cSDimitry Andric private: 1425349cc55cSDimitry Andric static AsmPrinter *Allocator(TargetMachine &TM, 1426349cc55cSDimitry Andric std::unique_ptr<MCStreamer> &&Streamer) { 1427349cc55cSDimitry Andric return new AsmPrinterImpl(TM, std::move(Streamer)); 1428349cc55cSDimitry Andric } 1429349cc55cSDimitry Andric }; 1430349cc55cSDimitry Andric 1431349cc55cSDimitry Andric /// RegisterMCCodeEmitter - Helper template for registering a target specific 1432349cc55cSDimitry Andric /// machine code emitter, for use in the target initialization 1433349cc55cSDimitry Andric /// function. Usage: 1434349cc55cSDimitry Andric /// 1435349cc55cSDimitry Andric /// extern "C" void LLVMInitializeFooMCCodeEmitter() { 1436349cc55cSDimitry Andric /// extern Target TheFooTarget; 1437349cc55cSDimitry Andric /// RegisterMCCodeEmitter<FooCodeEmitter> X(TheFooTarget); 1438349cc55cSDimitry Andric /// } 1439349cc55cSDimitry Andric template <class MCCodeEmitterImpl> struct RegisterMCCodeEmitter { 1440349cc55cSDimitry Andric RegisterMCCodeEmitter(Target &T) { 1441349cc55cSDimitry Andric TargetRegistry::RegisterMCCodeEmitter(T, &Allocator); 1442349cc55cSDimitry Andric } 1443349cc55cSDimitry Andric 1444349cc55cSDimitry Andric private: 1445349cc55cSDimitry Andric static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/, 1446349cc55cSDimitry Andric MCContext & /*Ctx*/) { 1447349cc55cSDimitry Andric return new MCCodeEmitterImpl(); 1448349cc55cSDimitry Andric } 1449349cc55cSDimitry Andric }; 1450349cc55cSDimitry Andric 1451349cc55cSDimitry Andric } // end namespace llvm 1452349cc55cSDimitry Andric 1453349cc55cSDimitry Andric #endif // LLVM_MC_TARGETREGISTRY_H 1454