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