LLVM: lib/IR/InlineAsm.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
23#include
24#include
25#include
26#include
27
28using namespace llvm;
29
30InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString,
31 const std::string &constraints, bool hasSideEffects,
32 bool isAlignStack, AsmDialect asmDialect, bool canThrow)
34 AsmString(asmString), Constraints(constraints), FTy(FTy),
35 HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
36 Dialect(asmDialect), CanThrow(canThrow) {
37#ifndef NDEBUG
38
40#endif
41}
42
53
54void InlineAsm::destroyConstant() {
56 delete this;
57}
58
62
66
67
68
69
70
71 if (AsmStr.empty())
72 return;
73 AsmStr.split(AsmStrs, "\n\t", -1, false);
74}
75
76
77
78
82 unsigned multipleAlternativeCount = Str.count('|') + 1;
83 unsigned multipleAlternativeIndex = 0;
85
86
91 }
98
99
100 if (*I == '~') {
102 ++I;
103
104
106 return true;
107 } else if (*I == '=') {
108 ++I;
110 } else if (*I == '!') {
111 ++I;
113 }
114
115 if (*I == '*') {
117 ++I;
118 }
119
120 if (I == E) return true;
121
122
123 bool DoneWithModifiers = false;
124 while (!DoneWithModifiers) {
125 switch (*I) {
126 default:
127 DoneWithModifiers = true;
128 break;
129 case '&':
132 return true;
134 break;
135 case '%':
138 return true;
140 break;
141 case '#':
142 case '*':
143 return true;
144 }
145
146 if (!DoneWithModifiers) {
147 ++I;
148 if (I == E) return true;
149 }
150 }
151
152
153 while (I != E) {
154 if (*I == '{') {
155
157 if (ConstraintEnd == E) return true;
158 pCodes->push_back(std::string(StringRef(I, ConstraintEnd + 1 - I)));
159 I = ConstraintEnd+1;
160 } else if (isdigit(static_cast<unsigned char>(*I))) {
161
163 while (I != E && isdigit(static_cast<unsigned char>(*I)))
164 ++I;
165 pCodes->push_back(std::string(StringRef(NumStart, I - NumStart)));
166 unsigned N = atoi(pCodes->back().c_str());
167
168 if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput||
170 return true;
171
172
173
175 if (multipleAlternativeIndex >=
177 return true;
179 ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex];
181 return true;
182
185 } else {
188 ConstraintsSoFar.size())
189 return true;
190
191 ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
193 }
194 } else if (*I == '|') {
195 multipleAlternativeIndex++;
197 ++I;
198 } else if (*I == '^') {
199
200
201 pCodes->push_back(std::string(StringRef(I + 1, 2)));
202 I += 3;
203 } else if (*I == '@') {
204
205 ++I;
206 unsigned char C = static_cast<unsigned char>(*I);
207 assert(isdigit(C) && "Expected a digit!");
209 assert(N > 0 && "Found a zero letter constraint!");
210 ++I;
211 pCodes->push_back(std::string(StringRef(I, N)));
213 } else {
214
215 pCodes->push_back(std::string(StringRef(I, 1)));
216 ++I;
217 }
218 }
219
220 return false;
221}
222
223
224
234
238
239
241 E = Constraints.end(); I != E; ) {
243
244
246
247 if (ConstraintEnd == I ||
248 Info.Parse(StringRef(I, ConstraintEnd-I), Result)) {
249 Result.clear();
250 break;
251 }
252
253 Result.push_back(Info);
254
255
256
257 I = ConstraintEnd;
258 if (I != E) {
259 ++I;
260 if (I == E) {
261 Result.clear();
262 break;
263 }
264 }
265 }
266
267 return Result;
268}
269
273
275 if (Ty->isVarArg())
277
279
280
281 if (Constraints.empty() && !ConstStr.empty())
283
284 unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
285 unsigned NumIndirect = 0, NumLabels = 0;
286
287 for (const ConstraintInfo &Constraint : Constraints) {
288 switch (Constraint.Type) {
290 if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0 || NumLabels != 0)
291 return makeStringError("output constraint occurs after input, "
292 "clobber or label constraint");
293
294 if (!Constraint.isIndirect) {
295 ++NumOutputs;
296 break;
297 }
298 ++NumIndirect;
299 [[fallthrough]];
301 if (NumClobbers)
302 return makeStringError("input constraint occurs after clobber "
303 "constraint");
304 ++NumInputs;
305 break;
307 ++NumClobbers;
308 break;
310 if (NumClobbers)
311 return makeStringError("label constraint occurs after clobber "
312 "constraint");
313
314 ++NumLabels;
315 break;
316 }
317 }
318
319 switch (NumOutputs) {
320 case 0:
321 if (!Ty->getReturnType()->isVoidTy())
322 return makeStringError("inline asm without outputs must return void");
323 break;
324 case 1:
325 if (Ty->getReturnType()->isStructTy())
326 return makeStringError("inline asm with one output cannot return struct");
327 break;
328 default:
331 return makeStringError("number of output constraints does not match "
332 "number of return struct elements");
333 break;
334 }
335
336 if (Ty->getNumParams() != NumInputs)
337 return makeStringError("number of input constraints does not match number "
338 "of parameters");
339
340
342}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Error makeStringError(const char *Msg)
Definition InlineAsm.cpp:270
static bool canThrow(const Value *V)
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Class to represent function types.
LLVM_ABI void collectAsmStrs(SmallVectorImpl< StringRef > &AsmStrs) const
Definition InlineAsm.cpp:63
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition InlineAsm.cpp:43
std::vector< ConstraintInfo > ConstraintInfoVector
friend struct InlineAsmKeyType
bool isAlignStack() const
LLVM_ABI FunctionType * getFunctionType() const
getFunctionType - InlineAsm's are always pointers to functions.
Definition InlineAsm.cpp:59
bool hasSideEffects() const
ConstraintInfoVector ParseConstraints() const
ParseConstraints - Parse the constraints of this inlineasm object, returning them the same way that P...
std::vector< std::string > ConstraintCodeVector
static LLVM_ABI Error verify(FunctionType *Ty, StringRef Constraints)
This static method can be used by the parser to check to see if the specified constraint string is le...
Definition InlineAsm.cpp:274
PointerType * getType() const
getType - InlineAsm's are always pointers.
ConstantUniqueMap< InlineAsm > InlineAsms
LLVMContextImpl *const pImpl
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr bool empty() const
empty - Check if the string is empty.
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
LLVM Value Representation.
@ C
The default llvm calling convention, compatible with C.
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
bool isCommutative
isCommutative - This is set to true for a constraint that is commutative with the next operand.
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber/label.
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
unsigned currentAlternativeIndex
The currently selected alternative constraint index.
LLVM_ABI bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar)
Parse - Analyze the specified string (e.g.
Definition InlineAsm.cpp:79
SubConstraintInfoVector multipleAlternatives
multipleAlternatives - If there are multiple alternative constraints, this array will contain them.
bool isIndirect
isIndirect - True if this operand is an indirect operand.
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
bool isMultipleAlternative
isMultipleAlternative - '|': has multiple-alternative constraints.
LLVM_ABI void selectAlternative(unsigned index)
selectAlternative - Point this constraint to the alternative constraint indicated by the index.
Definition InlineAsm.cpp:225
bool hasMatchingInput() const
hasMatchingInput - Return true if this is an output constraint that has a matching input constraint.
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...