15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- TargetRegistry.h ---------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#ifndef MCLD_SUPPORT_TARGETREGISTRY_H_ 1037b74a387bb3993387029859c2d9d051c41c724eStephen Hines#define MCLD_SUPPORT_TARGETREGISTRY_H_ 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/Target.h" 1237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines#include <llvm/ADT/Triple.h> 14f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <list> 1637b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include <string> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace llvm { 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass TargetMachine; 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCCodeEmitter; 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass MCContext; 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoclass AsmPrinter; 2337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace llvm 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld { 2622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 27f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines/** \class TargetRegistry 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines * \brief TargetRegistry is an object adapter of llvm::TargetRegistry 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines */ 3037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesclass TargetRegistry { 3137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef std::list<mcld::Target*> TargetListTy; 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao typedef TargetListTy::iterator iterator; 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines private: 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static TargetListTy s_TargetList; 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 3837b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static iterator begin() { return s_TargetList.begin(); } 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static iterator end() { return s_TargetList.end(); } 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static size_t size() { return s_TargetList.size(); } 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao static bool empty() { return s_TargetList.empty(); } 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// RegisterTarget - Register the given target. Attempts to register a 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// target which has already been registered will be ignored. 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// Clients are responsible for ensuring that registration doesn't occur 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// while another thread is attempting to access the registry. Typically 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// this is done by initializing all targets at program startup. 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param T - The target being registered. 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines static void RegisterTarget(Target& pTarget, 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* pName, 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Target::TripleMatchQualityFnTy pQualityFn); 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5722add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// RegisterEmulation - Register a emulation function for the target. 5822add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// target. 5922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// 6022add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @param T - the target being registered 6122add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao /// @param Fn - A emulation function 6237b74a387bb3993387029859c2d9d051c41c724eStephen Hines static void RegisterEmulation(mcld::Target& T, 6337b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::Target::EmulationFnTy Fn) { 6422add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao if (!T.EmulationFn) 6522add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao T.EmulationFn = Fn; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// RegisterTargetLDBackend - Register a TargetLDBackend implementation for 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// the given target. 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param T - The target being registered 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param Fn - A function to create TargetLDBackend for the target 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines static void RegisterTargetLDBackend(mcld::Target& T, 7437b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::Target::TargetLDBackendCtorTy Fn) { 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!T.TargetLDBackendCtorFn) 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao T.TargetLDBackendCtorFn = Fn; 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 79affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// RegisterTargetDiagnosticLineInfo - Register a DiagnosticLineInfo 80affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// implementation for the given target. 81affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// 82affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// @param T - The target being registered 83affc150dc44fab1911775a49636d0ce85333b634Zonr Chang /// @param Fn - A function to create DiagnosticLineInfo for the target 8437b74a387bb3993387029859c2d9d051c41c724eStephen Hines static void RegisterDiagnosticLineInfo( 8537b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::Target& T, 8637b74a387bb3993387029859c2d9d051c41c724eStephen Hines mcld::Target::DiagnosticLineInfoCtorTy Fn) { 87affc150dc44fab1911775a49636d0ce85333b634Zonr Chang if (!T.DiagnosticLineInfoCtorFn) 88affc150dc44fab1911775a49636d0ce85333b634Zonr Chang T.DiagnosticLineInfoCtorFn = Fn; 89affc150dc44fab1911775a49636d0ce85333b634Zonr Chang } 90affc150dc44fab1911775a49636d0ce85333b634Zonr Chang 91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// lookupTarget - Look up MCLinker target 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param Triple - The Triple string 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao /// @param Error - The returned error message 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const mcld::Target* lookupTarget(const std::string& pTriple, 96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::string& pError); 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// lookupTarget - Look up MCLinker target by an architecture name 99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// and a triple. If the architecture name is not empty, then the 100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// the lookup is done mainly by architecture. Otherwise, the target 101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// triple is used. 102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// 103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// @param pArch - The architecture name 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// @param pTriple - The target triple 105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines /// @param pError - The returned error message 10637b74a387bb3993387029859c2d9d051c41c724eStephen Hines static const mcld::Target* lookupTarget(const std::string& pArchName, 107f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple& pTriple, 10837b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::string& Error); 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// RegisterTarget - Helper function for registering a target, for use in the 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// target's initialization function. Usage: 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// Target TheFooTarget; // The global target instance. 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// 11622add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao/// extern "C" void MCLDInitializeFooTargetInfo() { 117f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines/// RegisterTarget<llvm::Foo> X(TheFooTarget, "foo", "Foo description"); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// } 11937b74a387bb3993387029859c2d9d051c41c724eStephen Hinestemplate <llvm::Triple::ArchType TargetArchType = llvm::Triple::UnknownArch> 12037b74a387bb3993387029859c2d9d051c41c724eStephen Hinesstruct RegisterTarget { 12137b74a387bb3993387029859c2d9d051c41c724eStephen Hines public: 12237b74a387bb3993387029859c2d9d051c41c724eStephen Hines RegisterTarget(mcld::Target& pTarget, const char* pName) { 123f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // if we've registered one, then return immediately. 124f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines TargetRegistry::iterator target, ie = TargetRegistry::end(); 125f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (target = TargetRegistry::begin(); target != ie; ++target) { 12637b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (strcmp((*target)->name(), pName) == 0) 127f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 12922add6ff3426df1a85089fe6a6e1597ee3b6f300Shih-wei Liao 130f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines TargetRegistry::RegisterTarget(pTarget, pName, &getTripleMatchQuality); 131f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 133f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines static unsigned int getTripleMatchQuality(const llvm::Triple& pTriple) { 134f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pTriple.getArch() == TargetArchType) 135f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return 20; 136f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return 0; 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao}; 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14037b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 14237b74a387bb3993387029859c2d9d051c41c724eStephen Hines#endif // MCLD_SUPPORT_TARGETREGISTRY_H_ 143