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