Bug Summary

File:lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Warning:line 2301, column 33
1st function call argument is an uninitialized value

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

1//==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
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#include "MCTargetDesc/AArch64AddressingModes.h"
11#include "MCTargetDesc/AArch64MCExpr.h"
12#include "MCTargetDesc/AArch64MCTargetDesc.h"
13#include "MCTargetDesc/AArch64TargetStreamer.h"
14#include "Utils/AArch64BaseInfo.h"
15#include "llvm/ADT/APFloat.h"
16#include "llvm/ADT/APInt.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/ADT/StringMap.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ADT/StringSwitch.h"
24#include "llvm/ADT/Twine.h"
25#include "llvm/MC/MCContext.h"
26#include "llvm/MC/MCExpr.h"
27#include "llvm/MC/MCInst.h"
28#include "llvm/MC/MCLinkerOptimizationHint.h"
29#include "llvm/MC/MCObjectFileInfo.h"
30#include "llvm/MC/MCParser/MCAsmLexer.h"
31#include "llvm/MC/MCParser/MCAsmParser.h"
32#include "llvm/MC/MCParser/MCAsmParserExtension.h"
33#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
34#include "llvm/MC/MCParser/MCTargetAsmParser.h"
35#include "llvm/MC/MCRegisterInfo.h"
36#include "llvm/MC/MCStreamer.h"
37#include "llvm/MC/MCSubtargetInfo.h"
38#include "llvm/MC/MCSymbol.h"
39#include "llvm/MC/MCTargetOptions.h"
40#include "llvm/MC/SubtargetFeature.h"
41#include "llvm/Support/Casting.h"
42#include "llvm/Support/Compiler.h"
43#include "llvm/Support/ErrorHandling.h"
44#include "llvm/Support/MathExtras.h"
45#include "llvm/Support/SMLoc.h"
46#include "llvm/Support/TargetParser.h"
47#include "llvm/Support/TargetRegistry.h"
48#include "llvm/Support/raw_ostream.h"
49#include <cassert>
50#include <cctype>
51#include <cstdint>
52#include <cstdio>
53#include <string>
54#include <tuple>
55#include <utility>
56#include <vector>
57
58using namespace llvm;
59
60namespace {
61
62enum class RegKind {Scalar, NeonVector, SVEDataVector};
63
64class AArch64AsmParser : public MCTargetAsmParser {
65private:
66 StringRef Mnemonic; ///< Instruction mnemonic.
67
68 // Map of register aliases registers via the .req directive.
69 StringMap<std::pair<RegKind, unsigned>> RegisterReqs;
70
71 AArch64TargetStreamer &getTargetStreamer() {
72 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
73 return static_cast<AArch64TargetStreamer &>(TS);
74 }
75
76 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
77
78 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
79 void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
80 AArch64CC::CondCode parseCondCodeString(StringRef Cond);
81 bool parseCondCode(OperandVector &Operands, bool invertCondCode);
82 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
83 int tryParseRegister();
84 int tryMatchVectorRegister(StringRef &Kind, bool expected);
85 int tryParseSVEDataVectorRegister(const AsmToken &Tok, StringRef &Kind);
86 bool parseRegister(OperandVector &Operands);
87 bool parseSymbolicImmVal(const MCExpr *&ImmVal);
88 bool parseVectorList(OperandVector &Operands);
89 bool parseOperand(OperandVector &Operands, bool isCondCode,
90 bool invertCondCode);
91
92 bool showMatchError(SMLoc Loc, unsigned ErrCode, OperandVector &Operands);
93
94 bool parseDirectiveArch(SMLoc L);
95 bool parseDirectiveCPU(SMLoc L);
96 bool parseDirectiveWord(unsigned Size, SMLoc L);
97 bool parseDirectiveInst(SMLoc L);
98
99 bool parseDirectiveTLSDescCall(SMLoc L);
100
101 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
102 bool parseDirectiveLtorg(SMLoc L);
103
104 bool parseDirectiveReq(StringRef Name, SMLoc L);
105 bool parseDirectiveUnreq(SMLoc L);
106
107 bool validateInstruction(MCInst &Inst, SmallVectorImpl<SMLoc> &Loc);
108 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
109 OperandVector &Operands, MCStreamer &Out,
110 uint64_t &ErrorInfo,
111 bool MatchingInlineAsm) override;
112/// @name Auto-generated Match Functions
113/// {
114
115#define GET_ASSEMBLER_HEADER
116#include "AArch64GenAsmMatcher.inc"
117
118 /// }
119
120 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
121 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
122 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
123 OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
124 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
125 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
126 OperandMatchResultTy tryParsePSBHint(OperandVector &Operands);
127 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
128 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
129 OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
130 OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
131 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
132 bool tryParseNeonVectorRegister(OperandVector &Operands);
133 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
134 template <bool ParseSuffix>
135 OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands);
136
137public:
138 enum AArch64MatchResultTy {
139 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
140#define GET_OPERAND_DIAGNOSTIC_TYPES
141#include "AArch64GenAsmMatcher.inc"
142 };
143 bool IsILP32;
144
145 AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
146 const MCInstrInfo &MII, const MCTargetOptions &Options)
147 : MCTargetAsmParser(Options, STI, MII) {
148 IsILP32 = Options.getABIName() == "ilp32";
149 MCAsmParserExtension::Initialize(Parser);
150 MCStreamer &S = getParser().getStreamer();
151 if (S.getTargetStreamer() == nullptr)
152 new AArch64TargetStreamer(S);
153
154 // Initialize the set of available features.
155 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
156 }
157
158 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
159 SMLoc NameLoc, OperandVector &Operands) override;
160 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
161 bool ParseDirective(AsmToken DirectiveID) override;
162 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
163 unsigned Kind) override;
164
165 static bool classifySymbolRef(const MCExpr *Expr,
166 AArch64MCExpr::VariantKind &ELFRefKind,
167 MCSymbolRefExpr::VariantKind &DarwinRefKind,
168 int64_t &Addend);
169};
170
171/// AArch64Operand - Instances of this class represent a parsed AArch64 machine
172/// instruction.
173class AArch64Operand : public MCParsedAsmOperand {
174private:
175 enum KindTy {
176 k_Immediate,
177 k_ShiftedImm,
178 k_CondCode,
179 k_Register,
180 k_VectorList,
181 k_VectorIndex,
182 k_Token,
183 k_SysReg,
184 k_SysCR,
185 k_Prefetch,
186 k_ShiftExtend,
187 k_FPImm,
188 k_Barrier,
189 k_PSBHint,
190 } Kind;
191
192 SMLoc StartLoc, EndLoc;
193
194 struct TokOp {
195 const char *Data;
196 unsigned Length;
197 bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
198 };
199
200 struct RegOp {
201 unsigned RegNum;
202 RegKind Kind;
203
204 int ElementWidth;
205 };
206
207 struct VectorListOp {
208 unsigned RegNum;
209 unsigned Count;
210 unsigned NumElements;
211 unsigned ElementKind;
212 };
213
214 struct VectorIndexOp {
215 unsigned Val;
216 };
217
218 struct ImmOp {
219 const MCExpr *Val;
220 };
221
222 struct ShiftedImmOp {
223 const MCExpr *Val;
224 unsigned ShiftAmount;
225 };
226
227 struct CondCodeOp {
228 AArch64CC::CondCode Code;
229 };
230
231 struct FPImmOp {
232 unsigned Val; // Encoded 8-bit representation.
233 };
234
235 struct BarrierOp {
236 const char *Data;
237 unsigned Length;
238 unsigned Val; // Not the enum since not all values have names.
239 };
240
241 struct SysRegOp {
242 const char *Data;
243 unsigned Length;
244 uint32_t MRSReg;
245 uint32_t MSRReg;
246 uint32_t PStateField;
247 };
248
249 struct SysCRImmOp {
250 unsigned Val;
251 };
252
253 struct PrefetchOp {
254 const char *Data;
255 unsigned Length;
256 unsigned Val;
257 };
258
259 struct PSBHintOp {
260 const char *Data;
261 unsigned Length;
262 unsigned Val;
263 };
264
265 struct ShiftExtendOp {
266 AArch64_AM::ShiftExtendType Type;
267 unsigned Amount;
268 bool HasExplicitAmount;
269 };
270
271 struct ExtendOp {
272 unsigned Val;
273 };
274
275 union {
276 struct TokOp Tok;
277 struct RegOp Reg;
278 struct VectorListOp VectorList;
279 struct VectorIndexOp VectorIndex;
280 struct ImmOp Imm;
281 struct ShiftedImmOp ShiftedImm;
282 struct CondCodeOp CondCode;
283 struct FPImmOp FPImm;
284 struct BarrierOp Barrier;
285 struct SysRegOp SysReg;
286 struct SysCRImmOp SysCRImm;
287 struct PrefetchOp Prefetch;
288 struct PSBHintOp PSBHint;
289 struct ShiftExtendOp ShiftExtend;
290 };
291
292 // Keep the MCContext around as the MCExprs may need manipulated during
293 // the add<>Operands() calls.
294 MCContext &Ctx;
295
296public:
297 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {}
298
299 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
300 Kind = o.Kind;
301 StartLoc = o.StartLoc;
302 EndLoc = o.EndLoc;
303 switch (Kind) {
304 case k_Token:
305 Tok = o.Tok;
306 break;
307 case k_Immediate:
308 Imm = o.Imm;
309 break;
310 case k_ShiftedImm:
311 ShiftedImm = o.ShiftedImm;
312 break;
313 case k_CondCode:
314 CondCode = o.CondCode;
315 break;
316 case k_FPImm:
317 FPImm = o.FPImm;
318 break;
319 case k_Barrier:
320 Barrier = o.Barrier;
321 break;
322 case k_Register:
323 Reg = o.Reg;
324 break;
325 case k_VectorList:
326 VectorList = o.VectorList;
327 break;
328 case k_VectorIndex:
329 VectorIndex = o.VectorIndex;
330 break;
331 case k_SysReg:
332 SysReg = o.SysReg;
333 break;
334 case k_SysCR:
335 SysCRImm = o.SysCRImm;
336 break;
337 case k_Prefetch:
338 Prefetch = o.Prefetch;
339 break;
340 case k_PSBHint:
341 PSBHint = o.PSBHint;
342 break;
343 case k_ShiftExtend:
344 ShiftExtend = o.ShiftExtend;
345 break;
346 }
347 }
348
349 /// getStartLoc - Get the location of the first token of this operand.
350 SMLoc getStartLoc() const override { return StartLoc; }
351 /// getEndLoc - Get the location of the last token of this operand.
352 SMLoc getEndLoc() const override { return EndLoc; }
353
354 StringRef getToken() const {
355 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 355, __PRETTY_FUNCTION__))
;
356 return StringRef(Tok.Data, Tok.Length);
357 }
358
359 bool isTokenSuffix() const {
360 assert(Kind == k_Token && "Invalid access!")((Kind == k_Token && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Token && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 360, __PRETTY_FUNCTION__))
;
361 return Tok.IsSuffix;
362 }
363
364 const MCExpr *getImm() const {
365 assert(Kind == k_Immediate && "Invalid access!")((Kind == k_Immediate && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Immediate && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 365, __PRETTY_FUNCTION__))
;
366 return Imm.Val;
367 }
368
369 const MCExpr *getShiftedImmVal() const {
370 assert(Kind == k_ShiftedImm && "Invalid access!")((Kind == k_ShiftedImm && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ShiftedImm && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 370, __PRETTY_FUNCTION__))
;
371 return ShiftedImm.Val;
372 }
373
374 unsigned getShiftedImmShift() const {
375 assert(Kind == k_ShiftedImm && "Invalid access!")((Kind == k_ShiftedImm && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ShiftedImm && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 375, __PRETTY_FUNCTION__))
;
376 return ShiftedImm.ShiftAmount;
377 }
378
379 AArch64CC::CondCode getCondCode() const {
380 assert(Kind == k_CondCode && "Invalid access!")((Kind == k_CondCode && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_CondCode && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 380, __PRETTY_FUNCTION__))
;
381 return CondCode.Code;
382 }
383
384 unsigned getFPImm() const {
385 assert(Kind == k_FPImm && "Invalid access!")((Kind == k_FPImm && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_FPImm && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 385, __PRETTY_FUNCTION__))
;
386 return FPImm.Val;
387 }
388
389 unsigned getBarrier() const {
390 assert(Kind == k_Barrier && "Invalid access!")((Kind == k_Barrier && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Barrier && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 390, __PRETTY_FUNCTION__))
;
391 return Barrier.Val;
392 }
393
394 StringRef getBarrierName() const {
395 assert(Kind == k_Barrier && "Invalid access!")((Kind == k_Barrier && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Barrier && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 395, __PRETTY_FUNCTION__))
;
396 return StringRef(Barrier.Data, Barrier.Length);
397 }
398
399 unsigned getReg() const override {
400 assert(Kind == k_Register && "Invalid access!")((Kind == k_Register && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Register && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 400, __PRETTY_FUNCTION__))
;
401 return Reg.RegNum;
402 }
403
404 unsigned getVectorListStart() const {
405 assert(Kind == k_VectorList && "Invalid access!")((Kind == k_VectorList && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_VectorList && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 405, __PRETTY_FUNCTION__))
;
406 return VectorList.RegNum;
407 }
408
409 unsigned getVectorListCount() const {
410 assert(Kind == k_VectorList && "Invalid access!")((Kind == k_VectorList && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_VectorList && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 410, __PRETTY_FUNCTION__))
;
411 return VectorList.Count;
412 }
413
414 unsigned getVectorIndex() const {
415 assert(Kind == k_VectorIndex && "Invalid access!")((Kind == k_VectorIndex && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_VectorIndex && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 415, __PRETTY_FUNCTION__))
;
416 return VectorIndex.Val;
417 }
418
419 StringRef getSysReg() const {
420 assert(Kind == k_SysReg && "Invalid access!")((Kind == k_SysReg && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_SysReg && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 420, __PRETTY_FUNCTION__))
;
421 return StringRef(SysReg.Data, SysReg.Length);
422 }
423
424 unsigned getSysCR() const {
425 assert(Kind == k_SysCR && "Invalid access!")((Kind == k_SysCR && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_SysCR && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 425, __PRETTY_FUNCTION__))
;
426 return SysCRImm.Val;
427 }
428
429 unsigned getPrefetch() const {
430 assert(Kind == k_Prefetch && "Invalid access!")((Kind == k_Prefetch && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Prefetch && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 430, __PRETTY_FUNCTION__))
;
431 return Prefetch.Val;
432 }
433
434 unsigned getPSBHint() const {
435 assert(Kind == k_PSBHint && "Invalid access!")((Kind == k_PSBHint && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_PSBHint && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 435, __PRETTY_FUNCTION__))
;
436 return PSBHint.Val;
437 }
438
439 StringRef getPSBHintName() const {
440 assert(Kind == k_PSBHint && "Invalid access!")((Kind == k_PSBHint && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_PSBHint && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 440, __PRETTY_FUNCTION__))
;
441 return StringRef(PSBHint.Data, PSBHint.Length);
442 }
443
444 StringRef getPrefetchName() const {
445 assert(Kind == k_Prefetch && "Invalid access!")((Kind == k_Prefetch && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_Prefetch && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 445, __PRETTY_FUNCTION__))
;
446 return StringRef(Prefetch.Data, Prefetch.Length);
447 }
448
449 AArch64_AM::ShiftExtendType getShiftExtendType() const {
450 assert(Kind == k_ShiftExtend && "Invalid access!")((Kind == k_ShiftExtend && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ShiftExtend && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 450, __PRETTY_FUNCTION__))
;
451 return ShiftExtend.Type;
452 }
453
454 unsigned getShiftExtendAmount() const {
455 assert(Kind == k_ShiftExtend && "Invalid access!")((Kind == k_ShiftExtend && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ShiftExtend && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 455, __PRETTY_FUNCTION__))
;
456 return ShiftExtend.Amount;
457 }
458
459 bool hasShiftExtendAmount() const {
460 assert(Kind == k_ShiftExtend && "Invalid access!")((Kind == k_ShiftExtend && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == k_ShiftExtend && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 460, __PRETTY_FUNCTION__))
;
461 return ShiftExtend.HasExplicitAmount;
462 }
463
464 bool isImm() const override { return Kind == k_Immediate; }
465 bool isMem() const override { return false; }
466 bool isSImm9() const {
467 if (!isImm())
468 return false;
469 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
470 if (!MCE)
471 return false;
472 int64_t Val = MCE->getValue();
473 return (Val >= -256 && Val < 256);
474 }
475 bool isSImm10s8() const {
476 if (!isImm())
477 return false;
478 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
479 if (!MCE)
480 return false;
481 int64_t Val = MCE->getValue();
482 return (Val >= -4096 && Val < 4089 && (Val & 7) == 0);
483 }
484 bool isSImm7s4() const {
485 if (!isImm())
486 return false;
487 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
488 if (!MCE)
489 return false;
490 int64_t Val = MCE->getValue();
491 return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
492 }
493 bool isSImm7s8() const {
494 if (!isImm())
495 return false;
496 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
497 if (!MCE)
498 return false;
499 int64_t Val = MCE->getValue();
500 return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
501 }
502 bool isSImm7s16() const {
503 if (!isImm())
504 return false;
505 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
506 if (!MCE)
507 return false;
508 int64_t Val = MCE->getValue();
509 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
510 }
511
512 bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
513 AArch64MCExpr::VariantKind ELFRefKind;
514 MCSymbolRefExpr::VariantKind DarwinRefKind;
515 int64_t Addend;
516 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
517 Addend)) {
518 // If we don't understand the expression, assume the best and
519 // let the fixup and relocation code deal with it.
520 return true;
521 }
522
523 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
524 ELFRefKind == AArch64MCExpr::VK_LO12 ||
525 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
526 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
527 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
528 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
529 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
530 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
531 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) {
532 // Note that we don't range-check the addend. It's adjusted modulo page
533 // size when converted, so there is no "out of range" condition when using
534 // @pageoff.
535 return Addend >= 0 && (Addend % Scale) == 0;
536 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
537 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
538 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
539 return Addend == 0;
540 }
541
542 return false;
543 }
544
545 template <int Scale> bool isUImm12Offset() const {
546 if (!isImm())
547 return false;
548
549 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
550 if (!MCE)
551 return isSymbolicUImm12Offset(getImm(), Scale);
552
553 int64_t Val = MCE->getValue();
554 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
555 }
556
557 template <int N, int M>
558 bool isImmInRange() const {
559 if (!isImm())
560 return false;
561 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
562 if (!MCE)
563 return false;
564 int64_t Val = MCE->getValue();
565 return (Val >= N && Val <= M);
566 }
567
568 bool isLogicalImm32() const {
569 if (!isImm())
570 return false;
571 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
572 if (!MCE)
573 return false;
574 int64_t Val = MCE->getValue();
575 if (Val >> 32 != 0 && Val >> 32 != ~0LL)
576 return false;
577 Val &= 0xFFFFFFFF;
578 return AArch64_AM::isLogicalImmediate(Val, 32);
579 }
580
581 bool isLogicalImm64() const {
582 if (!isImm())
583 return false;
584 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
585 if (!MCE)
586 return false;
587 return AArch64_AM::isLogicalImmediate(MCE->getValue(), 64);
588 }
589
590 bool isLogicalImm32Not() const {
591 if (!isImm())
592 return false;
593 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
594 if (!MCE)
595 return false;
596 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
597 return AArch64_AM::isLogicalImmediate(Val, 32);
598 }
599
600 bool isLogicalImm64Not() const {
601 if (!isImm())
602 return false;
603 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
604 if (!MCE)
605 return false;
606 return AArch64_AM::isLogicalImmediate(~MCE->getValue(), 64);
607 }
608
609 bool isShiftedImm() const { return Kind == k_ShiftedImm; }
610
611 bool isAddSubImm() const {
612 if (!isShiftedImm() && !isImm())
613 return false;
614
615 const MCExpr *Expr;
616
617 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
618 if (isShiftedImm()) {
619 unsigned Shift = ShiftedImm.ShiftAmount;
620 Expr = ShiftedImm.Val;
621 if (Shift != 0 && Shift != 12)
622 return false;
623 } else {
624 Expr = getImm();
625 }
626
627 AArch64MCExpr::VariantKind ELFRefKind;
628 MCSymbolRefExpr::VariantKind DarwinRefKind;
629 int64_t Addend;
630 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
631 DarwinRefKind, Addend)) {
632 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
633 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
634 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
635 || ELFRefKind == AArch64MCExpr::VK_LO12
636 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
637 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
638 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
639 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
640 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
641 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
642 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12;
643 }
644
645 // If it's a constant, it should be a real immediate in range:
646 if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
647 return CE->getValue() >= 0 && CE->getValue() <= 0xfff;
648
649 // If it's an expression, we hope for the best and let the fixup/relocation
650 // code deal with it.
651 return true;
652 }
653
654 bool isAddSubImmNeg() const {
655 if (!isShiftedImm() && !isImm())
656 return false;
657
658 const MCExpr *Expr;
659
660 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
661 if (isShiftedImm()) {
662 unsigned Shift = ShiftedImm.ShiftAmount;
663 Expr = ShiftedImm.Val;
664 if (Shift != 0 && Shift != 12)
665 return false;
666 } else
667 Expr = getImm();
668
669 // Otherwise it should be a real negative immediate in range:
670 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr);
671 return CE != nullptr && CE->getValue() < 0 && -CE->getValue() <= 0xfff;
672 }
673
674 bool isCondCode() const { return Kind == k_CondCode; }
675
676 bool isSIMDImmType10() const {
677 if (!isImm())
678 return false;
679 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
680 if (!MCE)
681 return false;
682 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
683 }
684
685 template<int N>
686 bool isBranchTarget() const {
687 if (!isImm())
688 return false;
689 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
690 if (!MCE)
691 return true;
692 int64_t Val = MCE->getValue();
693 if (Val & 0x3)
694 return false;
695 assert(N > 0 && "Branch target immediate cannot be 0 bits!")((N > 0 && "Branch target immediate cannot be 0 bits!"
) ? static_cast<void> (0) : __assert_fail ("N > 0 && \"Branch target immediate cannot be 0 bits!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 695, __PRETTY_FUNCTION__))
;
696 return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2));
697 }
698
699 bool
700 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
701 if (!isImm())
702 return false;
703
704 AArch64MCExpr::VariantKind ELFRefKind;
705 MCSymbolRefExpr::VariantKind DarwinRefKind;
706 int64_t Addend;
707 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
708 DarwinRefKind, Addend)) {
709 return false;
710 }
711 if (DarwinRefKind != MCSymbolRefExpr::VK_None)
712 return false;
713
714 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
715 if (ELFRefKind == AllowedModifiers[i])
716 return Addend == 0;
717 }
718
719 return false;
720 }
721
722 bool isMovZSymbolG3() const {
723 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
724 }
725
726 bool isMovZSymbolG2() const {
727 return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
728 AArch64MCExpr::VK_TPREL_G2,
729 AArch64MCExpr::VK_DTPREL_G2});
730 }
731
732 bool isMovZSymbolG1() const {
733 return isMovWSymbol({
734 AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
735 AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
736 AArch64MCExpr::VK_DTPREL_G1,
737 });
738 }
739
740 bool isMovZSymbolG0() const {
741 return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
742 AArch64MCExpr::VK_TPREL_G0,
743 AArch64MCExpr::VK_DTPREL_G0});
744 }
745
746 bool isMovKSymbolG3() const {
747 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
748 }
749
750 bool isMovKSymbolG2() const {
751 return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC);
752 }
753
754 bool isMovKSymbolG1() const {
755 return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC,
756 AArch64MCExpr::VK_TPREL_G1_NC,
757 AArch64MCExpr::VK_DTPREL_G1_NC});
758 }
759
760 bool isMovKSymbolG0() const {
761 return isMovWSymbol(
762 {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
763 AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC});
764 }
765
766 template<int RegWidth, int Shift>
767 bool isMOVZMovAlias() const {
768 if (!isImm()) return false;
769
770 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
771 if (!CE) return false;
772 uint64_t Value = CE->getValue();
773
774 return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth);
775 }
776
777 template<int RegWidth, int Shift>
778 bool isMOVNMovAlias() const {
779 if (!isImm()) return false;
780
781 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
782 if (!CE) return false;
783 uint64_t Value = CE->getValue();
784
785 return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth);
786 }
787
788 bool isFPImm() const { return Kind == k_FPImm; }
789 bool isBarrier() const { return Kind == k_Barrier; }
790 bool isSysReg() const { return Kind == k_SysReg; }
791
792 bool isMRSSystemRegister() const {
793 if (!isSysReg()) return false;
794
795 return SysReg.MRSReg != -1U;
796 }
797
798 bool isMSRSystemRegister() const {
799 if (!isSysReg()) return false;
800 return SysReg.MSRReg != -1U;
801 }
802
803 bool isSystemPStateFieldWithImm0_1() const {
804 if (!isSysReg()) return false;
805 return (SysReg.PStateField == AArch64PState::PAN ||
806 SysReg.PStateField == AArch64PState::UAO);
807 }
808
809 bool isSystemPStateFieldWithImm0_15() const {
810 if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false;
811 return SysReg.PStateField != -1U;
812 }
813
814 bool isReg() const override {
815 return Kind == k_Register && Reg.Kind == RegKind::Scalar;
816 }
817
818 bool isNeonVectorReg() const {
819 return Kind == k_Register && Reg.Kind == RegKind::NeonVector;
820 }
821
822 bool isNeonVectorRegLo() const {
823 return Kind == k_Register && Reg.Kind == RegKind::NeonVector &&
824 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
825 Reg.RegNum);
826 }
827
828 template <unsigned Class = AArch64::ZPRRegClassID>
829 bool isSVEDataVectorReg() const {
830 return (Kind == k_Register && Reg.Kind == RegKind::SVEDataVector) &&
831 AArch64MCRegisterClasses[Class].contains(getReg());
832 }
833
834 template <int ElementWidth> bool isSVEDataVectorRegOfWidth() const {
835 return isSVEDataVectorReg() &&
836 (ElementWidth == -1 || Reg.ElementWidth == ElementWidth);
837 }
838
839 bool isGPR32as64() const {
840 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
841 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
842 }
843
844 bool isWSeqPair() const {
845 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
846 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
847 Reg.RegNum);
848 }
849
850 bool isXSeqPair() const {
851 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
852 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
853 Reg.RegNum);
854 }
855
856 bool isGPR64sp0() const {
857 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
858 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
859 }
860
861 template<int64_t Angle, int64_t Remainder>
862 bool isComplexRotation() const {
863 if (!isImm()) return false;
864
865 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
866 if (!CE) return false;
867 uint64_t Value = CE->getValue();
868
869 return (Value % Angle == Remainder && Value <= 270);
870 }
871
872 /// Is this a vector list with the type implicit (presumably attached to the
873 /// instruction itself)?
874 template <unsigned NumRegs> bool isImplicitlyTypedVectorList() const {
875 return Kind == k_VectorList && VectorList.Count == NumRegs &&
876 !VectorList.ElementKind;
877 }
878
879 template <unsigned NumRegs, unsigned NumElements, char ElementKind>
880 bool isTypedVectorList() const {
881 if (Kind != k_VectorList)
882 return false;
883 if (VectorList.Count != NumRegs)
884 return false;
885 if (VectorList.ElementKind != ElementKind)
886 return false;
887 return VectorList.NumElements == NumElements;
888 }
889
890 bool isVectorIndex1() const {
891 return Kind == k_VectorIndex && VectorIndex.Val == 1;
892 }
893
894 bool isVectorIndexB() const {
895 return Kind == k_VectorIndex && VectorIndex.Val < 16;
896 }
897
898 bool isVectorIndexH() const {
899 return Kind == k_VectorIndex && VectorIndex.Val < 8;
900 }
901
902 bool isVectorIndexS() const {
903 return Kind == k_VectorIndex && VectorIndex.Val < 4;
904 }
905
906 bool isVectorIndexD() const {
907 return Kind == k_VectorIndex && VectorIndex.Val < 2;
908 }
909
910 bool isToken() const override { return Kind == k_Token; }
911
912 bool isTokenEqual(StringRef Str) const {
913 return Kind == k_Token && getToken() == Str;
914 }
915 bool isSysCR() const { return Kind == k_SysCR; }
916 bool isPrefetch() const { return Kind == k_Prefetch; }
917 bool isPSBHint() const { return Kind == k_PSBHint; }
918 bool isShiftExtend() const { return Kind == k_ShiftExtend; }
919 bool isShifter() const {
920 if (!isShiftExtend())
921 return false;
922
923 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
924 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
925 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
926 ST == AArch64_AM::MSL);
927 }
928 bool isExtend() const {
929 if (!isShiftExtend())
930 return false;
931
932 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
933 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
934 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
935 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
936 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
937 ET == AArch64_AM::LSL) &&
938 getShiftExtendAmount() <= 4;
939 }
940
941 bool isExtend64() const {
942 if (!isExtend())
943 return false;
944 // UXTX and SXTX require a 64-bit source register (the ExtendLSL64 class).
945 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
946 return ET != AArch64_AM::UXTX && ET != AArch64_AM::SXTX;
947 }
948
949 bool isExtendLSL64() const {
950 if (!isExtend())
951 return false;
952 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
953 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
954 ET == AArch64_AM::LSL) &&
955 getShiftExtendAmount() <= 4;
956 }
957
958 template<int Width> bool isMemXExtend() const {
959 if (!isExtend())
960 return false;
961 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
962 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
963 (getShiftExtendAmount() == Log2_32(Width / 8) ||
964 getShiftExtendAmount() == 0);
965 }
966
967 template<int Width> bool isMemWExtend() const {
968 if (!isExtend())
969 return false;
970 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
971 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
972 (getShiftExtendAmount() == Log2_32(Width / 8) ||
973 getShiftExtendAmount() == 0);
974 }
975
976 template <unsigned width>
977 bool isArithmeticShifter() const {
978 if (!isShifter())
979 return false;
980
981 // An arithmetic shifter is LSL, LSR, or ASR.
982 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
983 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
984 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
985 }
986
987 template <unsigned width>
988 bool isLogicalShifter() const {
989 if (!isShifter())
990 return false;
991
992 // A logical shifter is LSL, LSR, ASR or ROR.
993 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
994 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
995 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
996 getShiftExtendAmount() < width;
997 }
998
999 bool isMovImm32Shifter() const {
1000 if (!isShifter())
1001 return false;
1002
1003 // A MOVi shifter is LSL of 0, 16, 32, or 48.
1004 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1005 if (ST != AArch64_AM::LSL)
1006 return false;
1007 uint64_t Val = getShiftExtendAmount();
1008 return (Val == 0 || Val == 16);
1009 }
1010
1011 bool isMovImm64Shifter() const {
1012 if (!isShifter())
1013 return false;
1014
1015 // A MOVi shifter is LSL of 0 or 16.
1016 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1017 if (ST != AArch64_AM::LSL)
1018 return false;
1019 uint64_t Val = getShiftExtendAmount();
1020 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1021 }
1022
1023 bool isLogicalVecShifter() const {
1024 if (!isShifter())
1025 return false;
1026
1027 // A logical vector shifter is a left shift by 0, 8, 16, or 24.
1028 unsigned Shift = getShiftExtendAmount();
1029 return getShiftExtendType() == AArch64_AM::LSL &&
1030 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1031 }
1032
1033 bool isLogicalVecHalfWordShifter() const {
1034 if (!isLogicalVecShifter())
1035 return false;
1036
1037 // A logical vector shifter is a left shift by 0 or 8.
1038 unsigned Shift = getShiftExtendAmount();
1039 return getShiftExtendType() == AArch64_AM::LSL &&
1040 (Shift == 0 || Shift == 8);
1041 }
1042
1043 bool isMoveVecShifter() const {
1044 if (!isShiftExtend())
1045 return false;
1046
1047 // A logical vector shifter is a left shift by 8 or 16.
1048 unsigned Shift = getShiftExtendAmount();
1049 return getShiftExtendType() == AArch64_AM::MSL &&
1050 (Shift == 8 || Shift == 16);
1051 }
1052
1053 // Fallback unscaled operands are for aliases of LDR/STR that fall back
1054 // to LDUR/STUR when the offset is not legal for the former but is for
1055 // the latter. As such, in addition to checking for being a legal unscaled
1056 // address, also check that it is not a legal scaled address. This avoids
1057 // ambiguity in the matcher.
1058 template<int Width>
1059 bool isSImm9OffsetFB() const {
1060 return isSImm9() && !isUImm12Offset<Width / 8>();
1061 }
1062
1063 bool isAdrpLabel() const {
1064 // Validation was handled during parsing, so we just sanity check that
1065 // something didn't go haywire.
1066 if (!isImm())
1067 return false;
1068
1069 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1070 int64_t Val = CE->getValue();
1071 int64_t Min = - (4096 * (1LL << (21 - 1)));
1072 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1073 return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1074 }
1075
1076 return true;
1077 }
1078
1079 bool isAdrLabel() const {
1080 // Validation was handled during parsing, so we just sanity check that
1081 // something didn't go haywire.
1082 if (!isImm())
1083 return false;
1084
1085 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1086 int64_t Val = CE->getValue();
1087 int64_t Min = - (1LL << (21 - 1));
1088 int64_t Max = ((1LL << (21 - 1)) - 1);
1089 return Val >= Min && Val <= Max;
1090 }
1091
1092 return true;
1093 }
1094
1095 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1096 // Add as immediates when possible. Null MCExpr = 0.
1097 if (!Expr)
1098 Inst.addOperand(MCOperand::createImm(0));
1099 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1100 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1101 else
1102 Inst.addOperand(MCOperand::createExpr(Expr));
1103 }
1104
1105 void addRegOperands(MCInst &Inst, unsigned N) const {
1106 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1106, __PRETTY_FUNCTION__))
;
1107 Inst.addOperand(MCOperand::createReg(getReg()));
1108 }
1109
1110 void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
1111 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1111, __PRETTY_FUNCTION__))
;
1112 assert(((AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1113, __PRETTY_FUNCTION__))
1113 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()))((AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1113, __PRETTY_FUNCTION__))
;
1114
1115 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1116 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1117 RI->getEncodingValue(getReg()));
1118
1119 Inst.addOperand(MCOperand::createReg(Reg));
1120 }
1121
1122 void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
1123 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1123, __PRETTY_FUNCTION__))
;
1124 assert(((AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1125, __PRETTY_FUNCTION__))
1125 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()))((AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1125, __PRETTY_FUNCTION__))
;
1126 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0));
1127 }
1128
1129 void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1130 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1130, __PRETTY_FUNCTION__))
;
1131 assert(((AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1132, __PRETTY_FUNCTION__))
1132 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()))((AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains
(getReg())) ? static_cast<void> (0) : __assert_fail ("AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg())"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1132, __PRETTY_FUNCTION__))
;
1133 Inst.addOperand(MCOperand::createReg(getReg()));
1134 }
1135
1136 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
1137 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1137, __PRETTY_FUNCTION__))
;
1138 Inst.addOperand(MCOperand::createReg(getReg()));
1139 }
1140
1141 template <unsigned NumRegs>
1142 void addVectorList64Operands(MCInst &Inst, unsigned N) const {
1143 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1143, __PRETTY_FUNCTION__))
;
1144 static const unsigned FirstRegs[] = { AArch64::D0,
1145 AArch64::D0_D1,
1146 AArch64::D0_D1_D2,
1147 AArch64::D0_D1_D2_D3 };
1148 unsigned FirstReg = FirstRegs[NumRegs - 1];
1149
1150 Inst.addOperand(
1151 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1152 }
1153
1154 template <unsigned NumRegs>
1155 void addVectorList128Operands(MCInst &Inst, unsigned N) const {
1156 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1156, __PRETTY_FUNCTION__))
;
1157 static const unsigned FirstRegs[] = { AArch64::Q0,
1158 AArch64::Q0_Q1,
1159 AArch64::Q0_Q1_Q2,
1160 AArch64::Q0_Q1_Q2_Q3 };
1161 unsigned FirstReg = FirstRegs[NumRegs - 1];
1162
1163 Inst.addOperand(
1164 MCOperand::createReg(FirstReg + getVectorListStart() - AArch64::Q0));
1165 }
1166
1167 void addVectorIndex1Operands(MCInst &Inst, unsigned N) const {
1168 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1168, __PRETTY_FUNCTION__))
;
1169 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1170 }
1171
1172 void addVectorIndexBOperands(MCInst &Inst, unsigned N) const {
1173 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1173, __PRETTY_FUNCTION__))
;
1174 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1175 }
1176
1177 void addVectorIndexHOperands(MCInst &Inst, unsigned N) const {
1178 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1178, __PRETTY_FUNCTION__))
;
1179 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1180 }
1181
1182 void addVectorIndexSOperands(MCInst &Inst, unsigned N) const {
1183 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1183, __PRETTY_FUNCTION__))
;
1184 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1185 }
1186
1187 void addVectorIndexDOperands(MCInst &Inst, unsigned N) const {
1188 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1188, __PRETTY_FUNCTION__))
;
1189 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1190 }
1191
1192 void addImmOperands(MCInst &Inst, unsigned N) const {
1193 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1193, __PRETTY_FUNCTION__))
;
1194 // If this is a pageoff symrefexpr with an addend, adjust the addend
1195 // to be only the page-offset portion. Otherwise, just add the expr
1196 // as-is.
1197 addExpr(Inst, getImm());
1198 }
1199
1200 void addAddSubImmOperands(MCInst &Inst, unsigned N) const {
1201 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1201, __PRETTY_FUNCTION__))
;
1202 if (isShiftedImm()) {
1203 addExpr(Inst, getShiftedImmVal());
1204 Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
1205 } else {
1206 addExpr(Inst, getImm());
1207 Inst.addOperand(MCOperand::createImm(0));
1208 }
1209 }
1210
1211 void addAddSubImmNegOperands(MCInst &Inst, unsigned N) const {
1212 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1212, __PRETTY_FUNCTION__))
;
1213
1214 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
1215 const MCConstantExpr *CE = cast<MCConstantExpr>(MCE);
1216 int64_t Val = -CE->getValue();
1217 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
1218
1219 Inst.addOperand(MCOperand::createImm(Val));
1220 Inst.addOperand(MCOperand::createImm(ShiftAmt));
1221 }
1222
1223 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1224 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1224, __PRETTY_FUNCTION__))
;
1225 Inst.addOperand(MCOperand::createImm(getCondCode()));
1226 }
1227
1228 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1229 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1229, __PRETTY_FUNCTION__))
;
1230 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1231 if (!MCE)
1232 addExpr(Inst, getImm());
1233 else
1234 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12));
1235 }
1236
1237 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1238 addImmOperands(Inst, N);
1239 }
1240
1241 template<int Scale>
1242 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1243 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1243, __PRETTY_FUNCTION__))
;
1244 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1245
1246 if (!MCE) {
1247 Inst.addOperand(MCOperand::createExpr(getImm()));
1248 return;
1249 }
1250 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1251 }
1252
1253 void addSImm9Operands(MCInst &Inst, unsigned N) const {
1254 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1254, __PRETTY_FUNCTION__))
;
1255 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1256 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1257 }
1258
1259 void addSImm10s8Operands(MCInst &Inst, unsigned N) const {
1260 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1260, __PRETTY_FUNCTION__))
;
1261 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1262 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8));
1263 }
1264
1265 void addSImm7s4Operands(MCInst &Inst, unsigned N) const {
1266 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1266, __PRETTY_FUNCTION__))
;
1267 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1268 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 4));
1269 }
1270
1271 void addSImm7s8Operands(MCInst &Inst, unsigned N) const {
1272 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1272, __PRETTY_FUNCTION__))
;
1273 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1274 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 8));
1275 }
1276
1277 void addSImm7s16Operands(MCInst &Inst, unsigned N) const {
1278 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1278, __PRETTY_FUNCTION__))
;
1279 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1280 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 16));
1281 }
1282
1283 void addImm0_1Operands(MCInst &Inst, unsigned N) const {
1284 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1284, __PRETTY_FUNCTION__))
;
1285 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1286 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1287 }
1288
1289 void addImm0_7Operands(MCInst &Inst, unsigned N) const {
1290 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1290, __PRETTY_FUNCTION__))
;
1291 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1292 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1293 }
1294
1295 void addImm1_8Operands(MCInst &Inst, unsigned N) const {
1296 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1296, __PRETTY_FUNCTION__))
;
1297 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1298 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1299 }
1300
1301 void addImm0_15Operands(MCInst &Inst, unsigned N) const {
1302 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1302, __PRETTY_FUNCTION__))
;
1303 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1304 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1305 }
1306
1307 void addImm1_16Operands(MCInst &Inst, unsigned N) const {
1308 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1308, __PRETTY_FUNCTION__))
;
1309 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1310 assert(MCE && "Invalid constant immediate operand!")((MCE && "Invalid constant immediate operand!") ? static_cast
<void> (0) : __assert_fail ("MCE && \"Invalid constant immediate operand!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1310, __PRETTY_FUNCTION__))
;
1311 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1312 }
1313
1314 void addImm0_31Operands(MCInst &Inst, unsigned N) const {
1315 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1315, __PRETTY_FUNCTION__))
;
1316 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1317 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1318 }
1319
1320 void addImm1_31Operands(MCInst &Inst, unsigned N) const {
1321 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1321, __PRETTY_FUNCTION__))
;
1322 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1323 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1324 }
1325
1326 void addImm1_32Operands(MCInst &Inst, unsigned N) const {
1327 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1327, __PRETTY_FUNCTION__))
;
1328 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1329 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1330 }
1331
1332 void addImm0_63Operands(MCInst &Inst, unsigned N) const {
1333 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1333, __PRETTY_FUNCTION__))
;
1334 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1335 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1336 }
1337
1338 void addImm1_63Operands(MCInst &Inst, unsigned N) const {
1339 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1339, __PRETTY_FUNCTION__))
;
1340 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1341 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1342 }
1343
1344 void addImm1_64Operands(MCInst &Inst, unsigned N) const {
1345 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1345, __PRETTY_FUNCTION__))
;
1346 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1347 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1348 }
1349
1350 void addImm0_127Operands(MCInst &Inst, unsigned N) const {
1351 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1351, __PRETTY_FUNCTION__))
;
1352 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1353 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1354 }
1355
1356 void addImm0_255Operands(MCInst &Inst, unsigned N) const {
1357 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1357, __PRETTY_FUNCTION__))
;
1358 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1359 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1360 }
1361
1362 void addImm0_65535Operands(MCInst &Inst, unsigned N) const {
1363 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1363, __PRETTY_FUNCTION__))
;
1364 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1365 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1366 }
1367
1368 void addImm32_63Operands(MCInst &Inst, unsigned N) const {
1369 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1369, __PRETTY_FUNCTION__))
;
1370 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1371 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1372 }
1373
1374 void addLogicalImm32Operands(MCInst &Inst, unsigned N) const {
1375 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1375, __PRETTY_FUNCTION__))
;
1376 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1377 uint64_t encoding =
1378 AArch64_AM::encodeLogicalImmediate(MCE->getValue() & 0xFFFFFFFF, 32);
1379 Inst.addOperand(MCOperand::createImm(encoding));
1380 }
1381
1382 void addLogicalImm64Operands(MCInst &Inst, unsigned N) const {
1383 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1383, __PRETTY_FUNCTION__))
;
1384 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1385 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(MCE->getValue(), 64);
1386 Inst.addOperand(MCOperand::createImm(encoding));
1387 }
1388
1389 void addLogicalImm32NotOperands(MCInst &Inst, unsigned N) const {
1390 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1390, __PRETTY_FUNCTION__))
;
1391 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1392 int64_t Val = ~MCE->getValue() & 0xFFFFFFFF;
1393 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, 32);
1394 Inst.addOperand(MCOperand::createImm(encoding));
1395 }
1396
1397 void addLogicalImm64NotOperands(MCInst &Inst, unsigned N) const {
1398 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1398, __PRETTY_FUNCTION__))
;
1399 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1400 uint64_t encoding =
1401 AArch64_AM::encodeLogicalImmediate(~MCE->getValue(), 64);
1402 Inst.addOperand(MCOperand::createImm(encoding));
1403 }
1404
1405 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1406 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1406, __PRETTY_FUNCTION__))
;
1407 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1408 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1409 Inst.addOperand(MCOperand::createImm(encoding));
1410 }
1411
1412 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1413 // Branch operands don't encode the low bits, so shift them off
1414 // here. If it's a label, however, just put it on directly as there's
1415 // not enough information now to do anything.
1416 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1416, __PRETTY_FUNCTION__))
;
1417 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1418 if (!MCE) {
1419 addExpr(Inst, getImm());
1420 return;
1421 }
1422 assert(MCE && "Invalid constant immediate operand!")((MCE && "Invalid constant immediate operand!") ? static_cast
<void> (0) : __assert_fail ("MCE && \"Invalid constant immediate operand!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1422, __PRETTY_FUNCTION__))
;
1423 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1424 }
1425
1426 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1427 // Branch operands don't encode the low bits, so shift them off
1428 // here. If it's a label, however, just put it on directly as there's
1429 // not enough information now to do anything.
1430 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1430, __PRETTY_FUNCTION__))
;
1431 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1432 if (!MCE) {
1433 addExpr(Inst, getImm());
1434 return;
1435 }
1436 assert(MCE && "Invalid constant immediate operand!")((MCE && "Invalid constant immediate operand!") ? static_cast
<void> (0) : __assert_fail ("MCE && \"Invalid constant immediate operand!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1436, __PRETTY_FUNCTION__))
;
1437 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1438 }
1439
1440 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1441 // Branch operands don't encode the low bits, so shift them off
1442 // here. If it's a label, however, just put it on directly as there's
1443 // not enough information now to do anything.
1444 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1444, __PRETTY_FUNCTION__))
;
1445 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1446 if (!MCE) {
1447 addExpr(Inst, getImm());
1448 return;
1449 }
1450 assert(MCE && "Invalid constant immediate operand!")((MCE && "Invalid constant immediate operand!") ? static_cast
<void> (0) : __assert_fail ("MCE && \"Invalid constant immediate operand!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1450, __PRETTY_FUNCTION__))
;
1451 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1452 }
1453
1454 void addFPImmOperands(MCInst &Inst, unsigned N) const {
1455 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1455, __PRETTY_FUNCTION__))
;
1456 Inst.addOperand(MCOperand::createImm(getFPImm()));
1457 }
1458
1459 void addBarrierOperands(MCInst &Inst, unsigned N) const {
1460 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1460, __PRETTY_FUNCTION__))
;
1461 Inst.addOperand(MCOperand::createImm(getBarrier()));
1462 }
1463
1464 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1465 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1465, __PRETTY_FUNCTION__))
;
1466
1467 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg));
1468 }
1469
1470 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1471 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1471, __PRETTY_FUNCTION__))
;
1472
1473 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg));
1474 }
1475
1476 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const {
1477 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1477, __PRETTY_FUNCTION__))
;
1478
1479 Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1480 }
1481
1482 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const {
1483 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1483, __PRETTY_FUNCTION__))
;
1484
1485 Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1486 }
1487
1488 void addSysCROperands(MCInst &Inst, unsigned N) const {
1489 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1489, __PRETTY_FUNCTION__))
;
1490 Inst.addOperand(MCOperand::createImm(getSysCR()));
1491 }
1492
1493 void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1494 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1494, __PRETTY_FUNCTION__))
;
1495 Inst.addOperand(MCOperand::createImm(getPrefetch()));
1496 }
1497
1498 void addPSBHintOperands(MCInst &Inst, unsigned N) const {
1499 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1499, __PRETTY_FUNCTION__))
;
1500 Inst.addOperand(MCOperand::createImm(getPSBHint()));
1501 }
1502
1503 void addShifterOperands(MCInst &Inst, unsigned N) const {
1504 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1504, __PRETTY_FUNCTION__))
;
1505 unsigned Imm =
1506 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1507 Inst.addOperand(MCOperand::createImm(Imm));
1508 }
1509
1510 void addExtendOperands(MCInst &Inst, unsigned N) const {
1511 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1511, __PRETTY_FUNCTION__))
;
1512 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1513 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1514 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1515 Inst.addOperand(MCOperand::createImm(Imm));
1516 }
1517
1518 void addExtend64Operands(MCInst &Inst, unsigned N) const {
1519 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1519, __PRETTY_FUNCTION__))
;
1520 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1521 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1522 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1523 Inst.addOperand(MCOperand::createImm(Imm));
1524 }
1525
1526 void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1527 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1527, __PRETTY_FUNCTION__))
;
1528 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1529 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1530 Inst.addOperand(MCOperand::createImm(IsSigned));
1531 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0));
1532 }
1533
1534 // For 8-bit load/store instructions with a register offset, both the
1535 // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1536 // they're disambiguated by whether the shift was explicit or implicit rather
1537 // than its size.
1538 void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1539 assert(N == 2 && "Invalid number of operands!")((N == 2 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 2 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1539, __PRETTY_FUNCTION__))
;
1540 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1541 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1542 Inst.addOperand(MCOperand::createImm(IsSigned));
1543 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount()));
1544 }
1545
1546 template<int Shift>
1547 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
1548 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1548, __PRETTY_FUNCTION__))
;
1549
1550 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1551 uint64_t Value = CE->getValue();
1552 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff));
1553 }
1554
1555 template<int Shift>
1556 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
1557 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1557, __PRETTY_FUNCTION__))
;
1558
1559 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1560 uint64_t Value = CE->getValue();
1561 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff));
1562 }
1563
1564 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
1565 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1565, __PRETTY_FUNCTION__))
;
1566 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1567 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 90));
1568 }
1569
1570 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
1571 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1571, __PRETTY_FUNCTION__))
;
1572 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1573 Inst.addOperand(MCOperand::createImm((MCE->getValue() - 90) / 180));
1574 }
1575
1576 void print(raw_ostream &OS) const override;
1577
1578 static std::unique_ptr<AArch64Operand>
1579 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
1580 auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1581 Op->Tok.Data = Str.data();
1582 Op->Tok.Length = Str.size();
1583 Op->Tok.IsSuffix = IsSuffix;
1584 Op->StartLoc = S;
1585 Op->EndLoc = S;
1586 return Op;
1587 }
1588
1589 static std::unique_ptr<AArch64Operand>
1590 CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx) {
1591 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1592 Op->Reg.RegNum = RegNum;
1593 Op->Reg.Kind = Kind;
1594 Op->StartLoc = S;
1595 Op->EndLoc = E;
1596 return Op;
1597 }
1598
1599 static std::unique_ptr<AArch64Operand>
1600 CreateReg(unsigned RegNum, RegKind Kind, unsigned ElementWidth,
1601 SMLoc S, SMLoc E, MCContext &Ctx) {
1602 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1603 Op->Reg.RegNum = RegNum;
1604 Op->Reg.ElementWidth = ElementWidth;
1605 Op->Reg.Kind = Kind;
1606 Op->StartLoc = S;
1607 Op->EndLoc = E;
1608 return Op;
1609 }
1610
1611 static std::unique_ptr<AArch64Operand>
1612 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
1613 char ElementKind, SMLoc S, SMLoc E, MCContext &Ctx) {
1614 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1615 Op->VectorList.RegNum = RegNum;
1616 Op->VectorList.Count = Count;
1617 Op->VectorList.NumElements = NumElements;
1618 Op->VectorList.ElementKind = ElementKind;
1619 Op->StartLoc = S;
1620 Op->EndLoc = E;
1621 return Op;
1622 }
1623
1624 static std::unique_ptr<AArch64Operand>
1625 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
1626 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1627 Op->VectorIndex.Val = Idx;
1628 Op->StartLoc = S;
1629 Op->EndLoc = E;
1630 return Op;
1631 }
1632
1633 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
1634 SMLoc E, MCContext &Ctx) {
1635 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1636 Op->Imm.Val = Val;
1637 Op->StartLoc = S;
1638 Op->EndLoc = E;
1639 return Op;
1640 }
1641
1642 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
1643 unsigned ShiftAmount,
1644 SMLoc S, SMLoc E,
1645 MCContext &Ctx) {
1646 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1647 Op->ShiftedImm .Val = Val;
1648 Op->ShiftedImm.ShiftAmount = ShiftAmount;
1649 Op->StartLoc = S;
1650 Op->EndLoc = E;
1651 return Op;
1652 }
1653
1654 static std::unique_ptr<AArch64Operand>
1655 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
1656 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1657 Op->CondCode.Code = Code;
1658 Op->StartLoc = S;
1659 Op->EndLoc = E;
1660 return Op;
1661 }
1662
1663 static std::unique_ptr<AArch64Operand> CreateFPImm(unsigned Val, SMLoc S,
1664 MCContext &Ctx) {
1665 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1666 Op->FPImm.Val = Val;
1667 Op->StartLoc = S;
1668 Op->EndLoc = S;
1669 return Op;
1670 }
1671
1672 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
1673 StringRef Str,
1674 SMLoc S,
1675 MCContext &Ctx) {
1676 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1677 Op->Barrier.Val = Val;
1678 Op->Barrier.Data = Str.data();
1679 Op->Barrier.Length = Str.size();
1680 Op->StartLoc = S;
1681 Op->EndLoc = S;
1682 return Op;
1683 }
1684
1685 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
1686 uint32_t MRSReg,
1687 uint32_t MSRReg,
1688 uint32_t PStateField,
1689 MCContext &Ctx) {
1690 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1691 Op->SysReg.Data = Str.data();
1692 Op->SysReg.Length = Str.size();
1693 Op->SysReg.MRSReg = MRSReg;
1694 Op->SysReg.MSRReg = MSRReg;
1695 Op->SysReg.PStateField = PStateField;
1696 Op->StartLoc = S;
1697 Op->EndLoc = S;
1698 return Op;
1699 }
1700
1701 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
1702 SMLoc E, MCContext &Ctx) {
1703 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1704 Op->SysCRImm.Val = Val;
1705 Op->StartLoc = S;
1706 Op->EndLoc = E;
1707 return Op;
1708 }
1709
1710 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val,
1711 StringRef Str,
1712 SMLoc S,
1713 MCContext &Ctx) {
1714 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1715 Op->Prefetch.Val = Val;
1716 Op->Barrier.Data = Str.data();
1717 Op->Barrier.Length = Str.size();
1718 Op->StartLoc = S;
1719 Op->EndLoc = S;
1720 return Op;
1721 }
1722
1723 static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val,
1724 StringRef Str,
1725 SMLoc S,
1726 MCContext &Ctx) {
1727 auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx);
1728 Op->PSBHint.Val = Val;
1729 Op->PSBHint.Data = Str.data();
1730 Op->PSBHint.Length = Str.size();
1731 Op->StartLoc = S;
1732 Op->EndLoc = S;
1733 return Op;
1734 }
1735
1736 static std::unique_ptr<AArch64Operand>
1737 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
1738 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
1739 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1740 Op->ShiftExtend.Type = ShOp;
1741 Op->ShiftExtend.Amount = Val;
1742 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1743 Op->StartLoc = S;
1744 Op->EndLoc = E;
1745 return Op;
1746 }
1747};
1748
1749} // end anonymous namespace.
1750
1751void AArch64Operand::print(raw_ostream &OS) const {
1752 switch (Kind) {
1753 case k_FPImm:
1754 OS << "<fpimm " << getFPImm() << "("
1755 << AArch64_AM::getFPImmFloat(getFPImm()) << ") >";
1756 break;
1757 case k_Barrier: {
1758 StringRef Name = getBarrierName();
1759 if (!Name.empty())
1760 OS << "<barrier " << Name << ">";
1761 else
1762 OS << "<barrier invalid #" << getBarrier() << ">";
1763 break;
1764 }
1765 case k_Immediate:
1766 OS << *getImm();
1767 break;
1768 case k_ShiftedImm: {
1769 unsigned Shift = getShiftedImmShift();
1770 OS << "<shiftedimm ";
1771 OS << *getShiftedImmVal();
1772 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
1773 break;
1774 }
1775 case k_CondCode:
1776 OS << "<condcode " << getCondCode() << ">";
1777 break;
1778 case k_Register:
1779 OS << "<register " << getReg() << ">";
1780 break;
1781 case k_VectorList: {
1782 OS << "<vectorlist ";
1783 unsigned Reg = getVectorListStart();
1784 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1785 OS << Reg + i << " ";
1786 OS << ">";
1787 break;
1788 }
1789 case k_VectorIndex:
1790 OS << "<vectorindex " << getVectorIndex() << ">";
1791 break;
1792 case k_SysReg:
1793 OS << "<sysreg: " << getSysReg() << '>';
1794 break;
1795 case k_Token:
1796 OS << "'" << getToken() << "'";
1797 break;
1798 case k_SysCR:
1799 OS << "c" << getSysCR();
1800 break;
1801 case k_Prefetch: {
1802 StringRef Name = getPrefetchName();
1803 if (!Name.empty())
1804 OS << "<prfop " << Name << ">";
1805 else
1806 OS << "<prfop invalid #" << getPrefetch() << ">";
1807 break;
1808 }
1809 case k_PSBHint:
1810 OS << getPSBHintName();
1811 break;
1812 case k_ShiftExtend:
1813 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
1814 << getShiftExtendAmount();
1815 if (!hasShiftExtendAmount())
1816 OS << "<imp>";
1817 OS << '>';
1818 break;
1819 }
1820}
1821
1822/// @name Auto-generated Match Functions
1823/// {
1824
1825static unsigned MatchRegisterName(StringRef Name);
1826
1827/// }
1828
1829static unsigned MatchNeonVectorRegName(StringRef Name) {
1830 return StringSwitch<unsigned>(Name.lower())
1831 .Case("v0", AArch64::Q0)
1832 .Case("v1", AArch64::Q1)
1833 .Case("v2", AArch64::Q2)
1834 .Case("v3", AArch64::Q3)
1835 .Case("v4", AArch64::Q4)
1836 .Case("v5", AArch64::Q5)
1837 .Case("v6", AArch64::Q6)
1838 .Case("v7", AArch64::Q7)
1839 .Case("v8", AArch64::Q8)
1840 .Case("v9", AArch64::Q9)
1841 .Case("v10", AArch64::Q10)
1842 .Case("v11", AArch64::Q11)
1843 .Case("v12", AArch64::Q12)
1844 .Case("v13", AArch64::Q13)
1845 .Case("v14", AArch64::Q14)
1846 .Case("v15", AArch64::Q15)
1847 .Case("v16", AArch64::Q16)
1848 .Case("v17", AArch64::Q17)
1849 .Case("v18", AArch64::Q18)
1850 .Case("v19", AArch64::Q19)
1851 .Case("v20", AArch64::Q20)
1852 .Case("v21", AArch64::Q21)
1853 .Case("v22", AArch64::Q22)
1854 .Case("v23", AArch64::Q23)
1855 .Case("v24", AArch64::Q24)
1856 .Case("v25", AArch64::Q25)
1857 .Case("v26", AArch64::Q26)
1858 .Case("v27", AArch64::Q27)
1859 .Case("v28", AArch64::Q28)
1860 .Case("v29", AArch64::Q29)
1861 .Case("v30", AArch64::Q30)
1862 .Case("v31", AArch64::Q31)
1863 .Default(0);
1864}
1865
1866static bool isValidVectorKind(StringRef Name) {
1867 return StringSwitch<bool>(Name.lower())
1868 .Case(".8b", true)
1869 .Case(".16b", true)
1870 .Case(".4h", true)
1871 .Case(".8h", true)
1872 .Case(".2s", true)
1873 .Case(".4s", true)
1874 .Case(".1d", true)
1875 .Case(".2d", true)
1876 .Case(".1q", true)
1877 // Accept the width neutral ones, too, for verbose syntax. If those
1878 // aren't used in the right places, the token operand won't match so
1879 // all will work out.
1880 .Case(".b", true)
1881 .Case(".h", true)
1882 .Case(".s", true)
1883 .Case(".d", true)
1884 // Needed for fp16 scalar pairwise reductions
1885 .Case(".2h", true)
1886 // another special case for the ARMv8.2a dot product operand
1887 .Case(".4b", true)
1888 .Default(false);
1889}
1890
1891static unsigned matchSVEDataVectorRegName(StringRef Name) {
1892 return StringSwitch<unsigned>(Name.lower())
1893 .Case("z0", AArch64::Z0)
1894 .Case("z1", AArch64::Z1)
1895 .Case("z2", AArch64::Z2)
1896 .Case("z3", AArch64::Z3)
1897 .Case("z4", AArch64::Z4)
1898 .Case("z5", AArch64::Z5)
1899 .Case("z6", AArch64::Z6)
1900 .Case("z7", AArch64::Z7)
1901 .Case("z8", AArch64::Z8)
1902 .Case("z9", AArch64::Z9)
1903 .Case("z10", AArch64::Z10)
1904 .Case("z11", AArch64::Z11)
1905 .Case("z12", AArch64::Z12)
1906 .Case("z13", AArch64::Z13)
1907 .Case("z14", AArch64::Z14)
1908 .Case("z15", AArch64::Z15)
1909 .Case("z16", AArch64::Z16)
1910 .Case("z17", AArch64::Z17)
1911 .Case("z18", AArch64::Z18)
1912 .Case("z19", AArch64::Z19)
1913 .Case("z20", AArch64::Z20)
1914 .Case("z21", AArch64::Z21)
1915 .Case("z22", AArch64::Z22)
1916 .Case("z23", AArch64::Z23)
1917 .Case("z24", AArch64::Z24)
1918 .Case("z25", AArch64::Z25)
1919 .Case("z26", AArch64::Z26)
1920 .Case("z27", AArch64::Z27)
1921 .Case("z28", AArch64::Z28)
1922 .Case("z29", AArch64::Z29)
1923 .Case("z30", AArch64::Z30)
1924 .Case("z31", AArch64::Z31)
1925 .Default(0);
1926}
1927
1928static bool isValidSVEKind(StringRef Name) {
1929 return StringSwitch<bool>(Name.lower())
1930 .Case(".b", true)
1931 .Case(".h", true)
1932 .Case(".s", true)
1933 .Case(".d", true)
1934 .Case(".q", true)
1935 .Default(false);
1936}
1937
1938static bool isSVEDataVectorRegister(StringRef Name) {
1939 return Name[0] == 'z';
1940}
1941
1942static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1943 char &ElementKind) {
1944 assert(isValidVectorKind(Name))((isValidVectorKind(Name)) ? static_cast<void> (0) : __assert_fail
("isValidVectorKind(Name)", "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 1944, __PRETTY_FUNCTION__))
;
1945
1946 ElementKind = Name.lower()[Name.size() - 1];
1947 NumElements = 0;
1948
1949 if (Name.size() == 2)
1950 return;
1951
1952 // Parse the lane count
1953 Name = Name.drop_front();
1954 while (isdigit(Name.front())) {
1955 NumElements = 10 * NumElements + (Name.front() - '0');
1956 Name = Name.drop_front();
1957 }
1958}
1959
1960bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1961 SMLoc &EndLoc) {
1962 StartLoc = getLoc();
1963 RegNo = tryParseRegister();
1964 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1965 return (RegNo == (unsigned)-1);
1966}
1967
1968// Matches a register name or register alias previously defined by '.req'
1969unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1970 RegKind Kind) {
1971 unsigned RegNum;
1972 switch (Kind) {
1973 case RegKind::Scalar:
1974 RegNum = MatchRegisterName(Name);
1975 break;
1976 case RegKind::NeonVector:
1977 RegNum = MatchNeonVectorRegName(Name);
1978 break;
1979 case RegKind::SVEDataVector:
1980 RegNum = matchSVEDataVectorRegName(Name);
1981 break;
1982 }
1983
1984 if (!RegNum) {
1985 // Check for aliases registered via .req. Canonicalize to lower case.
1986 // That's more consistent since register names are case insensitive, and
1987 // it's how the original entry was passed in from MC/MCParser/AsmParser.
1988 auto Entry = RegisterReqs.find(Name.lower());
1989 if (Entry == RegisterReqs.end())
1990 return 0;
1991
1992 // set RegNum if the match is the right kind of register
1993 if (Kind == Entry->getValue().first)
1994 RegNum = Entry->getValue().second;
1995 }
1996 return RegNum;
1997}
1998
1999/// tryParseRegister - Try to parse a register name. The token must be an
2000/// Identifier when called, and if it is a register name the token is eaten and
2001/// the register is added to the operand list.
2002int AArch64AsmParser::tryParseRegister() {
2003 MCAsmParser &Parser = getParser();
2004 const AsmToken &Tok = Parser.getTok();
2005 if (Tok.isNot(AsmToken::Identifier))
2006 return -1;
2007
2008 std::string lowerCase = Tok.getString().lower();
2009 if (isSVEDataVectorRegister(lowerCase))
2010 return -1;
2011
2012 unsigned RegNum = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
2013 // Also handle a few aliases of registers.
2014 if (RegNum == 0)
2015 RegNum = StringSwitch<unsigned>(lowerCase)
2016 .Case("fp", AArch64::FP)
2017 .Case("lr", AArch64::LR)
2018 .Case("x31", AArch64::XZR)
2019 .Case("w31", AArch64::WZR)
2020 .Default(0);
2021
2022 if (RegNum == 0)
2023 return -1;
2024
2025 Parser.Lex(); // Eat identifier token.
2026 return RegNum;
2027}
2028
2029/// tryMatchVectorRegister - Try to parse a vector register name with optional
2030/// kind specifier. If it is a register specifier, eat the token and return it.
2031int AArch64AsmParser::tryMatchVectorRegister(StringRef &Kind, bool expected) {
2032 MCAsmParser &Parser = getParser();
2033 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2034 TokError("vector register expected");
2035 return -1;
2036 }
2037
2038 StringRef Name = Parser.getTok().getString();
2039 // If there is a kind specifier, it's separated from the register name by
2040 // a '.'.
2041 size_t Start = 0, Next = Name.find('.');
2042 StringRef Head = Name.slice(Start, Next);
2043 unsigned RegNum = matchRegisterNameAlias(Head, RegKind::NeonVector);
2044
2045 if (RegNum) {
2046 if (Next != StringRef::npos) {
2047 Kind = Name.slice(Next, StringRef::npos);
2048 if (!isValidVectorKind(Kind)) {
2049 TokError("invalid vector kind qualifier");
2050 return -1;
2051 }
2052 }
2053 Parser.Lex(); // Eat the register token.
2054 return RegNum;
2055 }
2056
2057 if (expected)
2058 TokError("vector register expected");
2059 return -1;
2060}
2061
2062/// tryParseSysCROperand - Try to parse a system instruction CR operand name.
2063OperandMatchResultTy
2064AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
2065 MCAsmParser &Parser = getParser();
2066 SMLoc S = getLoc();
2067
2068 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2069 Error(S, "Expected cN operand where 0 <= N <= 15");
2070 return MatchOperand_ParseFail;
2071 }
2072
2073 StringRef Tok = Parser.getTok().getIdentifier();
2074 if (Tok[0] != 'c' && Tok[0] != 'C') {
2075 Error(S, "Expected cN operand where 0 <= N <= 15");
2076 return MatchOperand_ParseFail;
2077 }
2078
2079 uint32_t CRNum;
2080 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
2081 if (BadNum || CRNum > 15) {
2082 Error(S, "Expected cN operand where 0 <= N <= 15");
2083 return MatchOperand_ParseFail;
2084 }
2085
2086 Parser.Lex(); // Eat identifier token.
2087 Operands.push_back(
2088 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
2089 return MatchOperand_Success;
2090}
2091
2092/// tryParsePrefetch - Try to parse a prefetch operand.
2093OperandMatchResultTy
2094AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
2095 MCAsmParser &Parser = getParser();
2096 SMLoc S = getLoc();
2097 const AsmToken &Tok = Parser.getTok();
2098 // Either an identifier for named values or a 5-bit immediate.
2099 // Eat optional hash.
2100 if (parseOptionalToken(AsmToken::Hash) ||
2101 Tok.is(AsmToken::Integer)) {
2102 const MCExpr *ImmVal;
2103 if (getParser().parseExpression(ImmVal))
2104 return MatchOperand_ParseFail;
2105
2106 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2107 if (!MCE) {
2108 TokError("immediate value expected for prefetch operand");
2109 return MatchOperand_ParseFail;
2110 }
2111 unsigned prfop = MCE->getValue();
2112 if (prfop > 31) {
2113 TokError("prefetch operand out of range, [0,31] expected");
2114 return MatchOperand_ParseFail;
2115 }
2116
2117 auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->getValue());
2118 Operands.push_back(AArch64Operand::CreatePrefetch(
2119 prfop, PRFM ? PRFM->Name : "", S, getContext()));
2120 return MatchOperand_Success;
2121 }
2122
2123 if (Tok.isNot(AsmToken::Identifier)) {
2124 TokError("pre-fetch hint expected");
2125 return MatchOperand_ParseFail;
2126 }
2127
2128 auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.getString());
2129 if (!PRFM) {
2130 TokError("pre-fetch hint expected");
2131 return MatchOperand_ParseFail;
2132 }
2133
2134 Parser.Lex(); // Eat identifier token.
2135 Operands.push_back(AArch64Operand::CreatePrefetch(
2136 PRFM->Encoding, Tok.getString(), S, getContext()));
2137 return MatchOperand_Success;
2138}
2139
2140/// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
2141OperandMatchResultTy
2142AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
2143 MCAsmParser &Parser = getParser();
2144 SMLoc S = getLoc();
2145 const AsmToken &Tok = Parser.getTok();
2146 if (Tok.isNot(AsmToken::Identifier)) {
2147 TokError("invalid operand for instruction");
2148 return MatchOperand_ParseFail;
2149 }
2150
2151 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
2152 if (!PSB) {
2153 TokError("invalid operand for instruction");
2154 return MatchOperand_ParseFail;
2155 }
2156
2157 Parser.Lex(); // Eat identifier token.
2158 Operands.push_back(AArch64Operand::CreatePSBHint(
2159 PSB->Encoding, Tok.getString(), S, getContext()));
2160 return MatchOperand_Success;
2161}
2162
2163/// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2164/// instruction.
2165OperandMatchResultTy
2166AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2167 MCAsmParser &Parser = getParser();
2168 SMLoc S = getLoc();
2169 const MCExpr *Expr;
2170
2171 if (Parser.getTok().is(AsmToken::Hash)) {
2172 Parser.Lex(); // Eat hash token.
2173 }
2174
2175 if (parseSymbolicImmVal(Expr))
2176 return MatchOperand_ParseFail;
2177
2178 AArch64MCExpr::VariantKind ELFRefKind;
2179 MCSymbolRefExpr::VariantKind DarwinRefKind;
2180 int64_t Addend;
2181 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2182 if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2183 ELFRefKind == AArch64MCExpr::VK_INVALID) {
2184 // No modifier was specified at all; this is the syntax for an ELF basic
2185 // ADRP relocation (unfortunately).
2186 Expr =
2187 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2188 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2189 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2190 Addend != 0) {
2191 Error(S, "gotpage label reference not allowed an addend");
2192 return MatchOperand_ParseFail;
2193 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2194 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2195 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2196 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2197 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2198 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2199 // The operand must be an @page or @gotpage qualified symbolref.
2200 Error(S, "page or gotpage label reference expected");
2201 return MatchOperand_ParseFail;
2202 }
2203 }
2204
2205 // We have either a label reference possibly with addend or an immediate. The
2206 // addend is a raw value here. The linker will adjust it to only reference the
2207 // page.
2208 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2209 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2210
2211 return MatchOperand_Success;
2212}
2213
2214/// tryParseAdrLabel - Parse and validate a source label for the ADR
2215/// instruction.
2216OperandMatchResultTy
2217AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2218 SMLoc S = getLoc();
2219 const MCExpr *Expr;
2220
2221 parseOptionalToken(AsmToken::Hash);
2222 if (getParser().parseExpression(Expr))
2223 return MatchOperand_ParseFail;
2224
2225 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2226 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2227
2228 return MatchOperand_Success;
2229}
2230
2231/// tryParseFPImm - A floating point immediate expression operand.
2232OperandMatchResultTy
2233AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2234 MCAsmParser &Parser = getParser();
2235 SMLoc S = getLoc();
2236
2237 bool Hash = parseOptionalToken(AsmToken::Hash);
2238
2239 // Handle negation, as that still comes through as a separate token.
2240 bool isNegative = parseOptionalToken(AsmToken::Minus);
2241
2242 const AsmToken &Tok = Parser.getTok();
2243 if (Tok.is(AsmToken::Real) || Tok.is(AsmToken::Integer)) {
2244 int64_t Val;
2245 if (Tok.is(AsmToken::Integer) && !isNegative && Tok.getString().startswith("0x")) {
2246 Val = Tok.getIntVal();
2247 if (Val > 255 || Val < 0) {
2248 TokError("encoded floating point value out of range");
2249 return MatchOperand_ParseFail;
2250 }
2251 } else {
2252 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
2253 if (isNegative)
2254 RealVal.changeSign();
2255
2256 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
2257 Val = AArch64_AM::getFP64Imm(APInt(64, IntVal));
2258
2259 // Check for out of range values. As an exception we let Zero through,
2260 // but as tokens instead of an FPImm so that it can be matched by the
2261 // appropriate alias if one exists.
2262 if (RealVal.isPosZero()) {
2263 Parser.Lex(); // Eat the token.
2264 Operands.push_back(AArch64Operand::CreateToken("#0", false, S, getContext()));
2265 Operands.push_back(AArch64Operand::CreateToken(".0", false, S, getContext()));
2266 return MatchOperand_Success;
2267 } else if (Val == -1) {
2268 TokError("expected compatible register or floating-point constant");
2269 return MatchOperand_ParseFail;
2270 }
2271 }
2272 Parser.Lex(); // Eat the token.
2273 Operands.push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2274 return MatchOperand_Success;
2275 }
2276
2277 if (!Hash)
2278 return MatchOperand_NoMatch;
2279
2280 TokError("invalid floating point immediate");
2281 return MatchOperand_ParseFail;
2282}
2283
2284/// tryParseAddSubImm - Parse ADD/SUB shifted immediate operand
2285OperandMatchResultTy
2286AArch64AsmParser::tryParseAddSubImm(OperandVector &Operands) {
2287 MCAsmParser &Parser = getParser();
2288 SMLoc S = getLoc();
2289
2290 if (Parser.getTok().is(AsmToken::Hash))
1
Taking false branch
2291 Parser.Lex(); // Eat '#'
2292 else if (Parser.getTok().isNot(AsmToken::Integer))
2
Taking false branch
2293 // Operand should start from # or should be integer, emit error otherwise.
2294 return MatchOperand_NoMatch;
2295
2296 const MCExpr *Imm;
3
'Imm' declared without an initial value
2297 if (parseSymbolicImmVal(Imm))
4
Calling 'AArch64AsmParser::parseSymbolicImmVal'
29
Returning from 'AArch64AsmParser::parseSymbolicImmVal'
30
Assuming the condition is false
31
Taking false branch
2298 return MatchOperand_ParseFail;
2299 else if (Parser.getTok().isNot(AsmToken::Comma)) {
32
Taking true branch
2300 uint64_t ShiftAmount = 0;
2301 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Imm);
33
1st function call argument is an uninitialized value
2302 if (MCE) {
2303 int64_t Val = MCE->getValue();
2304 if (Val > 0xfff && (Val & 0xfff) == 0) {
2305 Imm = MCConstantExpr::create(Val >> 12, getContext());
2306 ShiftAmount = 12;
2307 }
2308 }
2309 SMLoc E = Parser.getTok().getLoc();
2310 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2311 getContext()));
2312 return MatchOperand_Success;
2313 }
2314
2315 // Eat ','
2316 Parser.Lex();
2317
2318 // The optional operand must be "lsl #N" where N is non-negative.
2319 if (!Parser.getTok().is(AsmToken::Identifier) ||
2320 !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2321 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2322 return MatchOperand_ParseFail;
2323 }
2324
2325 // Eat 'lsl'
2326 Parser.Lex();
2327
2328 parseOptionalToken(AsmToken::Hash);
2329
2330 if (Parser.getTok().isNot(AsmToken::Integer)) {
2331 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2332 return MatchOperand_ParseFail;
2333 }
2334
2335 int64_t ShiftAmount = Parser.getTok().getIntVal();
2336
2337 if (ShiftAmount < 0) {
2338 Error(Parser.getTok().getLoc(), "positive shift amount required");
2339 return MatchOperand_ParseFail;
2340 }
2341 Parser.Lex(); // Eat the number
2342
2343 SMLoc E = Parser.getTok().getLoc();
2344 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2345 S, E, getContext()));
2346 return MatchOperand_Success;
2347}
2348
2349/// parseCondCodeString - Parse a Condition Code string.
2350AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2351 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2352 .Case("eq", AArch64CC::EQ)
2353 .Case("ne", AArch64CC::NE)
2354 .Case("cs", AArch64CC::HS)
2355 .Case("hs", AArch64CC::HS)
2356 .Case("cc", AArch64CC::LO)
2357 .Case("lo", AArch64CC::LO)
2358 .Case("mi", AArch64CC::MI)
2359 .Case("pl", AArch64CC::PL)
2360 .Case("vs", AArch64CC::VS)
2361 .Case("vc", AArch64CC::VC)
2362 .Case("hi", AArch64CC::HI)
2363 .Case("ls", AArch64CC::LS)
2364 .Case("ge", AArch64CC::GE)
2365 .Case("lt", AArch64CC::LT)
2366 .Case("gt", AArch64CC::GT)
2367 .Case("le", AArch64CC::LE)
2368 .Case("al", AArch64CC::AL)
2369 .Case("nv", AArch64CC::NV)
2370 .Default(AArch64CC::Invalid);
2371 return CC;
2372}
2373
2374/// parseCondCode - Parse a Condition Code operand.
2375bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2376 bool invertCondCode) {
2377 MCAsmParser &Parser = getParser();
2378 SMLoc S = getLoc();
2379 const AsmToken &Tok = Parser.getTok();
2380 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier")((Tok.is(AsmToken::Identifier) && "Token is not an Identifier"
) ? static_cast<void> (0) : __assert_fail ("Tok.is(AsmToken::Identifier) && \"Token is not an Identifier\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 2380, __PRETTY_FUNCTION__))
;
2381
2382 StringRef Cond = Tok.getString();
2383 AArch64CC::CondCode CC = parseCondCodeString(Cond);
2384 if (CC == AArch64CC::Invalid)
2385 return TokError("invalid condition code");
2386 Parser.Lex(); // Eat identifier token.
2387
2388 if (invertCondCode) {
2389 if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2390 return TokError("condition codes AL and NV are invalid for this instruction");
2391 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2392 }
2393
2394 Operands.push_back(
2395 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2396 return false;
2397}
2398
2399/// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2400/// them if present.
2401OperandMatchResultTy
2402AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
2403 MCAsmParser &Parser = getParser();
2404 const AsmToken &Tok = Parser.getTok();
2405 std::string LowerID = Tok.getString().lower();
2406 AArch64_AM::ShiftExtendType ShOp =
2407 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2408 .Case("lsl", AArch64_AM::LSL)
2409 .Case("lsr", AArch64_AM::LSR)
2410 .Case("asr", AArch64_AM::ASR)
2411 .Case("ror", AArch64_AM::ROR)
2412 .Case("msl", AArch64_AM::MSL)
2413 .Case("uxtb", AArch64_AM::UXTB)
2414 .Case("uxth", AArch64_AM::UXTH)
2415 .Case("uxtw", AArch64_AM::UXTW)
2416 .Case("uxtx", AArch64_AM::UXTX)
2417 .Case("sxtb", AArch64_AM::SXTB)
2418 .Case("sxth", AArch64_AM::SXTH)
2419 .Case("sxtw", AArch64_AM::SXTW)
2420 .Case("sxtx", AArch64_AM::SXTX)
2421 .Default(AArch64_AM::InvalidShiftExtend);
2422
2423 if (ShOp == AArch64_AM::InvalidShiftExtend)
2424 return MatchOperand_NoMatch;
2425
2426 SMLoc S = Tok.getLoc();
2427 Parser.Lex();
2428
2429 bool Hash = parseOptionalToken(AsmToken::Hash);
2430
2431 if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2432 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2433 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2434 ShOp == AArch64_AM::MSL) {
2435 // We expect a number here.
2436 TokError("expected #imm after shift specifier");
2437 return MatchOperand_ParseFail;
2438 }
2439
2440 // "extend" type operations don't need an immediate, #0 is implicit.
2441 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2442 Operands.push_back(
2443 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2444 return MatchOperand_Success;
2445 }
2446
2447 // Make sure we do actually have a number, identifier or a parenthesized
2448 // expression.
2449 SMLoc E = Parser.getTok().getLoc();
2450 if (!Parser.getTok().is(AsmToken::Integer) &&
2451 !Parser.getTok().is(AsmToken::LParen) &&
2452 !Parser.getTok().is(AsmToken::Identifier)) {
2453 Error(E, "expected integer shift amount");
2454 return MatchOperand_ParseFail;
2455 }
2456
2457 const MCExpr *ImmVal;
2458 if (getParser().parseExpression(ImmVal))
2459 return MatchOperand_ParseFail;
2460
2461 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2462 if (!MCE) {
2463 Error(E, "expected constant '#imm' after shift specifier");
2464 return MatchOperand_ParseFail;
2465 }
2466
2467 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2468 Operands.push_back(AArch64Operand::CreateShiftExtend(
2469 ShOp, MCE->getValue(), true, S, E, getContext()));
2470 return MatchOperand_Success;
2471}
2472
2473static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
2474 if (FBS[AArch64::HasV8_1aOps])
2475 Str += "ARMv8.1a";
2476 else if (FBS[AArch64::HasV8_2aOps])
2477 Str += "ARMv8.2a";
2478 else
2479 Str += "(unknown)";
2480}
2481
2482void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands,
2483 SMLoc S) {
2484 const uint16_t Op2 = Encoding & 7;
2485 const uint16_t Cm = (Encoding & 0x78) >> 3;
2486 const uint16_t Cn = (Encoding & 0x780) >> 7;
2487 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
2488
2489 const MCExpr *Expr = MCConstantExpr::create(Op1, getContext());
2490
2491 Operands.push_back(
2492 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
2493 Operands.push_back(
2494 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
2495 Operands.push_back(
2496 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
2497 Expr = MCConstantExpr::create(Op2, getContext());
2498 Operands.push_back(
2499 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
2500}
2501
2502/// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2503/// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2504bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2505 OperandVector &Operands) {
2506 if (Name.find('.') != StringRef::npos)
2507 return TokError("invalid operand");
2508
2509 Mnemonic = Name;
2510 Operands.push_back(
2511 AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
2512
2513 MCAsmParser &Parser = getParser();
2514 const AsmToken &Tok = Parser.getTok();
2515 StringRef Op = Tok.getString();
2516 SMLoc S = Tok.getLoc();
2517
2518 if (Mnemonic == "ic") {
2519 const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op);
2520 if (!IC)
2521 return TokError("invalid operand for IC instruction");
2522 else if (!IC->haveFeatures(getSTI().getFeatureBits())) {
2523 std::string Str("IC " + std::string(IC->Name) + " requires ");
2524 setRequiredFeatureString(IC->getRequiredFeatures(), Str);
2525 return TokError(Str.c_str());
2526 }
2527 createSysAlias(IC->Encoding, Operands, S);
2528 } else if (Mnemonic == "dc") {
2529 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op);
2530 if (!DC)
2531 return TokError("invalid operand for DC instruction");
2532 else if (!DC->haveFeatures(getSTI().getFeatureBits())) {
2533 std::string Str("DC " + std::string(DC->Name) + " requires ");
2534 setRequiredFeatureString(DC->getRequiredFeatures(), Str);
2535 return TokError(Str.c_str());
2536 }
2537 createSysAlias(DC->Encoding, Operands, S);
2538 } else if (Mnemonic == "at") {
2539 const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op);
2540 if (!AT)
2541 return TokError("invalid operand for AT instruction");
2542 else if (!AT->haveFeatures(getSTI().getFeatureBits())) {
2543 std::string Str("AT " + std::string(AT->Name) + " requires ");
2544 setRequiredFeatureString(AT->getRequiredFeatures(), Str);
2545 return TokError(Str.c_str());
2546 }
2547 createSysAlias(AT->Encoding, Operands, S);
2548 } else if (Mnemonic == "tlbi") {
2549 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op);
2550 if (!TLBI)
2551 return TokError("invalid operand for TLBI instruction");
2552 else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) {
2553 std::string Str("TLBI " + std::string(TLBI->Name) + " requires ");
2554 setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
2555 return TokError(Str.c_str());
2556 }
2557 createSysAlias(TLBI->Encoding, Operands, S);
2558 }
2559
2560 Parser.Lex(); // Eat operand.
2561
2562 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2563 bool HasRegister = false;
2564
2565 // Check for the optional register operand.
2566 if (parseOptionalToken(AsmToken::Comma)) {
2567 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2568 return TokError("expected register operand");
2569 HasRegister = true;
2570 }
2571
2572 if (ExpectRegister && !HasRegister)
2573 return TokError("specified " + Mnemonic + " op requires a register");
2574 else if (!ExpectRegister && HasRegister)
2575 return TokError("specified " + Mnemonic + " op does not use a register");
2576
2577 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
2578 return true;
2579
2580 return false;
2581}
2582
2583OperandMatchResultTy
2584AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
2585 MCAsmParser &Parser = getParser();
2586 const AsmToken &Tok = Parser.getTok();
2587
2588 // Can be either a #imm style literal or an option name
2589 if (parseOptionalToken(AsmToken::Hash) ||
2590 Tok.is(AsmToken::Integer)) {
2591 // Immediate operand.
2592 const MCExpr *ImmVal;
2593 SMLoc ExprLoc = getLoc();
2594 if (getParser().parseExpression(ImmVal))
2595 return MatchOperand_ParseFail;
2596 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2597 if (!MCE) {
2598 Error(ExprLoc, "immediate value expected for barrier operand");
2599 return MatchOperand_ParseFail;
2600 }
2601 if (MCE->getValue() < 0 || MCE->getValue() > 15) {
2602 Error(ExprLoc, "barrier operand out of range");
2603 return MatchOperand_ParseFail;
2604 }
2605 auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue());
2606 Operands.push_back(AArch64Operand::CreateBarrier(
2607 MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext()));
2608 return MatchOperand_Success;
2609 }
2610
2611 if (Tok.isNot(AsmToken::Identifier)) {
2612 TokError("invalid operand for instruction");
2613 return MatchOperand_ParseFail;
2614 }
2615
2616 // The only valid named option for ISB is 'sy'
2617 auto DB = AArch64DB::lookupDBByName(Tok.getString());
2618 if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
2619 TokError("'sy' or #imm operand expected");
2620 return MatchOperand_ParseFail;
2621 } else if (!DB) {
2622 TokError("invalid barrier option name");
2623 return MatchOperand_ParseFail;
2624 }
2625
2626 Operands.push_back(AArch64Operand::CreateBarrier(
2627 DB->Encoding, Tok.getString(), getLoc(), getContext()));
2628 Parser.Lex(); // Consume the option
2629
2630 return MatchOperand_Success;
2631}
2632
2633OperandMatchResultTy
2634AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
2635 MCAsmParser &Parser = getParser();
2636 const AsmToken &Tok = Parser.getTok();
2637
2638 if (Tok.isNot(AsmToken::Identifier))
2639 return MatchOperand_NoMatch;
2640
2641 int MRSReg, MSRReg;
2642 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString());
2643 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
2644 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
2645 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
2646 } else
2647 MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
2648
2649 auto PState = AArch64PState::lookupPStateByName(Tok.getString());
2650 unsigned PStateImm = -1;
2651 if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
2652 PStateImm = PState->Encoding;
2653
2654 Operands.push_back(
2655 AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,
2656 PStateImm, getContext()));
2657 Parser.Lex(); // Eat identifier
2658
2659 return MatchOperand_Success;
2660}
2661
2662/// tryParseNeonVectorRegister - Parse a vector register operand.
2663bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
2664 MCAsmParser &Parser = getParser();
2665 if (Parser.getTok().isNot(AsmToken::Identifier))
2666 return true;
2667
2668 SMLoc S = getLoc();
2669 // Check for a vector register specifier first.
2670 StringRef Kind;
2671 int64_t Reg = tryMatchVectorRegister(Kind, false);
2672 if (Reg == -1)
2673 return true;
2674 Operands.push_back(
2675 AArch64Operand::CreateReg(Reg, RegKind::NeonVector, S, getLoc(),
2676 getContext()));
2677
2678 // If there was an explicit qualifier, that goes on as a literal text
2679 // operand.
2680 if (!Kind.empty())
2681 Operands.push_back(
2682 AArch64Operand::CreateToken(Kind, false, S, getContext()));
2683
2684 // If there is an index specifier following the register, parse that too.
2685 SMLoc SIdx = getLoc();
2686 if (parseOptionalToken(AsmToken::LBrac)) {
2687 const MCExpr *ImmVal;
2688 if (getParser().parseExpression(ImmVal))
2689 return false;
2690 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2691 if (!MCE) {
2692 TokError("immediate value expected for vector index");
2693 return false;
2694 }
2695
2696 SMLoc E = getLoc();
2697
2698 if (parseToken(AsmToken::RBrac, "']' expected"))
2699 return false;
2700
2701 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2702 E, getContext()));
2703 }
2704
2705 return false;
2706}
2707
2708// tryParseSVEDataVectorRegister - Try to parse a SVE vector register name with
2709// optional kind specifier. If it is a register specifier, eat the token
2710// and return it.
2711int AArch64AsmParser::tryParseSVEDataVectorRegister(const AsmToken &Tok,
2712 StringRef &Kind) {
2713 if (Tok.isNot(AsmToken::Identifier))
2714 return -1;
2715
2716 StringRef Name = Tok.getString();
2717 // If there is a kind specifier, it's separated from the register name by
2718 // a '.'.
2719 size_t Start = 0, Next = Name.find('.');
2720 StringRef Head = Name.slice(Start, Next);
2721 unsigned RegNum = matchRegisterNameAlias(Head, RegKind::SVEDataVector);
2722
2723 if (RegNum) {
2724 if (Next != StringRef::npos) {
2725 Kind = Name.slice(Next, StringRef::npos);
2726 if (!isValidSVEKind(Kind)) {
2727 TokError("invalid sve vector kind qualifier");
2728 return -1;
2729 }
2730 }
2731 return RegNum;
2732 }
2733
2734 return -1;
2735}
2736
2737/// parseRegister - Parse a non-vector register operand.
2738bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
2739 SMLoc S = getLoc();
2740 // Try for a vector (neon) register.
2741 if (!tryParseNeonVectorRegister(Operands))
2742 return false;
2743
2744 // Try for a scalar register.
2745 int64_t Reg = tryParseRegister();
2746 if (Reg == -1)
2747 return true;
2748 Operands.push_back(AArch64Operand::CreateReg(Reg, RegKind::Scalar, S,
2749 getLoc(), getContext()));
2750
2751 return false;
2752}
2753
2754bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
2755 MCAsmParser &Parser = getParser();
5
Calling 'MCAsmParserExtension::getParser'
6
Returning from 'MCAsmParserExtension::getParser'
2756 bool HasELFModifier = false;
2757 AArch64MCExpr::VariantKind RefKind;
2758
2759 if (parseOptionalToken(AsmToken::Colon)) {
7
Calling 'MCAsmParserExtension::parseOptionalToken'
10
Returning from 'MCAsmParserExtension::parseOptionalToken'
11
Assuming the condition is true
12
Taking true branch
2760 HasELFModifier = true;
2761
2762 if (Parser.getTok().isNot(AsmToken::Identifier))
13
Calling 'AsmToken::isNot'
15
Returning from 'AsmToken::isNot'
16
Taking true branch
2763 return TokError("expect relocation specifier in operand after ':'");
17
Calling constructor for 'Twine'
24
Returning from constructor for 'Twine'
25
Calling 'MCAsmParserExtension::TokError'
28
Returning from 'MCAsmParserExtension::TokError'
2764
2765 std::string LowerCase = Parser.getTok().getIdentifier().lower();
2766 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
2767 .Case("lo12", AArch64MCExpr::VK_LO12)
2768 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
2769 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
2770 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
2771 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
2772 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
2773 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
2774 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
2775 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
2776 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
2777 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
2778 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
2779 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
2780 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
2781 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
2782 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
2783 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
2784 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
2785 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
2786 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
2787 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
2788 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
2789 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
2790 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
2791 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
2792 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
2793 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
2794 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
2795 .Case("got", AArch64MCExpr::VK_GOT_PAGE)
2796 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
2797 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
2798 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
2799 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
2800 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
2801 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
2802 .Default(AArch64MCExpr::VK_INVALID);
2803
2804 if (RefKind == AArch64MCExpr::VK_INVALID)
2805 return TokError("expect relocation specifier in operand after ':'");
2806
2807 Parser.Lex(); // Eat identifier
2808
2809 if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
2810 return true;
2811 }
2812
2813 if (getParser().parseExpression(ImmVal))
2814 return true;
2815
2816 if (HasELFModifier)
2817 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
2818
2819 return false;
2820}
2821
2822/// parseVectorList - Parse a vector list operand for AdvSIMD instructions.
2823bool AArch64AsmParser::parseVectorList(OperandVector &Operands) {
2824 MCAsmParser &Parser = getParser();
2825 assert(Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket")((Parser.getTok().is(AsmToken::LCurly) && "Token is not a Left Bracket"
) ? static_cast<void> (0) : __assert_fail ("Parser.getTok().is(AsmToken::LCurly) && \"Token is not a Left Bracket\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 2825, __PRETTY_FUNCTION__))
;
2826 SMLoc S = getLoc();
2827 Parser.Lex(); // Eat left bracket token.
2828 StringRef Kind;
2829 int64_t FirstReg = tryMatchVectorRegister(Kind, true);
2830 if (FirstReg == -1)
2831 return true;
2832 int64_t PrevReg = FirstReg;
2833 unsigned Count = 1;
2834
2835 if (parseOptionalToken(AsmToken::Minus)) {
2836 SMLoc Loc = getLoc();
2837 StringRef NextKind;
2838 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2839 if (Reg == -1)
2840 return true;
2841 // Any Kind suffices must match on all regs in the list.
2842 if (Kind != NextKind)
2843 return Error(Loc, "mismatched register size suffix");
2844
2845 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2846
2847 if (Space == 0 || Space > 3) {
2848 return Error(Loc, "invalid number of vectors");
2849 }
2850
2851 Count += Space;
2852 }
2853 else {
2854 while (parseOptionalToken(AsmToken::Comma)) {
2855 SMLoc Loc = getLoc();
2856 StringRef NextKind;
2857 int64_t Reg = tryMatchVectorRegister(NextKind, true);
2858 if (Reg == -1)
2859 return true;
2860 // Any Kind suffices must match on all regs in the list.
2861 if (Kind != NextKind)
2862 return Error(Loc, "mismatched register size suffix");
2863
2864 // Registers must be incremental (with wraparound at 31)
2865 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2866 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2867 return Error(Loc, "registers must be sequential");
2868
2869 PrevReg = Reg;
2870 ++Count;
2871 }
2872 }
2873
2874 if (parseToken(AsmToken::RCurly, "'}' expected"))
2875 return true;
2876
2877 if (Count > 4)
2878 return Error(S, "invalid number of vectors");
2879
2880 unsigned NumElements = 0;
2881 char ElementKind = 0;
2882 if (!Kind.empty())
2883 parseValidVectorKind(Kind, NumElements, ElementKind);
2884
2885 Operands.push_back(AArch64Operand::CreateVectorList(
2886 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2887
2888 // If there is an index specifier following the list, parse that too.
2889 SMLoc SIdx = getLoc();
2890 if (parseOptionalToken(AsmToken::LBrac)) { // Eat left bracket token.
2891 const MCExpr *ImmVal;
2892 if (getParser().parseExpression(ImmVal))
2893 return false;
2894 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2895 if (!MCE) {
2896 TokError("immediate value expected for vector index");
2897 return false;
2898 }
2899
2900 SMLoc E = getLoc();
2901 if (parseToken(AsmToken::RBrac, "']' expected"))
2902 return false;
2903
2904 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
2905 E, getContext()));
2906 }
2907 return false;
2908}
2909
2910OperandMatchResultTy
2911AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
2912 MCAsmParser &Parser = getParser();
2913 const AsmToken &Tok = Parser.getTok();
2914 if (!Tok.is(AsmToken::Identifier))
2915 return MatchOperand_NoMatch;
2916
2917 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), RegKind::Scalar);
2918
2919 MCContext &Ctx = getContext();
2920 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
2921 if (!RI->getRegClass(AArch64::GPR64spRegClassID).contains(RegNum))
2922 return MatchOperand_NoMatch;
2923
2924 SMLoc S = getLoc();
2925 Parser.Lex(); // Eat register
2926
2927 if (!parseOptionalToken(AsmToken::Comma)) {
2928 Operands.push_back(
2929 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx));
2930 return MatchOperand_Success;
2931 }
2932
2933 parseOptionalToken(AsmToken::Hash);
2934
2935 if (Parser.getTok().isNot(AsmToken::Integer)) {
2936 Error(getLoc(), "index must be absent or #0");
2937 return MatchOperand_ParseFail;
2938 }
2939
2940 const MCExpr *ImmVal;
2941 if (Parser.parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
2942 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
2943 Error(getLoc(), "index must be absent or #0");
2944 return MatchOperand_ParseFail;
2945 }
2946
2947 Operands.push_back(
2948 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx));
2949 return MatchOperand_Success;
2950}
2951
2952/// parseOperand - Parse a arm instruction operand. For now this parses the
2953/// operand regardless of the mnemonic.
2954bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
2955 bool invertCondCode) {
2956 MCAsmParser &Parser = getParser();
2957 // Check if the current operand has a custom associated parser, if so, try to
2958 // custom parse the operand, or fallback to the general approach.
2959 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2960 if (ResTy == MatchOperand_Success)
2961 return false;
2962 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2963 // there was a match, but an error occurred, in which case, just return that
2964 // the operand parsing failed.
2965 if (ResTy == MatchOperand_ParseFail)
2966 return true;
2967
2968 // Nothing custom, so do general case parsing.
2969 SMLoc S, E;
2970 switch (getLexer().getKind()) {
2971 default: {
2972 SMLoc S = getLoc();
2973 const MCExpr *Expr;
2974 if (parseSymbolicImmVal(Expr))
2975 return Error(S, "invalid operand");
2976
2977 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2978 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2979 return false;
2980 }
2981 case AsmToken::LBrac: {
2982 SMLoc Loc = Parser.getTok().getLoc();
2983 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
2984 getContext()));
2985 Parser.Lex(); // Eat '['
2986
2987 // There's no comma after a '[', so we can parse the next operand
2988 // immediately.
2989 return parseOperand(Operands, false, false);
2990 }
2991 case AsmToken::LCurly:
2992 return parseVectorList(Operands);
2993 case AsmToken::Identifier: {
2994 // If we're expecting a Condition Code operand, then just parse that.
2995 if (isCondCode)
2996 return parseCondCode(Operands, invertCondCode);
2997
2998 // If it's a register name, parse it.
2999 if (!parseRegister(Operands))
3000 return false;
3001
3002 // This could be an optional "shift" or "extend" operand.
3003 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3004 // We can only continue if no tokens were eaten.
3005 if (GotShift != MatchOperand_NoMatch)
3006 return GotShift;
3007
3008 // This was not a register so parse other operands that start with an
3009 // identifier (like labels) as expressions and create them as immediates.
3010 const MCExpr *IdVal;
3011 S = getLoc();
3012 if (getParser().parseExpression(IdVal))
3013 return true;
3014 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3015 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3016 return false;
3017 }
3018 case AsmToken::Integer:
3019 case AsmToken::Real:
3020 case AsmToken::Hash: {
3021 // #42 -> immediate.
3022 S = getLoc();
3023
3024 parseOptionalToken(AsmToken::Hash);
3025
3026 // Parse a negative sign
3027 bool isNegative = false;
3028 if (Parser.getTok().is(AsmToken::Minus)) {
3029 isNegative = true;
3030 // We need to consume this token only when we have a Real, otherwise
3031 // we let parseSymbolicImmVal take care of it
3032 if (Parser.getLexer().peekTok().is(AsmToken::Real))
3033 Parser.Lex();
3034 }
3035
3036 // The only Real that should come through here is a literal #0.0 for
3037 // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3038 // so convert the value.
3039 const AsmToken &Tok = Parser.getTok();
3040 if (Tok.is(AsmToken::Real)) {
3041 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
3042 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3043 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3044 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3045 Mnemonic != "fcmlt")
3046 return TokError("unexpected floating point literal");
3047 else if (IntVal != 0 || isNegative)
3048 return TokError("expected floating-point constant #0.0");
3049 Parser.Lex(); // Eat the token.
3050
3051 Operands.push_back(
3052 AArch64Operand::CreateToken("#0", false, S, getContext()));
3053 Operands.push_back(
3054 AArch64Operand::CreateToken(".0", false, S, getContext()));
3055 return false;
3056 }
3057
3058 const MCExpr *ImmVal;
3059 if (parseSymbolicImmVal(ImmVal))
3060 return true;
3061
3062 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3063 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3064 return false;
3065 }
3066 case AsmToken::Equal: {
3067 SMLoc Loc = getLoc();
3068 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3069 return TokError("unexpected token in operand");
3070 Parser.Lex(); // Eat '='
3071 const MCExpr *SubExprVal;
3072 if (getParser().parseExpression(SubExprVal))
3073 return true;
3074
3075 if (Operands.size() < 2 ||
3076 !static_cast<AArch64Operand &>(*Operands[1]).isReg())
3077 return Error(Loc, "Only valid when first operand is register");
3078
3079 bool IsXReg =
3080 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3081 Operands[1]->getReg());
3082
3083 MCContext& Ctx = getContext();
3084 E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3085 // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3086 if (isa<MCConstantExpr>(SubExprVal)) {
3087 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3088 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3089 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3090 ShiftAmt += 16;
3091 Imm >>= 16;
3092 }
3093 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3094 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3095 Operands.push_back(AArch64Operand::CreateImm(
3096 MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
3097 if (ShiftAmt)
3098 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3099 ShiftAmt, true, S, E, Ctx));
3100 return false;
3101 }
3102 APInt Simm = APInt(64, Imm << ShiftAmt);
3103 // check if the immediate is an unsigned or signed 32-bit int for W regs
3104 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3105 return Error(Loc, "Immediate too large for register");
3106 }
3107 // If it is a label or an imm that cannot fit in a movz, put it into CP.
3108 const MCExpr *CPLoc =
3109 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
3110 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3111 return false;
3112 }
3113 }
3114}
3115
3116/// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3117/// operands.
3118bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3119 StringRef Name, SMLoc NameLoc,
3120 OperandVector &Operands) {
3121 MCAsmParser &Parser = getParser();
3122 Name = StringSwitch<StringRef>(Name.lower())
3123 .Case("beq", "b.eq")
3124 .Case("bne", "b.ne")
3125 .Case("bhs", "b.hs")
3126 .Case("bcs", "b.cs")
3127 .Case("blo", "b.lo")
3128 .Case("bcc", "b.cc")
3129 .Case("bmi", "b.mi")
3130 .Case("bpl", "b.pl")
3131 .Case("bvs", "b.vs")
3132 .Case("bvc", "b.vc")
3133 .Case("bhi", "b.hi")
3134 .Case("bls", "b.ls")
3135 .Case("bge", "b.ge")
3136 .Case("blt", "b.lt")
3137 .Case("bgt", "b.gt")
3138 .Case("ble", "b.le")
3139 .Case("bal", "b.al")
3140 .Case("bnv", "b.nv")
3141 .Default(Name);
3142
3143 // First check for the AArch64-specific .req directive.
3144 if (Parser.getTok().is(AsmToken::Identifier) &&
3145 Parser.getTok().getIdentifier() == ".req") {
3146 parseDirectiveReq(Name, NameLoc);
3147 // We always return 'error' for this, as we're done with this
3148 // statement and don't need to match the 'instruction."
3149 return true;
3150 }
3151
3152 // Create the leading tokens for the mnemonic, split by '.' characters.
3153 size_t Start = 0, Next = Name.find('.');
3154 StringRef Head = Name.slice(Start, Next);
3155
3156 // IC, DC, AT, and TLBI instructions are aliases for the SYS instruction.
3157 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi")
3158 return parseSysAlias(Head, NameLoc, Operands);
3159
3160 Operands.push_back(
3161 AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3162 Mnemonic = Head;
3163
3164 // Handle condition codes for a branch mnemonic
3165 if (Head == "b" && Next != StringRef::npos) {
3166 Start = Next;
3167 Next = Name.find('.', Start + 1);
3168 Head = Name.slice(Start + 1, Next);
3169
3170 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3171 (Head.data() - Name.data()));
3172 AArch64CC::CondCode CC = parseCondCodeString(Head);
3173 if (CC == AArch64CC::Invalid)
3174 return Error(SuffixLoc, "invalid condition code");
3175 Operands.push_back(
3176 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3177 Operands.push_back(
3178 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3179 }
3180
3181 // Add the remaining tokens in the mnemonic.
3182 while (Next != StringRef::npos) {
3183 Start = Next;
3184 Next = Name.find('.', Start + 1);
3185 Head = Name.slice(Start, Next);
3186 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3187 (Head.data() - Name.data()) + 1);
3188 Operands.push_back(
3189 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3190 }
3191
3192 // Conditional compare instructions have a Condition Code operand, which needs
3193 // to be parsed and an immediate operand created.
3194 bool condCodeFourthOperand =
3195 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3196 Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3197 Head == "csinc" || Head == "csinv" || Head == "csneg");
3198
3199 // These instructions are aliases to some of the conditional select
3200 // instructions. However, the condition code is inverted in the aliased
3201 // instruction.
3202 //
3203 // FIXME: Is this the correct way to handle these? Or should the parser
3204 // generate the aliased instructions directly?
3205 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3206 bool condCodeThirdOperand =
3207 (Head == "cinc" || Head == "cinv" || Head == "cneg");
3208
3209 // Read the remaining operands.
3210 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3211 // Read the first operand.
3212 if (parseOperand(Operands, false, false)) {
3213 return true;
3214 }
3215
3216 unsigned N = 2;
3217 while (parseOptionalToken(AsmToken::Comma)) {
3218 // Parse and remember the operand.
3219 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3220 (N == 3 && condCodeThirdOperand) ||
3221 (N == 2 && condCodeSecondOperand),
3222 condCodeSecondOperand || condCodeThirdOperand)) {
3223 return true;
3224 }
3225
3226 // After successfully parsing some operands there are two special cases to
3227 // consider (i.e. notional operands not separated by commas). Both are due
3228 // to memory specifiers:
3229 // + An RBrac will end an address for load/store/prefetch
3230 // + An '!' will indicate a pre-indexed operation.
3231 //
3232 // It's someone else's responsibility to make sure these tokens are sane
3233 // in the given context!
3234
3235 SMLoc RLoc = Parser.getTok().getLoc();
3236 if (parseOptionalToken(AsmToken::RBrac))
3237 Operands.push_back(
3238 AArch64Operand::CreateToken("]", false, RLoc, getContext()));
3239 SMLoc ELoc = Parser.getTok().getLoc();
3240 if (parseOptionalToken(AsmToken::Exclaim))
3241 Operands.push_back(
3242 AArch64Operand::CreateToken("!", false, ELoc, getContext()));
3243
3244 ++N;
3245 }
3246 }
3247
3248 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3249 return true;
3250
3251 return false;
3252}
3253
3254// FIXME: This entire function is a giant hack to provide us with decent
3255// operand range validation/diagnostics until TableGen/MC can be extended
3256// to support autogeneration of this kind of validation.
3257bool AArch64AsmParser::validateInstruction(MCInst &Inst,
3258 SmallVectorImpl<SMLoc> &Loc) {
3259 const MCRegisterInfo *RI = getContext().getRegisterInfo();
3260 // Check for indexed addressing modes w/ the base register being the
3261 // same as a destination/source register or pair load where
3262 // the Rt == Rt2. All of those are undefined behaviour.
3263 switch (Inst.getOpcode()) {
3264 case AArch64::LDPSWpre:
3265 case AArch64::LDPWpost:
3266 case AArch64::LDPWpre:
3267 case AArch64::LDPXpost:
3268 case AArch64::LDPXpre: {
3269 unsigned Rt = Inst.getOperand(1).getReg();
3270 unsigned Rt2 = Inst.getOperand(2).getReg();
3271 unsigned Rn = Inst.getOperand(3).getReg();
3272 if (RI->isSubRegisterEq(Rn, Rt))
3273 return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3274 "is also a destination");
3275 if (RI->isSubRegisterEq(Rn, Rt2))
3276 return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3277 "is also a destination");
3278 LLVM_FALLTHROUGH[[clang::fallthrough]];
3279 }
3280 case AArch64::LDPDi:
3281 case AArch64::LDPQi:
3282 case AArch64::LDPSi:
3283 case AArch64::LDPSWi:
3284 case AArch64::LDPWi:
3285 case AArch64::LDPXi: {
3286 unsigned Rt = Inst.getOperand(0).getReg();
3287 unsigned Rt2 = Inst.getOperand(1).getReg();
3288 if (Rt == Rt2)
3289 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3290 break;
3291 }
3292 case AArch64::LDPDpost:
3293 case AArch64::LDPDpre:
3294 case AArch64::LDPQpost:
3295 case AArch64::LDPQpre:
3296 case AArch64::LDPSpost:
3297 case AArch64::LDPSpre:
3298 case AArch64::LDPSWpost: {
3299 unsigned Rt = Inst.getOperand(1).getReg();
3300 unsigned Rt2 = Inst.getOperand(2).getReg();
3301 if (Rt == Rt2)
3302 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3303 break;
3304 }
3305 case AArch64::STPDpost:
3306 case AArch64::STPDpre:
3307 case AArch64::STPQpost:
3308 case AArch64::STPQpre:
3309 case AArch64::STPSpost:
3310 case AArch64::STPSpre:
3311 case AArch64::STPWpost:
3312 case AArch64::STPWpre:
3313 case AArch64::STPXpost:
3314 case AArch64::STPXpre: {
3315 unsigned Rt = Inst.getOperand(1).getReg();
3316 unsigned Rt2 = Inst.getOperand(2).getReg();
3317 unsigned Rn = Inst.getOperand(3).getReg();
3318 if (RI->isSubRegisterEq(Rn, Rt))
3319 return Error(Loc[0], "unpredictable STP instruction, writeback base "
3320 "is also a source");
3321 if (RI->isSubRegisterEq(Rn, Rt2))
3322 return Error(Loc[1], "unpredictable STP instruction, writeback base "
3323 "is also a source");
3324 break;
3325 }
3326 case AArch64::LDRBBpre:
3327 case AArch64::LDRBpre:
3328 case AArch64::LDRHHpre:
3329 case AArch64::LDRHpre:
3330 case AArch64::LDRSBWpre:
3331 case AArch64::LDRSBXpre:
3332 case AArch64::LDRSHWpre:
3333 case AArch64::LDRSHXpre:
3334 case AArch64::LDRSWpre:
3335 case AArch64::LDRWpre:
3336 case AArch64::LDRXpre:
3337 case AArch64::LDRBBpost:
3338 case AArch64::LDRBpost:
3339 case AArch64::LDRHHpost:
3340 case AArch64::LDRHpost:
3341 case AArch64::LDRSBWpost:
3342 case AArch64::LDRSBXpost:
3343 case AArch64::LDRSHWpost:
3344 case AArch64::LDRSHXpost:
3345 case AArch64::LDRSWpost:
3346 case AArch64::LDRWpost:
3347 case AArch64::LDRXpost: {
3348 unsigned Rt = Inst.getOperand(1).getReg();
3349 unsigned Rn = Inst.getOperand(2).getReg();
3350 if (RI->isSubRegisterEq(Rn, Rt))
3351 return Error(Loc[0], "unpredictable LDR instruction, writeback base "
3352 "is also a source");
3353 break;
3354 }
3355 case AArch64::STRBBpost:
3356 case AArch64::STRBpost:
3357 case AArch64::STRHHpost:
3358 case AArch64::STRHpost:
3359 case AArch64::STRWpost:
3360 case AArch64::STRXpost:
3361 case AArch64::STRBBpre:
3362 case AArch64::STRBpre:
3363 case AArch64::STRHHpre:
3364 case AArch64::STRHpre:
3365 case AArch64::STRWpre:
3366 case AArch64::STRXpre: {
3367 unsigned Rt = Inst.getOperand(1).getReg();
3368 unsigned Rn = Inst.getOperand(2).getReg();
3369 if (RI->isSubRegisterEq(Rn, Rt))
3370 return Error(Loc[0], "unpredictable STR instruction, writeback base "
3371 "is also a source");
3372 break;
3373 }
3374 }
3375
3376 // Now check immediate ranges. Separate from the above as there is overlap
3377 // in the instructions being checked and this keeps the nested conditionals
3378 // to a minimum.
3379 switch (Inst.getOpcode()) {
3380 case AArch64::ADDSWri:
3381 case AArch64::ADDSXri:
3382 case AArch64::ADDWri:
3383 case AArch64::ADDXri:
3384 case AArch64::SUBSWri:
3385 case AArch64::SUBSXri:
3386 case AArch64::SUBWri:
3387 case AArch64::SUBXri: {
3388 // Annoyingly we can't do this in the isAddSubImm predicate, so there is
3389 // some slight duplication here.
3390 if (Inst.getOperand(2).isExpr()) {
3391 const MCExpr *Expr = Inst.getOperand(2).getExpr();
3392 AArch64MCExpr::VariantKind ELFRefKind;
3393 MCSymbolRefExpr::VariantKind DarwinRefKind;
3394 int64_t Addend;
3395 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3396
3397 // Only allow these with ADDXri.
3398 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
3399 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
3400 Inst.getOpcode() == AArch64::ADDXri)
3401 return false;
3402
3403 // Only allow these with ADDXri/ADDWri
3404 if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
3405 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
3406 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
3407 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
3408 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
3409 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
3410 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
3411 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12) &&
3412 (Inst.getOpcode() == AArch64::ADDXri ||
3413 Inst.getOpcode() == AArch64::ADDWri))
3414 return false;
3415
3416 // Don't allow symbol refs in the immediate field otherwise
3417 // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
3418 // operands of the original instruction (i.e. 'add w0, w1, borked' vs
3419 // 'cmp w0, 'borked')
3420 return Error(Loc.back(), "invalid immediate expression");
3421 }
3422 // We don't validate more complex expressions here
3423 }
3424 return false;
3425 }
3426 default:
3427 return false;
3428 }
3429}
3430
3431static std::string AArch64MnemonicSpellCheck(StringRef S, uint64_t FBS,
3432 unsigned VariantID = 0);
3433
3434bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
3435 OperandVector &Operands) {
3436 switch (ErrCode) {
3437 case Match_MissingFeature:
3438 return Error(Loc,
3439 "instruction requires a CPU feature not currently enabled");
3440 case Match_InvalidOperand:
3441 return Error(Loc, "invalid operand for instruction");
3442 case Match_InvalidSuffix:
3443 return Error(Loc, "invalid type suffix for instruction");
3444 case Match_InvalidCondCode:
3445 return Error(Loc, "expected AArch64 condition code");
3446 case Match_AddSubRegExtendSmall:
3447 return Error(Loc,
3448 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3449 case Match_AddSubRegExtendLarge:
3450 return Error(Loc,
3451 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3452 case Match_AddSubSecondSource:
3453 return Error(Loc,
3454 "expected compatible register, symbol or integer in range [0, 4095]");
3455 case Match_LogicalSecondSource:
3456 return Error(Loc, "expected compatible register or logical immediate");
3457 case Match_InvalidMovImm32Shift:
3458 return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
3459 case Match_InvalidMovImm64Shift:
3460 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
3461 case Match_AddSubRegShift32:
3462 return Error(Loc,
3463 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3464 case Match_AddSubRegShift64:
3465 return Error(Loc,
3466 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3467 case Match_InvalidFPImm:
3468 return Error(Loc,
3469 "expected compatible register or floating-point constant");
3470 case Match_InvalidMemoryIndexedSImm9:
3471 return Error(Loc, "index must be an integer in range [-256, 255].");
3472 case Match_InvalidMemoryIndexedSImm10:
3473 return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088].");
3474 case Match_InvalidMemoryIndexed4SImm7:
3475 return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
3476 case Match_InvalidMemoryIndexed8SImm7:
3477 return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
3478 case Match_InvalidMemoryIndexed16SImm7:
3479 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
3480 case Match_InvalidMemoryWExtend8:
3481 return Error(Loc,
3482 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3483 case Match_InvalidMemoryWExtend16:
3484 return Error(Loc,
3485 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3486 case Match_InvalidMemoryWExtend32:
3487 return Error(Loc,
3488 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3489 case Match_InvalidMemoryWExtend64:
3490 return Error(Loc,
3491 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3492 case Match_InvalidMemoryWExtend128:
3493 return Error(Loc,
3494 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3495 case Match_InvalidMemoryXExtend8:
3496 return Error(Loc,
3497 "expected 'lsl' or 'sxtx' with optional shift of #0");
3498 case Match_InvalidMemoryXExtend16:
3499 return Error(Loc,
3500 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3501 case Match_InvalidMemoryXExtend32:
3502 return Error(Loc,
3503 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3504 case Match_InvalidMemoryXExtend64:
3505 return Error(Loc,
3506 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3507 case Match_InvalidMemoryXExtend128:
3508 return Error(Loc,
3509 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3510 case Match_InvalidMemoryIndexed1:
3511 return Error(Loc, "index must be an integer in range [0, 4095].");
3512 case Match_InvalidMemoryIndexed2:
3513 return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
3514 case Match_InvalidMemoryIndexed4:
3515 return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
3516 case Match_InvalidMemoryIndexed8:
3517 return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
3518 case Match_InvalidMemoryIndexed16:
3519 return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
3520 case Match_InvalidImm0_1:
3521 return Error(Loc, "immediate must be an integer in range [0, 1].");
3522 case Match_InvalidImm0_7:
3523 return Error(Loc, "immediate must be an integer in range [0, 7].");
3524 case Match_InvalidImm0_15:
3525 return Error(Loc, "immediate must be an integer in range [0, 15].");
3526 case Match_InvalidImm0_31:
3527 return Error(Loc, "immediate must be an integer in range [0, 31].");
3528 case Match_InvalidImm0_63:
3529 return Error(Loc, "immediate must be an integer in range [0, 63].");
3530 case Match_InvalidImm0_127:
3531 return Error(Loc, "immediate must be an integer in range [0, 127].");
3532 case Match_InvalidImm0_255:
3533 return Error(Loc, "immediate must be an integer in range [0, 255].");
3534 case Match_InvalidImm0_65535:
3535 return Error(Loc, "immediate must be an integer in range [0, 65535].");
3536 case Match_InvalidImm1_8:
3537 return Error(Loc, "immediate must be an integer in range [1, 8].");
3538 case Match_InvalidImm1_16:
3539 return Error(Loc, "immediate must be an integer in range [1, 16].");
3540 case Match_InvalidImm1_32:
3541 return Error(Loc, "immediate must be an integer in range [1, 32].");
3542 case Match_InvalidImm1_64:
3543 return Error(Loc, "immediate must be an integer in range [1, 64].");
3544 case Match_InvalidIndex1:
3545 return Error(Loc, "expected lane specifier '[1]'");
3546 case Match_InvalidIndexB:
3547 return Error(Loc, "vector lane must be an integer in range [0, 15].");
3548 case Match_InvalidIndexH:
3549 return Error(Loc, "vector lane must be an integer in range [0, 7].");
3550 case Match_InvalidIndexS:
3551 return Error(Loc, "vector lane must be an integer in range [0, 3].");
3552 case Match_InvalidIndexD:
3553 return Error(Loc, "vector lane must be an integer in range [0, 1].");
3554 case Match_InvalidLabel:
3555 return Error(Loc, "expected label or encodable integer pc offset");
3556 case Match_MRS:
3557 return Error(Loc, "expected readable system register");
3558 case Match_MSR:
3559 return Error(Loc, "expected writable system register or pstate");
3560 case Match_InvalidComplexRotationEven:
3561 return Error(Loc, "complex rotation must be 0, 90, 180 or 270.");
3562 case Match_InvalidComplexRotationOdd:
3563 return Error(Loc, "complex rotation must be 90 or 270.");
3564 case Match_MnemonicFail: {
3565 std::string Suggestion = AArch64MnemonicSpellCheck(
3566 ((AArch64Operand &)*Operands[0]).getToken(),
3567 ComputeAvailableFeatures(STI->getFeatureBits()));
3568 return Error(Loc, "unrecognized instruction mnemonic" + Suggestion);
3569 }
3570 default:
3571 llvm_unreachable("unexpected error code!")::llvm::llvm_unreachable_internal("unexpected error code!", "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3571)
;
3572 }
3573}
3574
3575static const char *getSubtargetFeatureName(uint64_t Val);
3576
3577bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3578 OperandVector &Operands,
3579 MCStreamer &Out,
3580 uint64_t &ErrorInfo,
3581 bool MatchingInlineAsm) {
3582 assert(!Operands.empty() && "Unexpect empty operand list!")((!Operands.empty() && "Unexpect empty operand list!"
) ? static_cast<void> (0) : __assert_fail ("!Operands.empty() && \"Unexpect empty operand list!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3582, __PRETTY_FUNCTION__))
;
3583 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
3584 assert(Op.isToken() && "Leading operand should always be a mnemonic!")((Op.isToken() && "Leading operand should always be a mnemonic!"
) ? static_cast<void> (0) : __assert_fail ("Op.isToken() && \"Leading operand should always be a mnemonic!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3584, __PRETTY_FUNCTION__))
;
3585
3586 StringRef Tok = Op.getToken();
3587 unsigned NumOperands = Operands.size();
3588
3589 if (NumOperands == 4 && Tok == "lsl") {
3590 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
3591 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3592 if (Op2.isReg() && Op3.isImm()) {
3593 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3594 if (Op3CE) {
3595 uint64_t Op3Val = Op3CE->getValue();
3596 uint64_t NewOp3Val = 0;
3597 uint64_t NewOp4Val = 0;
3598 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
3599 Op2.getReg())) {
3600 NewOp3Val = (32 - Op3Val) & 0x1f;
3601 NewOp4Val = 31 - Op3Val;
3602 } else {
3603 NewOp3Val = (64 - Op3Val) & 0x3f;
3604 NewOp4Val = 63 - Op3Val;
3605 }
3606
3607 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
3608 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
3609
3610 Operands[0] = AArch64Operand::CreateToken(
3611 "ubfm", false, Op.getStartLoc(), getContext());
3612 Operands.push_back(AArch64Operand::CreateImm(
3613 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3614 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3615 Op3.getEndLoc(), getContext());
3616 }
3617 }
3618 } else if (NumOperands == 4 && Tok == "bfc") {
3619 // FIXME: Horrible hack to handle BFC->BFM alias.
3620 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3621 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
3622 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
3623
3624 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3625 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
3626 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
3627
3628 if (LSBCE && WidthCE) {
3629 uint64_t LSB = LSBCE->getValue();
3630 uint64_t Width = WidthCE->getValue();
3631
3632 uint64_t RegWidth = 0;
3633 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3634 Op1.getReg()))
3635 RegWidth = 64;
3636 else
3637 RegWidth = 32;
3638
3639 if (LSB >= RegWidth)
3640 return Error(LSBOp.getStartLoc(),
3641 "expected integer in range [0, 31]");
3642 if (Width < 1 || Width > RegWidth)
3643 return Error(WidthOp.getStartLoc(),
3644 "expected integer in range [1, 32]");
3645
3646 uint64_t ImmR = 0;
3647 if (RegWidth == 32)
3648 ImmR = (32 - LSB) & 0x1f;
3649 else
3650 ImmR = (64 - LSB) & 0x3f;
3651
3652 uint64_t ImmS = Width - 1;
3653
3654 if (ImmR != 0 && ImmS >= ImmR)
3655 return Error(WidthOp.getStartLoc(),
3656 "requested insert overflows register");
3657
3658 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
3659 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
3660 Operands[0] = AArch64Operand::CreateToken(
3661 "bfm", false, Op.getStartLoc(), getContext());
3662 Operands[2] = AArch64Operand::CreateReg(
3663 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
3664 SMLoc(), SMLoc(), getContext());
3665 Operands[3] = AArch64Operand::CreateImm(
3666 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3667 Operands.emplace_back(
3668 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3669 WidthOp.getEndLoc(), getContext()));
3670 }
3671 }
3672 } else if (NumOperands == 5) {
3673 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
3674 // UBFIZ -> UBFM aliases.
3675 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
3676 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3677 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3678 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3679
3680 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3681 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3682 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3683
3684 if (Op3CE && Op4CE) {
3685 uint64_t Op3Val = Op3CE->getValue();
3686 uint64_t Op4Val = Op4CE->getValue();
3687
3688 uint64_t RegWidth = 0;
3689 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3690 Op1.getReg()))
3691 RegWidth = 64;
3692 else
3693 RegWidth = 32;
3694
3695 if (Op3Val >= RegWidth)
3696 return Error(Op3.getStartLoc(),
3697 "expected integer in range [0, 31]");
3698 if (Op4Val < 1 || Op4Val > RegWidth)
3699 return Error(Op4.getStartLoc(),
3700 "expected integer in range [1, 32]");
3701
3702 uint64_t NewOp3Val = 0;
3703 if (RegWidth == 32)
3704 NewOp3Val = (32 - Op3Val) & 0x1f;
3705 else
3706 NewOp3Val = (64 - Op3Val) & 0x3f;
3707
3708 uint64_t NewOp4Val = Op4Val - 1;
3709
3710 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3711 return Error(Op4.getStartLoc(),
3712 "requested insert overflows register");
3713
3714 const MCExpr *NewOp3 =
3715 MCConstantExpr::create(NewOp3Val, getContext());
3716 const MCExpr *NewOp4 =
3717 MCConstantExpr::create(NewOp4Val, getContext());
3718 Operands[3] = AArch64Operand::CreateImm(
3719 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3720 Operands[4] = AArch64Operand::CreateImm(
3721 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3722 if (Tok == "bfi")
3723 Operands[0] = AArch64Operand::CreateToken(
3724 "bfm", false, Op.getStartLoc(), getContext());
3725 else if (Tok == "sbfiz")
3726 Operands[0] = AArch64Operand::CreateToken(
3727 "sbfm", false, Op.getStartLoc(), getContext());
3728 else if (Tok == "ubfiz")
3729 Operands[0] = AArch64Operand::CreateToken(
3730 "ubfm", false, Op.getStartLoc(), getContext());
3731 else
3732 llvm_unreachable("No valid mnemonic for alias?")::llvm::llvm_unreachable_internal("No valid mnemonic for alias?"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3732)
;
3733 }
3734 }
3735
3736 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
3737 // UBFX -> UBFM aliases.
3738 } else if (NumOperands == 5 &&
3739 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
3740 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
3741 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
3742 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
3743
3744 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3745 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
3746 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
3747
3748 if (Op3CE && Op4CE) {
3749 uint64_t Op3Val = Op3CE->getValue();
3750 uint64_t Op4Val = Op4CE->getValue();
3751
3752 uint64_t RegWidth = 0;
3753 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3754 Op1.getReg()))
3755 RegWidth = 64;
3756 else
3757 RegWidth = 32;
3758
3759 if (Op3Val >= RegWidth)
3760 return Error(Op3.getStartLoc(),
3761 "expected integer in range [0, 31]");
3762 if (Op4Val < 1 || Op4Val > RegWidth)
3763 return Error(Op4.getStartLoc(),
3764 "expected integer in range [1, 32]");
3765
3766 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3767
3768 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3769 return Error(Op4.getStartLoc(),
3770 "requested extract overflows register");
3771
3772 const MCExpr *NewOp4 =
3773 MCConstantExpr::create(NewOp4Val, getContext());
3774 Operands[4] = AArch64Operand::CreateImm(
3775 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3776 if (Tok == "bfxil")
3777 Operands[0] = AArch64Operand::CreateToken(
3778 "bfm", false, Op.getStartLoc(), getContext());
3779 else if (Tok == "sbfx")
3780 Operands[0] = AArch64Operand::CreateToken(
3781 "sbfm", false, Op.getStartLoc(), getContext());
3782 else if (Tok == "ubfx")
3783 Operands[0] = AArch64Operand::CreateToken(
3784 "ubfm", false, Op.getStartLoc(), getContext());
3785 else
3786 llvm_unreachable("No valid mnemonic for alias?")::llvm::llvm_unreachable_internal("No valid mnemonic for alias?"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3786)
;
3787 }
3788 }
3789 }
3790 }
3791 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
3792 // InstAlias can't quite handle this since the reg classes aren't
3793 // subclasses.
3794 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
3795 // The source register can be Wn here, but the matcher expects a
3796 // GPR64. Twiddle it here if necessary.
3797 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3798 if (Op.isReg()) {
3799 unsigned Reg = getXRegFromWReg(Op.getReg());
3800 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3801 Op.getStartLoc(), Op.getEndLoc(),
3802 getContext());
3803 }
3804 }
3805 // FIXME: Likewise for sxt[bh] with a Xd dst operand
3806 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
3807 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3808 if (Op.isReg() &&
3809 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3810 Op.getReg())) {
3811 // The source register can be Wn here, but the matcher expects a
3812 // GPR64. Twiddle it here if necessary.
3813 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
3814 if (Op.isReg()) {
3815 unsigned Reg = getXRegFromWReg(Op.getReg());
3816 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3817 Op.getStartLoc(),
3818 Op.getEndLoc(), getContext());
3819 }
3820 }
3821 }
3822 // FIXME: Likewise for uxt[bh] with a Xd dst operand
3823 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
3824 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3825 if (Op.isReg() &&
3826 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3827 Op.getReg())) {
3828 // The source register can be Wn here, but the matcher expects a
3829 // GPR32. Twiddle it here if necessary.
3830 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
3831 if (Op.isReg()) {
3832 unsigned Reg = getWRegFromXReg(Op.getReg());
3833 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3834 Op.getStartLoc(),
3835 Op.getEndLoc(), getContext());
3836 }
3837 }
3838 }
3839
3840 MCInst Inst;
3841 // First try to match against the secondary set of tables containing the
3842 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
3843 unsigned MatchResult =
3844 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3845
3846 // If that fails, try against the alternate table containing long-form NEON:
3847 // "fadd v0.2s, v1.2s, v2.2s"
3848 if (MatchResult != Match_Success) {
3849 // But first, save the short-form match result: we can use it in case the
3850 // long-form match also fails.
3851 auto ShortFormNEONErrorInfo = ErrorInfo;
3852 auto ShortFormNEONMatchResult = MatchResult;
3853
3854 MatchResult =
3855 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3856
3857 // Now, both matches failed, and the long-form match failed on the mnemonic
3858 // suffix token operand. The short-form match failure is probably more
3859 // relevant: use it instead.
3860 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
3861 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
3862 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
3863 MatchResult = ShortFormNEONMatchResult;
3864 ErrorInfo = ShortFormNEONErrorInfo;
3865 }
3866 }
3867
3868 switch (MatchResult) {
3869 case Match_Success: {
3870 // Perform range checking and other semantic validations
3871 SmallVector<SMLoc, 8> OperandLocs;
3872 NumOperands = Operands.size();
3873 for (unsigned i = 1; i < NumOperands; ++i)
3874 OperandLocs.push_back(Operands[i]->getStartLoc());
3875 if (validateInstruction(Inst, OperandLocs))
3876 return true;
3877
3878 Inst.setLoc(IDLoc);
3879 Out.EmitInstruction(Inst, getSTI());
3880 return false;
3881 }
3882 case Match_MissingFeature: {
3883 assert(ErrorInfo && "Unknown missing feature!")((ErrorInfo && "Unknown missing feature!") ? static_cast
<void> (0) : __assert_fail ("ErrorInfo && \"Unknown missing feature!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3883, __PRETTY_FUNCTION__))
;
3884 // Special case the error message for the very common case where only
3885 // a single subtarget feature is missing (neon, e.g.).
3886 std::string Msg = "instruction requires:";
3887 uint64_t Mask = 1;
3888 for (unsigned i = 0; i < (sizeof(ErrorInfo)*8-1); ++i) {
3889 if (ErrorInfo & Mask) {
3890 Msg += " ";
3891 Msg += getSubtargetFeatureName(ErrorInfo & Mask);
3892 }
3893 Mask <<= 1;
3894 }
3895 return Error(IDLoc, Msg);
3896 }
3897 case Match_MnemonicFail:
3898 return showMatchError(IDLoc, MatchResult, Operands);
3899 case Match_InvalidOperand: {
3900 SMLoc ErrorLoc = IDLoc;
3901
3902 if (ErrorInfo != ~0ULL) {
3903 if (ErrorInfo >= Operands.size())
3904 return Error(IDLoc, "too few operands for instruction",
3905 SMRange(IDLoc, getTok().getLoc()));
3906
3907 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3908 if (ErrorLoc == SMLoc())
3909 ErrorLoc = IDLoc;
3910 }
3911 // If the match failed on a suffix token operand, tweak the diagnostic
3912 // accordingly.
3913 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3914 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3915 MatchResult = Match_InvalidSuffix;
3916
3917 return showMatchError(ErrorLoc, MatchResult, Operands);
3918 }
3919 case Match_InvalidMemoryIndexed1:
3920 case Match_InvalidMemoryIndexed2:
3921 case Match_InvalidMemoryIndexed4:
3922 case Match_InvalidMemoryIndexed8:
3923 case Match_InvalidMemoryIndexed16:
3924 case Match_InvalidCondCode:
3925 case Match_AddSubRegExtendSmall:
3926 case Match_AddSubRegExtendLarge:
3927 case Match_AddSubSecondSource:
3928 case Match_LogicalSecondSource:
3929 case Match_AddSubRegShift32:
3930 case Match_AddSubRegShift64:
3931 case Match_InvalidMovImm32Shift:
3932 case Match_InvalidMovImm64Shift:
3933 case Match_InvalidFPImm:
3934 case Match_InvalidMemoryWExtend8:
3935 case Match_InvalidMemoryWExtend16:
3936 case Match_InvalidMemoryWExtend32:
3937 case Match_InvalidMemoryWExtend64:
3938 case Match_InvalidMemoryWExtend128:
3939 case Match_InvalidMemoryXExtend8:
3940 case Match_InvalidMemoryXExtend16:
3941 case Match_InvalidMemoryXExtend32:
3942 case Match_InvalidMemoryXExtend64:
3943 case Match_InvalidMemoryXExtend128:
3944 case Match_InvalidMemoryIndexed4SImm7:
3945 case Match_InvalidMemoryIndexed8SImm7:
3946 case Match_InvalidMemoryIndexed16SImm7:
3947 case Match_InvalidMemoryIndexedSImm9:
3948 case Match_InvalidMemoryIndexedSImm10:
3949 case Match_InvalidImm0_1:
3950 case Match_InvalidImm0_7:
3951 case Match_InvalidImm0_15:
3952 case Match_InvalidImm0_31:
3953 case Match_InvalidImm0_63:
3954 case Match_InvalidImm0_127:
3955 case Match_InvalidImm0_255:
3956 case Match_InvalidImm0_65535:
3957 case Match_InvalidImm1_8:
3958 case Match_InvalidImm1_16:
3959 case Match_InvalidImm1_32:
3960 case Match_InvalidImm1_64:
3961 case Match_InvalidIndex1:
3962 case Match_InvalidIndexB:
3963 case Match_InvalidIndexH:
3964 case Match_InvalidIndexS:
3965 case Match_InvalidIndexD:
3966 case Match_InvalidLabel:
3967 case Match_InvalidComplexRotationEven:
3968 case Match_InvalidComplexRotationOdd:
3969 case Match_MSR:
3970 case Match_MRS: {
3971 if (ErrorInfo >= Operands.size())
3972 return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
3973 // Any time we get here, there's nothing fancy to do. Just get the
3974 // operand SMLoc and display the diagnostic.
3975 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3976 if (ErrorLoc == SMLoc())
3977 ErrorLoc = IDLoc;
3978 return showMatchError(ErrorLoc, MatchResult, Operands);
3979 }
3980 }
3981
3982 llvm_unreachable("Implement any new match types added!")::llvm::llvm_unreachable_internal("Implement any new match types added!"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 3982)
;
3983}
3984
3985/// ParseDirective parses the arm specific directives
3986bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
3987 const MCObjectFileInfo::Environment Format =
3988 getContext().getObjectFileInfo()->getObjectFileType();
3989 bool IsMachO = Format == MCObjectFileInfo::IsMachO;
3990 bool IsCOFF = Format == MCObjectFileInfo::IsCOFF;
3991
3992 StringRef IDVal = DirectiveID.getIdentifier();
3993 SMLoc Loc = DirectiveID.getLoc();
3994 if (IDVal == ".arch")
3995 parseDirectiveArch(Loc);
3996 else if (IDVal == ".cpu")
3997 parseDirectiveCPU(Loc);
3998 else if (IDVal == ".hword")
3999 parseDirectiveWord(2, Loc);
4000 else if (IDVal == ".word")
4001 parseDirectiveWord(4, Loc);
4002 else if (IDVal == ".xword")
4003 parseDirectiveWord(8, Loc);
4004 else if (IDVal == ".tlsdesccall")
4005 parseDirectiveTLSDescCall(Loc);
4006 else if (IDVal == ".ltorg" || IDVal == ".pool")
4007 parseDirectiveLtorg(Loc);
4008 else if (IDVal == ".unreq")
4009 parseDirectiveUnreq(Loc);
4010 else if (!IsMachO && !IsCOFF) {
4011 if (IDVal == ".inst")
4012 parseDirectiveInst(Loc);
4013 else
4014 return true;
4015 } else if (IDVal == MCLOHDirectiveName())
4016 parseDirectiveLOH(IDVal, Loc);
4017 else
4018 return true;
4019 return false;
4020}
4021
4022static const struct {
4023 const char *Name;
4024 const FeatureBitset Features;
4025} ExtensionMap[] = {
4026 { "crc", {AArch64::FeatureCRC} },
4027 { "crypto", {AArch64::FeatureCrypto} },
4028 { "fp", {AArch64::FeatureFPARMv8} },
4029 { "simd", {AArch64::FeatureNEON} },
4030 { "ras", {AArch64::FeatureRAS} },
4031 { "lse", {AArch64::FeatureLSE} },
4032
4033 // FIXME: Unsupported extensions
4034 { "pan", {} },
4035 { "lor", {} },
4036 { "rdma", {} },
4037 { "profile", {} },
4038};
4039
4040/// parseDirectiveArch
4041/// ::= .arch token
4042bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
4043 SMLoc ArchLoc = getLoc();
4044
4045 StringRef Arch, ExtensionString;
4046 std::tie(Arch, ExtensionString) =
4047 getParser().parseStringToEndOfStatement().trim().split('+');
4048
4049 AArch64::ArchKind ID = AArch64::parseArch(Arch);
4050 if (ID == AArch64::ArchKind::INVALID)
4051 return Error(ArchLoc, "unknown arch name");
4052
4053 if (parseToken(AsmToken::EndOfStatement))
4054 return true;
4055
4056 // Get the architecture and extension features.
4057 std::vector<StringRef> AArch64Features;
4058 AArch64::getArchFeatures(ID, AArch64Features);
4059 AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
4060 AArch64Features);
4061
4062 MCSubtargetInfo &STI = copySTI();
4063 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
4064 STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ","));
4065
4066 SmallVector<StringRef, 4> RequestedExtensions;
4067 if (!ExtensionString.empty())
4068 ExtensionString.split(RequestedExtensions, '+');
4069
4070 FeatureBitset Features = STI.getFeatureBits();
4071 for (auto Name : RequestedExtensions) {
4072 bool EnableFeature = true;
4073
4074 if (Name.startswith_lower("no")) {
4075 EnableFeature = false;
4076 Name = Name.substr(2);
4077 }
4078
4079 for (const auto &Extension : ExtensionMap) {
4080 if (Extension.Name != Name)
4081 continue;
4082
4083 if (Extension.Features.none())
4084 report_fatal_error("unsupported architectural extension: " + Name);
4085
4086 FeatureBitset ToggleFeatures = EnableFeature
4087 ? (~Features & Extension.Features)
4088 : ( Features & Extension.Features);
4089 uint64_t Features =
4090 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4091 setAvailableFeatures(Features);
4092 break;
4093 }
4094 }
4095 return false;
4096}
4097
4098static SMLoc incrementLoc(SMLoc L, int Offset) {
4099 return SMLoc::getFromPointer(L.getPointer() + Offset);
4100}
4101
4102/// parseDirectiveCPU
4103/// ::= .cpu id
4104bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
4105 SMLoc CurLoc = getLoc();
4106
4107 StringRef CPU, ExtensionString;
4108 std::tie(CPU, ExtensionString) =
4109 getParser().parseStringToEndOfStatement().trim().split('+');
4110
4111 if (parseToken(AsmToken::EndOfStatement))
4112 return true;
4113
4114 SmallVector<StringRef, 4> RequestedExtensions;
4115 if (!ExtensionString.empty())
4116 ExtensionString.split(RequestedExtensions, '+');
4117
4118 // FIXME This is using tablegen data, but should be moved to ARMTargetParser
4119 // once that is tablegen'ed
4120 if (!getSTI().isCPUStringValid(CPU)) {
4121 Error(CurLoc, "unknown CPU name");
4122 return false;
4123 }
4124
4125 MCSubtargetInfo &STI = copySTI();
4126 STI.setDefaultFeatures(CPU, "");
4127 CurLoc = incrementLoc(CurLoc, CPU.size());
4128
4129 FeatureBitset Features = STI.getFeatureBits();
4130 for (auto Name : RequestedExtensions) {
4131 // Advance source location past '+'.
4132 CurLoc = incrementLoc(CurLoc, 1);
4133
4134 bool EnableFeature = true;
4135
4136 if (Name.startswith_lower("no")) {
4137 EnableFeature = false;
4138 Name = Name.substr(2);
4139 }
4140
4141 bool FoundExtension = false;
4142 for (const auto &Extension : ExtensionMap) {
4143 if (Extension.Name != Name)
4144 continue;
4145
4146 if (Extension.Features.none())
4147 report_fatal_error("unsupported architectural extension: " + Name);
4148
4149 FeatureBitset ToggleFeatures = EnableFeature
4150 ? (~Features & Extension.Features)
4151 : ( Features & Extension.Features);
4152 uint64_t Features =
4153 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
4154 setAvailableFeatures(Features);
4155 FoundExtension = true;
4156
4157 break;
4158 }
4159
4160 if (!FoundExtension)
4161 Error(CurLoc, "unsupported architectural extension");
4162
4163 CurLoc = incrementLoc(CurLoc, Name.size());
4164 }
4165 return false;
4166}
4167
4168/// parseDirectiveWord
4169/// ::= .word [ expression (, expression)* ]
4170bool AArch64AsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
4171 auto parseOp = [&]() -> bool {
4172 const MCExpr *Value;
4173 if (getParser().parseExpression(Value))
4174 return true;
4175 getParser().getStreamer().EmitValue(Value, Size, L);
4176 return false;
4177 };
4178
4179 if (parseMany(parseOp))
4180 return true;
4181 return false;
4182}
4183
4184/// parseDirectiveInst
4185/// ::= .inst opcode [, ...]
4186bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
4187 if (getLexer().is(AsmToken::EndOfStatement))
4188 return Error(Loc, "expected expression following '.inst' directive");
4189
4190 auto parseOp = [&]() -> bool {
4191 SMLoc L = getLoc();
4192 const MCExpr *Expr;
4193 if (check(getParser().parseExpression(Expr), L, "expected expression"))
4194 return true;
4195 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4196 if (check(!Value, L, "expected constant expression"))
4197 return true;
4198 getTargetStreamer().emitInst(Value->getValue());
4199 return false;
4200 };
4201
4202 if (parseMany(parseOp))
4203 return addErrorSuffix(" in '.inst' directive");
4204 return false;
4205}
4206
4207// parseDirectiveTLSDescCall:
4208// ::= .tlsdesccall symbol
4209bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
4210 StringRef Name;
4211 if (check(getParser().parseIdentifier(Name), L,
4212 "expected symbol after directive") ||
4213 parseToken(AsmToken::EndOfStatement))
4214 return true;
4215
4216 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4217 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
4218 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
4219
4220 MCInst Inst;
4221 Inst.setOpcode(AArch64::TLSDESCCALL);
4222 Inst.addOperand(MCOperand::createExpr(Expr));
4223
4224 getParser().getStreamer().EmitInstruction(Inst, getSTI());
4225 return false;
4226}
4227
4228/// ::= .loh <lohName | lohId> label1, ..., labelN
4229/// The number of arguments depends on the loh identifier.
4230bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
4231 MCLOHType Kind;
4232 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4233 if (getParser().getTok().isNot(AsmToken::Integer))
4234 return TokError("expected an identifier or a number in directive");
4235 // We successfully get a numeric value for the identifier.
4236 // Check if it is valid.
4237 int64_t Id = getParser().getTok().getIntVal();
4238 if (Id <= -1U && !isValidMCLOHType(Id))
4239 return TokError("invalid numeric identifier in directive");
4240 Kind = (MCLOHType)Id;
4241 } else {
4242 StringRef Name = getTok().getIdentifier();
4243 // We successfully parse an identifier.
4244 // Check if it is a recognized one.
4245 int Id = MCLOHNameToId(Name);
4246
4247 if (Id == -1)
4248 return TokError("invalid identifier in directive");
4249 Kind = (MCLOHType)Id;
4250 }
4251 // Consume the identifier.
4252 Lex();
4253 // Get the number of arguments of this LOH.
4254 int NbArgs = MCLOHIdToNbArgs(Kind);
4255
4256 assert(NbArgs != -1 && "Invalid number of arguments")((NbArgs != -1 && "Invalid number of arguments") ? static_cast
<void> (0) : __assert_fail ("NbArgs != -1 && \"Invalid number of arguments\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp"
, 4256, __PRETTY_FUNCTION__))
;
4257
4258 SmallVector<MCSymbol *, 3> Args;
4259 for (int Idx = 0; Idx < NbArgs; ++Idx) {
4260 StringRef Name;
4261 if (getParser().parseIdentifier(Name))
4262 return TokError("expected identifier in directive");
4263 Args.push_back(getContext().getOrCreateSymbol(Name));
4264
4265 if (Idx + 1 == NbArgs)
4266 break;
4267 if (parseToken(AsmToken::Comma,
4268 "unexpected token in '" + Twine(IDVal) + "' directive"))
4269 return true;
4270 }
4271 if (parseToken(AsmToken::EndOfStatement,
4272 "unexpected token in '" + Twine(IDVal) + "' directive"))
4273 return true;
4274
4275 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
4276 return false;
4277}
4278
4279/// parseDirectiveLtorg
4280/// ::= .ltorg | .pool
4281bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
4282 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
4283 return true;
4284 getTargetStreamer().emitCurrentConstantPool();
4285 return false;
4286}
4287
4288/// parseDirectiveReq
4289/// ::= name .req registername
4290bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4291 MCAsmParser &Parser = getParser();
4292 Parser.Lex(); // Eat the '.req' token.
4293 SMLoc SRegLoc = getLoc();
4294 unsigned RegNum = tryParseRegister();
4295 RegKind RegisterKind = RegKind::Scalar;
4296
4297 if (RegNum == static_cast<unsigned>(-1)) {
4298 StringRef Kind;
4299 RegisterKind = RegKind::NeonVector;
4300 RegNum = tryMatchVectorRegister(Kind, false);
4301 if (!Kind.empty())
4302 return Error(SRegLoc, "vector register without type specifier expected");
4303 }
4304
4305 if (RegNum == static_cast<unsigned>(-1)) {
4306 StringRef Kind;
4307 RegisterKind = RegKind::SVEDataVector;
4308 int RegNumTmp = tryParseSVEDataVectorRegister(Parser.getTok(), Kind);
4309 if (RegNumTmp != -1)
4310 Parser.Lex();
4311 RegNum = RegNumTmp;
4312 if (!Kind.empty())
4313 return Error(SRegLoc, "sve vector register without type specifier expected");
4314 }
4315
4316 if (RegNum == static_cast<unsigned>(-1))
4317 return Error(SRegLoc, "register name or alias expected");
4318
4319 // Shouldn't be anything else.
4320 if (parseToken(AsmToken::EndOfStatement,
4321 "unexpected input in .req directive"))
4322 return true;
4323
4324 auto pair = std::make_pair(RegisterKind, RegNum);
4325 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4326 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
4327
4328 return false;
4329}
4330
4331/// parseDirectiveUneq
4332/// ::= .unreq registername
4333bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
4334 MCAsmParser &Parser = getParser();
4335 if (getTok().isNot(AsmToken::Identifier))
4336 return TokError("unexpected input in .unreq directive.");
4337 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
4338 Parser.Lex(); // Eat the identifier.
4339 if (parseToken(AsmToken::EndOfStatement))
4340 return addErrorSuffix("in '.unreq' directive");
4341 return false;
4342}
4343
4344bool
4345AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
4346 AArch64MCExpr::VariantKind &ELFRefKind,
4347 MCSymbolRefExpr::VariantKind &DarwinRefKind,
4348 int64_t &Addend) {
4349 ELFRefKind = AArch64MCExpr::VK_INVALID;
4350 DarwinRefKind = MCSymbolRefExpr::VK_None;
4351 Addend = 0;
4352
4353 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4354 ELFRefKind = AE->getKind();
4355 Expr = AE->getSubExpr();
4356 }
4357
4358 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
4359 if (SE) {
4360 // It's a simple symbol reference with no addend.
4361 DarwinRefKind = SE->getKind();
4362 return true;
4363 }
4364
4365 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
4366 if (!BE)
4367 return false;
4368
4369 SE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
4370 if (!SE)
4371 return false;
4372 DarwinRefKind = SE->getKind();
4373
4374 if (BE->getOpcode() != MCBinaryExpr::Add &&
4375 BE->getOpcode() != MCBinaryExpr::Sub)
4376 return false;
4377
4378 // See if the addend is is a constant, otherwise there's more going
4379 // on here than we can deal with.
4380 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
4381 if (!AddendExpr)
4382 return false;
4383
4384 Addend = AddendExpr->getValue();
4385 if (BE->getOpcode() == MCBinaryExpr::Sub)
4386 Addend = -Addend;
4387
4388 // It's some symbol reference + a constant addend, but really
4389 // shouldn't use both Darwin and ELF syntax.
4390 return ELFRefKind == AArch64MCExpr::VK_INVALID ||
4391 DarwinRefKind == MCSymbolRefExpr::VK_None;
4392}
4393
4394/// Force static initialization.
4395extern "C" void LLVMInitializeAArch64AsmParser() {
4396 RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
4397 RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
4398 RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
4399}
4400
4401#define GET_REGISTER_MATCHER
4402#define GET_SUBTARGET_FEATURE_NAME
4403#define GET_MATCHER_IMPLEMENTATION
4404#define GET_MNEMONIC_SPELL_CHECKER
4405#include "AArch64GenAsmMatcher.inc"
4406
4407// Define this matcher function after the auto-generated include so we
4408// have the match class enum definitions.
4409unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
4410 unsigned Kind) {
4411 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
4412 // If the kind is a token for a literal immediate, check if our asm
4413 // operand matches. This is for InstAliases which have a fixed-value
4414 // immediate in the syntax.
4415 int64_t ExpectedVal;
4416 switch (Kind) {
4417 default:
4418 return Match_InvalidOperand;
4419 case MCK__35_0:
4420 ExpectedVal = 0;
4421 break;
4422 case MCK__35_1:
4423 ExpectedVal = 1;
4424 break;
4425 case MCK__35_12:
4426 ExpectedVal = 12;
4427 break;
4428 case MCK__35_16:
4429 ExpectedVal = 16;
4430 break;
4431 case MCK__35_2:
4432 ExpectedVal = 2;
4433 break;
4434 case MCK__35_24:
4435 ExpectedVal = 24;
4436 break;
4437 case MCK__35_3:
4438 ExpectedVal = 3;
4439 break;
4440 case MCK__35_32:
4441 ExpectedVal = 32;
4442 break;
4443 case MCK__35_4:
4444 ExpectedVal = 4;
4445 break;
4446 case MCK__35_48:
4447 ExpectedVal = 48;
4448 break;
4449 case MCK__35_6:
4450 ExpectedVal = 6;
4451 break;
4452 case MCK__35_64:
4453 ExpectedVal = 64;
4454 break;
4455 case MCK__35_8:
4456 ExpectedVal = 8;
4457 break;
4458 }
4459 if (!Op.isImm())
4460 return Match_InvalidOperand;
4461 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
4462 if (!CE)
4463 return Match_InvalidOperand;
4464 if (CE->getValue() == ExpectedVal)
4465 return Match_Success;
4466 return Match_InvalidOperand;
4467}
4468
4469OperandMatchResultTy
4470AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
4471
4472 SMLoc S = getLoc();
4473
4474 if (getParser().getTok().isNot(AsmToken::Identifier)) {
4475 Error(S, "expected register");
4476 return MatchOperand_ParseFail;
4477 }
4478
4479 int FirstReg = tryParseRegister();
4480 if (FirstReg == -1) {
4481 return MatchOperand_ParseFail;
4482 }
4483 const MCRegisterClass &WRegClass =
4484 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4485 const MCRegisterClass &XRegClass =
4486 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4487
4488 bool isXReg = XRegClass.contains(FirstReg),
4489 isWReg = WRegClass.contains(FirstReg);
4490 if (!isXReg && !isWReg) {
4491 Error(S, "expected first even register of a "
4492 "consecutive same-size even/odd register pair");
4493 return MatchOperand_ParseFail;
4494 }
4495
4496 const MCRegisterInfo *RI = getContext().getRegisterInfo();
4497 unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
4498
4499 if (FirstEncoding & 0x1) {
4500 Error(S, "expected first even register of a "
4501 "consecutive same-size even/odd register pair");
4502 return MatchOperand_ParseFail;
4503 }
4504
4505 SMLoc M = getLoc();
4506 if (getParser().getTok().isNot(AsmToken::Comma)) {
4507 Error(M, "expected comma");
4508 return MatchOperand_ParseFail;
4509 }
4510 // Eat the comma
4511 getParser().Lex();
4512
4513 SMLoc E = getLoc();
4514 int SecondReg = tryParseRegister();
4515 if (SecondReg ==-1) {
4516 return MatchOperand_ParseFail;
4517 }
4518
4519 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
4520 (isXReg && !XRegClass.contains(SecondReg)) ||
4521 (isWReg && !WRegClass.contains(SecondReg))) {
4522 Error(E,"expected second odd register of a "
4523 "consecutive same-size even/odd register pair");
4524 return MatchOperand_ParseFail;
4525 }
4526
4527 unsigned Pair = 0;
4528 if (isXReg) {
4529 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
4530 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4531 } else {
4532 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
4533 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4534 }
4535
4536 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
4537 getLoc(), getContext()));
4538
4539 return MatchOperand_Success;
4540}
4541
4542template <bool ParseSuffix>
4543OperandMatchResultTy
4544AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
4545 MCAsmParser &Parser = getParser();
4546 const SMLoc S = getLoc();
4547 // Check for a SVE vector register specifier first.
4548 StringRef Kind;
4549 int RegNum = tryParseSVEDataVectorRegister(Parser.getTok(), Kind);
4550 if (RegNum == -1)
4551 return MatchOperand_NoMatch;
4552
4553 // Eat the SVE Register Token
4554 Parser.Lex();
4555
4556 if (ParseSuffix && Kind.empty())
4557 return MatchOperand_NoMatch;
4558
4559 unsigned ElementWidth = StringSwitch<unsigned>(Kind.lower())
4560 .Case("", -1)
4561 .Case(".b", 8)
4562 .Case(".h", 16)
4563 .Case(".s", 32)
4564 .Case(".d", 64)
4565 .Case(".q", 128)
4566 .Default(0);
4567 if (!ElementWidth)
4568 return MatchOperand_NoMatch;
4569
4570 Operands.push_back(
4571 AArch64Operand::CreateReg(RegNum, RegKind::SVEDataVector, ElementWidth,
4572 S, S, getContext()));
4573
4574 return MatchOperand_Success;
4575}

/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmParserExtension.h

1//===- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks --------*- C++ -*-===//
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#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
11#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
12
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/MC/MCParser/MCAsmLexer.h"
16#include "llvm/MC/MCParser/MCAsmParser.h"
17#include "llvm/Support/SMLoc.h"
18
19namespace llvm {
20
21class Twine;
22
23/// \brief Generic interface for extending the MCAsmParser,
24/// which is implemented by target and object file assembly parser
25/// implementations.
26class MCAsmParserExtension {
27 MCAsmParser *Parser;
28
29protected:
30 MCAsmParserExtension();
31
32 // Helper template for implementing static dispatch functions.
33 template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
34 static bool HandleDirective(MCAsmParserExtension *Target,
35 StringRef Directive,
36 SMLoc DirectiveLoc) {
37 T *Obj = static_cast<T*>(Target);
38 return (Obj->*Handler)(Directive, DirectiveLoc);
39 }
40
41 bool BracketExpressionsSupported = false;
42
43public:
44 MCAsmParserExtension(const MCAsmParserExtension &) = delete;
45 MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete;
46 virtual ~MCAsmParserExtension();
47
48 /// \brief Initialize the extension for parsing using the given \p Parser.
49 /// The extension should use the AsmParser interfaces to register its
50 /// parsing routines.
51 virtual void Initialize(MCAsmParser &Parser);
52
53 /// \name MCAsmParser Proxy Interfaces
54 /// @{
55
56 MCContext &getContext() { return getParser().getContext(); }
57
58 MCAsmLexer &getLexer() { return getParser().getLexer(); }
59 const MCAsmLexer &getLexer() const {
60 return const_cast<MCAsmParserExtension *>(this)->getLexer();
61 }
62
63 MCAsmParser &getParser() { return *Parser; }
64 const MCAsmParser &getParser() const {
65 return const_cast<MCAsmParserExtension*>(this)->getParser();
66 }
67
68 SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
69 MCStreamer &getStreamer() { return getParser().getStreamer(); }
70
71 bool Warning(SMLoc L, const Twine &Msg) {
72 return getParser().Warning(L, Msg);
73 }
74
75 bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
76 return getParser().Error(L, Msg, Range);
77 }
78
79 void Note(SMLoc L, const Twine &Msg) {
80 getParser().Note(L, Msg);
81 }
82
83 bool TokError(const Twine &Msg) {
84 return getParser().TokError(Msg);
26
Calling 'MCAsmParserExtension::getParser'
27
Returning from 'MCAsmParserExtension::getParser'
85 }
86
87 const AsmToken &Lex() { return getParser().Lex(); }
88 const AsmToken &getTok() { return getParser().getTok(); }
89 bool parseToken(AsmToken::TokenKind T,
90 const Twine &Msg = "unexpected token") {
91 return getParser().parseToken(T, Msg);
92 }
93
94 bool parseMany(function_ref<bool()> parseOne, bool hasComma = true) {
95 return getParser().parseMany(parseOne, hasComma);
96 }
97
98 bool parseOptionalToken(AsmToken::TokenKind T) {
99 return getParser().parseOptionalToken(T);
8
Calling 'MCAsmParserExtension::getParser'
9
Returning from 'MCAsmParserExtension::getParser'
100 }
101
102 bool check(bool P, const Twine &Msg) {
103 return getParser().check(P, Msg);
104 }
105
106 bool check(bool P, SMLoc Loc, const Twine &Msg) {
107 return getParser().check(P, Loc, Msg);
108 }
109
110 bool addErrorSuffix(const Twine &Suffix) {
111 return getParser().addErrorSuffix(Suffix);
112 }
113
114 bool HasBracketExpressions() const { return BracketExpressionsSupported; }
115
116 /// @}
117};
118
119} // end namespace llvm
120
121#endif // LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H

/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h

1//===- llvm/MC/MCAsmLexer.h - Abstract Asm Lexer Interface ------*- C++ -*-===//
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#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
11#define LLVM_MC_MCPARSER_MCASMLEXER_H
12
13#include "llvm/ADT/APInt.h"
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/SmallVector.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/SMLoc.h"
18#include <algorithm>
19#include <cassert>
20#include <cstddef>
21#include <cstdint>
22#include <string>
23
24namespace llvm {
25
26/// Target independent representation for an assembler token.
27class AsmToken {
28public:
29 enum TokenKind {
30 // Markers
31 Eof, Error,
32
33 // String values.
34 Identifier,
35 String,
36
37 // Integer values.
38 Integer,
39 BigNum, // larger than 64 bits
40
41 // Real values.
42 Real,
43
44 // Comments
45 Comment,
46 HashDirective,
47 // No-value.
48 EndOfStatement,
49 Colon,
50 Space,
51 Plus, Minus, Tilde,
52 Slash, // '/'
53 BackSlash, // '\'
54 LParen, RParen, LBrac, RBrac, LCurly, RCurly,
55 Star, Dot, Comma, Dollar, Equal, EqualEqual,
56
57 Pipe, PipePipe, Caret,
58 Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
59 Less, LessEqual, LessLess, LessGreater,
60 Greater, GreaterEqual, GreaterGreater, At,
61
62 // MIPS unary expression operators such as %neg.
63 PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
64 PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
65 PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
66 PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
67 PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
68 PercentTprel_Lo
69 };
70
71private:
72 TokenKind Kind;
73
74 /// A reference to the entire token contents; this is always a pointer into
75 /// a memory buffer owned by the source manager.
76 StringRef Str;
77
78 APInt IntVal;
79
80public:
81 AsmToken() = default;
82 AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
83 : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
84 AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
85 : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
86
87 TokenKind getKind() const { return Kind; }
88 bool is(TokenKind K) const { return Kind == K; }
89 bool isNot(TokenKind K) const { return Kind != K; }
14
Assuming the condition is true
90
91 SMLoc getLoc() const;
92 SMLoc getEndLoc() const;
93 SMRange getLocRange() const;
94
95 /// Get the contents of a string token (without quotes).
96 StringRef getStringContents() const {
97 assert(Kind == String && "This token isn't a string!")((Kind == String && "This token isn't a string!") ? static_cast
<void> (0) : __assert_fail ("Kind == String && \"This token isn't a string!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 97, __PRETTY_FUNCTION__))
;
98 return Str.slice(1, Str.size() - 1);
99 }
100
101 /// Get the identifier string for the current token, which should be an
102 /// identifier or a string. This gets the portion of the string which should
103 /// be used as the identifier, e.g., it does not include the quotes on
104 /// strings.
105 StringRef getIdentifier() const {
106 if (Kind == Identifier)
107 return getString();
108 return getStringContents();
109 }
110
111 /// Get the string for the current token, this includes all characters (for
112 /// example, the quotes on strings) in the token.
113 ///
114 /// The returned StringRef points into the source manager's memory buffer, and
115 /// is safe to store across calls to Lex().
116 StringRef getString() const { return Str; }
117
118 // FIXME: Don't compute this in advance, it makes every token larger, and is
119 // also not generally what we want (it is nicer for recovery etc. to lex 123br
120 // as a single token, then diagnose as an invalid number).
121 int64_t getIntVal() const {
122 assert(Kind == Integer && "This token isn't an integer!")((Kind == Integer && "This token isn't an integer!") ?
static_cast<void> (0) : __assert_fail ("Kind == Integer && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 122, __PRETTY_FUNCTION__))
;
123 return IntVal.getZExtValue();
124 }
125
126 APInt getAPIntVal() const {
127 assert((Kind == Integer || Kind == BigNum) &&(((Kind == Integer || Kind == BigNum) && "This token isn't an integer!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __PRETTY_FUNCTION__))
128 "This token isn't an integer!")(((Kind == Integer || Kind == BigNum) && "This token isn't an integer!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __PRETTY_FUNCTION__))
;
129 return IntVal;
130 }
131};
132
133/// A callback class which is notified of each comment in an assembly file as
134/// it is lexed.
135class AsmCommentConsumer {
136public:
137 virtual ~AsmCommentConsumer() = default;
138
139 /// Callback function for when a comment is lexed. Loc is the start of the
140 /// comment text (excluding the comment-start marker). CommentText is the text
141 /// of the comment, excluding the comment start and end markers, and the
142 /// newline for single-line comments.
143 virtual void HandleComment(SMLoc Loc, StringRef CommentText) = 0;
144};
145
146
147/// Generic assembler lexer interface, for use by target specific assembly
148/// lexers.
149class MCAsmLexer {
150 /// The current token, stored in the base class for faster access.
151 SmallVector<AsmToken, 1> CurTok;
152
153 /// The location and description of the current error
154 SMLoc ErrLoc;
155 std::string Err;
156
157protected: // Can only create subclasses.
158 const char *TokStart = nullptr;
159 bool SkipSpace = true;
160 bool AllowAtInIdentifier;
161 bool IsAtStartOfStatement = true;
162 AsmCommentConsumer *CommentConsumer = nullptr;
163
164 bool AltMacroMode;
165 MCAsmLexer();
166
167 virtual AsmToken LexToken() = 0;
168
169 void SetError(SMLoc errLoc, const std::string &err) {
170 ErrLoc = errLoc;
171 Err = err;
172 }
173
174public:
175 MCAsmLexer(const MCAsmLexer &) = delete;
176 MCAsmLexer &operator=(const MCAsmLexer &) = delete;
177 virtual ~MCAsmLexer();
178
179 bool IsaAltMacroMode() {
180 return AltMacroMode;
181 }
182
183 void SetAltMacroMode(bool AltMacroSet) {
184 AltMacroMode = AltMacroSet;
185 }
186
187 /// Consume the next token from the input stream and return it.
188 ///
189 /// The lexer will continuosly return the end-of-file token once the end of
190 /// the main input file has been reached.
191 const AsmToken &Lex() {
192 assert(!CurTok.empty())((!CurTok.empty()) ? static_cast<void> (0) : __assert_fail
("!CurTok.empty()", "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 192, __PRETTY_FUNCTION__))
;
193 // Mark if we parsing out a EndOfStatement.
194 IsAtStartOfStatement = CurTok.front().getKind() == AsmToken::EndOfStatement;
195 CurTok.erase(CurTok.begin());
196 // LexToken may generate multiple tokens via UnLex but will always return
197 // the first one. Place returned value at head of CurTok vector.
198 if (CurTok.empty()) {
199 AsmToken T = LexToken();
200 CurTok.insert(CurTok.begin(), T);
201 }
202 return CurTok.front();
203 }
204
205 void UnLex(AsmToken const &Token) {
206 IsAtStartOfStatement = false;
207 CurTok.insert(CurTok.begin(), Token);
208 }
209
210 bool isAtStartOfStatement() { return IsAtStartOfStatement; }
211
212 virtual StringRef LexUntilEndOfStatement() = 0;
213
214 /// Get the current source location.
215 SMLoc getLoc() const;
216
217 /// Get the current (last) lexed token.
218 const AsmToken &getTok() const {
219 return CurTok[0];
220 }
221
222 /// Look ahead at the next token to be lexed.
223 const AsmToken peekTok(bool ShouldSkipSpace = true) {
224 AsmToken Tok;
225
226 MutableArrayRef<AsmToken> Buf(Tok);
227 size_t ReadCount = peekTokens(Buf, ShouldSkipSpace);
228
229 assert(ReadCount == 1)((ReadCount == 1) ? static_cast<void> (0) : __assert_fail
("ReadCount == 1", "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/MC/MCParser/MCAsmLexer.h"
, 229, __PRETTY_FUNCTION__))
;
230 (void)ReadCount;
231
232 return Tok;
233 }
234
235 /// Look ahead an arbitrary number of tokens.
236 virtual size_t peekTokens(MutableArrayRef<AsmToken> Buf,
237 bool ShouldSkipSpace = true) = 0;
238
239 /// Get the current error location
240 SMLoc getErrLoc() {
241 return ErrLoc;
242 }
243
244 /// Get the current error string
245 const std::string &getErr() {
246 return Err;
247 }
248
249 /// Get the kind of current token.
250 AsmToken::TokenKind getKind() const { return getTok().getKind(); }
251
252 /// Check if the current token has kind \p K.
253 bool is(AsmToken::TokenKind K) const { return getTok().is(K); }
254
255 /// Check if the current token has kind \p K.
256 bool isNot(AsmToken::TokenKind K) const { return getTok().isNot(K); }
257
258 /// Set whether spaces should be ignored by the lexer
259 void setSkipSpace(bool val) { SkipSpace = val; }
260
261 bool getAllowAtInIdentifier() { return AllowAtInIdentifier; }
262 void setAllowAtInIdentifier(bool v) { AllowAtInIdentifier = v; }
263
264 void setCommentConsumer(AsmCommentConsumer *CommentConsumer) {
265 this->CommentConsumer = CommentConsumer;
266 }
267};
268
269} // end namespace llvm
270
271#endif // LLVM_MC_MCPARSER_MCASMLEXER_H

/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h

1//===- Twine.h - Fast Temporary String Concatenation ------------*- C++ -*-===//
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#ifndef LLVM_ADT_TWINE_H
11#define LLVM_ADT_TWINE_H
12
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/ErrorHandling.h"
16#include <cassert>
17#include <cstdint>
18#include <string>
19
20namespace llvm {
21
22 class formatv_object_base;
23 class raw_ostream;
24
25 /// Twine - A lightweight data structure for efficiently representing the
26 /// concatenation of temporary values as strings.
27 ///
28 /// A Twine is a kind of rope, it represents a concatenated string using a
29 /// binary-tree, where the string is the preorder of the nodes. Since the
30 /// Twine can be efficiently rendered into a buffer when its result is used,
31 /// it avoids the cost of generating temporary values for intermediate string
32 /// results -- particularly in cases when the Twine result is never
33 /// required. By explicitly tracking the type of leaf nodes, we can also avoid
34 /// the creation of temporary strings for conversions operations (such as
35 /// appending an integer to a string).
36 ///
37 /// A Twine is not intended for use directly and should not be stored, its
38 /// implementation relies on the ability to store pointers to temporary stack
39 /// objects which may be deallocated at the end of a statement. Twines should
40 /// only be used accepted as const references in arguments, when an API wishes
41 /// to accept possibly-concatenated strings.
42 ///
43 /// Twines support a special 'null' value, which always concatenates to form
44 /// itself, and renders as an empty string. This can be returned from APIs to
45 /// effectively nullify any concatenations performed on the result.
46 ///
47 /// \b Implementation
48 ///
49 /// Given the nature of a Twine, it is not possible for the Twine's
50 /// concatenation method to construct interior nodes; the result must be
51 /// represented inside the returned value. For this reason a Twine object
52 /// actually holds two values, the left- and right-hand sides of a
53 /// concatenation. We also have nullary Twine objects, which are effectively
54 /// sentinel values that represent empty strings.
55 ///
56 /// Thus, a Twine can effectively have zero, one, or two children. The \see
57 /// isNullary(), \see isUnary(), and \see isBinary() predicates exist for
58 /// testing the number of children.
59 ///
60 /// We maintain a number of invariants on Twine objects (FIXME: Why):
61 /// - Nullary twines are always represented with their Kind on the left-hand
62 /// side, and the Empty kind on the right-hand side.
63 /// - Unary twines are always represented with the value on the left-hand
64 /// side, and the Empty kind on the right-hand side.
65 /// - If a Twine has another Twine as a child, that child should always be
66 /// binary (otherwise it could have been folded into the parent).
67 ///
68 /// These invariants are check by \see isValid().
69 ///
70 /// \b Efficiency Considerations
71 ///
72 /// The Twine is designed to yield efficient and small code for common
73 /// situations. For this reason, the concat() method is inlined so that
74 /// concatenations of leaf nodes can be optimized into stores directly into a
75 /// single stack allocated object.
76 ///
77 /// In practice, not all compilers can be trusted to optimize concat() fully,
78 /// so we provide two additional methods (and accompanying operator+
79 /// overloads) to guarantee that particularly important cases (cstring plus
80 /// StringRef) codegen as desired.
81 class Twine {
82 /// NodeKind - Represent the type of an argument.
83 enum NodeKind : unsigned char {
84 /// An empty string; the result of concatenating anything with it is also
85 /// empty.
86 NullKind,
87
88 /// The empty string.
89 EmptyKind,
90
91 /// A pointer to a Twine instance.
92 TwineKind,
93
94 /// A pointer to a C string instance.
95 CStringKind,
96
97 /// A pointer to an std::string instance.
98 StdStringKind,
99
100 /// A pointer to a StringRef instance.
101 StringRefKind,
102
103 /// A pointer to a SmallString instance.
104 SmallStringKind,
105
106 /// A pointer to a formatv_object_base instance.
107 FormatvObjectKind,
108
109 /// A char value, to render as a character.
110 CharKind,
111
112 /// An unsigned int value, to render as an unsigned decimal integer.
113 DecUIKind,
114
115 /// An int value, to render as a signed decimal integer.
116 DecIKind,
117
118 /// A pointer to an unsigned long value, to render as an unsigned decimal
119 /// integer.
120 DecULKind,
121
122 /// A pointer to a long value, to render as a signed decimal integer.
123 DecLKind,
124
125 /// A pointer to an unsigned long long value, to render as an unsigned
126 /// decimal integer.
127 DecULLKind,
128
129 /// A pointer to a long long value, to render as a signed decimal integer.
130 DecLLKind,
131
132 /// A pointer to a uint64_t value, to render as an unsigned hexadecimal
133 /// integer.
134 UHexKind
135 };
136
137 union Child
138 {
139 const Twine *twine;
140 const char *cString;
141 const std::string *stdString;
142 const StringRef *stringRef;
143 const SmallVectorImpl<char> *smallString;
144 const formatv_object_base *formatvObject;
145 char character;
146 unsigned int decUI;
147 int decI;
148 const unsigned long *decUL;
149 const long *decL;
150 const unsigned long long *decULL;
151 const long long *decLL;
152 const uint64_t *uHex;
153 };
154
155 /// LHS - The prefix in the concatenation, which may be uninitialized for
156 /// Null or Empty kinds.
157 Child LHS;
158
159 /// RHS - The suffix in the concatenation, which may be uninitialized for
160 /// Null or Empty kinds.
161 Child RHS;
162
163 /// LHSKind - The NodeKind of the left hand side, \see getLHSKind().
164 NodeKind LHSKind = EmptyKind;
165
166 /// RHSKind - The NodeKind of the right hand side, \see getRHSKind().
167 NodeKind RHSKind = EmptyKind;
168
169 /// Construct a nullary twine; the kind must be NullKind or EmptyKind.
170 explicit Twine(NodeKind Kind) : LHSKind(Kind) {
171 assert(isNullary() && "Invalid kind!")((isNullary() && "Invalid kind!") ? static_cast<void
> (0) : __assert_fail ("isNullary() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 171, __PRETTY_FUNCTION__))
;
172 }
173
174 /// Construct a binary twine.
175 explicit Twine(const Twine &LHS, const Twine &RHS)
176 : LHSKind(TwineKind), RHSKind(TwineKind) {
177 this->LHS.twine = &LHS;
178 this->RHS.twine = &RHS;
179 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 179, __PRETTY_FUNCTION__))
;
180 }
181
182 /// Construct a twine from explicit values.
183 explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
184 : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
185 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 185, __PRETTY_FUNCTION__))
;
186 }
187
188 /// Check for the null twine.
189 bool isNull() const {
190 return getLHSKind() == NullKind;
191 }
192
193 /// Check for the empty twine.
194 bool isEmpty() const {
195 return getLHSKind() == EmptyKind;
196 }
197
198 /// Check if this is a nullary twine (null or empty).
199 bool isNullary() const {
200 return isNull() || isEmpty();
201 }
202
203 /// Check if this is a unary twine.
204 bool isUnary() const {
205 return getRHSKind() == EmptyKind && !isNullary();
206 }
207
208 /// Check if this is a binary twine.
209 bool isBinary() const {
210 return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
211 }
212
213 /// Check if this is a valid twine (satisfying the invariants on
214 /// order and number of arguments).
215 bool isValid() const {
216 // Nullary twines always have Empty on the RHS.
217 if (isNullary() && getRHSKind() != EmptyKind)
218 return false;
219
220 // Null should never appear on the RHS.
221 if (getRHSKind() == NullKind)
222 return false;
223
224 // The RHS cannot be non-empty if the LHS is empty.
225 if (getRHSKind() != EmptyKind && getLHSKind() == EmptyKind)
226 return false;
227
228 // A twine child should always be binary.
229 if (getLHSKind() == TwineKind &&
230 !LHS.twine->isBinary())
231 return false;
232 if (getRHSKind() == TwineKind &&
233 !RHS.twine->isBinary())
234 return false;
235
236 return true;
237 }
238
239 /// Get the NodeKind of the left-hand side.
240 NodeKind getLHSKind() const { return LHSKind; }
241
242 /// Get the NodeKind of the right-hand side.
243 NodeKind getRHSKind() const { return RHSKind; }
244
245 /// Print one child from a twine.
246 void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
247
248 /// Print the representation of one child from a twine.
249 void printOneChildRepr(raw_ostream &OS, Child Ptr,
250 NodeKind Kind) const;
251
252 public:
253 /// @name Constructors
254 /// @{
255
256 /// Construct from an empty string.
257 /*implicit*/ Twine() {
258 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 258, __PRETTY_FUNCTION__))
;
259 }
260
261 Twine(const Twine &) = default;
262
263 /// Construct from a C string.
264 ///
265 /// We take care here to optimize "" into the empty twine -- this will be
266 /// optimized out for string constants. This allows Twine arguments have
267 /// default "" values, without introducing unnecessary string constants.
268 /*implicit*/ Twine(const char *Str) {
18
Calling implicit default constructor for 'Child'
19
Returning from default constructor for 'Child'
20
Calling implicit default constructor for 'Child'
21
Returning from default constructor for 'Child'
269 if (Str[0] != '\0') {
22
Taking true branch
270 LHS.cString = Str;
271 LHSKind = CStringKind;
272 } else
273 LHSKind = EmptyKind;
274
275 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 275, __PRETTY_FUNCTION__))
;
23
Within the expansion of the macro 'assert':
a
Assuming the condition is true
276 }
277
278 /// Construct from an std::string.
279 /*implicit*/ Twine(const std::string &Str) : LHSKind(StdStringKind) {
280 LHS.stdString = &Str;
281 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 281, __PRETTY_FUNCTION__))
;
282 }
283
284 /// Construct from a StringRef.
285 /*implicit*/ Twine(const StringRef &Str) : LHSKind(StringRefKind) {
286 LHS.stringRef = &Str;
287 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 287, __PRETTY_FUNCTION__))
;
288 }
289
290 /// Construct from a SmallString.
291 /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
292 : LHSKind(SmallStringKind) {
293 LHS.smallString = &Str;
294 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 294, __PRETTY_FUNCTION__))
;
295 }
296
297 /// Construct from a formatv_object_base.
298 /*implicit*/ Twine(const formatv_object_base &Fmt)
299 : LHSKind(FormatvObjectKind) {
300 LHS.formatvObject = &Fmt;
301 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 301, __PRETTY_FUNCTION__))
;
302 }
303
304 /// Construct from a char.
305 explicit Twine(char Val) : LHSKind(CharKind) {
306 LHS.character = Val;
307 }
308
309 /// Construct from a signed char.
310 explicit Twine(signed char Val) : LHSKind(CharKind) {
311 LHS.character = static_cast<char>(Val);
312 }
313
314 /// Construct from an unsigned char.
315 explicit Twine(unsigned char Val) : LHSKind(CharKind) {
316 LHS.character = static_cast<char>(Val);
317 }
318
319 /// Construct a twine to print \p Val as an unsigned decimal integer.
320 explicit Twine(unsigned Val) : LHSKind(DecUIKind) {
321 LHS.decUI = Val;
322 }
323
324 /// Construct a twine to print \p Val as a signed decimal integer.
325 explicit Twine(int Val) : LHSKind(DecIKind) {
326 LHS.decI = Val;
327 }
328
329 /// Construct a twine to print \p Val as an unsigned decimal integer.
330 explicit Twine(const unsigned long &Val) : LHSKind(DecULKind) {
331 LHS.decUL = &Val;
332 }
333
334 /// Construct a twine to print \p Val as a signed decimal integer.
335 explicit Twine(const long &Val) : LHSKind(DecLKind) {
336 LHS.decL = &Val;
337 }
338
339 /// Construct a twine to print \p Val as an unsigned decimal integer.
340 explicit Twine(const unsigned long long &Val) : LHSKind(DecULLKind) {
341 LHS.decULL = &Val;
342 }
343
344 /// Construct a twine to print \p Val as a signed decimal integer.
345 explicit Twine(const long long &Val) : LHSKind(DecLLKind) {
346 LHS.decLL = &Val;
347 }
348
349 // FIXME: Unfortunately, to make sure this is as efficient as possible we
350 // need extra binary constructors from particular types. We can't rely on
351 // the compiler to be smart enough to fold operator+()/concat() down to the
352 // right thing. Yet.
353
354 /// Construct as the concatenation of a C string and a StringRef.
355 /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
356 : LHSKind(CStringKind), RHSKind(StringRefKind) {
357 this->LHS.cString = LHS;
358 this->RHS.stringRef = &RHS;
359 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 359, __PRETTY_FUNCTION__))
;
360 }
361
362 /// Construct as the concatenation of a StringRef and a C string.
363 /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
364 : LHSKind(StringRefKind), RHSKind(CStringKind) {
365 this->LHS.stringRef = &LHS;
366 this->RHS.cString = RHS;
367 assert(isValid() && "Invalid twine!")((isValid() && "Invalid twine!") ? static_cast<void
> (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 367, __PRETTY_FUNCTION__))
;
368 }
369
370 /// Since the intended use of twines is as temporary objects, assignments
371 /// when concatenating might cause undefined behavior or stack corruptions
372 Twine &operator=(const Twine &) = delete;
373
374 /// Create a 'null' string, which is an empty string that always
375 /// concatenates to form another empty string.
376 static Twine createNull() {
377 return Twine(NullKind);
378 }
379
380 /// @}
381 /// @name Numeric Conversions
382 /// @{
383
384 // Construct a twine to print \p Val as an unsigned hexadecimal integer.
385 static Twine utohexstr(const uint64_t &Val) {
386 Child LHS, RHS;
387 LHS.uHex = &Val;
388 RHS.twine = nullptr;
389 return Twine(LHS, UHexKind, RHS, EmptyKind);
390 }
391
392 /// @}
393 /// @name Predicate Operations
394 /// @{
395
396 /// Check if this twine is trivially empty; a false return value does not
397 /// necessarily mean the twine is empty.
398 bool isTriviallyEmpty() const {
399 return isNullary();
400 }
401
402 /// Return true if this twine can be dynamically accessed as a single
403 /// StringRef value with getSingleStringRef().
404 bool isSingleStringRef() const {
405 if (getRHSKind() != EmptyKind) return false;
406
407 switch (getLHSKind()) {
408 case EmptyKind:
409 case CStringKind:
410 case StdStringKind:
411 case StringRefKind:
412 case SmallStringKind:
413 return true;
414 default:
415 return false;
416 }
417 }
418
419 /// @}
420 /// @name String Operations
421 /// @{
422
423 Twine concat(const Twine &Suffix) const;
424
425 /// @}
426 /// @name Output & Conversion.
427 /// @{
428
429 /// Return the twine contents as a std::string.
430 std::string str() const;
431
432 /// Append the concatenated string into the given SmallString or SmallVector.
433 void toVector(SmallVectorImpl<char> &Out) const;
434
435 /// This returns the twine as a single StringRef. This method is only valid
436 /// if isSingleStringRef() is true.
437 StringRef getSingleStringRef() const {
438 assert(isSingleStringRef() &&"This cannot be had as a single stringref!")((isSingleStringRef() &&"This cannot be had as a single stringref!"
) ? static_cast<void> (0) : __assert_fail ("isSingleStringRef() &&\"This cannot be had as a single stringref!\""
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 438, __PRETTY_FUNCTION__))
;
439 switch (getLHSKind()) {
440 default: llvm_unreachable("Out of sync with isSingleStringRef")::llvm::llvm_unreachable_internal("Out of sync with isSingleStringRef"
, "/build/llvm-toolchain-snapshot-6.0~svn318211/include/llvm/ADT/Twine.h"
, 440)
;
441 case EmptyKind: return StringRef();
442 case CStringKind: return StringRef(LHS.cString);
443 case StdStringKind: return StringRef(*LHS.stdString);
444 case StringRefKind: return *LHS.stringRef;
445 case SmallStringKind:
446 return StringRef(LHS.smallString->data(), LHS.smallString->size());
447 }
448 }
449
450 /// This returns the twine as a single StringRef if it can be
451 /// represented as such. Otherwise the twine is written into the given
452 /// SmallVector and a StringRef to the SmallVector's data is returned.
453 StringRef toStringRef(SmallVectorImpl<char> &Out) const {
454 if (isSingleStringRef())
455 return getSingleStringRef();
456 toVector(Out);
457 return StringRef(Out.data(), Out.size());
458 }
459
460 /// This returns the twine as a single null terminated StringRef if it
461 /// can be represented as such. Otherwise the twine is written into the
462 /// given SmallVector and a StringRef to the SmallVector's data is returned.
463 ///
464 /// The returned StringRef's size does not include the null terminator.
465 StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
466
467 /// Write the concatenated string represented by this twine to the
468 /// stream \p OS.
469 void print(raw_ostream &OS) const;
470
471 /// Dump the concatenated string represented by this twine to stderr.
472 void dump() const;
473
474 /// Write the representation of this twine to the stream \p OS.
475 void printRepr(raw_ostream &OS) const;
476
477 /// Dump the representation of this twine to stderr.
478 void dumpRepr() const;
479
480 /// @}
481 };
482
483 /// @name Twine Inline Implementations
484 /// @{
485
486 inline Twine Twine::concat(const Twine &Suffix) const {
487 // Concatenation with null is null.
488 if (isNull() || Suffix.isNull())
489 return Twine(NullKind);
490
491 // Concatenation with empty yields the other side.
492 if (isEmpty())
493 return Suffix;
494 if (Suffix.isEmpty())
495 return *this;
496
497 // Otherwise we need to create a new node, taking care to fold in unary
498 // twines.
499 Child NewLHS, NewRHS;
500 NewLHS.twine = this;
501 NewRHS.twine = &Suffix;
502 NodeKind NewLHSKind = TwineKind, NewRHSKind = TwineKind;
503 if (isUnary()) {
504 NewLHS = LHS;
505 NewLHSKind = getLHSKind();
506 }
507 if (Suffix.isUnary()) {
508 NewRHS = Suffix.LHS;
509 NewRHSKind = Suffix.getLHSKind();
510 }
511
512 return Twine(NewLHS, NewLHSKind, NewRHS, NewRHSKind);
513 }
514
515 inline Twine operator+(const Twine &LHS, const Twine &RHS) {
516 return LHS.concat(RHS);
517 }
518
519 /// Additional overload to guarantee simplified codegen; this is equivalent to
520 /// concat().
521
522 inline Twine operator+(const char *LHS, const StringRef &RHS) {
523 return Twine(LHS, RHS);
524 }
525
526 /// Additional overload to guarantee simplified codegen; this is equivalent to
527 /// concat().
528
529 inline Twine operator+(const StringRef &LHS, const char *RHS) {
530 return Twine(LHS, RHS);
531 }
532
533 inline raw_ostream &operator<<(raw_ostream &OS, const Twine &RHS) {
534 RHS.print(OS);
535 return OS;
536 }
537
538 /// @}
539
540} // end namespace llvm
541
542#endif // LLVM_ADT_TWINE_H