LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
InlineAsm.cpp
Go to the documentation of this file.
1 //===-- InlineAsm.cpp - Implement the InlineAsm class ---------------------===//
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 InlineAsm class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/InlineAsm.h"
15 #include "ConstantsContext.h"
16 #include "LLVMContextImpl.h"
17 #include "llvm/IR/DerivedTypes.h"
18 #include <algorithm>
19 #include <cctype>
20 using namespace llvm;
21 
22 // Implement the first virtual method in this class in this file so the
23 // InlineAsm vtable is emitted here.
24 InlineAsm::~InlineAsm() {
25 }
26 
27 
29  StringRef Constraints, bool hasSideEffects,
30  bool isAlignStack, AsmDialect asmDialect) {
31  InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack,
32  asmDialect);
33  LLVMContextImpl *pImpl = Ty->getContext().pImpl;
34  return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
35 }
36 
37 InlineAsm::InlineAsm(PointerType *Ty, const std::string &asmString,
38  const std::string &constraints, bool hasSideEffects,
39  bool isAlignStack, AsmDialect asmDialect)
40  : Value(Ty, Value::InlineAsmVal),
41  AsmString(asmString), Constraints(constraints),
42  HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
43  Dialect(asmDialect) {
44 
45  // Do various checks on the constraint string and type.
46  assert(Verify(getFunctionType(), constraints) &&
47  "Function type not legal for constraints!");
48 }
49 
50 void InlineAsm::destroyConstant() {
51  getType()->getContext().pImpl->InlineAsms.remove(this);
52  delete this;
53 }
54 
56  return cast<FunctionType>(getType()->getElementType());
57 }
58 
59 ///Default constructor.
61  Type(isInput), isEarlyClobber(false),
62  MatchingInput(-1), isCommutative(false),
63  isIndirect(false), isMultipleAlternative(false),
64  currentAlternativeIndex(0) {
65 }
66 
67 /// Copy constructor.
69  Type(other.Type), isEarlyClobber(other.isEarlyClobber),
70  MatchingInput(other.MatchingInput), isCommutative(other.isCommutative),
71  isIndirect(other.isIndirect), Codes(other.Codes),
72  isMultipleAlternative(other.isMultipleAlternative),
73  multipleAlternatives(other.multipleAlternatives),
74  currentAlternativeIndex(other.currentAlternativeIndex) {
75 }
76 
77 /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
78 /// fields in this structure. If the constraint string is not understood,
79 /// return true, otherwise return false.
81  InlineAsm::ConstraintInfoVector &ConstraintsSoFar) {
82  StringRef::iterator I = Str.begin(), E = Str.end();
83  unsigned multipleAlternativeCount = Str.count('|') + 1;
84  unsigned multipleAlternativeIndex = 0;
85  ConstraintCodeVector *pCodes = &Codes;
86 
87  // Initialize
88  isMultipleAlternative = (multipleAlternativeCount > 1 ? true : false);
89  if (isMultipleAlternative) {
90  multipleAlternatives.resize(multipleAlternativeCount);
91  pCodes = &multipleAlternatives[0].Codes;
92  }
93  Type = isInput;
94  isEarlyClobber = false;
95  MatchingInput = -1;
96  isCommutative = false;
97  isIndirect = false;
98  currentAlternativeIndex = 0;
99 
100  // Parse prefixes.
101  if (*I == '~') {
102  Type = isClobber;
103  ++I;
104  } else if (*I == '=') {
105  ++I;
106  Type = isOutput;
107  }
108 
109  if (*I == '*') {
110  isIndirect = true;
111  ++I;
112  }
113 
114  if (I == E) return true; // Just a prefix, like "==" or "~".
115 
116  // Parse the modifiers.
117  bool DoneWithModifiers = false;
118  while (!DoneWithModifiers) {
119  switch (*I) {
120  default:
121  DoneWithModifiers = true;
122  break;
123  case '&': // Early clobber.
124  if (Type != isOutput || // Cannot early clobber anything but output.
125  isEarlyClobber) // Reject &&&&&&
126  return true;
127  isEarlyClobber = true;
128  break;
129  case '%': // Commutative.
130  if (Type == isClobber || // Cannot commute clobbers.
131  isCommutative) // Reject %%%%%
132  return true;
133  isCommutative = true;
134  break;
135  case '#': // Comment.
136  case '*': // Register preferencing.
137  return true; // Not supported.
138  }
139 
140  if (!DoneWithModifiers) {
141  ++I;
142  if (I == E) return true; // Just prefixes and modifiers!
143  }
144  }
145 
146  // Parse the various constraints.
147  while (I != E) {
148  if (*I == '{') { // Physical register reference.
149  // Find the end of the register name.
150  StringRef::iterator ConstraintEnd = std::find(I+1, E, '}');
151  if (ConstraintEnd == E) return true; // "{foo"
152  pCodes->push_back(std::string(I, ConstraintEnd+1));
153  I = ConstraintEnd+1;
154  } else if (isdigit(static_cast<unsigned char>(*I))) { // Matching Constraint
155  // Maximal munch numbers.
156  StringRef::iterator NumStart = I;
157  while (I != E && isdigit(static_cast<unsigned char>(*I)))
158  ++I;
159  pCodes->push_back(std::string(NumStart, I));
160  unsigned N = atoi(pCodes->back().c_str());
161  // Check that this is a valid matching constraint!
162  if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput||
163  Type != isInput)
164  return true; // Invalid constraint number.
165 
166  // If Operand N already has a matching input, reject this. An output
167  // can't be constrained to the same value as multiple inputs.
168  if (isMultipleAlternative) {
170  ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex];
171  if (scInfo.MatchingInput != -1)
172  return true;
173  // Note that operand #n has a matching input.
174  scInfo.MatchingInput = ConstraintsSoFar.size();
175  } else {
176  if (ConstraintsSoFar[N].hasMatchingInput())
177  return true;
178  // Note that operand #n has a matching input.
179  ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
180  }
181  } else if (*I == '|') {
182  multipleAlternativeIndex++;
183  pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes;
184  ++I;
185  } else if (*I == '^') {
186  // Multi-letter constraint
187  // FIXME: For now assuming these are 2-character constraints.
188  pCodes->push_back(std::string(I+1, I+3));
189  I += 3;
190  } else {
191  // Single letter constraint.
192  pCodes->push_back(std::string(I, I+1));
193  ++I;
194  }
195  }
196 
197  return false;
198 }
199 
200 /// selectAlternative - Point this constraint to the alternative constraint
201 /// indicated by the index.
203  if (index < multipleAlternatives.size()) {
204  currentAlternativeIndex = index;
206  multipleAlternatives[currentAlternativeIndex];
207  MatchingInput = scInfo.MatchingInput;
208  Codes = scInfo.Codes;
209  }
210 }
211 
214  ConstraintInfoVector Result;
215 
216  // Scan the constraints string.
217  for (StringRef::iterator I = Constraints.begin(),
218  E = Constraints.end(); I != E; ) {
219  ConstraintInfo Info;
220 
221  // Find the end of this constraint.
222  StringRef::iterator ConstraintEnd = std::find(I, E, ',');
223 
224  if (ConstraintEnd == I || // Empty constraint like ",,"
225  Info.Parse(StringRef(I, ConstraintEnd-I), Result)) {
226  Result.clear(); // Erroneous constraint?
227  break;
228  }
229 
230  Result.push_back(Info);
231 
232  // ConstraintEnd may be either the next comma or the end of the string. In
233  // the former case, we skip the comma.
234  I = ConstraintEnd;
235  if (I != E) {
236  ++I;
237  if (I == E) { Result.clear(); break; } // don't allow "xyz,"
238  }
239  }
240 
241  return Result;
242 }
243 
244 /// Verify - Verify that the specified constraint string is reasonable for the
245 /// specified function type, and otherwise validate the constraint string.
247  if (Ty->isVarArg()) return false;
248 
249  ConstraintInfoVector Constraints = ParseConstraints(ConstStr);
250 
251  // Error parsing constraints.
252  if (Constraints.empty() && !ConstStr.empty()) return false;
253 
254  unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
255  unsigned NumIndirect = 0;
256 
257  for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
258  switch (Constraints[i].Type) {
259  case InlineAsm::isOutput:
260  if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
261  return false; // outputs before inputs and clobbers.
262  if (!Constraints[i].isIndirect) {
263  ++NumOutputs;
264  break;
265  }
266  ++NumIndirect;
267  // FALLTHROUGH for Indirect Outputs.
268  case InlineAsm::isInput:
269  if (NumClobbers) return false; // inputs before clobbers.
270  ++NumInputs;
271  break;
273  ++NumClobbers;
274  break;
275  }
276  }
277 
278  switch (NumOutputs) {
279  case 0:
280  if (!Ty->getReturnType()->isVoidTy()) return false;
281  break;
282  case 1:
283  if (Ty->getReturnType()->isStructTy()) return false;
284  break;
285  default:
287  if (STy == 0 || STy->getNumElements() != NumOutputs)
288  return false;
289  break;
290  }
291 
292  if (Ty->getNumParams() != NumInputs) return false;
293  return true;
294 }
295 
unsigned getNumParams() const
Definition: DerivedTypes.h:133
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:266
int isdigit(int c);
bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar)
Definition: InlineAsm.cpp:80
static bool isInput(const llvm::StringSet<> &Prefixes, StringRef Arg)
Definition: OptTable.cpp:168
ConstraintInfoVector ParseConstraints() const
Definition: InlineAsm.h:187
#define false
Definition: ConvertUTF.c:64
int atoi(const char *str);
LLVMContext & getContext() const
getContext - Return the LLVMContext in which this type was uniqued.
Definition: Type.h:128
static bool Verify(FunctionType *Ty, StringRef Constraints)
Definition: InlineAsm.cpp:246
Type * getElementType() const
Definition: DerivedTypes.h:319
iterator begin() const
Definition: StringRef.h:97
ConstraintInfo()
Default constructor.
Definition: InlineAsm.cpp:60
size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:316
PointerType * getType() const
Definition: InlineAsm.h:78
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:39
const char * iterator
Definition: StringRef.h:43
FunctionType * getFunctionType() const
Definition: InlineAsm.cpp:55
std::vector< std::string > ConstraintCodeVector
Definition: InlineAsm.h:102
ConstraintCodeVector Codes
Definition: InlineAsm.h:112
static PointerType * getUnqual(Type *ElementType)
Definition: DerivedTypes.h:436
bool isStructTy() const
Definition: Type.h:212
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
ConstantUniqueMap< InlineAsmKeyType, const InlineAsmKeyType &, PointerType, InlineAsm > InlineAsms
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
Definition: InlineAsm.cpp:28
bool isVarArg() const
Definition: DerivedTypes.h:120
Type * getReturnType() const
Definition: DerivedTypes.h:121
LLVM Value Representation.
Definition: Value.h:66
iterator end() const
Definition: StringRef.h:99
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:286
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:118
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
Definition: Type.h:140
void selectAlternative(unsigned index)
Definition: InlineAsm.cpp:202
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110