15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- TargetRegistry.cpp -------------------------------------------------===// 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//===----------------------------------------------------------------------===// 9affc150dc44fab1911775a49636d0ce85333b634Zonr Chang#include <mcld/Support/TargetRegistry.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 11f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesusing namespace mcld; 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 13f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen HinesTargetRegistry::TargetListTy mcld::TargetRegistry::s_TargetList; 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 15f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 16f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines// TargetRegistry 17f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines//===----------------------------------------------------------------------===// 18f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesvoid TargetRegistry::RegisterTarget(Target& pTarget, 19f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const char* pName, 20f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Target::TripleMatchQualityFnTy pQualityFn) 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTarget.Name = pName; 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTarget.TripleMatchQualityFn = pQualityFn; 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 25f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines s_TargetList.push_back(&pTarget); 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 28f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesconst Target* TargetRegistry::lookupTarget(const std::string &pTriple, 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::string &pError) 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (empty()) { 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = "Unable to find target for this triple (no target are registered)"; 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 35f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple triple(pTriple); 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines Target* best = NULL, *ambiguity = NULL; 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines unsigned int highest = 0; 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator target = begin(), ie = end(); target != ie; ++target) { 41f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines unsigned int quality = (*target)->getTripleQuality(triple); 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (quality > 0) { 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL == best || highest < quality) { 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines highest = quality; 45f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines best = *target; 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ambiguity = NULL; 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 48f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else if (highest == quality) { 49f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ambiguity = *target; 50f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL == best) { 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = "No availaible targets are compatible with this triple."; 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 57f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 58f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 59f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL != ambiguity) { 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = std::string("Ambiguous targets: \"") + 61f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines best->name() + "\" and \"" + ambiguity->name() + "\""; 62d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return NULL; 63f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 64d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return best; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesconst Target* TargetRegistry::lookupTarget(const std::string& pArchName, 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple& pTriple, 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::string& pError) 71f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines{ 72f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const Target* result = NULL; 73f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!pArchName.empty()) { 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(), 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ie = mcld::TargetRegistry::end(); it != ie; ++it) { 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pArchName == (*it)->name()) { 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result = *it; 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 80f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL == result) { 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = std::string("invalid target '") + pArchName + "'.\n"; 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Adjust the triple to match (if known), otherwise stick with the 88f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // module/host triple. 89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple::ArchType type = 90f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple::getArchTypeForLLVMName(pArchName); 91f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (llvm::Triple::UnknownArch != type) 92f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTriple.setArch(type); 93f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 94f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines else { 95f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::string error; 96f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result = lookupTarget(pTriple.getTriple(), error); 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL == result) { 98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = std::string("unable to get target for `") + 99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTriple.getTriple() + "'\n" + 100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines "(Detail: " + error + ")\n"; 101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 102f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 103f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 104f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 105f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 106