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