Bug Summary

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

Annotated Source Code

[?] Use j/k keys for keyboard navigation

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

/build/llvm-toolchain-snapshot-6.0~svn321639/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~svn321639/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!")(static_cast <bool> (Kind == String && "This token isn't a string!"
) ? void (0) : __assert_fail ("Kind == String && \"This token isn't a string!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 97, __extension__ __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!")(static_cast <bool> (Kind == Integer && "This token isn't an integer!"
) ? void (0) : __assert_fail ("Kind == Integer && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 122, __extension__ __PRETTY_FUNCTION__))
;
123 return IntVal.getZExtValue();
124 }
125
126 APInt getAPIntVal() const {
127 assert((Kind == Integer || Kind == BigNum) &&(static_cast <bool> ((Kind == Integer || Kind == BigNum
) && "This token isn't an integer!") ? void (0) : __assert_fail
("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __extension__ __PRETTY_FUNCTION__))
128 "This token isn't an integer!")(static_cast <bool> ((Kind == Integer || Kind == BigNum
) && "This token isn't an integer!") ? void (0) : __assert_fail
("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 128, __extension__ __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())(static_cast <bool> (!CurTok.empty()) ? void (0) : __assert_fail
("!CurTok.empty()", "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 192, __extension__ __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)(static_cast <bool> (ReadCount == 1) ? void (0) : __assert_fail
("ReadCount == 1", "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/MC/MCParser/MCAsmLexer.h"
, 229, __extension__ __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~svn321639/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!")(static_cast <bool> (isNullary() && "Invalid kind!"
) ? void (0) : __assert_fail ("isNullary() && \"Invalid kind!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 171, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 179, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 185, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 258, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 275, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 281, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 287, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 294, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 301, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 359, __extension__ __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!")(static_cast <bool> (isValid() && "Invalid twine!"
) ? void (0) : __assert_fail ("isValid() && \"Invalid twine!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 367, __extension__ __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!")(static_cast <bool> (isSingleStringRef() &&"This cannot be had as a single stringref!"
) ? void (0) : __assert_fail ("isSingleStringRef() &&\"This cannot be had as a single stringref!\""
, "/build/llvm-toolchain-snapshot-6.0~svn321639/include/llvm/ADT/Twine.h"
, 438, __extension__ __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~svn321639/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