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//===----------------------------------------------------------------------===// 937b74a387bb3993387029859c2d9d051c41c724eStephen Hines#include "mcld/Support/TargetRegistry.h" 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1137b74a387bb3993387029859c2d9d051c41c724eStephen Hinesnamespace 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, 2037b74a387bb3993387029859c2d9d051c41c724eStephen Hines Target::TripleMatchQualityFnTy pQualityFn) { 21f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTarget.Name = pName; 22f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTarget.TripleMatchQualityFn = pQualityFn; 23f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 24f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines s_TargetList.push_back(&pTarget); 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2737b74a387bb3993387029859c2d9d051c41c724eStephen Hinesconst Target* TargetRegistry::lookupTarget(const std::string& pTriple, 2837b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::string& pError) { 29f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (empty()) { 30f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = "Unable to find target for this triple (no target are registered)"; 31f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 32f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 33f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 34f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple triple(pTriple); 3537b74a387bb3993387029859c2d9d051c41c724eStephen Hines Target* best = NULL, * ambiguity = NULL; 36f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines unsigned int highest = 0; 37f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 38f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (iterator target = begin(), ie = end(); target != ie; ++target) { 39f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines unsigned int quality = (*target)->getTripleQuality(triple); 40f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (quality > 0) { 4137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (best == NULL || highest < quality) { 42f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines highest = quality; 43f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines best = *target; 44f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ambiguity = NULL; 4537b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else if (highest == quality) { 46f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines ambiguity = *target; 47f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 5137b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (best == NULL) { 52f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = "No availaible targets are compatible with this triple."; 53f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 54f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 55f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 56f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (NULL != ambiguity) { 5737b74a387bb3993387029859c2d9d051c41c724eStephen Hines pError = std::string("Ambiguous targets: \"") + best->name() + "\" and \"" + 5837b74a387bb3993387029859c2d9d051c41c724eStephen Hines ambiguity->name() + "\""; 59d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao return NULL; 60f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 61d0fbbb227051be16931a1aa9b4a7722ac039c698Shih-wei Liao 62f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return best; 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 65f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hinesconst Target* TargetRegistry::lookupTarget(const std::string& pArchName, 66f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple& pTriple, 6737b74a387bb3993387029859c2d9d051c41c724eStephen Hines std::string& pError) { 68f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines const Target* result = NULL; 69f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (!pArchName.empty()) { 70f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines for (mcld::TargetRegistry::iterator it = mcld::TargetRegistry::begin(), 7137b74a387bb3993387029859c2d9d051c41c724eStephen Hines ie = mcld::TargetRegistry::end(); 7237b74a387bb3993387029859c2d9d051c41c724eStephen Hines it != ie; 7337b74a387bb3993387029859c2d9d051c41c724eStephen Hines ++it) { 74f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (pArchName == (*it)->name()) { 75f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result = *it; 76f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines break; 77f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 78f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 79f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 8037b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (result == NULL) { 81f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pError = std::string("invalid target '") + pArchName + "'.\n"; 82f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 83f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 84f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines 85f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // Adjust the triple to match (if known), otherwise stick with the 86f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines // module/host triple. 87f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines llvm::Triple::ArchType type = 8837b74a387bb3993387029859c2d9d051c41c724eStephen Hines llvm::Triple::getArchTypeForLLVMName(pArchName); 89f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines if (llvm::Triple::UnknownArch != type) 90f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines pTriple.setArch(type); 9137b74a387bb3993387029859c2d9d051c41c724eStephen Hines } else { 92f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines std::string error; 93f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines result = lookupTarget(pTriple.getTriple(), error); 9437b74a387bb3993387029859c2d9d051c41c724eStephen Hines if (result == NULL) { 9537b74a387bb3993387029859c2d9d051c41c724eStephen Hines pError = std::string("unable to get target for `") + pTriple.getTriple() + 9637b74a387bb3993387029859c2d9d051c41c724eStephen Hines "'\n" + "(Detail: " + error + ")\n"; 97f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return NULL; 98f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 99f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines } 100f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines return result; 101f33f6de54db174aa679a4b6d1e040d37e95541c0Stephen Hines} 10237b74a387bb3993387029859c2d9d051c41c724eStephen Hines 10337b74a387bb3993387029859c2d9d051c41c724eStephen Hines} // namespace mcld 104