TargetInfo.cpp revision 198893
1193326Sed//===--- TargetInfo.cpp - Information about Target machine ----------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed//  This file implements the TargetInfo and TargetInfoImpl interfaces.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Basic/TargetInfo.h"
15193326Sed#include "llvm/ADT/APFloat.h"
16193326Sed#include "llvm/ADT/STLExtras.h"
17193326Sed#include <cstdlib>
18193326Sedusing namespace clang;
19193326Sed
20193326Sed// TargetInfo Constructor.
21193326SedTargetInfo::TargetInfo(const std::string &T) : Triple(T) {
22193326Sed  // Set defaults.  Defaults are set for a 32-bit RISC platform,
23193326Sed  // like PPC or SPARC.
24193326Sed  // These should be overridden by concrete targets as needed.
25193326Sed  TLSSupported = true;
26193326Sed  PointerWidth = PointerAlign = 32;
27193326Sed  WCharWidth = WCharAlign = 32;
28198092Srdivacky  Char16Width = Char16Align = 16;
29198092Srdivacky  Char32Width = Char32Align = 32;
30193326Sed  IntWidth = IntAlign = 32;
31193326Sed  LongWidth = LongAlign = 32;
32193326Sed  LongLongWidth = LongLongAlign = 64;
33193326Sed  FloatWidth = 32;
34193326Sed  FloatAlign = 32;
35193326Sed  DoubleWidth = 64;
36193326Sed  DoubleAlign = 64;
37193326Sed  LongDoubleWidth = 64;
38193326Sed  LongDoubleAlign = 64;
39193326Sed  IntMaxTWidth = 64;
40193326Sed  SizeType = UnsignedLong;
41193326Sed  PtrDiffType = SignedLong;
42193326Sed  IntMaxType = SignedLongLong;
43193326Sed  UIntMaxType = UnsignedLongLong;
44193326Sed  IntPtrType = SignedLong;
45193326Sed  WCharType = SignedInt;
46198398Srdivacky  WIntType = SignedInt;
47198092Srdivacky  Char16Type = UnsignedShort;
48198092Srdivacky  Char32Type = UnsignedInt;
49195341Sed  Int64Type = SignedLongLong;
50193326Sed  FloatFormat = &llvm::APFloat::IEEEsingle;
51193326Sed  DoubleFormat = &llvm::APFloat::IEEEdouble;
52193326Sed  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
53193326Sed  DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
54193326Sed                      "i64:64:64-f32:32:32-f64:64:64";
55193326Sed  UserLabelPrefix = "_";
56193326Sed}
57193326Sed
58193326Sed// Out of line virtual dtor for TargetInfo.
59193326SedTargetInfo::~TargetInfo() {}
60193326Sed
61193326Sed/// getTypeName - Return the user string for the specified integer type enum.
62193326Sed/// For example, SignedShort -> "short".
63193326Sedconst char *TargetInfo::getTypeName(IntType T) {
64193326Sed  switch (T) {
65193326Sed  default: assert(0 && "not an integer!");
66193326Sed  case SignedShort:      return "short";
67193326Sed  case UnsignedShort:    return "unsigned short";
68193326Sed  case SignedInt:        return "int";
69193326Sed  case UnsignedInt:      return "unsigned int";
70193326Sed  case SignedLong:       return "long int";
71193326Sed  case UnsignedLong:     return "long unsigned int";
72193326Sed  case SignedLongLong:   return "long long int";
73193326Sed  case UnsignedLongLong: return "long long unsigned int";
74193326Sed  }
75193326Sed}
76193326Sed
77198398Srdivacky/// getTypeConstantSuffix - Return the constant suffix for the specified
78198398Srdivacky/// integer type enum. For example, SignedLong -> "L".
79198398Srdivackyconst char *TargetInfo::getTypeConstantSuffix(IntType T) {
80198398Srdivacky  switch (T) {
81198398Srdivacky  default: assert(0 && "not an integer!");
82198398Srdivacky  case SignedShort:
83198398Srdivacky  case SignedInt:        return "";
84198398Srdivacky  case SignedLong:       return "L";
85198398Srdivacky  case SignedLongLong:   return "LL";
86198398Srdivacky  case UnsignedShort:
87198398Srdivacky  case UnsignedInt:      return "U";
88198398Srdivacky  case UnsignedLong:     return "UL";
89198398Srdivacky  case UnsignedLongLong: return "ULL";
90198398Srdivacky  }
91198398Srdivacky}
92198398Srdivacky
93198398Srdivacky/// getTypeWidth - Return the width (in bits) of the specified integer type
94198398Srdivacky/// enum. For example, SignedInt -> getIntWidth().
95198398Srdivackyunsigned TargetInfo::getTypeWidth(IntType T) const {
96198398Srdivacky  switch (T) {
97198398Srdivacky  default: assert(0 && "not an integer!");
98198398Srdivacky  case SignedShort:      return getShortWidth();
99198398Srdivacky  case UnsignedShort:    return getShortWidth();
100198398Srdivacky  case SignedInt:        return getIntWidth();
101198398Srdivacky  case UnsignedInt:      return getIntWidth();
102198398Srdivacky  case SignedLong:       return getLongWidth();
103198398Srdivacky  case UnsignedLong:     return getLongWidth();
104198398Srdivacky  case SignedLongLong:   return getLongLongWidth();
105198398Srdivacky  case UnsignedLongLong: return getLongLongWidth();
106198398Srdivacky  };
107198398Srdivacky}
108198398Srdivacky
109198893Srdivacky/// isTypeSigned - Return whether an integer types is signed. Returns true if
110198398Srdivacky/// the type is signed; false otherwise.
111198893Srdivackybool TargetInfo::isTypeSigned(IntType T) const {
112198398Srdivacky  switch (T) {
113198398Srdivacky  default: assert(0 && "not an integer!");
114198398Srdivacky  case SignedShort:
115198398Srdivacky  case SignedInt:
116198398Srdivacky  case SignedLong:
117198398Srdivacky  case SignedLongLong:
118198398Srdivacky    return true;
119198398Srdivacky  case UnsignedShort:
120198398Srdivacky  case UnsignedInt:
121198398Srdivacky  case UnsignedLong:
122198398Srdivacky  case UnsignedLongLong:
123198398Srdivacky    return false;
124198398Srdivacky  };
125198398Srdivacky}
126198398Srdivacky
127198398Srdivacky
128193326Sed//===----------------------------------------------------------------------===//
129193326Sed
130193326Sed
131193326Sedstatic void removeGCCRegisterPrefix(const char *&Name) {
132193326Sed  if (Name[0] == '%' || Name[0] == '#')
133193326Sed    Name++;
134193326Sed}
135193326Sed
136193326Sed/// isValidGCCRegisterName - Returns whether the passed in string
137193326Sed/// is a valid register name according to GCC. This is used by Sema for
138193326Sed/// inline asm statements.
139193326Sedbool TargetInfo::isValidGCCRegisterName(const char *Name) const {
140193326Sed  const char * const *Names;
141193326Sed  unsigned NumNames;
142198092Srdivacky
143193326Sed  // Get rid of any register prefix.
144193326Sed  removeGCCRegisterPrefix(Name);
145193326Sed
146198092Srdivacky
147193326Sed  if (strcmp(Name, "memory") == 0 ||
148193326Sed      strcmp(Name, "cc") == 0)
149193326Sed    return true;
150198092Srdivacky
151193326Sed  getGCCRegNames(Names, NumNames);
152198092Srdivacky
153193326Sed  // If we have a number it maps to an entry in the register name array.
154193326Sed  if (isdigit(Name[0])) {
155193326Sed    char *End;
156193326Sed    int n = (int)strtol(Name, &End, 0);
157193326Sed    if (*End == 0)
158193326Sed      return n >= 0 && (unsigned)n < NumNames;
159193326Sed  }
160193326Sed
161193326Sed  // Check register names.
162193326Sed  for (unsigned i = 0; i < NumNames; i++) {
163193326Sed    if (strcmp(Name, Names[i]) == 0)
164193326Sed      return true;
165193326Sed  }
166198092Srdivacky
167193326Sed  // Now check aliases.
168193326Sed  const GCCRegAlias *Aliases;
169193326Sed  unsigned NumAliases;
170198092Srdivacky
171193326Sed  getGCCRegAliases(Aliases, NumAliases);
172193326Sed  for (unsigned i = 0; i < NumAliases; i++) {
173193326Sed    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
174193326Sed      if (!Aliases[i].Aliases[j])
175193326Sed        break;
176193326Sed      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
177193326Sed        return true;
178193326Sed    }
179193326Sed  }
180198092Srdivacky
181193326Sed  return false;
182193326Sed}
183193326Sed
184193326Sedconst char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const {
185193326Sed  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
186198092Srdivacky
187193326Sed  removeGCCRegisterPrefix(Name);
188198092Srdivacky
189193326Sed  const char * const *Names;
190193326Sed  unsigned NumNames;
191193326Sed
192193326Sed  getGCCRegNames(Names, NumNames);
193193326Sed
194193326Sed  // First, check if we have a number.
195193326Sed  if (isdigit(Name[0])) {
196193326Sed    char *End;
197193326Sed    int n = (int)strtol(Name, &End, 0);
198193326Sed    if (*End == 0) {
199198092Srdivacky      assert(n >= 0 && (unsigned)n < NumNames &&
200193326Sed             "Out of bounds register number!");
201193326Sed      return Names[n];
202193326Sed    }
203193326Sed  }
204198092Srdivacky
205193326Sed  // Now check aliases.
206193326Sed  const GCCRegAlias *Aliases;
207193326Sed  unsigned NumAliases;
208198092Srdivacky
209193326Sed  getGCCRegAliases(Aliases, NumAliases);
210193326Sed  for (unsigned i = 0; i < NumAliases; i++) {
211193326Sed    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
212193326Sed      if (!Aliases[i].Aliases[j])
213193326Sed        break;
214193326Sed      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
215193326Sed        return Aliases[i].Register;
216193326Sed    }
217193326Sed  }
218198092Srdivacky
219193326Sed  return Name;
220193326Sed}
221193326Sed
222193326Sedbool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
223193326Sed  const char *Name = Info.getConstraintStr().c_str();
224193326Sed  // An output constraint must start with '=' or '+'
225193326Sed  if (*Name != '=' && *Name != '+')
226193326Sed    return false;
227193326Sed
228193326Sed  if (*Name == '+')
229193326Sed    Info.setIsReadWrite();
230193326Sed
231193326Sed  Name++;
232193326Sed  while (*Name) {
233193326Sed    switch (*Name) {
234193326Sed    default:
235193326Sed      if (!validateAsmConstraint(Name, Info)) {
236193326Sed        // FIXME: We temporarily return false
237193326Sed        // so we can add more constraints as we hit it.
238193326Sed        // Eventually, an unknown constraint should just be treated as 'g'.
239193326Sed        return false;
240193326Sed      }
241193326Sed    case '&': // early clobber.
242193326Sed      break;
243198092Srdivacky    case '%': // commutative.
244198092Srdivacky      // FIXME: Check that there is a another register after this one.
245198092Srdivacky      break;
246193326Sed    case 'r': // general register.
247193326Sed      Info.setAllowsRegister();
248193326Sed      break;
249193326Sed    case 'm': // memory operand.
250193326Sed      Info.setAllowsMemory();
251193326Sed      break;
252193326Sed    case 'g': // general register, memory operand or immediate integer.
253193326Sed    case 'X': // any operand.
254193326Sed      Info.setAllowsRegister();
255193326Sed      Info.setAllowsMemory();
256193326Sed      break;
257193326Sed    }
258198092Srdivacky
259193326Sed    Name++;
260193326Sed  }
261198092Srdivacky
262193326Sed  return true;
263193326Sed}
264193326Sed
265193326Sedbool TargetInfo::resolveSymbolicName(const char *&Name,
266193326Sed                                     ConstraintInfo *OutputConstraints,
267193326Sed                                     unsigned NumOutputs,
268193326Sed                                     unsigned &Index) const {
269193326Sed  assert(*Name == '[' && "Symbolic name did not start with '['");
270193326Sed  Name++;
271193326Sed  const char *Start = Name;
272193326Sed  while (*Name && *Name != ']')
273193326Sed    Name++;
274198092Srdivacky
275193326Sed  if (!*Name) {
276193326Sed    // Missing ']'
277193326Sed    return false;
278193326Sed  }
279198092Srdivacky
280193326Sed  std::string SymbolicName(Start, Name - Start);
281198092Srdivacky
282193326Sed  for (Index = 0; Index != NumOutputs; ++Index)
283193326Sed    if (SymbolicName == OutputConstraints[Index].getName())
284193326Sed      return true;
285193326Sed
286193326Sed  return false;
287193326Sed}
288193326Sed
289193326Sedbool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
290193326Sed                                         unsigned NumOutputs,
291193326Sed                                         ConstraintInfo &Info) const {
292193326Sed  const char *Name = Info.ConstraintStr.c_str();
293193326Sed
294193326Sed  while (*Name) {
295193326Sed    switch (*Name) {
296193326Sed    default:
297193326Sed      // Check if we have a matching constraint
298193326Sed      if (*Name >= '0' && *Name <= '9') {
299193326Sed        unsigned i = *Name - '0';
300198092Srdivacky
301193326Sed        // Check if matching constraint is out of bounds.
302193326Sed        if (i >= NumOutputs)
303193326Sed          return false;
304198092Srdivacky
305198092Srdivacky        // The constraint should have the same info as the respective
306193326Sed        // output constraint.
307193326Sed        Info.setTiedOperand(i, OutputConstraints[i]);
308193326Sed      } else if (!validateAsmConstraint(Name, Info)) {
309193326Sed        // FIXME: This error return is in place temporarily so we can
310193326Sed        // add more constraints as we hit it.  Eventually, an unknown
311193326Sed        // constraint should just be treated as 'g'.
312193326Sed        return false;
313193326Sed      }
314193326Sed      break;
315193326Sed    case '[': {
316193326Sed      unsigned Index = 0;
317193326Sed      if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
318193326Sed        return false;
319198092Srdivacky
320193326Sed      break;
321198092Srdivacky    }
322193326Sed    case '%': // commutative
323193326Sed      // FIXME: Fail if % is used with the last operand.
324193326Sed      break;
325193326Sed    case 'i': // immediate integer.
326193326Sed    case 'n': // immediate integer with a known value.
327193326Sed      break;
328193326Sed    case 'I':  // Various constant constraints with target-specific meanings.
329193326Sed    case 'J':
330193326Sed    case 'K':
331193326Sed    case 'L':
332193326Sed    case 'M':
333193326Sed    case 'N':
334193326Sed    case 'O':
335193326Sed    case 'P':
336193326Sed      break;
337193326Sed    case 'r': // general register.
338193326Sed      Info.setAllowsRegister();
339193326Sed      break;
340193326Sed    case 'm': // memory operand.
341193326Sed      Info.setAllowsMemory();
342193326Sed      break;
343193326Sed    case 'g': // general register, memory operand or immediate integer.
344193326Sed    case 'X': // any operand.
345193326Sed      Info.setAllowsRegister();
346193326Sed      Info.setAllowsMemory();
347193326Sed      break;
348193326Sed    }
349198092Srdivacky
350193326Sed    Name++;
351193326Sed  }
352198092Srdivacky
353193326Sed  return true;
354193326Sed}
355