TargetInfo.cpp revision 198398
10Sstevel@tonic-gate//===--- TargetInfo.cpp - Information about Target machine ----------------===//
20Sstevel@tonic-gate//
30Sstevel@tonic-gate//                     The LLVM Compiler Infrastructure
40Sstevel@tonic-gate//
50Sstevel@tonic-gate// This file is distributed under the University of Illinois Open Source
60Sstevel@tonic-gate// License. See LICENSE.TXT for details.
70Sstevel@tonic-gate//
80Sstevel@tonic-gate//===----------------------------------------------------------------------===//
90Sstevel@tonic-gate//
100Sstevel@tonic-gate//  This file implements the TargetInfo and TargetInfoImpl interfaces.
110Sstevel@tonic-gate//
120Sstevel@tonic-gate//===----------------------------------------------------------------------===//
130Sstevel@tonic-gate
140Sstevel@tonic-gate#include "clang/Basic/TargetInfo.h"
150Sstevel@tonic-gate#include "llvm/ADT/APFloat.h"
160Sstevel@tonic-gate#include "llvm/ADT/STLExtras.h"
170Sstevel@tonic-gate#include <cstdlib>
180Sstevel@tonic-gateusing namespace clang;
190Sstevel@tonic-gate
200Sstevel@tonic-gate// TargetInfo Constructor.
210Sstevel@tonic-gateTargetInfo::TargetInfo(const std::string &T) : Triple(T) {
220Sstevel@tonic-gate  // Set defaults.  Defaults are set for a 32-bit RISC platform,
230Sstevel@tonic-gate  // like PPC or SPARC.
240Sstevel@tonic-gate  // These should be overridden by concrete targets as needed.
250Sstevel@tonic-gate  TLSSupported = true;
260Sstevel@tonic-gate  PointerWidth = PointerAlign = 32;
270Sstevel@tonic-gate  WCharWidth = WCharAlign = 32;
280Sstevel@tonic-gate  Char16Width = Char16Align = 16;
290Sstevel@tonic-gate  Char32Width = Char32Align = 32;
300Sstevel@tonic-gate  IntWidth = IntAlign = 32;
310Sstevel@tonic-gate  LongWidth = LongAlign = 32;
320Sstevel@tonic-gate  LongLongWidth = LongLongAlign = 64;
330Sstevel@tonic-gate  FloatWidth = 32;
340Sstevel@tonic-gate  FloatAlign = 32;
350Sstevel@tonic-gate  DoubleWidth = 64;
360Sstevel@tonic-gate  DoubleAlign = 64;
370Sstevel@tonic-gate  LongDoubleWidth = 64;
380Sstevel@tonic-gate  LongDoubleAlign = 64;
390Sstevel@tonic-gate  IntMaxTWidth = 64;
400Sstevel@tonic-gate  SizeType = UnsignedLong;
410Sstevel@tonic-gate  PtrDiffType = SignedLong;
420Sstevel@tonic-gate  IntMaxType = SignedLongLong;
430Sstevel@tonic-gate  UIntMaxType = UnsignedLongLong;
440Sstevel@tonic-gate  IntPtrType = SignedLong;
450Sstevel@tonic-gate  WCharType = SignedInt;
460Sstevel@tonic-gate  WIntType = SignedInt;
470Sstevel@tonic-gate  Char16Type = UnsignedShort;
480Sstevel@tonic-gate  Char32Type = UnsignedInt;
490Sstevel@tonic-gate  Int64Type = SignedLongLong;
500Sstevel@tonic-gate  FloatFormat = &llvm::APFloat::IEEEsingle;
510Sstevel@tonic-gate  DoubleFormat = &llvm::APFloat::IEEEdouble;
520Sstevel@tonic-gate  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
530Sstevel@tonic-gate  DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
540Sstevel@tonic-gate                      "i64:64:64-f32:32:32-f64:64:64";
550Sstevel@tonic-gate  UserLabelPrefix = "_";
560Sstevel@tonic-gate}
570Sstevel@tonic-gate
580Sstevel@tonic-gate// Out of line virtual dtor for TargetInfo.
590Sstevel@tonic-gateTargetInfo::~TargetInfo() {}
600Sstevel@tonic-gate
610Sstevel@tonic-gate/// getTypeName - Return the user string for the specified integer type enum.
620Sstevel@tonic-gate/// For example, SignedShort -> "short".
630Sstevel@tonic-gateconst char *TargetInfo::getTypeName(IntType T) {
640Sstevel@tonic-gate  switch (T) {
650Sstevel@tonic-gate  default: assert(0 && "not an integer!");
660Sstevel@tonic-gate  case SignedShort:      return "short";
670Sstevel@tonic-gate  case UnsignedShort:    return "unsigned short";
680Sstevel@tonic-gate  case SignedInt:        return "int";
690Sstevel@tonic-gate  case UnsignedInt:      return "unsigned int";
700Sstevel@tonic-gate  case SignedLong:       return "long int";
710Sstevel@tonic-gate  case UnsignedLong:     return "long unsigned int";
72  case SignedLongLong:   return "long long int";
73  case UnsignedLongLong: return "long long unsigned int";
74  }
75}
76
77/// getTypeConstantSuffix - Return the constant suffix for the specified
78/// integer type enum. For example, SignedLong -> "L".
79const char *TargetInfo::getTypeConstantSuffix(IntType T) {
80  switch (T) {
81  default: assert(0 && "not an integer!");
82  case SignedShort:
83  case SignedInt:        return "";
84  case SignedLong:       return "L";
85  case SignedLongLong:   return "LL";
86  case UnsignedShort:
87  case UnsignedInt:      return "U";
88  case UnsignedLong:     return "UL";
89  case UnsignedLongLong: return "ULL";
90  }
91}
92
93/// getTypeWidth - Return the width (in bits) of the specified integer type
94/// enum. For example, SignedInt -> getIntWidth().
95unsigned TargetInfo::getTypeWidth(IntType T) const {
96  switch (T) {
97  default: assert(0 && "not an integer!");
98  case SignedShort:      return getShortWidth();
99  case UnsignedShort:    return getShortWidth();
100  case SignedInt:        return getIntWidth();
101  case UnsignedInt:      return getIntWidth();
102  case SignedLong:       return getLongWidth();
103  case UnsignedLong:     return getLongWidth();
104  case SignedLongLong:   return getLongLongWidth();
105  case UnsignedLongLong: return getLongLongWidth();
106  };
107}
108
109/// getTypeSigned - Return whether an integer types is signed. Returns true if
110/// the type is signed; false otherwise.
111bool TargetInfo::getTypeSigned(IntType T) const {
112  switch (T) {
113  default: assert(0 && "not an integer!");
114  case SignedShort:
115  case SignedInt:
116  case SignedLong:
117  case SignedLongLong:
118    return true;
119  case UnsignedShort:
120  case UnsignedInt:
121  case UnsignedLong:
122  case UnsignedLongLong:
123    return false;
124  };
125}
126
127
128//===----------------------------------------------------------------------===//
129
130
131static void removeGCCRegisterPrefix(const char *&Name) {
132  if (Name[0] == '%' || Name[0] == '#')
133    Name++;
134}
135
136/// isValidGCCRegisterName - Returns whether the passed in string
137/// is a valid register name according to GCC. This is used by Sema for
138/// inline asm statements.
139bool TargetInfo::isValidGCCRegisterName(const char *Name) const {
140  const char * const *Names;
141  unsigned NumNames;
142
143  // Get rid of any register prefix.
144  removeGCCRegisterPrefix(Name);
145
146
147  if (strcmp(Name, "memory") == 0 ||
148      strcmp(Name, "cc") == 0)
149    return true;
150
151  getGCCRegNames(Names, NumNames);
152
153  // If we have a number it maps to an entry in the register name array.
154  if (isdigit(Name[0])) {
155    char *End;
156    int n = (int)strtol(Name, &End, 0);
157    if (*End == 0)
158      return n >= 0 && (unsigned)n < NumNames;
159  }
160
161  // Check register names.
162  for (unsigned i = 0; i < NumNames; i++) {
163    if (strcmp(Name, Names[i]) == 0)
164      return true;
165  }
166
167  // Now check aliases.
168  const GCCRegAlias *Aliases;
169  unsigned NumAliases;
170
171  getGCCRegAliases(Aliases, NumAliases);
172  for (unsigned i = 0; i < NumAliases; i++) {
173    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
174      if (!Aliases[i].Aliases[j])
175        break;
176      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
177        return true;
178    }
179  }
180
181  return false;
182}
183
184const char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const {
185  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
186
187  removeGCCRegisterPrefix(Name);
188
189  const char * const *Names;
190  unsigned NumNames;
191
192  getGCCRegNames(Names, NumNames);
193
194  // First, check if we have a number.
195  if (isdigit(Name[0])) {
196    char *End;
197    int n = (int)strtol(Name, &End, 0);
198    if (*End == 0) {
199      assert(n >= 0 && (unsigned)n < NumNames &&
200             "Out of bounds register number!");
201      return Names[n];
202    }
203  }
204
205  // Now check aliases.
206  const GCCRegAlias *Aliases;
207  unsigned NumAliases;
208
209  getGCCRegAliases(Aliases, NumAliases);
210  for (unsigned i = 0; i < NumAliases; i++) {
211    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
212      if (!Aliases[i].Aliases[j])
213        break;
214      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
215        return Aliases[i].Register;
216    }
217  }
218
219  return Name;
220}
221
222bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
223  const char *Name = Info.getConstraintStr().c_str();
224  // An output constraint must start with '=' or '+'
225  if (*Name != '=' && *Name != '+')
226    return false;
227
228  if (*Name == '+')
229    Info.setIsReadWrite();
230
231  Name++;
232  while (*Name) {
233    switch (*Name) {
234    default:
235      if (!validateAsmConstraint(Name, Info)) {
236        // FIXME: We temporarily return false
237        // so we can add more constraints as we hit it.
238        // Eventually, an unknown constraint should just be treated as 'g'.
239        return false;
240      }
241    case '&': // early clobber.
242      break;
243    case '%': // commutative.
244      // FIXME: Check that there is a another register after this one.
245      break;
246    case 'r': // general register.
247      Info.setAllowsRegister();
248      break;
249    case 'm': // memory operand.
250      Info.setAllowsMemory();
251      break;
252    case 'g': // general register, memory operand or immediate integer.
253    case 'X': // any operand.
254      Info.setAllowsRegister();
255      Info.setAllowsMemory();
256      break;
257    }
258
259    Name++;
260  }
261
262  return true;
263}
264
265bool TargetInfo::resolveSymbolicName(const char *&Name,
266                                     ConstraintInfo *OutputConstraints,
267                                     unsigned NumOutputs,
268                                     unsigned &Index) const {
269  assert(*Name == '[' && "Symbolic name did not start with '['");
270  Name++;
271  const char *Start = Name;
272  while (*Name && *Name != ']')
273    Name++;
274
275  if (!*Name) {
276    // Missing ']'
277    return false;
278  }
279
280  std::string SymbolicName(Start, Name - Start);
281
282  for (Index = 0; Index != NumOutputs; ++Index)
283    if (SymbolicName == OutputConstraints[Index].getName())
284      return true;
285
286  return false;
287}
288
289bool TargetInfo::validateInputConstraint(ConstraintInfo *OutputConstraints,
290                                         unsigned NumOutputs,
291                                         ConstraintInfo &Info) const {
292  const char *Name = Info.ConstraintStr.c_str();
293
294  while (*Name) {
295    switch (*Name) {
296    default:
297      // Check if we have a matching constraint
298      if (*Name >= '0' && *Name <= '9') {
299        unsigned i = *Name - '0';
300
301        // Check if matching constraint is out of bounds.
302        if (i >= NumOutputs)
303          return false;
304
305        // The constraint should have the same info as the respective
306        // output constraint.
307        Info.setTiedOperand(i, OutputConstraints[i]);
308      } else if (!validateAsmConstraint(Name, Info)) {
309        // FIXME: This error return is in place temporarily so we can
310        // add more constraints as we hit it.  Eventually, an unknown
311        // constraint should just be treated as 'g'.
312        return false;
313      }
314      break;
315    case '[': {
316      unsigned Index = 0;
317      if (!resolveSymbolicName(Name, OutputConstraints, NumOutputs, Index))
318        return false;
319
320      break;
321    }
322    case '%': // commutative
323      // FIXME: Fail if % is used with the last operand.
324      break;
325    case 'i': // immediate integer.
326    case 'n': // immediate integer with a known value.
327      break;
328    case 'I':  // Various constant constraints with target-specific meanings.
329    case 'J':
330    case 'K':
331    case 'L':
332    case 'M':
333    case 'N':
334    case 'O':
335    case 'P':
336      break;
337    case 'r': // general register.
338      Info.setAllowsRegister();
339      break;
340    case 'm': // memory operand.
341      Info.setAllowsMemory();
342      break;
343    case 'g': // general register, memory operand or immediate integer.
344    case 'X': // any operand.
345      Info.setAllowsRegister();
346      Info.setAllowsMemory();
347      break;
348    }
349
350    Name++;
351  }
352
353  return true;
354}
355