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

105 if (I != E && *I != '{')

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 '&':

130 if (Type != isOutput ||

132 return true;

134 break;

135 case '%':

136 if (Type == isClobber ||

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!");

208 int N = C - '0';

209 assert(N > 0 && "Found a zero letter constraint!");

210 ++I;

211 pCodes->push_back(std::string(StringRef(I, N)));

212 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...