TargetInfo.cpp revision d229d965d39c529a4dd3ac820824ec4309b86a44
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/Diagnostic.h"
16#include "clang/AST/Builtins.h"
17#include "llvm/ADT/APFloat.h"
18#include "llvm/ADT/STLExtras.h"
19#include <cstdlib>
20using namespace clang;
21
22// TargetInfo Constructor.
23TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
24  // Set defaults.  These should be overridden by concrete targets as needed.
25  CharIsSigned = true;
26  WCharWidth = WCharAlign = 32;
27  DoubleWidth = 64;
28  DoubleAlign = 32;
29  FloatFormat = &llvm::APFloat::IEEEsingle;
30  DoubleFormat = &llvm::APFloat::IEEEdouble;
31  LongDoubleFormat = &llvm::APFloat::IEEEdouble;
32}
33
34// Out of line virtual dtor for TargetInfo.
35TargetInfo::~TargetInfo() {}
36
37//===----------------------------------------------------------------------===//
38
39
40static void removeGCCRegisterPrefix(const char *&Name) {
41  if (Name[0] == '%' || Name[0] == '#')
42    Name++;
43}
44
45/// isValidGCCRegisterName - Returns whether the passed in string
46/// is a valid register name according to GCC. This is used by Sema for
47/// inline asm statements.
48bool TargetInfo::isValidGCCRegisterName(const char *Name) const {
49  const char * const *Names;
50  unsigned NumNames;
51
52  // Get rid of any register prefix.
53  removeGCCRegisterPrefix(Name);
54
55
56  if (strcmp(Name, "memory") == 0 ||
57      strcmp(Name, "cc") == 0)
58    return true;
59
60  getGCCRegNames(Names, NumNames);
61
62  // If we have a number it maps to an entry in the register name array.
63  if (isdigit(Name[0])) {
64    char *End;
65    int n = (int)strtol(Name, &End, 0);
66    if (*End == 0)
67      return n >= 0 && (unsigned)n < NumNames;
68  }
69
70  // Check register names.
71  for (unsigned i = 0; i < NumNames; i++) {
72    if (strcmp(Name, Names[i]) == 0)
73      return true;
74  }
75
76  // Now check aliases.
77  const GCCRegAlias *Aliases;
78  unsigned NumAliases;
79
80  getGCCRegAliases(Aliases, NumAliases);
81  for (unsigned i = 0; i < NumAliases; i++) {
82    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
83      if (!Aliases[i].Aliases[j])
84        break;
85      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
86        return true;
87    }
88  }
89
90  return false;
91}
92
93const char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const {
94  assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
95
96  removeGCCRegisterPrefix(Name);
97
98  const char * const *Names;
99  unsigned NumNames;
100
101  getGCCRegNames(Names, NumNames);
102
103  // First, check if we have a number.
104  if (isdigit(Name[0])) {
105    char *End;
106    int n = (int)strtol(Name, &End, 0);
107    if (*End == 0) {
108      assert(n >= 0 && (unsigned)n < NumNames &&
109             "Out of bounds register number!");
110      return Names[n];
111    }
112  }
113
114  // Now check aliases.
115  const GCCRegAlias *Aliases;
116  unsigned NumAliases;
117
118  getGCCRegAliases(Aliases, NumAliases);
119  for (unsigned i = 0; i < NumAliases; i++) {
120    for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
121      if (!Aliases[i].Aliases[j])
122        break;
123      if (strcmp(Aliases[i].Aliases[j], Name) == 0)
124        return Aliases[i].Register;
125    }
126  }
127
128  return Name;
129}
130
131bool TargetInfo::validateOutputConstraint(const char *Name,
132                                          ConstraintInfo &info) const
133{
134  // An output constraint must start with '=' or '+'
135  if (*Name != '=' && *Name != '+')
136    return false;
137
138  if (*Name == '+')
139    info = CI_ReadWrite;
140  else
141    info = CI_None;
142
143  Name++;
144  while (*Name) {
145    switch (*Name) {
146    default:
147      if (!validateAsmConstraint(*Name, info)) {
148        // FIXME: We temporarily return false
149        // so we can add more constraints as we hit it.
150        // Eventually, an unknown constraint should just be treated as 'g'.
151        return false;
152      }
153    case '&': // early clobber.
154      break;
155    case 'r': // general register.
156      info = (ConstraintInfo)(info|CI_AllowsRegister);
157      break;
158    case 'm': // memory operand.
159      info = (ConstraintInfo)(info|CI_AllowsMemory);
160      break;
161    case 'g': // general register, memory operand or immediate integer.
162      info = (ConstraintInfo)(info|CI_AllowsMemory|CI_AllowsRegister);
163      break;
164    }
165
166    Name++;
167  }
168
169  return true;
170}
171
172bool TargetInfo::validateInputConstraint(const char *Name,
173                                         unsigned NumOutputs,
174                                         ConstraintInfo &info) const {
175  while (*Name) {
176    switch (*Name) {
177    default:
178      // Check if we have a matching constraint
179      if (*Name >= '0' && *Name <= '9') {
180        unsigned i = *Name - '0';
181
182        // Check if matching constraint is out of bounds.
183        if (i >= NumOutputs)
184          return false;
185      } else if (!validateAsmConstraint(*Name, info)) {
186        // FIXME: This assert is in place temporarily
187        // so we can add more constraints as we hit it.
188        // Eventually, an unknown constraint should just be treated as 'g'.
189        assert(0 && "Unknown input constraint type!");
190      }
191    case '%': // commutative
192      // FIXME: Fail if % is used with the last operand.
193      break;
194    case 'i': // immediate integer.
195    case 'I':
196    case 'n': // immediate integer with a known value.
197      break;
198    case 'r': // general register.
199      info = (ConstraintInfo)(info|CI_AllowsRegister);
200      break;
201    case 'm': // memory operand.
202      info = (ConstraintInfo)(info|CI_AllowsMemory);
203      break;
204    case 'g': // general register, memory operand or immediate integer.
205      info = (ConstraintInfo)(info|CI_AllowsMemory|CI_AllowsRegister);
206      break;
207    }
208
209    Name++;
210  }
211
212  return true;
213}
214