Update CMake file.
[oota-llvm.git] / lib / Support / TargetRegistry.cpp
1 //===--- TargetRegistry.cpp - Target registration -------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Target/TargetRegistry.h"
11 #include <cassert>
12 using namespace llvm;
13
14 // FIXME: Worry about locking? In general everything should be registered at
15 // startup.
16
17 static Target *FirstTarget = 0;
18
19 const Target *
20 TargetRegistry::getClosestStaticTargetForTriple(const std::string &TT,
21                                                 std::string &Error) {
22   Target *Best = 0, *EquallyBest = 0;
23   unsigned BestQuality = 0;
24   // FIXME: Use iterator.
25   for (Target *i = FirstTarget; i; i = i->Next) {
26     if (unsigned Qual = i->TripleMatchQualityFn(TT)) {
27       if (!Best || Qual > BestQuality) {
28         Best = i;
29         EquallyBest = 0;
30         BestQuality = Qual;
31       } else if (Qual == BestQuality)
32         EquallyBest = i;
33     }
34   }
35
36   if (!Best) {
37     Error = "No available targets are compatible with this module";
38     return 0;
39   }
40
41   // Otherwise, take the best target, but make sure we don't have two equally
42   // good best targets.
43   if (EquallyBest) {
44     Error = std::string("Cannot choose between targets \"") +
45       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
46     return 0;
47   }
48
49   return Best;
50 }
51
52 const Target *
53 TargetRegistry::getClosestStaticTargetForModule(const Module &M,
54                                                 std::string &Error) {
55   Target *Best = 0, *EquallyBest = 0;
56   unsigned BestQuality = 0;
57   // FIXME: Use iterator.
58   for (Target *i = FirstTarget; i; i = i->Next) {
59     if (unsigned Qual = i->ModuleMatchQualityFn(M)) {
60       if (!Best || Qual > BestQuality) {
61         Best = i;
62         EquallyBest = 0;
63         BestQuality = Qual;
64       } else if (Qual == BestQuality)
65         EquallyBest = i;
66     }
67   }
68
69   if (!Best) {
70     Error = "No available targets are compatible with this module";
71     return 0;
72   }
73
74   // Otherwise, take the best target, but make sure we don't have two equally
75   // good best targets.
76   if (EquallyBest) {
77     Error = std::string("Cannot choose between targets \"") +
78       Best->Name  + "\" and \"" + EquallyBest->Name + "\"";
79     return 0;
80   }
81
82   return Best;
83 }
84
85 const Target *
86 TargetRegistry::getClosestTargetForJIT(std::string &Error) {
87   Target *Best = 0, *EquallyBest = 0;
88   unsigned BestQuality = 0;
89   // FIXME: Use iterator.
90   for (Target *i = FirstTarget; i; i = i->Next) {
91     if (unsigned Qual = i->JITMatchQualityFn()) {
92       if (!Best || Qual > BestQuality) {
93         Best = i;
94         EquallyBest = 0;
95         BestQuality = Qual;
96       } else if (Qual == BestQuality)
97         EquallyBest = i;
98     }
99   }
100
101   if (!Best) {
102     Error = "No JIT is available for this host";
103     return 0;
104   }
105
106   // Return the best, ignoring ties.
107   return Best;
108 }
109
110 void TargetRegistry::RegisterTarget(Target &T,
111                                     const char *Name,
112                                     const char *ShortDesc,
113                                     Target::TripleMatchQualityFnTy TQualityFn,
114                                     Target::ModuleMatchQualityFnTy MQualityFn,
115                                     Target::JITMatchQualityFnTy JITQualityFn) {
116   // Note that we don't require the constructor functions already be defined, in
117   // case a module happens to initialize the optional functionality before the
118   // target.
119   assert(!T.Next && !T.Name && !T.ShortDesc && !T.TripleMatchQualityFn &&
120          !T.ModuleMatchQualityFn && !T.JITMatchQualityFn && 
121          "This Target already registered!");
122
123   assert(Name && ShortDesc && TQualityFn && MQualityFn && JITQualityFn &&
124          "Missing required target information!");
125          
126   // Add to the list of targets.
127   T.Next = FirstTarget;
128   FirstTarget = T.Next;
129
130   T.Name = Name;
131   T.ShortDesc = ShortDesc;
132   T.TripleMatchQualityFn = TQualityFn;
133   T.ModuleMatchQualityFn = MQualityFn;
134   T.JITMatchQualityFn = JITQualityFn;
135 }
136