 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
73.0% |
100 / 137 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
92.7% |
127 / 137 |
| |
|
Line Coverage: |
87.4% |
153 / 175 |
| |
 |
|
 |
1 : //===--- TargetInfo.cpp - Information about Target machine ----------------===//
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 : // This file implements the TargetInfo and TargetInfoImpl interfaces.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #include "clang/Basic/TargetInfo.h"
15 : #include "clang/Basic/LangOptions.h"
16 : #include "llvm/ADT/APFloat.h"
17 : #include "llvm/ADT/STLExtras.h"
18 : #include <cstdlib>
19 : using namespace clang;
20 :
21 : // TargetInfo Constructor.
22 2535: TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
23 : // Set defaults. Defaults are set for a 32-bit RISC platform,
24 : // like PPC or SPARC.
25 : // These should be overridden by concrete targets as needed.
26 2535: TLSSupported = true;
27 2535: PointerWidth = PointerAlign = 32;
28 2535: IntWidth = IntAlign = 32;
29 2535: LongWidth = LongAlign = 32;
30 2535: LongLongWidth = LongLongAlign = 64;
31 2535: FloatWidth = 32;
32 2535: FloatAlign = 32;
33 2535: DoubleWidth = 64;
34 2535: DoubleAlign = 64;
35 2535: LongDoubleWidth = 64;
36 2535: LongDoubleAlign = 64;
37 2535: SizeType = UnsignedLong;
38 2535: PtrDiffType = SignedLong;
39 2535: IntMaxType = SignedLongLong;
40 2535: UIntMaxType = UnsignedLongLong;
41 2535: IntPtrType = SignedLong;
42 2535: WCharType = SignedInt;
43 2535: WIntType = SignedInt;
44 2535: Char16Type = UnsignedShort;
45 2535: Char32Type = UnsignedInt;
46 2535: Int64Type = SignedLongLong;
47 2535: SigAtomicType = SignedInt;
48 2535: FloatFormat = &llvm::APFloat::IEEEsingle;
49 2535: DoubleFormat = &llvm::APFloat::IEEEdouble;
50 2535: LongDoubleFormat = &llvm::APFloat::IEEEdouble;
51 : DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
52 2535: "i64:64:64-f32:32:32-f64:64:64-n32";
53 2535: UserLabelPrefix = "_";
54 2535: }
55 :
56 : // Out of line virtual dtor for TargetInfo.
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
0: branch 9 not taken
2532: branch 10 taken
57 2532: TargetInfo::~TargetInfo() {}
58 :
59 : /// getTypeName - Return the user string for the specified integer type enum.
60 : /// For example, SignedShort -> "short".
61 25183: const char *TargetInfo::getTypeName(IntType T) {
0: branch 0 not taken
2526: branch 1 taken
3: branch 2 taken
12007: branch 3 taken
2172: branch 4 taken
989: branch 5 taken
556: branch 6 taken
4620: branch 7 taken
2310: branch 8 taken
62 25183: switch (T) {
63 0: default: assert(0 && "not an integer!");
64 2526: case SignedShort: return "short";
65 3: case UnsignedShort: return "unsigned short";
66 12007: case SignedInt: return "int";
67 2172: case UnsignedInt: return "unsigned int";
68 989: case SignedLong: return "long int";
69 556: case UnsignedLong: return "long unsigned int";
70 4620: case SignedLongLong: return "long long int";
71 2310: case UnsignedLongLong: return "long long unsigned int";
72 : }
73 : }
74 :
75 : /// getTypeConstantSuffix - Return the constant suffix for the specified
76 : /// integer type enum. For example, SignedLong -> "L".
77 22664: const char *TargetInfo::getTypeConstantSuffix(IntType T) {
0: branch 0 not taken
12584: branch 1 taken
2938: branch 2 taken
7139: branch 3 taken
3: branch 4 taken
0: branch 5 not taken
0: branch 6 not taken
78 22664: switch (T) {
79 0: default: assert(0 && "not an integer!");
80 : case SignedShort:
81 12584: case SignedInt: return "";
82 2938: case SignedLong: return "L";
83 7139: case SignedLongLong: return "LL";
84 : case UnsignedShort:
85 3: case UnsignedInt: return "U";
86 0: case UnsignedLong: return "UL";
87 0: case UnsignedLongLong: return "ULL";
88 : }
89 : }
90 :
91 : /// getTypeWidth - Return the width (in bits) of the specified integer type
92 : /// enum. For example, SignedInt -> getIntWidth().
93 46387: unsigned TargetInfo::getTypeWidth(IntType T) const {
0: branch 0 not taken
5055: branch 1 taken
21956: branch 2 taken
5017: branch 3 taken
14359: branch 4 taken
94 46387: switch (T) {
95 0: default: assert(0 && "not an integer!");
96 : case SignedShort:
97 5055: case UnsignedShort: return getShortWidth();
98 : case SignedInt:
99 21956: case UnsignedInt: return getIntWidth();
100 : case SignedLong:
101 5017: case UnsignedLong: return getLongWidth();
102 : case SignedLongLong:
103 14359: case UnsignedLongLong: return getLongLongWidth();
104 : };
105 : }
106 :
107 : /// getTypeAlign - Return the alignment (in bits) of the specified integer type
108 : /// enum. For example, SignedInt -> getIntAlign().
109 8: unsigned TargetInfo::getTypeAlign(IntType T) const {
0: branch 0 not taken
0: branch 1 not taken
8: branch 2 taken
0: branch 3 not taken
0: branch 4 not taken
110 8: switch (T) {
111 0: default: assert(0 && "not an integer!");
112 : case SignedShort:
113 0: case UnsignedShort: return getShortAlign();
114 : case SignedInt:
115 8: case UnsignedInt: return getIntAlign();
116 : case SignedLong:
117 0: case UnsignedLong: return getLongAlign();
118 : case SignedLongLong:
119 0: case UnsignedLongLong: return getLongLongAlign();
120 : };
121 : }
122 :
123 : /// isTypeSigned - Return whether an integer types is signed. Returns true if
124 : /// the type is signed; false otherwise.
125 15114: bool TargetInfo::isTypeSigned(IntType T) const {
0: branch 0 not taken
15111: branch 1 taken
3: branch 2 taken
126 15114: switch (T) {
127 0: default: assert(0 && "not an integer!");
128 : case SignedShort:
129 : case SignedInt:
130 : case SignedLong:
131 : case SignedLongLong:
132 15111: return true;
133 : case UnsignedShort:
134 : case UnsignedInt:
135 : case UnsignedLong:
136 : case UnsignedLongLong:
137 3: return false;
138 : };
139 : }
140 :
141 : /// setForcedLangOptions - Set forced language options.
142 : /// Apply changes to the target information with respect to certain
143 : /// language options which change the target configuration.
144 2522: void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
1: branch 0 taken
2521: branch 1 taken
145 2522: if (Opts.ShortWChar) {
146 1: WCharType = UnsignedShort;
147 : }
148 2522: }
149 :
150 : //===----------------------------------------------------------------------===//
151 :
152 :
153 91: static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
85: branch 1 taken
6: branch 2 taken
6: branch 4 taken
79: branch 5 taken
12: branch 6 taken
79: branch 7 taken
154 91: if (Name[0] == '%' || Name[0] == '#')
155 12: Name = Name.substr(1);
156 :
157 91: return Name;
158 : }
159 :
160 : /// isValidGCCRegisterName - Returns whether the passed in string
161 : /// is a valid register name according to GCC. This is used by Sema for
162 : /// inline asm statements.
163 73: bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
0: branch 1 not taken
73: branch 2 taken
164 73: if (Name.empty())
165 0: return false;
166 :
167 : const char * const *Names;
168 : unsigned NumNames;
169 :
170 : // Get rid of any register prefix.
171 73: Name = removeGCCRegisterPrefix(Name);
172 :
69: branch 2 taken
4: branch 3 taken
2: branch 6 taken
67: branch 7 taken
6: branch 8 taken
67: branch 9 taken
173 73: if (Name == "memory" || Name == "cc")
174 6: return true;
175 :
176 67: getGCCRegNames(Names, NumNames);
177 :
178 : // If we have a number it maps to an entry in the register name array.
11: branch 1 taken
56: branch 2 taken
179 67: if (isdigit(Name[0])) {
180 : int n;
11: branch 1 taken
0: branch 2 not taken
181 11: if (!Name.getAsInteger(0, n))
11: branch 0 taken
0: branch 1 not taken
10: branch 2 taken
1: branch 3 taken
182 11: return n >= 0 && (unsigned)n < NumNames;
183 : }
184 :
185 : // Check register names.
1134: branch 0 taken
31: branch 1 taken
186 1165: for (unsigned i = 0; i < NumNames; i++) {
25: branch 2 taken
1109: branch 3 taken
187 1134: if (Name == Names[i])
188 25: return true;
189 : }
190 :
191 : // Now check aliases.
192 : const GCCRegAlias *Aliases;
193 : unsigned NumAliases;
194 :
195 31: getGCCRegAliases(Aliases, NumAliases);
110: branch 0 taken
3: branch 1 taken
196 113: for (unsigned i = 0; i < NumAliases; i++) {
258: branch 1 taken
0: branch 2 not taken
197 258: for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
82: branch 0 taken
176: branch 1 taken
198 258: if (!Aliases[i].Aliases[j])
199 82: break;
28: branch 2 taken
148: branch 3 taken
200 176: if (Aliases[i].Aliases[j] == Name)
201 28: return true;
202 : }
203 : }
204 :
205 3: return false;
206 : }
207 :
208 : llvm::StringRef
209 18: TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const {
18: branch 1 taken
0: branch 2 not taken
210 18: assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
211 :
212 : // Get rid of any register prefix.
213 18: Name = removeGCCRegisterPrefix(Name);
214 :
215 : const char * const *Names;
216 : unsigned NumNames;
217 :
218 18: getGCCRegNames(Names, NumNames);
219 :
220 : // First, check if we have a number.
0: branch 1 not taken
18: branch 2 taken
221 18: if (isdigit(Name[0])) {
222 : int n;
0: branch 1 not taken
0: branch 2 not taken
223 0: if (!Name.getAsInteger(0, n)) {
224 : assert(n >= 0 && (unsigned)n < NumNames &&
0: branch 0 not taken
0: branch 1 not taken
0: branch 2 not taken
0: branch 3 not taken
225 0: "Out of bounds register number!");
226 0: return Names[n];
227 : }
228 : }
229 :
230 : // Now check aliases.
231 : const GCCRegAlias *Aliases;
232 : unsigned NumAliases;
233 :
234 18: getGCCRegAliases(Aliases, NumAliases);
197: branch 0 taken
10: branch 1 taken
235 207: for (unsigned i = 0; i < NumAliases; i++) {
396: branch 1 taken
0: branch 2 not taken
236 396: for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
189: branch 0 taken
207: branch 1 taken
237 396: if (!Aliases[i].Aliases[j])
238 189: break;
8: branch 2 taken
199: branch 3 taken
239 207: if (Aliases[i].Aliases[j] == Name)
240 8: return Aliases[i].Register;
241 : }
242 : }
243 :
244 10: return Name;
245 : }
246 :
247 57: bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
248 57: const char *Name = Info.getConstraintStr().c_str();
249 : // An output constraint must start with '=' or '+'
18: branch 0 taken
39: branch 1 taken
0: branch 2 not taken
18: branch 3 taken
250 57: if (*Name != '=' && *Name != '+')
251 0: return false;
252 :
18: branch 0 taken
39: branch 1 taken
253 57: if (*Name == '+')
254 18: Info.setIsReadWrite();
255 :
256 57: Name++;
63: branch 0 taken
57: branch 1 taken
257 177: while (*Name) {
27: branch 0 taken
4: branch 1 taken
2: branch 2 taken
24: branch 3 taken
6: branch 4 taken
0: branch 5 not taken
258 63: switch (*Name) {
259 : default:
0: branch 1 not taken
27: branch 2 taken
260 27: if (!validateAsmConstraint(Name, Info)) {
261 : // FIXME: We temporarily return false
262 : // so we can add more constraints as we hit it.
263 : // Eventually, an unknown constraint should just be treated as 'g'.
264 0: return false;
265 : }
266 : case '&': // early clobber.
267 31: break;
268 : case '%': // commutative.
269 : // FIXME: Check that there is a another register after this one.
270 2: break;
271 : case 'r': // general register.
272 24: Info.setAllowsRegister();
273 24: break;
274 : case 'm': // memory operand.
275 6: Info.setAllowsMemory();
276 6: break;
277 : case 'g': // general register, memory operand or immediate integer.
278 : case 'X': // any operand.
279 0: Info.setAllowsRegister();
280 0: Info.setAllowsMemory();
281 : break;
282 : }
283 :
284 63: Name++;
285 : }
286 :
287 57: return true;
288 : }
289 :
290 : bool TargetInfo::resolveSymbolicName(const char *&Name,
291 : ConstraintInfo *OutputConstraints,
292 : unsigned NumOutputs,
293 6: unsigned &Index) const {
0: branch 0 not taken
6: branch 1 taken
294 6: assert(*Name == '[' && "Symbolic name did not start with '['");
295 6: Name++;
296 6: const char *Start = Name;
59: branch 0 taken
2: branch 1 taken
55: branch 2 taken
4: branch 3 taken
297 67: while (*Name && *Name != ']')
298 55: Name++;
299 :
2: branch 0 taken
4: branch 1 taken
300 6: if (!*Name) {
301 : // Missing ']'
302 2: return false;
303 : }
304 :
305 4: std::string SymbolicName(Start, Name - Start);
306 :
4: branch 0 taken
1: branch 1 taken
307 5: for (Index = 0; Index != NumOutputs; ++Index)
3: branch 2 taken
1: branch 3 taken
308 4: if (SymbolicName == OutputConstraints[Index].getName())
309 3: return true;
310 :
311 1: return false;
312 : }
313 :
314 : bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
315 : unsigned NumOutputs,
316 73: ConstraintInfo &Info) const {
317 73: const char *Name = Info.ConstraintStr.c_str();
318 :
78: branch 0 taken
70: branch 1 taken
319 221: while (*Name) {
34: branch 0 taken
6: branch 1 taken
0: branch 2 not taken
11: branch 3 taken
0: branch 4 not taken
11: branch 5 taken
15: branch 6 taken
1: branch 7 taken
320 78: switch (*Name) {
321 : default:
322 : // Check if we have a matching constraint
34: branch 0 taken
0: branch 1 not taken
11: branch 2 taken
23: branch 3 taken
323 45: if (*Name >= '0' && *Name <= '9') {
324 11: unsigned i = *Name - '0';
325 :
326 : // Check if matching constraint is out of bounds.
0: branch 0 not taken
11: branch 1 taken
327 11: if (i >= NumOutputs)
328 0: return false;
329 :
330 : // The constraint should have the same info as the respective
331 : // output constraint.
332 11: Info.setTiedOperand(i, OutputConstraints[i]);
0: branch 1 not taken
23: branch 2 taken
333 23: } else if (!validateAsmConstraint(Name, Info)) {
334 : // FIXME: This error return is in place temporarily so we can
335 : // add more constraints as we hit it. Eventually, an unknown
336 : // constraint should just be treated as 'g'.
337 0: return false;
338 : }
339 34: break;
340 : case '[': {
341 6: unsigned Index = 0;
3: branch 1 taken
3: branch 2 taken
342 6: if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
343 3: return false;
344 :
345 3: break;
346 : }
347 : case '%': // commutative
348 : // FIXME: Fail if % is used with the last operand.
349 0: break;
350 : case 'i': // immediate integer.
351 : case 'n': // immediate integer with a known value.
352 11: break;
353 : case 'I': // Various constant constraints with target-specific meanings.
354 : case 'J':
355 : case 'K':
356 : case 'L':
357 : case 'M':
358 : case 'N':
359 : case 'O':
360 : case 'P':
361 0: break;
362 : case 'r': // general register.
363 11: Info.setAllowsRegister();
364 11: break;
365 : case 'm': // memory operand.
366 : case 'o': // offsettable memory operand
367 : case 'V': // non-offsettable memory operand
368 15: Info.setAllowsMemory();
369 15: break;
370 : case 'g': // general register, memory operand or immediate integer.
371 : case 'X': // any operand.
372 1: Info.setAllowsRegister();
373 1: Info.setAllowsMemory();
374 : break;
375 : }
376 :
377 75: Name++;
378 : }
379 :
380 70: return true;
381 : }
Generated: 2010-02-10 01:31 by zcov