1 //==- AArch64AsmParser.cpp - Parse AArch64 assembly to MCInst instructions -==//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/AArch64AddressingModes.h"
10 #include "MCTargetDesc/AArch64MCExpr.h"
11 #include "MCTargetDesc/AArch64MCTargetDesc.h"
12 #include "MCTargetDesc/AArch64TargetStreamer.h"
13 #include "TargetInfo/AArch64TargetInfo.h"
14 #include "AArch64InstrInfo.h"
15 #include "Utils/AArch64BaseInfo.h"
16 #include "llvm/ADT/APFloat.h"
17 #include "llvm/ADT/APInt.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/STLExtras.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/ADT/StringMap.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/MC/MCContext.h"
27 #include "llvm/MC/MCExpr.h"
28 #include "llvm/MC/MCInst.h"
29 #include "llvm/MC/MCLinkerOptimizationHint.h"
30 #include "llvm/MC/MCObjectFileInfo.h"
31 #include "llvm/MC/MCParser/MCAsmLexer.h"
32 #include "llvm/MC/MCParser/MCAsmParser.h"
33 #include "llvm/MC/MCParser/MCAsmParserExtension.h"
34 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
35 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
36 #include "llvm/MC/MCRegisterInfo.h"
37 #include "llvm/MC/MCStreamer.h"
38 #include "llvm/MC/MCSubtargetInfo.h"
39 #include "llvm/MC/MCSymbol.h"
40 #include "llvm/MC/MCTargetOptions.h"
41 #include "llvm/MC/SubtargetFeature.h"
42 #include "llvm/MC/MCValue.h"
43 #include "llvm/Support/Casting.h"
44 #include "llvm/Support/Compiler.h"
45 #include "llvm/Support/ErrorHandling.h"
46 #include "llvm/Support/MathExtras.h"
47 #include "llvm/Support/SMLoc.h"
48 #include "llvm/Support/TargetParser.h"
49 #include "llvm/Support/TargetRegistry.h"
50 #include "llvm/Support/raw_ostream.h"
71 enum RegConstraintEqualityTy {
77 class AArch64AsmParser : public MCTargetAsmParser {
79 StringRef Mnemonic; ///< Instruction mnemonic.
81 // Map of register aliases registers via the .req directive.
82 StringMap<std::pair<RegKind, unsigned>> RegisterReqs;
86 static PrefixInfo CreateFromInst(const MCInst &Inst, uint64_t TSFlags) {
88 switch (Inst.getOpcode()) {
89 case AArch64::MOVPRFX_ZZ:
91 Prefix.Dst = Inst.getOperand(0).getReg();
93 case AArch64::MOVPRFX_ZPmZ_B:
94 case AArch64::MOVPRFX_ZPmZ_H:
95 case AArch64::MOVPRFX_ZPmZ_S:
96 case AArch64::MOVPRFX_ZPmZ_D:
98 Prefix.Predicated = true;
99 Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask;
100 assert(Prefix.ElementSize != AArch64::ElementSizeNone &&
101 "No destructive element size set for movprfx");
102 Prefix.Dst = Inst.getOperand(0).getReg();
103 Prefix.Pg = Inst.getOperand(2).getReg();
105 case AArch64::MOVPRFX_ZPzZ_B:
106 case AArch64::MOVPRFX_ZPzZ_H:
107 case AArch64::MOVPRFX_ZPzZ_S:
108 case AArch64::MOVPRFX_ZPzZ_D:
109 Prefix.Active = true;
110 Prefix.Predicated = true;
111 Prefix.ElementSize = TSFlags & AArch64::ElementSizeMask;
112 assert(Prefix.ElementSize != AArch64::ElementSizeNone &&
113 "No destructive element size set for movprfx");
114 Prefix.Dst = Inst.getOperand(0).getReg();
115 Prefix.Pg = Inst.getOperand(1).getReg();
124 PrefixInfo() : Active(false), Predicated(false) {}
125 bool isActive() const { return Active; }
126 bool isPredicated() const { return Predicated; }
127 unsigned getElementSize() const {
131 unsigned getDstReg() const { return Dst; }
132 unsigned getPgReg() const {
140 unsigned ElementSize;
145 AArch64TargetStreamer &getTargetStreamer() {
146 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
147 return static_cast<AArch64TargetStreamer &>(TS);
150 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
152 bool parseSysAlias(StringRef Name, SMLoc NameLoc, OperandVector &Operands);
153 void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
154 AArch64CC::CondCode parseCondCodeString(StringRef Cond);
155 bool parseCondCode(OperandVector &Operands, bool invertCondCode);
156 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
157 bool parseRegister(OperandVector &Operands);
158 bool parseSymbolicImmVal(const MCExpr *&ImmVal);
159 bool parseNeonVectorList(OperandVector &Operands);
160 bool parseOptionalMulOperand(OperandVector &Operands);
161 bool parseOperand(OperandVector &Operands, bool isCondCode,
162 bool invertCondCode);
164 bool showMatchError(SMLoc Loc, unsigned ErrCode, uint64_t ErrorInfo,
165 OperandVector &Operands);
167 bool parseDirectiveArch(SMLoc L);
168 bool parseDirectiveArchExtension(SMLoc L);
169 bool parseDirectiveCPU(SMLoc L);
170 bool parseDirectiveInst(SMLoc L);
172 bool parseDirectiveTLSDescCall(SMLoc L);
174 bool parseDirectiveLOH(StringRef LOH, SMLoc L);
175 bool parseDirectiveLtorg(SMLoc L);
177 bool parseDirectiveReq(StringRef Name, SMLoc L);
178 bool parseDirectiveUnreq(SMLoc L);
179 bool parseDirectiveCFINegateRAState();
180 bool parseDirectiveCFIBKeyFrame();
182 bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
183 SmallVectorImpl<SMLoc> &Loc);
184 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
185 OperandVector &Operands, MCStreamer &Out,
187 bool MatchingInlineAsm) override;
188 /// @name Auto-generated Match Functions
191 #define GET_ASSEMBLER_HEADER
192 #include "AArch64GenAsmMatcher.inc"
196 OperandMatchResultTy tryParseScalarRegister(unsigned &Reg);
197 OperandMatchResultTy tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
199 OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands);
200 OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands);
201 OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
202 OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
203 OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
204 template <bool IsSVEPrefetch = false>
205 OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
206 OperandMatchResultTy tryParsePSBHint(OperandVector &Operands);
207 OperandMatchResultTy tryParseBTIHint(OperandVector &Operands);
208 OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
209 OperandMatchResultTy tryParseAdrLabel(OperandVector &Operands);
210 template<bool AddFPZeroAsLiteral>
211 OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
212 OperandMatchResultTy tryParseImmWithOptionalShift(OperandVector &Operands);
213 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
214 bool tryParseNeonVectorRegister(OperandVector &Operands);
215 OperandMatchResultTy tryParseVectorIndex(OperandVector &Operands);
216 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
217 template <bool ParseShiftExtend,
218 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
219 OperandMatchResultTy tryParseGPROperand(OperandVector &Operands);
220 template <bool ParseShiftExtend, bool ParseSuffix>
221 OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands);
222 OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands);
223 template <RegKind VectorKind>
224 OperandMatchResultTy tryParseVectorList(OperandVector &Operands,
225 bool ExpectMatch = false);
226 OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands);
229 enum AArch64MatchResultTy {
230 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
231 #define GET_OPERAND_DIAGNOSTIC_TYPES
232 #include "AArch64GenAsmMatcher.inc"
236 AArch64AsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
237 const MCInstrInfo &MII, const MCTargetOptions &Options)
238 : MCTargetAsmParser(Options, STI, MII) {
239 IsILP32 = Options.getABIName() == "ilp32";
240 MCAsmParserExtension::Initialize(Parser);
241 MCStreamer &S = getParser().getStreamer();
242 if (S.getTargetStreamer() == nullptr)
243 new AArch64TargetStreamer(S);
245 // Alias .hword/.word/.[dx]word to the target-independent
246 // .2byte/.4byte/.8byte directives as they have the same form and
248 /// ::= (.hword | .word | .dword | .xword ) [ expression (, expression)* ]
249 Parser.addAliasForDirective(".hword", ".2byte");
250 Parser.addAliasForDirective(".word", ".4byte");
251 Parser.addAliasForDirective(".dword", ".8byte");
252 Parser.addAliasForDirective(".xword", ".8byte");
254 // Initialize the set of available features.
255 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
258 bool regsEqual(const MCParsedAsmOperand &Op1,
259 const MCParsedAsmOperand &Op2) const override;
260 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
261 SMLoc NameLoc, OperandVector &Operands) override;
262 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
263 bool ParseDirective(AsmToken DirectiveID) override;
264 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
265 unsigned Kind) override;
267 static bool classifySymbolRef(const MCExpr *Expr,
268 AArch64MCExpr::VariantKind &ELFRefKind,
269 MCSymbolRefExpr::VariantKind &DarwinRefKind,
273 /// AArch64Operand - Instances of this class represent a parsed AArch64 machine
275 class AArch64Operand : public MCParsedAsmOperand {
295 SMLoc StartLoc, EndLoc;
300 bool IsSuffix; // Is the operand actually a suffix on the mnemonic.
303 // Separate shift/extend operand.
304 struct ShiftExtendOp {
305 AArch64_AM::ShiftExtendType Type;
307 bool HasExplicitAmount;
315 // The register may be allowed as a different register class,
316 // e.g. for GPR64as32 or GPR32as64.
317 RegConstraintEqualityTy EqualityTy;
319 // In some cases the shift/extend needs to be explicitly parsed together
320 // with the register, rather than as a separate operand. This is needed
321 // for addressing modes where the instruction as a whole dictates the
322 // scaling/extend, rather than specific bits in the instruction.
323 // By parsing them as a single operand, we avoid the need to pass an
324 // extra operand in all CodeGen patterns (because all operands need to
325 // have an associated value), and we avoid the need to update TableGen to
326 // accept operands that have no associated bits in the instruction.
328 // An added benefit of parsing them together is that the assembler
329 // can give a sensible diagnostic if the scaling is not correct.
331 // The default is 'lsl #0' (HasExplicitAmount = false) if no
332 // ShiftExtend is specified.
333 ShiftExtendOp ShiftExtend;
336 struct VectorListOp {
339 unsigned NumElements;
340 unsigned ElementWidth;
341 RegKind RegisterKind;
344 struct VectorIndexOp {
352 struct ShiftedImmOp {
354 unsigned ShiftAmount;
358 AArch64CC::CondCode Code;
362 uint64_t Val; // APFloat value bitcasted to uint64_t.
363 bool IsExact; // describes whether parsed value was exact.
369 unsigned Val; // Not the enum since not all values have names.
377 uint32_t PStateField;
409 struct VectorListOp VectorList;
410 struct VectorIndexOp VectorIndex;
412 struct ShiftedImmOp ShiftedImm;
413 struct CondCodeOp CondCode;
414 struct FPImmOp FPImm;
415 struct BarrierOp Barrier;
416 struct SysRegOp SysReg;
417 struct SysCRImmOp SysCRImm;
418 struct PrefetchOp Prefetch;
419 struct PSBHintOp PSBHint;
420 struct BTIHintOp BTIHint;
421 struct ShiftExtendOp ShiftExtend;
424 // Keep the MCContext around as the MCExprs may need manipulated during
425 // the add<>Operands() calls.
429 AArch64Operand(KindTy K, MCContext &Ctx) : Kind(K), Ctx(Ctx) {}
431 AArch64Operand(const AArch64Operand &o) : MCParsedAsmOperand(), Ctx(o.Ctx) {
433 StartLoc = o.StartLoc;
443 ShiftedImm = o.ShiftedImm;
446 CondCode = o.CondCode;
458 VectorList = o.VectorList;
461 VectorIndex = o.VectorIndex;
467 SysCRImm = o.SysCRImm;
470 Prefetch = o.Prefetch;
479 ShiftExtend = o.ShiftExtend;
484 /// getStartLoc - Get the location of the first token of this operand.
485 SMLoc getStartLoc() const override { return StartLoc; }
486 /// getEndLoc - Get the location of the last token of this operand.
487 SMLoc getEndLoc() const override { return EndLoc; }
489 StringRef getToken() const {
490 assert(Kind == k_Token && "Invalid access!");
491 return StringRef(Tok.Data, Tok.Length);
494 bool isTokenSuffix() const {
495 assert(Kind == k_Token && "Invalid access!");
499 const MCExpr *getImm() const {
500 assert(Kind == k_Immediate && "Invalid access!");
504 const MCExpr *getShiftedImmVal() const {
505 assert(Kind == k_ShiftedImm && "Invalid access!");
506 return ShiftedImm.Val;
509 unsigned getShiftedImmShift() const {
510 assert(Kind == k_ShiftedImm && "Invalid access!");
511 return ShiftedImm.ShiftAmount;
514 AArch64CC::CondCode getCondCode() const {
515 assert(Kind == k_CondCode && "Invalid access!");
516 return CondCode.Code;
519 APFloat getFPImm() const {
520 assert (Kind == k_FPImm && "Invalid access!");
521 return APFloat(APFloat::IEEEdouble(), APInt(64, FPImm.Val, true));
524 bool getFPImmIsExact() const {
525 assert (Kind == k_FPImm && "Invalid access!");
526 return FPImm.IsExact;
529 unsigned getBarrier() const {
530 assert(Kind == k_Barrier && "Invalid access!");
534 StringRef getBarrierName() const {
535 assert(Kind == k_Barrier && "Invalid access!");
536 return StringRef(Barrier.Data, Barrier.Length);
539 unsigned getReg() const override {
540 assert(Kind == k_Register && "Invalid access!");
544 RegConstraintEqualityTy getRegEqualityTy() const {
545 assert(Kind == k_Register && "Invalid access!");
546 return Reg.EqualityTy;
549 unsigned getVectorListStart() const {
550 assert(Kind == k_VectorList && "Invalid access!");
551 return VectorList.RegNum;
554 unsigned getVectorListCount() const {
555 assert(Kind == k_VectorList && "Invalid access!");
556 return VectorList.Count;
559 unsigned getVectorIndex() const {
560 assert(Kind == k_VectorIndex && "Invalid access!");
561 return VectorIndex.Val;
564 StringRef getSysReg() const {
565 assert(Kind == k_SysReg && "Invalid access!");
566 return StringRef(SysReg.Data, SysReg.Length);
569 unsigned getSysCR() const {
570 assert(Kind == k_SysCR && "Invalid access!");
574 unsigned getPrefetch() const {
575 assert(Kind == k_Prefetch && "Invalid access!");
579 unsigned getPSBHint() const {
580 assert(Kind == k_PSBHint && "Invalid access!");
584 StringRef getPSBHintName() const {
585 assert(Kind == k_PSBHint && "Invalid access!");
586 return StringRef(PSBHint.Data, PSBHint.Length);
589 unsigned getBTIHint() const {
590 assert(Kind == k_BTIHint && "Invalid access!");
594 StringRef getBTIHintName() const {
595 assert(Kind == k_BTIHint && "Invalid access!");
596 return StringRef(BTIHint.Data, BTIHint.Length);
599 StringRef getPrefetchName() const {
600 assert(Kind == k_Prefetch && "Invalid access!");
601 return StringRef(Prefetch.Data, Prefetch.Length);
604 AArch64_AM::ShiftExtendType getShiftExtendType() const {
605 if (Kind == k_ShiftExtend)
606 return ShiftExtend.Type;
607 if (Kind == k_Register)
608 return Reg.ShiftExtend.Type;
609 llvm_unreachable("Invalid access!");
612 unsigned getShiftExtendAmount() const {
613 if (Kind == k_ShiftExtend)
614 return ShiftExtend.Amount;
615 if (Kind == k_Register)
616 return Reg.ShiftExtend.Amount;
617 llvm_unreachable("Invalid access!");
620 bool hasShiftExtendAmount() const {
621 if (Kind == k_ShiftExtend)
622 return ShiftExtend.HasExplicitAmount;
623 if (Kind == k_Register)
624 return Reg.ShiftExtend.HasExplicitAmount;
625 llvm_unreachable("Invalid access!");
628 bool isImm() const override { return Kind == k_Immediate; }
629 bool isMem() const override { return false; }
631 bool isUImm6() const {
634 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
637 int64_t Val = MCE->getValue();
638 return (Val >= 0 && Val < 64);
641 template <int Width> bool isSImm() const { return isSImmScaled<Width, 1>(); }
643 template <int Bits, int Scale> DiagnosticPredicate isSImmScaled() const {
644 return isImmScaled<Bits, Scale>(true);
647 template <int Bits, int Scale> DiagnosticPredicate isUImmScaled() const {
648 return isImmScaled<Bits, Scale>(false);
651 template <int Bits, int Scale>
652 DiagnosticPredicate isImmScaled(bool Signed) const {
654 return DiagnosticPredicateTy::NoMatch;
656 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
658 return DiagnosticPredicateTy::NoMatch;
660 int64_t MinVal, MaxVal;
662 int64_t Shift = Bits - 1;
663 MinVal = (int64_t(1) << Shift) * -Scale;
664 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
667 MaxVal = ((int64_t(1) << Bits) - 1) * Scale;
670 int64_t Val = MCE->getValue();
671 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
672 return DiagnosticPredicateTy::Match;
674 return DiagnosticPredicateTy::NearMatch;
677 DiagnosticPredicate isSVEPattern() const {
679 return DiagnosticPredicateTy::NoMatch;
680 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
682 return DiagnosticPredicateTy::NoMatch;
683 int64_t Val = MCE->getValue();
684 if (Val >= 0 && Val < 32)
685 return DiagnosticPredicateTy::Match;
686 return DiagnosticPredicateTy::NearMatch;
689 bool isSymbolicUImm12Offset(const MCExpr *Expr) const {
690 AArch64MCExpr::VariantKind ELFRefKind;
691 MCSymbolRefExpr::VariantKind DarwinRefKind;
693 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
695 // If we don't understand the expression, assume the best and
696 // let the fixup and relocation code deal with it.
700 if (DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
701 ELFRefKind == AArch64MCExpr::VK_LO12 ||
702 ELFRefKind == AArch64MCExpr::VK_GOT_LO12 ||
703 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
704 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
705 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
706 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
707 ELFRefKind == AArch64MCExpr::VK_GOTTPREL_LO12_NC ||
708 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
709 ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
710 ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) {
711 // Note that we don't range-check the addend. It's adjusted modulo page
712 // size when converted, so there is no "out of range" condition when using
715 } else if (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF ||
716 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) {
717 // @gotpageoff/@tlvppageoff can only be used directly, not with an addend.
724 template <int Scale> bool isUImm12Offset() const {
728 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
730 return isSymbolicUImm12Offset(getImm());
732 int64_t Val = MCE->getValue();
733 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
736 template <int N, int M>
737 bool isImmInRange() const {
740 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
743 int64_t Val = MCE->getValue();
744 return (Val >= N && Val <= M);
747 // NOTE: Also used for isLogicalImmNot as anything that can be represented as
748 // a logical immediate can always be represented when inverted.
749 template <typename T>
750 bool isLogicalImm() const {
753 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
757 int64_t Val = MCE->getValue();
758 int64_t SVal = typename std::make_signed<T>::type(Val);
759 int64_t UVal = typename std::make_unsigned<T>::type(Val);
760 if (Val != SVal && Val != UVal)
763 return AArch64_AM::isLogicalImmediate(UVal, sizeof(T) * 8);
766 bool isShiftedImm() const { return Kind == k_ShiftedImm; }
768 /// Returns the immediate value as a pair of (imm, shift) if the immediate is
769 /// a shifted immediate by value 'Shift' or '0', or if it is an unshifted
770 /// immediate that can be shifted by 'Shift'.
771 template <unsigned Width>
772 Optional<std::pair<int64_t, unsigned> > getShiftedVal() const {
773 if (isShiftedImm() && Width == getShiftedImmShift())
774 if (auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
775 return std::make_pair(CE->getValue(), Width);
778 if (auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
779 int64_t Val = CE->getValue();
780 if ((Val != 0) && (uint64_t(Val >> Width) << Width) == uint64_t(Val))
781 return std::make_pair(Val >> Width, Width);
783 return std::make_pair(Val, 0u);
789 bool isAddSubImm() const {
790 if (!isShiftedImm() && !isImm())
795 // An ADD/SUB shifter is either 'lsl #0' or 'lsl #12'.
796 if (isShiftedImm()) {
797 unsigned Shift = ShiftedImm.ShiftAmount;
798 Expr = ShiftedImm.Val;
799 if (Shift != 0 && Shift != 12)
805 AArch64MCExpr::VariantKind ELFRefKind;
806 MCSymbolRefExpr::VariantKind DarwinRefKind;
808 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
809 DarwinRefKind, Addend)) {
810 return DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF
811 || DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF
812 || (DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGEOFF && Addend == 0)
813 || ELFRefKind == AArch64MCExpr::VK_LO12
814 || ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12
815 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12
816 || ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC
817 || ELFRefKind == AArch64MCExpr::VK_TPREL_HI12
818 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12
819 || ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC
820 || ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12
821 || ELFRefKind == AArch64MCExpr::VK_SECREL_HI12
822 || ELFRefKind == AArch64MCExpr::VK_SECREL_LO12;
825 // If it's a constant, it should be a real immediate in range.
826 if (auto ShiftedVal = getShiftedVal<12>())
827 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
829 // If it's an expression, we hope for the best and let the fixup/relocation
830 // code deal with it.
834 bool isAddSubImmNeg() const {
835 if (!isShiftedImm() && !isImm())
838 // Otherwise it should be a real negative immediate in range.
839 if (auto ShiftedVal = getShiftedVal<12>())
840 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
845 // Signed value in the range -128 to +127. For element widths of
846 // 16 bits or higher it may also be a signed multiple of 256 in the
847 // range -32768 to +32512.
848 // For element-width of 8 bits a range of -128 to 255 is accepted,
849 // since a copy of a byte can be either signed/unsigned.
850 template <typename T>
851 DiagnosticPredicate isSVECpyImm() const {
852 if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
853 return DiagnosticPredicateTy::NoMatch;
856 std::is_same<int8_t, typename std::make_signed<T>::type>::value;
857 if (auto ShiftedImm = getShiftedVal<8>())
858 if (!(IsByte && ShiftedImm->second) &&
859 AArch64_AM::isSVECpyImm<T>(uint64_t(ShiftedImm->first)
860 << ShiftedImm->second))
861 return DiagnosticPredicateTy::Match;
863 return DiagnosticPredicateTy::NearMatch;
866 // Unsigned value in the range 0 to 255. For element widths of
867 // 16 bits or higher it may also be a signed multiple of 256 in the
869 template <typename T> DiagnosticPredicate isSVEAddSubImm() const {
870 if (!isShiftedImm() && (!isImm() || !isa<MCConstantExpr>(getImm())))
871 return DiagnosticPredicateTy::NoMatch;
874 std::is_same<int8_t, typename std::make_signed<T>::type>::value;
875 if (auto ShiftedImm = getShiftedVal<8>())
876 if (!(IsByte && ShiftedImm->second) &&
877 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
878 << ShiftedImm->second))
879 return DiagnosticPredicateTy::Match;
881 return DiagnosticPredicateTy::NearMatch;
884 template <typename T> DiagnosticPredicate isSVEPreferredLogicalImm() const {
885 if (isLogicalImm<T>() && !isSVECpyImm<T>())
886 return DiagnosticPredicateTy::Match;
887 return DiagnosticPredicateTy::NoMatch;
890 bool isCondCode() const { return Kind == k_CondCode; }
892 bool isSIMDImmType10() const {
895 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
898 return AArch64_AM::isAdvSIMDModImmType10(MCE->getValue());
902 bool isBranchTarget() const {
905 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
908 int64_t Val = MCE->getValue();
911 assert(N > 0 && "Branch target immediate cannot be 0 bits!");
912 return (Val >= -((1<<(N-1)) << 2) && Val <= (((1<<(N-1))-1) << 2));
916 isMovWSymbol(ArrayRef<AArch64MCExpr::VariantKind> AllowedModifiers) const {
920 AArch64MCExpr::VariantKind ELFRefKind;
921 MCSymbolRefExpr::VariantKind DarwinRefKind;
923 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
924 DarwinRefKind, Addend)) {
927 if (DarwinRefKind != MCSymbolRefExpr::VK_None)
930 for (unsigned i = 0; i != AllowedModifiers.size(); ++i) {
931 if (ELFRefKind == AllowedModifiers[i])
938 bool isMovZSymbolG3() const {
939 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
942 bool isMovZSymbolG2() const {
943 return isMovWSymbol({AArch64MCExpr::VK_ABS_G2, AArch64MCExpr::VK_ABS_G2_S,
944 AArch64MCExpr::VK_TPREL_G2,
945 AArch64MCExpr::VK_DTPREL_G2});
948 bool isMovZSymbolG1() const {
949 return isMovWSymbol({
950 AArch64MCExpr::VK_ABS_G1, AArch64MCExpr::VK_ABS_G1_S,
951 AArch64MCExpr::VK_GOTTPREL_G1, AArch64MCExpr::VK_TPREL_G1,
952 AArch64MCExpr::VK_DTPREL_G1,
956 bool isMovZSymbolG0() const {
957 return isMovWSymbol({AArch64MCExpr::VK_ABS_G0, AArch64MCExpr::VK_ABS_G0_S,
958 AArch64MCExpr::VK_TPREL_G0,
959 AArch64MCExpr::VK_DTPREL_G0});
962 bool isMovKSymbolG3() const {
963 return isMovWSymbol(AArch64MCExpr::VK_ABS_G3);
966 bool isMovKSymbolG2() const {
967 return isMovWSymbol(AArch64MCExpr::VK_ABS_G2_NC);
970 bool isMovKSymbolG1() const {
971 return isMovWSymbol({AArch64MCExpr::VK_ABS_G1_NC,
972 AArch64MCExpr::VK_TPREL_G1_NC,
973 AArch64MCExpr::VK_DTPREL_G1_NC});
976 bool isMovKSymbolG0() const {
978 {AArch64MCExpr::VK_ABS_G0_NC, AArch64MCExpr::VK_GOTTPREL_G0_NC,
979 AArch64MCExpr::VK_TPREL_G0_NC, AArch64MCExpr::VK_DTPREL_G0_NC});
982 template<int RegWidth, int Shift>
983 bool isMOVZMovAlias() const {
984 if (!isImm()) return false;
986 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
987 if (!CE) return false;
988 uint64_t Value = CE->getValue();
990 return AArch64_AM::isMOVZMovAlias(Value, Shift, RegWidth);
993 template<int RegWidth, int Shift>
994 bool isMOVNMovAlias() const {
995 if (!isImm()) return false;
997 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
998 if (!CE) return false;
999 uint64_t Value = CE->getValue();
1001 return AArch64_AM::isMOVNMovAlias(Value, Shift, RegWidth);
1004 bool isFPImm() const {
1005 return Kind == k_FPImm &&
1006 AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt()) != -1;
1009 bool isBarrier() const { return Kind == k_Barrier; }
1010 bool isSysReg() const { return Kind == k_SysReg; }
1012 bool isMRSSystemRegister() const {
1013 if (!isSysReg()) return false;
1015 return SysReg.MRSReg != -1U;
1018 bool isMSRSystemRegister() const {
1019 if (!isSysReg()) return false;
1020 return SysReg.MSRReg != -1U;
1023 bool isSystemPStateFieldWithImm0_1() const {
1024 if (!isSysReg()) return false;
1025 return (SysReg.PStateField == AArch64PState::PAN ||
1026 SysReg.PStateField == AArch64PState::DIT ||
1027 SysReg.PStateField == AArch64PState::UAO ||
1028 SysReg.PStateField == AArch64PState::SSBS);
1031 bool isSystemPStateFieldWithImm0_15() const {
1032 if (!isSysReg() || isSystemPStateFieldWithImm0_1()) return false;
1033 return SysReg.PStateField != -1U;
1036 bool isReg() const override {
1037 return Kind == k_Register;
1040 bool isScalarReg() const {
1041 return Kind == k_Register && Reg.Kind == RegKind::Scalar;
1044 bool isNeonVectorReg() const {
1045 return Kind == k_Register && Reg.Kind == RegKind::NeonVector;
1048 bool isNeonVectorRegLo() const {
1049 return Kind == k_Register && Reg.Kind == RegKind::NeonVector &&
1050 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1054 template <unsigned Class> bool isSVEVectorReg() const {
1057 case AArch64::ZPRRegClassID:
1058 case AArch64::ZPR_3bRegClassID:
1059 case AArch64::ZPR_4bRegClassID:
1060 RK = RegKind::SVEDataVector;
1062 case AArch64::PPRRegClassID:
1063 case AArch64::PPR_3bRegClassID:
1064 RK = RegKind::SVEPredicateVector;
1067 llvm_unreachable("Unsupport register class");
1070 return (Kind == k_Register && Reg.Kind == RK) &&
1071 AArch64MCRegisterClasses[Class].contains(getReg());
1074 template <unsigned Class> bool isFPRasZPR() const {
1075 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1076 AArch64MCRegisterClasses[Class].contains(getReg());
1079 template <int ElementWidth, unsigned Class>
1080 DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const {
1081 if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector)
1082 return DiagnosticPredicateTy::NoMatch;
1084 if (isSVEVectorReg<Class>() && (Reg.ElementWidth == ElementWidth))
1085 return DiagnosticPredicateTy::Match;
1087 return DiagnosticPredicateTy::NearMatch;
1090 template <int ElementWidth, unsigned Class>
1091 DiagnosticPredicate isSVEDataVectorRegOfWidth() const {
1092 if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector)
1093 return DiagnosticPredicateTy::NoMatch;
1095 if (isSVEVectorReg<Class>() && Reg.ElementWidth == ElementWidth)
1096 return DiagnosticPredicateTy::Match;
1098 return DiagnosticPredicateTy::NearMatch;
1101 template <int ElementWidth, unsigned Class,
1102 AArch64_AM::ShiftExtendType ShiftExtendTy, int ShiftWidth,
1103 bool ShiftWidthAlwaysSame>
1104 DiagnosticPredicate isSVEDataVectorRegWithShiftExtend() const {
1105 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1106 if (!VectorMatch.isMatch())
1107 return DiagnosticPredicateTy::NoMatch;
1109 // Give a more specific diagnostic when the user has explicitly typed in
1110 // a shift-amount that does not match what is expected, but for which
1111 // there is also an unscaled addressing mode (e.g. sxtw/uxtw).
1112 bool MatchShift = getShiftExtendAmount() == Log2_32(ShiftWidth / 8);
1113 if (!MatchShift && (ShiftExtendTy == AArch64_AM::UXTW ||
1114 ShiftExtendTy == AArch64_AM::SXTW) &&
1115 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1116 return DiagnosticPredicateTy::NoMatch;
1118 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1119 return DiagnosticPredicateTy::Match;
1121 return DiagnosticPredicateTy::NearMatch;
1124 bool isGPR32as64() const {
1125 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1126 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
1129 bool isGPR64as32() const {
1130 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1131 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(Reg.RegNum);
1134 bool isWSeqPair() const {
1135 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1136 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1140 bool isXSeqPair() const {
1141 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1142 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1146 template<int64_t Angle, int64_t Remainder>
1147 DiagnosticPredicate isComplexRotation() const {
1148 if (!isImm()) return DiagnosticPredicateTy::NoMatch;
1150 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
1151 if (!CE) return DiagnosticPredicateTy::NoMatch;
1152 uint64_t Value = CE->getValue();
1154 if (Value % Angle == Remainder && Value <= 270)
1155 return DiagnosticPredicateTy::Match;
1156 return DiagnosticPredicateTy::NearMatch;
1159 template <unsigned RegClassID> bool isGPR64() const {
1160 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
1161 AArch64MCRegisterClasses[RegClassID].contains(getReg());
1164 template <unsigned RegClassID, int ExtWidth>
1165 DiagnosticPredicate isGPR64WithShiftExtend() const {
1166 if (Kind != k_Register || Reg.Kind != RegKind::Scalar)
1167 return DiagnosticPredicateTy::NoMatch;
1169 if (isGPR64<RegClassID>() && getShiftExtendType() == AArch64_AM::LSL &&
1170 getShiftExtendAmount() == Log2_32(ExtWidth / 8))
1171 return DiagnosticPredicateTy::Match;
1172 return DiagnosticPredicateTy::NearMatch;
1175 /// Is this a vector list with the type implicit (presumably attached to the
1176 /// instruction itself)?
1177 template <RegKind VectorKind, unsigned NumRegs>
1178 bool isImplicitlyTypedVectorList() const {
1179 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1180 VectorList.NumElements == 0 &&
1181 VectorList.RegisterKind == VectorKind;
1184 template <RegKind VectorKind, unsigned NumRegs, unsigned NumElements,
1185 unsigned ElementWidth>
1186 bool isTypedVectorList() const {
1187 if (Kind != k_VectorList)
1189 if (VectorList.Count != NumRegs)
1191 if (VectorList.RegisterKind != VectorKind)
1193 if (VectorList.ElementWidth != ElementWidth)
1195 return VectorList.NumElements == NumElements;
1198 template <int Min, int Max>
1199 DiagnosticPredicate isVectorIndex() const {
1200 if (Kind != k_VectorIndex)
1201 return DiagnosticPredicateTy::NoMatch;
1202 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1203 return DiagnosticPredicateTy::Match;
1204 return DiagnosticPredicateTy::NearMatch;
1207 bool isToken() const override { return Kind == k_Token; }
1209 bool isTokenEqual(StringRef Str) const {
1210 return Kind == k_Token && getToken() == Str;
1212 bool isSysCR() const { return Kind == k_SysCR; }
1213 bool isPrefetch() const { return Kind == k_Prefetch; }
1214 bool isPSBHint() const { return Kind == k_PSBHint; }
1215 bool isBTIHint() const { return Kind == k_BTIHint; }
1216 bool isShiftExtend() const { return Kind == k_ShiftExtend; }
1217 bool isShifter() const {
1218 if (!isShiftExtend())
1221 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1222 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1223 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR ||
1224 ST == AArch64_AM::MSL);
1227 template <unsigned ImmEnum> DiagnosticPredicate isExactFPImm() const {
1228 if (Kind != k_FPImm)
1229 return DiagnosticPredicateTy::NoMatch;
1231 if (getFPImmIsExact()) {
1232 // Lookup the immediate from table of supported immediates.
1233 auto *Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1234 assert(Desc && "Unknown enum value");
1236 // Calculate its FP value.
1237 APFloat RealVal(APFloat::IEEEdouble());
1238 if (RealVal.convertFromString(Desc->Repr, APFloat::rmTowardZero) !=
1240 llvm_unreachable("FP immediate is not exact");
1242 if (getFPImm().bitwiseIsEqual(RealVal))
1243 return DiagnosticPredicateTy::Match;
1246 return DiagnosticPredicateTy::NearMatch;
1249 template <unsigned ImmA, unsigned ImmB>
1250 DiagnosticPredicate isExactFPImm() const {
1251 DiagnosticPredicate Res = DiagnosticPredicateTy::NoMatch;
1252 if ((Res = isExactFPImm<ImmA>()))
1253 return DiagnosticPredicateTy::Match;
1254 if ((Res = isExactFPImm<ImmB>()))
1255 return DiagnosticPredicateTy::Match;
1259 bool isExtend() const {
1260 if (!isShiftExtend())
1263 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1264 return (ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
1265 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
1266 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW ||
1267 ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
1268 ET == AArch64_AM::LSL) &&
1269 getShiftExtendAmount() <= 4;
1272 bool isExtend64() const {
1275 // Make sure the extend expects a 32-bit source register.
1276 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1277 return ET == AArch64_AM::UXTB || ET == AArch64_AM::SXTB ||
1278 ET == AArch64_AM::UXTH || ET == AArch64_AM::SXTH ||
1279 ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW;
1282 bool isExtendLSL64() const {
1285 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1286 return (ET == AArch64_AM::UXTX || ET == AArch64_AM::SXTX ||
1287 ET == AArch64_AM::LSL) &&
1288 getShiftExtendAmount() <= 4;
1291 template<int Width> bool isMemXExtend() const {
1294 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1295 return (ET == AArch64_AM::LSL || ET == AArch64_AM::SXTX) &&
1296 (getShiftExtendAmount() == Log2_32(Width / 8) ||
1297 getShiftExtendAmount() == 0);
1300 template<int Width> bool isMemWExtend() const {
1303 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1304 return (ET == AArch64_AM::UXTW || ET == AArch64_AM::SXTW) &&
1305 (getShiftExtendAmount() == Log2_32(Width / 8) ||
1306 getShiftExtendAmount() == 0);
1309 template <unsigned width>
1310 bool isArithmeticShifter() const {
1314 // An arithmetic shifter is LSL, LSR, or ASR.
1315 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1316 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1317 ST == AArch64_AM::ASR) && getShiftExtendAmount() < width;
1320 template <unsigned width>
1321 bool isLogicalShifter() const {
1325 // A logical shifter is LSL, LSR, ASR or ROR.
1326 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1327 return (ST == AArch64_AM::LSL || ST == AArch64_AM::LSR ||
1328 ST == AArch64_AM::ASR || ST == AArch64_AM::ROR) &&
1329 getShiftExtendAmount() < width;
1332 bool isMovImm32Shifter() const {
1336 // A MOVi shifter is LSL of 0, 16, 32, or 48.
1337 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1338 if (ST != AArch64_AM::LSL)
1340 uint64_t Val = getShiftExtendAmount();
1341 return (Val == 0 || Val == 16);
1344 bool isMovImm64Shifter() const {
1348 // A MOVi shifter is LSL of 0 or 16.
1349 AArch64_AM::ShiftExtendType ST = getShiftExtendType();
1350 if (ST != AArch64_AM::LSL)
1352 uint64_t Val = getShiftExtendAmount();
1353 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1356 bool isLogicalVecShifter() const {
1360 // A logical vector shifter is a left shift by 0, 8, 16, or 24.
1361 unsigned Shift = getShiftExtendAmount();
1362 return getShiftExtendType() == AArch64_AM::LSL &&
1363 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1366 bool isLogicalVecHalfWordShifter() const {
1367 if (!isLogicalVecShifter())
1370 // A logical vector shifter is a left shift by 0 or 8.
1371 unsigned Shift = getShiftExtendAmount();
1372 return getShiftExtendType() == AArch64_AM::LSL &&
1373 (Shift == 0 || Shift == 8);
1376 bool isMoveVecShifter() const {
1377 if (!isShiftExtend())
1380 // A logical vector shifter is a left shift by 8 or 16.
1381 unsigned Shift = getShiftExtendAmount();
1382 return getShiftExtendType() == AArch64_AM::MSL &&
1383 (Shift == 8 || Shift == 16);
1386 // Fallback unscaled operands are for aliases of LDR/STR that fall back
1387 // to LDUR/STUR when the offset is not legal for the former but is for
1388 // the latter. As such, in addition to checking for being a legal unscaled
1389 // address, also check that it is not a legal scaled address. This avoids
1390 // ambiguity in the matcher.
1392 bool isSImm9OffsetFB() const {
1393 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1396 bool isAdrpLabel() const {
1397 // Validation was handled during parsing, so we just sanity check that
1398 // something didn't go haywire.
1402 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1403 int64_t Val = CE->getValue();
1404 int64_t Min = - (4096 * (1LL << (21 - 1)));
1405 int64_t Max = 4096 * ((1LL << (21 - 1)) - 1);
1406 return (Val % 4096) == 0 && Val >= Min && Val <= Max;
1412 bool isAdrLabel() const {
1413 // Validation was handled during parsing, so we just sanity check that
1414 // something didn't go haywire.
1418 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1419 int64_t Val = CE->getValue();
1420 int64_t Min = - (1LL << (21 - 1));
1421 int64_t Max = ((1LL << (21 - 1)) - 1);
1422 return Val >= Min && Val <= Max;
1428 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1429 // Add as immediates when possible. Null MCExpr = 0.
1431 Inst.addOperand(MCOperand::createImm(0));
1432 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1433 Inst.addOperand(MCOperand::createImm(CE->getValue()));
1435 Inst.addOperand(MCOperand::createExpr(Expr));
1438 void addRegOperands(MCInst &Inst, unsigned N) const {
1439 assert(N == 1 && "Invalid number of operands!");
1440 Inst.addOperand(MCOperand::createReg(getReg()));
1443 void addGPR32as64Operands(MCInst &Inst, unsigned N) const {
1444 assert(N == 1 && "Invalid number of operands!");
1446 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(getReg()));
1448 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1449 uint32_t Reg = RI->getRegClass(AArch64::GPR32RegClassID).getRegister(
1450 RI->getEncodingValue(getReg()));
1452 Inst.addOperand(MCOperand::createReg(Reg));
1455 void addGPR64as32Operands(MCInst &Inst, unsigned N) const {
1456 assert(N == 1 && "Invalid number of operands!");
1458 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(getReg()));
1460 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
1461 uint32_t Reg = RI->getRegClass(AArch64::GPR64RegClassID).getRegister(
1462 RI->getEncodingValue(getReg()));
1464 Inst.addOperand(MCOperand::createReg(Reg));
1467 template <int Width>
1468 void addFPRasZPRRegOperands(MCInst &Inst, unsigned N) const {
1471 case 8: Base = AArch64::B0; break;
1472 case 16: Base = AArch64::H0; break;
1473 case 32: Base = AArch64::S0; break;
1474 case 64: Base = AArch64::D0; break;
1475 case 128: Base = AArch64::Q0; break;
1477 llvm_unreachable("Unsupported width");
1479 Inst.addOperand(MCOperand::createReg(AArch64::Z0 + getReg() - Base));
1482 void addVectorReg64Operands(MCInst &Inst, unsigned N) const {
1483 assert(N == 1 && "Invalid number of operands!");
1485 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1486 Inst.addOperand(MCOperand::createReg(AArch64::D0 + getReg() - AArch64::Q0));
1489 void addVectorReg128Operands(MCInst &Inst, unsigned N) const {
1490 assert(N == 1 && "Invalid number of operands!");
1492 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].contains(getReg()));
1493 Inst.addOperand(MCOperand::createReg(getReg()));
1496 void addVectorRegLoOperands(MCInst &Inst, unsigned N) const {
1497 assert(N == 1 && "Invalid number of operands!");
1498 Inst.addOperand(MCOperand::createReg(getReg()));
1501 enum VecListIndexType {
1502 VecListIdx_DReg = 0,
1503 VecListIdx_QReg = 1,
1504 VecListIdx_ZReg = 2,
1507 template <VecListIndexType RegTy, unsigned NumRegs>
1508 void addVectorListOperands(MCInst &Inst, unsigned N) const {
1509 assert(N == 1 && "Invalid number of operands!");
1510 static const unsigned FirstRegs[][5] = {
1511 /* DReg */ { AArch64::Q0,
1512 AArch64::D0, AArch64::D0_D1,
1513 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1514 /* QReg */ { AArch64::Q0,
1515 AArch64::Q0, AArch64::Q0_Q1,
1516 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1517 /* ZReg */ { AArch64::Z0,
1518 AArch64::Z0, AArch64::Z0_Z1,
1519 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 }
1522 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1523 " NumRegs must be <= 4 for ZRegs");
1525 unsigned FirstReg = FirstRegs[(unsigned)RegTy][NumRegs];
1526 Inst.addOperand(MCOperand::createReg(FirstReg + getVectorListStart() -
1527 FirstRegs[(unsigned)RegTy][0]));
1530 void addVectorIndexOperands(MCInst &Inst, unsigned N) const {
1531 assert(N == 1 && "Invalid number of operands!");
1532 Inst.addOperand(MCOperand::createImm(getVectorIndex()));
1535 template <unsigned ImmIs0, unsigned ImmIs1>
1536 void addExactFPImmOperands(MCInst &Inst, unsigned N) const {
1537 assert(N == 1 && "Invalid number of operands!");
1538 assert(bool(isExactFPImm<ImmIs0, ImmIs1>()) && "Invalid operand");
1539 Inst.addOperand(MCOperand::createImm(bool(isExactFPImm<ImmIs1>())));
1542 void addImmOperands(MCInst &Inst, unsigned N) const {
1543 assert(N == 1 && "Invalid number of operands!");
1544 // If this is a pageoff symrefexpr with an addend, adjust the addend
1545 // to be only the page-offset portion. Otherwise, just add the expr
1547 addExpr(Inst, getImm());
1550 template <int Shift>
1551 void addImmWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
1552 assert(N == 2 && "Invalid number of operands!");
1553 if (auto ShiftedVal = getShiftedVal<Shift>()) {
1554 Inst.addOperand(MCOperand::createImm(ShiftedVal->first));
1555 Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
1556 } else if (isShiftedImm()) {
1557 addExpr(Inst, getShiftedImmVal());
1558 Inst.addOperand(MCOperand::createImm(getShiftedImmShift()));
1560 addExpr(Inst, getImm());
1561 Inst.addOperand(MCOperand::createImm(0));
1565 template <int Shift>
1566 void addImmNegWithOptionalShiftOperands(MCInst &Inst, unsigned N) const {
1567 assert(N == 2 && "Invalid number of operands!");
1568 if (auto ShiftedVal = getShiftedVal<Shift>()) {
1569 Inst.addOperand(MCOperand::createImm(-ShiftedVal->first));
1570 Inst.addOperand(MCOperand::createImm(ShiftedVal->second));
1572 llvm_unreachable("Not a shifted negative immediate");
1575 void addCondCodeOperands(MCInst &Inst, unsigned N) const {
1576 assert(N == 1 && "Invalid number of operands!");
1577 Inst.addOperand(MCOperand::createImm(getCondCode()));
1580 void addAdrpLabelOperands(MCInst &Inst, unsigned N) const {
1581 assert(N == 1 && "Invalid number of operands!");
1582 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1584 addExpr(Inst, getImm());
1586 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 12));
1589 void addAdrLabelOperands(MCInst &Inst, unsigned N) const {
1590 addImmOperands(Inst, N);
1594 void addUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
1595 assert(N == 1 && "Invalid number of operands!");
1596 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1599 Inst.addOperand(MCOperand::createExpr(getImm()));
1602 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1605 void addUImm6Operands(MCInst &Inst, unsigned N) const {
1606 assert(N == 1 && "Invalid number of operands!");
1607 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1608 Inst.addOperand(MCOperand::createImm(MCE->getValue()));
1611 template <int Scale>
1612 void addImmScaledOperands(MCInst &Inst, unsigned N) const {
1613 assert(N == 1 && "Invalid number of operands!");
1614 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1615 Inst.addOperand(MCOperand::createImm(MCE->getValue() / Scale));
1618 template <typename T>
1619 void addLogicalImmOperands(MCInst &Inst, unsigned N) const {
1620 assert(N == 1 && "Invalid number of operands!");
1621 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1622 typename std::make_unsigned<T>::type Val = MCE->getValue();
1623 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
1624 Inst.addOperand(MCOperand::createImm(encoding));
1627 template <typename T>
1628 void addLogicalImmNotOperands(MCInst &Inst, unsigned N) const {
1629 assert(N == 1 && "Invalid number of operands!");
1630 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1631 typename std::make_unsigned<T>::type Val = ~MCE->getValue();
1632 uint64_t encoding = AArch64_AM::encodeLogicalImmediate(Val, sizeof(T) * 8);
1633 Inst.addOperand(MCOperand::createImm(encoding));
1636 void addSIMDImmType10Operands(MCInst &Inst, unsigned N) const {
1637 assert(N == 1 && "Invalid number of operands!");
1638 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1639 uint64_t encoding = AArch64_AM::encodeAdvSIMDModImmType10(MCE->getValue());
1640 Inst.addOperand(MCOperand::createImm(encoding));
1643 void addBranchTarget26Operands(MCInst &Inst, unsigned N) const {
1644 // Branch operands don't encode the low bits, so shift them off
1645 // here. If it's a label, however, just put it on directly as there's
1646 // not enough information now to do anything.
1647 assert(N == 1 && "Invalid number of operands!");
1648 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1650 addExpr(Inst, getImm());
1653 assert(MCE && "Invalid constant immediate operand!");
1654 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1657 void addPCRelLabel19Operands(MCInst &Inst, unsigned N) const {
1658 // Branch operands don't encode the low bits, so shift them off
1659 // here. If it's a label, however, just put it on directly as there's
1660 // not enough information now to do anything.
1661 assert(N == 1 && "Invalid number of operands!");
1662 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1664 addExpr(Inst, getImm());
1667 assert(MCE && "Invalid constant immediate operand!");
1668 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1671 void addBranchTarget14Operands(MCInst &Inst, unsigned N) const {
1672 // Branch operands don't encode the low bits, so shift them off
1673 // here. If it's a label, however, just put it on directly as there's
1674 // not enough information now to do anything.
1675 assert(N == 1 && "Invalid number of operands!");
1676 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(getImm());
1678 addExpr(Inst, getImm());
1681 assert(MCE && "Invalid constant immediate operand!");
1682 Inst.addOperand(MCOperand::createImm(MCE->getValue() >> 2));
1685 void addFPImmOperands(MCInst &Inst, unsigned N) const {
1686 assert(N == 1 && "Invalid number of operands!");
1687 Inst.addOperand(MCOperand::createImm(
1688 AArch64_AM::getFP64Imm(getFPImm().bitcastToAPInt())));
1691 void addBarrierOperands(MCInst &Inst, unsigned N) const {
1692 assert(N == 1 && "Invalid number of operands!");
1693 Inst.addOperand(MCOperand::createImm(getBarrier()));
1696 void addMRSSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1697 assert(N == 1 && "Invalid number of operands!");
1699 Inst.addOperand(MCOperand::createImm(SysReg.MRSReg));
1702 void addMSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1703 assert(N == 1 && "Invalid number of operands!");
1705 Inst.addOperand(MCOperand::createImm(SysReg.MSRReg));
1708 void addSystemPStateFieldWithImm0_1Operands(MCInst &Inst, unsigned N) const {
1709 assert(N == 1 && "Invalid number of operands!");
1711 Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1714 void addSystemPStateFieldWithImm0_15Operands(MCInst &Inst, unsigned N) const {
1715 assert(N == 1 && "Invalid number of operands!");
1717 Inst.addOperand(MCOperand::createImm(SysReg.PStateField));
1720 void addSysCROperands(MCInst &Inst, unsigned N) const {
1721 assert(N == 1 && "Invalid number of operands!");
1722 Inst.addOperand(MCOperand::createImm(getSysCR()));
1725 void addPrefetchOperands(MCInst &Inst, unsigned N) const {
1726 assert(N == 1 && "Invalid number of operands!");
1727 Inst.addOperand(MCOperand::createImm(getPrefetch()));
1730 void addPSBHintOperands(MCInst &Inst, unsigned N) const {
1731 assert(N == 1 && "Invalid number of operands!");
1732 Inst.addOperand(MCOperand::createImm(getPSBHint()));
1735 void addBTIHintOperands(MCInst &Inst, unsigned N) const {
1736 assert(N == 1 && "Invalid number of operands!");
1737 Inst.addOperand(MCOperand::createImm(getBTIHint()));
1740 void addShifterOperands(MCInst &Inst, unsigned N) const {
1741 assert(N == 1 && "Invalid number of operands!");
1743 AArch64_AM::getShifterImm(getShiftExtendType(), getShiftExtendAmount());
1744 Inst.addOperand(MCOperand::createImm(Imm));
1747 void addExtendOperands(MCInst &Inst, unsigned N) const {
1748 assert(N == 1 && "Invalid number of operands!");
1749 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1750 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTW;
1751 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1752 Inst.addOperand(MCOperand::createImm(Imm));
1755 void addExtend64Operands(MCInst &Inst, unsigned N) const {
1756 assert(N == 1 && "Invalid number of operands!");
1757 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1758 if (ET == AArch64_AM::LSL) ET = AArch64_AM::UXTX;
1759 unsigned Imm = AArch64_AM::getArithExtendImm(ET, getShiftExtendAmount());
1760 Inst.addOperand(MCOperand::createImm(Imm));
1763 void addMemExtendOperands(MCInst &Inst, unsigned N) const {
1764 assert(N == 2 && "Invalid number of operands!");
1765 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1766 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1767 Inst.addOperand(MCOperand::createImm(IsSigned));
1768 Inst.addOperand(MCOperand::createImm(getShiftExtendAmount() != 0));
1771 // For 8-bit load/store instructions with a register offset, both the
1772 // "DoShift" and "NoShift" variants have a shift of 0. Because of this,
1773 // they're disambiguated by whether the shift was explicit or implicit rather
1775 void addMemExtend8Operands(MCInst &Inst, unsigned N) const {
1776 assert(N == 2 && "Invalid number of operands!");
1777 AArch64_AM::ShiftExtendType ET = getShiftExtendType();
1778 bool IsSigned = ET == AArch64_AM::SXTW || ET == AArch64_AM::SXTX;
1779 Inst.addOperand(MCOperand::createImm(IsSigned));
1780 Inst.addOperand(MCOperand::createImm(hasShiftExtendAmount()));
1784 void addMOVZMovAliasOperands(MCInst &Inst, unsigned N) const {
1785 assert(N == 1 && "Invalid number of operands!");
1787 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1788 uint64_t Value = CE->getValue();
1789 Inst.addOperand(MCOperand::createImm((Value >> Shift) & 0xffff));
1793 void addMOVNMovAliasOperands(MCInst &Inst, unsigned N) const {
1794 assert(N == 1 && "Invalid number of operands!");
1796 const MCConstantExpr *CE = cast<MCConstantExpr>(getImm());
1797 uint64_t Value = CE->getValue();
1798 Inst.addOperand(MCOperand::createImm((~Value >> Shift) & 0xffff));
1801 void addComplexRotationEvenOperands(MCInst &Inst, unsigned N) const {
1802 assert(N == 1 && "Invalid number of operands!");
1803 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1804 Inst.addOperand(MCOperand::createImm(MCE->getValue() / 90));
1807 void addComplexRotationOddOperands(MCInst &Inst, unsigned N) const {
1808 assert(N == 1 && "Invalid number of operands!");
1809 const MCConstantExpr *MCE = cast<MCConstantExpr>(getImm());
1810 Inst.addOperand(MCOperand::createImm((MCE->getValue() - 90) / 180));
1813 void print(raw_ostream &OS) const override;
1815 static std::unique_ptr<AArch64Operand>
1816 CreateToken(StringRef Str, bool IsSuffix, SMLoc S, MCContext &Ctx) {
1817 auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1818 Op->Tok.Data = Str.data();
1819 Op->Tok.Length = Str.size();
1820 Op->Tok.IsSuffix = IsSuffix;
1826 static std::unique_ptr<AArch64Operand>
1827 CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx,
1828 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
1829 AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL,
1830 unsigned ShiftAmount = 0,
1831 unsigned HasExplicitAmount = false) {
1832 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1833 Op->Reg.RegNum = RegNum;
1834 Op->Reg.Kind = Kind;
1835 Op->Reg.ElementWidth = 0;
1836 Op->Reg.EqualityTy = EqTy;
1837 Op->Reg.ShiftExtend.Type = ExtTy;
1838 Op->Reg.ShiftExtend.Amount = ShiftAmount;
1839 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1845 static std::unique_ptr<AArch64Operand>
1846 CreateVectorReg(unsigned RegNum, RegKind Kind, unsigned ElementWidth,
1847 SMLoc S, SMLoc E, MCContext &Ctx,
1848 AArch64_AM::ShiftExtendType ExtTy = AArch64_AM::LSL,
1849 unsigned ShiftAmount = 0,
1850 unsigned HasExplicitAmount = false) {
1851 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
1852 Kind == RegKind::SVEPredicateVector) &&
1853 "Invalid vector kind");
1854 auto Op = CreateReg(RegNum, Kind, S, E, Ctx, EqualsReg, ExtTy, ShiftAmount,
1856 Op->Reg.ElementWidth = ElementWidth;
1860 static std::unique_ptr<AArch64Operand>
1861 CreateVectorList(unsigned RegNum, unsigned Count, unsigned NumElements,
1862 unsigned ElementWidth, RegKind RegisterKind, SMLoc S, SMLoc E,
1864 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1865 Op->VectorList.RegNum = RegNum;
1866 Op->VectorList.Count = Count;
1867 Op->VectorList.NumElements = NumElements;
1868 Op->VectorList.ElementWidth = ElementWidth;
1869 Op->VectorList.RegisterKind = RegisterKind;
1875 static std::unique_ptr<AArch64Operand>
1876 CreateVectorIndex(unsigned Idx, SMLoc S, SMLoc E, MCContext &Ctx) {
1877 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1878 Op->VectorIndex.Val = Idx;
1884 static std::unique_ptr<AArch64Operand> CreateImm(const MCExpr *Val, SMLoc S,
1885 SMLoc E, MCContext &Ctx) {
1886 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1893 static std::unique_ptr<AArch64Operand> CreateShiftedImm(const MCExpr *Val,
1894 unsigned ShiftAmount,
1897 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1898 Op->ShiftedImm .Val = Val;
1899 Op->ShiftedImm.ShiftAmount = ShiftAmount;
1905 static std::unique_ptr<AArch64Operand>
1906 CreateCondCode(AArch64CC::CondCode Code, SMLoc S, SMLoc E, MCContext &Ctx) {
1907 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1908 Op->CondCode.Code = Code;
1914 static std::unique_ptr<AArch64Operand>
1915 CreateFPImm(APFloat Val, bool IsExact, SMLoc S, MCContext &Ctx) {
1916 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1917 Op->FPImm.Val = Val.bitcastToAPInt().getSExtValue();
1918 Op->FPImm.IsExact = IsExact;
1924 static std::unique_ptr<AArch64Operand> CreateBarrier(unsigned Val,
1928 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1929 Op->Barrier.Val = Val;
1930 Op->Barrier.Data = Str.data();
1931 Op->Barrier.Length = Str.size();
1937 static std::unique_ptr<AArch64Operand> CreateSysReg(StringRef Str, SMLoc S,
1940 uint32_t PStateField,
1942 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1943 Op->SysReg.Data = Str.data();
1944 Op->SysReg.Length = Str.size();
1945 Op->SysReg.MRSReg = MRSReg;
1946 Op->SysReg.MSRReg = MSRReg;
1947 Op->SysReg.PStateField = PStateField;
1953 static std::unique_ptr<AArch64Operand> CreateSysCR(unsigned Val, SMLoc S,
1954 SMLoc E, MCContext &Ctx) {
1955 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1956 Op->SysCRImm.Val = Val;
1962 static std::unique_ptr<AArch64Operand> CreatePrefetch(unsigned Val,
1966 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1967 Op->Prefetch.Val = Val;
1968 Op->Barrier.Data = Str.data();
1969 Op->Barrier.Length = Str.size();
1975 static std::unique_ptr<AArch64Operand> CreatePSBHint(unsigned Val,
1979 auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx);
1980 Op->PSBHint.Val = Val;
1981 Op->PSBHint.Data = Str.data();
1982 Op->PSBHint.Length = Str.size();
1988 static std::unique_ptr<AArch64Operand> CreateBTIHint(unsigned Val,
1992 auto Op = make_unique<AArch64Operand>(k_BTIHint, Ctx);
1993 Op->BTIHint.Val = Val << 1 | 32;
1994 Op->BTIHint.Data = Str.data();
1995 Op->BTIHint.Length = Str.size();
2001 static std::unique_ptr<AArch64Operand>
2002 CreateShiftExtend(AArch64_AM::ShiftExtendType ShOp, unsigned Val,
2003 bool HasExplicitAmount, SMLoc S, SMLoc E, MCContext &Ctx) {
2004 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2005 Op->ShiftExtend.Type = ShOp;
2006 Op->ShiftExtend.Amount = Val;
2007 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2014 } // end anonymous namespace.
2016 void AArch64Operand::print(raw_ostream &OS) const {
2019 OS << "<fpimm " << getFPImm().bitcastToAPInt().getZExtValue();
2020 if (!getFPImmIsExact())
2025 StringRef Name = getBarrierName();
2027 OS << "<barrier " << Name << ">";
2029 OS << "<barrier invalid #" << getBarrier() << ">";
2035 case k_ShiftedImm: {
2036 unsigned Shift = getShiftedImmShift();
2037 OS << "<shiftedimm ";
2038 OS << *getShiftedImmVal();
2039 OS << ", lsl #" << AArch64_AM::getShiftValue(Shift) << ">";
2043 OS << "<condcode " << getCondCode() << ">";
2045 case k_VectorList: {
2046 OS << "<vectorlist ";
2047 unsigned Reg = getVectorListStart();
2048 for (unsigned i = 0, e = getVectorListCount(); i != e; ++i)
2049 OS << Reg + i << " ";
2054 OS << "<vectorindex " << getVectorIndex() << ">";
2057 OS << "<sysreg: " << getSysReg() << '>';
2060 OS << "'" << getToken() << "'";
2063 OS << "c" << getSysCR();
2066 StringRef Name = getPrefetchName();
2068 OS << "<prfop " << Name << ">";
2070 OS << "<prfop invalid #" << getPrefetch() << ">";
2074 OS << getPSBHintName();
2077 OS << "<register " << getReg() << ">";
2078 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2082 OS << getBTIHintName();
2085 OS << "<" << AArch64_AM::getShiftExtendName(getShiftExtendType()) << " #"
2086 << getShiftExtendAmount();
2087 if (!hasShiftExtendAmount())
2094 /// @name Auto-generated Match Functions
2097 static unsigned MatchRegisterName(StringRef Name);
2101 static unsigned MatchNeonVectorRegName(StringRef Name) {
2102 return StringSwitch<unsigned>(Name.lower())
2103 .Case("v0", AArch64::Q0)
2104 .Case("v1", AArch64::Q1)
2105 .Case("v2", AArch64::Q2)
2106 .Case("v3", AArch64::Q3)
2107 .Case("v4", AArch64::Q4)
2108 .Case("v5", AArch64::Q5)
2109 .Case("v6", AArch64::Q6)
2110 .Case("v7", AArch64::Q7)
2111 .Case("v8", AArch64::Q8)
2112 .Case("v9", AArch64::Q9)
2113 .Case("v10", AArch64::Q10)
2114 .Case("v11", AArch64::Q11)
2115 .Case("v12", AArch64::Q12)
2116 .Case("v13", AArch64::Q13)
2117 .Case("v14", AArch64::Q14)
2118 .Case("v15", AArch64::Q15)
2119 .Case("v16", AArch64::Q16)
2120 .Case("v17", AArch64::Q17)
2121 .Case("v18", AArch64::Q18)
2122 .Case("v19", AArch64::Q19)
2123 .Case("v20", AArch64::Q20)
2124 .Case("v21", AArch64::Q21)
2125 .Case("v22", AArch64::Q22)
2126 .Case("v23", AArch64::Q23)
2127 .Case("v24", AArch64::Q24)
2128 .Case("v25", AArch64::Q25)
2129 .Case("v26", AArch64::Q26)
2130 .Case("v27", AArch64::Q27)
2131 .Case("v28", AArch64::Q28)
2132 .Case("v29", AArch64::Q29)
2133 .Case("v30", AArch64::Q30)
2134 .Case("v31", AArch64::Q31)
2138 /// Returns an optional pair of (#elements, element-width) if Suffix
2139 /// is a valid vector kind. Where the number of elements in a vector
2140 /// or the vector width is implicit or explicitly unknown (but still a
2141 /// valid suffix kind), 0 is used.
2142 static Optional<std::pair<int, int>> parseVectorKind(StringRef Suffix,
2143 RegKind VectorKind) {
2144 std::pair<int, int> Res = {-1, -1};
2146 switch (VectorKind) {
2147 case RegKind::NeonVector:
2149 StringSwitch<std::pair<int, int>>(Suffix.lower())
2151 .Case(".1d", {1, 64})
2152 .Case(".1q", {1, 128})
2153 // '.2h' needed for fp16 scalar pairwise reductions
2154 .Case(".2h", {2, 16})
2155 .Case(".2s", {2, 32})
2156 .Case(".2d", {2, 64})
2157 // '.4b' is another special case for the ARMv8.2a dot product
2159 .Case(".4b", {4, 8})
2160 .Case(".4h", {4, 16})
2161 .Case(".4s", {4, 32})
2162 .Case(".8b", {8, 8})
2163 .Case(".8h", {8, 16})
2164 .Case(".16b", {16, 8})
2165 // Accept the width neutral ones, too, for verbose syntax. If those
2166 // aren't used in the right places, the token operand won't match so
2167 // all will work out.
2169 .Case(".h", {0, 16})
2170 .Case(".s", {0, 32})
2171 .Case(".d", {0, 64})
2174 case RegKind::SVEPredicateVector:
2175 case RegKind::SVEDataVector:
2176 Res = StringSwitch<std::pair<int, int>>(Suffix.lower())
2179 .Case(".h", {0, 16})
2180 .Case(".s", {0, 32})
2181 .Case(".d", {0, 64})
2182 .Case(".q", {0, 128})
2186 llvm_unreachable("Unsupported RegKind");
2189 if (Res == std::make_pair(-1, -1))
2190 return Optional<std::pair<int, int>>();
2192 return Optional<std::pair<int, int>>(Res);
2195 static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind) {
2196 return parseVectorKind(Suffix, VectorKind).hasValue();
2199 static unsigned matchSVEDataVectorRegName(StringRef Name) {
2200 return StringSwitch<unsigned>(Name.lower())
2201 .Case("z0", AArch64::Z0)
2202 .Case("z1", AArch64::Z1)
2203 .Case("z2", AArch64::Z2)
2204 .Case("z3", AArch64::Z3)
2205 .Case("z4", AArch64::Z4)
2206 .Case("z5", AArch64::Z5)
2207 .Case("z6", AArch64::Z6)
2208 .Case("z7", AArch64::Z7)
2209 .Case("z8", AArch64::Z8)
2210 .Case("z9", AArch64::Z9)
2211 .Case("z10", AArch64::Z10)
2212 .Case("z11", AArch64::Z11)
2213 .Case("z12", AArch64::Z12)
2214 .Case("z13", AArch64::Z13)
2215 .Case("z14", AArch64::Z14)
2216 .Case("z15", AArch64::Z15)
2217 .Case("z16", AArch64::Z16)
2218 .Case("z17", AArch64::Z17)
2219 .Case("z18", AArch64::Z18)
2220 .Case("z19", AArch64::Z19)
2221 .Case("z20", AArch64::Z20)
2222 .Case("z21", AArch64::Z21)
2223 .Case("z22", AArch64::Z22)
2224 .Case("z23", AArch64::Z23)
2225 .Case("z24", AArch64::Z24)
2226 .Case("z25", AArch64::Z25)
2227 .Case("z26", AArch64::Z26)
2228 .Case("z27", AArch64::Z27)
2229 .Case("z28", AArch64::Z28)
2230 .Case("z29", AArch64::Z29)
2231 .Case("z30", AArch64::Z30)
2232 .Case("z31", AArch64::Z31)
2236 static unsigned matchSVEPredicateVectorRegName(StringRef Name) {
2237 return StringSwitch<unsigned>(Name.lower())
2238 .Case("p0", AArch64::P0)
2239 .Case("p1", AArch64::P1)
2240 .Case("p2", AArch64::P2)
2241 .Case("p3", AArch64::P3)
2242 .Case("p4", AArch64::P4)
2243 .Case("p5", AArch64::P5)
2244 .Case("p6", AArch64::P6)
2245 .Case("p7", AArch64::P7)
2246 .Case("p8", AArch64::P8)
2247 .Case("p9", AArch64::P9)
2248 .Case("p10", AArch64::P10)
2249 .Case("p11", AArch64::P11)
2250 .Case("p12", AArch64::P12)
2251 .Case("p13", AArch64::P13)
2252 .Case("p14", AArch64::P14)
2253 .Case("p15", AArch64::P15)
2257 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2259 StartLoc = getLoc();
2260 auto Res = tryParseScalarRegister(RegNo);
2261 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2262 return Res != MatchOperand_Success;
2265 // Matches a register name or register alias previously defined by '.req'
2266 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2268 unsigned RegNum = 0;
2269 if ((RegNum = matchSVEDataVectorRegName(Name)))
2270 return Kind == RegKind::SVEDataVector ? RegNum : 0;
2272 if ((RegNum = matchSVEPredicateVectorRegName(Name)))
2273 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
2275 if ((RegNum = MatchNeonVectorRegName(Name)))
2276 return Kind == RegKind::NeonVector ? RegNum : 0;
2278 // The parsed register must be of RegKind Scalar
2279 if ((RegNum = MatchRegisterName(Name)))
2280 return Kind == RegKind::Scalar ? RegNum : 0;
2283 // Handle a few common aliases of registers.
2284 if (auto RegNum = StringSwitch<unsigned>(Name.lower())
2285 .Case("fp", AArch64::FP)
2286 .Case("lr", AArch64::LR)
2287 .Case("x31", AArch64::XZR)
2288 .Case("w31", AArch64::WZR)
2290 return Kind == RegKind::Scalar ? RegNum : 0;
2292 // Check for aliases registered via .req. Canonicalize to lower case.
2293 // That's more consistent since register names are case insensitive, and
2294 // it's how the original entry was passed in from MC/MCParser/AsmParser.
2295 auto Entry = RegisterReqs.find(Name.lower());
2296 if (Entry == RegisterReqs.end())
2299 // set RegNum if the match is the right kind of register
2300 if (Kind == Entry->getValue().first)
2301 RegNum = Entry->getValue().second;
2306 /// tryParseScalarRegister - Try to parse a register name. The token must be an
2307 /// Identifier when called, and if it is a register name the token is eaten and
2308 /// the register is added to the operand list.
2309 OperandMatchResultTy
2310 AArch64AsmParser::tryParseScalarRegister(unsigned &RegNum) {
2311 MCAsmParser &Parser = getParser();
2312 const AsmToken &Tok = Parser.getTok();
2313 if (Tok.isNot(AsmToken::Identifier))
2314 return MatchOperand_NoMatch;
2316 std::string lowerCase = Tok.getString().lower();
2317 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
2319 return MatchOperand_NoMatch;
2322 Parser.Lex(); // Eat identifier token.
2323 return MatchOperand_Success;
2326 /// tryParseSysCROperand - Try to parse a system instruction CR operand name.
2327 OperandMatchResultTy
2328 AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
2329 MCAsmParser &Parser = getParser();
2332 if (Parser.getTok().isNot(AsmToken::Identifier)) {
2333 Error(S, "Expected cN operand where 0 <= N <= 15");
2334 return MatchOperand_ParseFail;
2337 StringRef Tok = Parser.getTok().getIdentifier();
2338 if (Tok[0] != 'c' && Tok[0] != 'C') {
2339 Error(S, "Expected cN operand where 0 <= N <= 15");
2340 return MatchOperand_ParseFail;
2344 bool BadNum = Tok.drop_front().getAsInteger(10, CRNum);
2345 if (BadNum || CRNum > 15) {
2346 Error(S, "Expected cN operand where 0 <= N <= 15");
2347 return MatchOperand_ParseFail;
2350 Parser.Lex(); // Eat identifier token.
2352 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
2353 return MatchOperand_Success;
2356 /// tryParsePrefetch - Try to parse a prefetch operand.
2357 template <bool IsSVEPrefetch>
2358 OperandMatchResultTy
2359 AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
2360 MCAsmParser &Parser = getParser();
2362 const AsmToken &Tok = Parser.getTok();
2364 auto LookupByName = [](StringRef N) {
2365 if (IsSVEPrefetch) {
2366 if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(N))
2367 return Optional<unsigned>(Res->Encoding);
2368 } else if (auto Res = AArch64PRFM::lookupPRFMByName(N))
2369 return Optional<unsigned>(Res->Encoding);
2370 return Optional<unsigned>();
2373 auto LookupByEncoding = [](unsigned E) {
2374 if (IsSVEPrefetch) {
2375 if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E))
2376 return Optional<StringRef>(Res->Name);
2377 } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E))
2378 return Optional<StringRef>(Res->Name);
2379 return Optional<StringRef>();
2381 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
2383 // Either an identifier for named values or a 5-bit immediate.
2384 // Eat optional hash.
2385 if (parseOptionalToken(AsmToken::Hash) ||
2386 Tok.is(AsmToken::Integer)) {
2387 const MCExpr *ImmVal;
2388 if (getParser().parseExpression(ImmVal))
2389 return MatchOperand_ParseFail;
2391 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2393 TokError("immediate value expected for prefetch operand");
2394 return MatchOperand_ParseFail;
2396 unsigned prfop = MCE->getValue();
2397 if (prfop > MaxVal) {
2398 TokError("prefetch operand out of range, [0," + utostr(MaxVal) +
2400 return MatchOperand_ParseFail;
2403 auto PRFM = LookupByEncoding(MCE->getValue());
2404 Operands.push_back(AArch64Operand::CreatePrefetch(
2405 prfop, PRFM.getValueOr(""), S, getContext()));
2406 return MatchOperand_Success;
2409 if (Tok.isNot(AsmToken::Identifier)) {
2410 TokError("prefetch hint expected");
2411 return MatchOperand_ParseFail;
2414 auto PRFM = LookupByName(Tok.getString());
2416 TokError("prefetch hint expected");
2417 return MatchOperand_ParseFail;
2420 Parser.Lex(); // Eat identifier token.
2421 Operands.push_back(AArch64Operand::CreatePrefetch(
2422 *PRFM, Tok.getString(), S, getContext()));
2423 return MatchOperand_Success;
2426 /// tryParsePSBHint - Try to parse a PSB operand, mapped to Hint command
2427 OperandMatchResultTy
2428 AArch64AsmParser::tryParsePSBHint(OperandVector &Operands) {
2429 MCAsmParser &Parser = getParser();
2431 const AsmToken &Tok = Parser.getTok();
2432 if (Tok.isNot(AsmToken::Identifier)) {
2433 TokError("invalid operand for instruction");
2434 return MatchOperand_ParseFail;
2437 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.getString());
2439 TokError("invalid operand for instruction");
2440 return MatchOperand_ParseFail;
2443 Parser.Lex(); // Eat identifier token.
2444 Operands.push_back(AArch64Operand::CreatePSBHint(
2445 PSB->Encoding, Tok.getString(), S, getContext()));
2446 return MatchOperand_Success;
2449 /// tryParseBTIHint - Try to parse a BTI operand, mapped to Hint command
2450 OperandMatchResultTy
2451 AArch64AsmParser::tryParseBTIHint(OperandVector &Operands) {
2452 MCAsmParser &Parser = getParser();
2454 const AsmToken &Tok = Parser.getTok();
2455 if (Tok.isNot(AsmToken::Identifier)) {
2456 TokError("invalid operand for instruction");
2457 return MatchOperand_ParseFail;
2460 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.getString());
2462 TokError("invalid operand for instruction");
2463 return MatchOperand_ParseFail;
2466 Parser.Lex(); // Eat identifier token.
2467 Operands.push_back(AArch64Operand::CreateBTIHint(
2468 BTI->Encoding, Tok.getString(), S, getContext()));
2469 return MatchOperand_Success;
2472 /// tryParseAdrpLabel - Parse and validate a source label for the ADRP
2474 OperandMatchResultTy
2475 AArch64AsmParser::tryParseAdrpLabel(OperandVector &Operands) {
2476 MCAsmParser &Parser = getParser();
2478 const MCExpr *Expr = nullptr;
2480 if (Parser.getTok().is(AsmToken::Hash)) {
2481 Parser.Lex(); // Eat hash token.
2484 if (parseSymbolicImmVal(Expr))
2485 return MatchOperand_ParseFail;
2487 AArch64MCExpr::VariantKind ELFRefKind;
2488 MCSymbolRefExpr::VariantKind DarwinRefKind;
2490 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2491 if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2492 ELFRefKind == AArch64MCExpr::VK_INVALID) {
2493 // No modifier was specified at all; this is the syntax for an ELF basic
2494 // ADRP relocation (unfortunately).
2496 AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS_PAGE, getContext());
2497 } else if ((DarwinRefKind == MCSymbolRefExpr::VK_GOTPAGE ||
2498 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGE) &&
2500 Error(S, "gotpage label reference not allowed an addend");
2501 return MatchOperand_ParseFail;
2502 } else if (DarwinRefKind != MCSymbolRefExpr::VK_PAGE &&
2503 DarwinRefKind != MCSymbolRefExpr::VK_GOTPAGE &&
2504 DarwinRefKind != MCSymbolRefExpr::VK_TLVPPAGE &&
2505 ELFRefKind != AArch64MCExpr::VK_ABS_PAGE_NC &&
2506 ELFRefKind != AArch64MCExpr::VK_GOT_PAGE &&
2507 ELFRefKind != AArch64MCExpr::VK_GOTTPREL_PAGE &&
2508 ELFRefKind != AArch64MCExpr::VK_TLSDESC_PAGE) {
2509 // The operand must be an @page or @gotpage qualified symbolref.
2510 Error(S, "page or gotpage label reference expected");
2511 return MatchOperand_ParseFail;
2515 // We have either a label reference possibly with addend or an immediate. The
2516 // addend is a raw value here. The linker will adjust it to only reference the
2518 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2519 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2521 return MatchOperand_Success;
2524 /// tryParseAdrLabel - Parse and validate a source label for the ADR
2526 OperandMatchResultTy
2527 AArch64AsmParser::tryParseAdrLabel(OperandVector &Operands) {
2529 const MCExpr *Expr = nullptr;
2531 // Leave anything with a bracket to the default for SVE
2532 if (getParser().getTok().is(AsmToken::LBrac))
2533 return MatchOperand_NoMatch;
2535 if (getParser().getTok().is(AsmToken::Hash))
2536 getParser().Lex(); // Eat hash token.
2538 if (parseSymbolicImmVal(Expr))
2539 return MatchOperand_ParseFail;
2541 AArch64MCExpr::VariantKind ELFRefKind;
2542 MCSymbolRefExpr::VariantKind DarwinRefKind;
2544 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2545 if (DarwinRefKind == MCSymbolRefExpr::VK_None &&
2546 ELFRefKind == AArch64MCExpr::VK_INVALID) {
2547 // No modifier was specified at all; this is the syntax for an ELF basic
2548 // ADR relocation (unfortunately).
2549 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_ABS, getContext());
2551 Error(S, "unexpected adr label");
2552 return MatchOperand_ParseFail;
2556 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2557 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2558 return MatchOperand_Success;
2561 /// tryParseFPImm - A floating point immediate expression operand.
2562 template<bool AddFPZeroAsLiteral>
2563 OperandMatchResultTy
2564 AArch64AsmParser::tryParseFPImm(OperandVector &Operands) {
2565 MCAsmParser &Parser = getParser();
2568 bool Hash = parseOptionalToken(AsmToken::Hash);
2570 // Handle negation, as that still comes through as a separate token.
2571 bool isNegative = parseOptionalToken(AsmToken::Minus);
2573 const AsmToken &Tok = Parser.getTok();
2574 if (!Tok.is(AsmToken::Real) && !Tok.is(AsmToken::Integer)) {
2576 return MatchOperand_NoMatch;
2577 TokError("invalid floating point immediate");
2578 return MatchOperand_ParseFail;
2581 // Parse hexadecimal representation.
2582 if (Tok.is(AsmToken::Integer) && Tok.getString().startswith("0x")) {
2583 if (Tok.getIntVal() > 255 || isNegative) {
2584 TokError("encoded floating point value out of range");
2585 return MatchOperand_ParseFail;
2588 APFloat F((double)AArch64_AM::getFPImmFloat(Tok.getIntVal()));
2590 AArch64Operand::CreateFPImm(F, true, S, getContext()));
2592 // Parse FP representation.
2593 APFloat RealVal(APFloat::IEEEdouble());
2595 RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
2597 RealVal.changeSign();
2599 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
2601 AArch64Operand::CreateToken("#0", false, S, getContext()));
2603 AArch64Operand::CreateToken(".0", false, S, getContext()));
2605 Operands.push_back(AArch64Operand::CreateFPImm(
2606 RealVal, Status == APFloat::opOK, S, getContext()));
2609 Parser.Lex(); // Eat the token.
2611 return MatchOperand_Success;
2614 /// tryParseImmWithOptionalShift - Parse immediate operand, optionally with
2615 /// a shift suffix, for example '#1, lsl #12'.
2616 OperandMatchResultTy
2617 AArch64AsmParser::tryParseImmWithOptionalShift(OperandVector &Operands) {
2618 MCAsmParser &Parser = getParser();
2621 if (Parser.getTok().is(AsmToken::Hash))
2622 Parser.Lex(); // Eat '#'
2623 else if (Parser.getTok().isNot(AsmToken::Integer))
2624 // Operand should start from # or should be integer, emit error otherwise.
2625 return MatchOperand_NoMatch;
2627 const MCExpr *Imm = nullptr;
2628 if (parseSymbolicImmVal(Imm))
2629 return MatchOperand_ParseFail;
2630 else if (Parser.getTok().isNot(AsmToken::Comma)) {
2631 SMLoc E = Parser.getTok().getLoc();
2633 AArch64Operand::CreateImm(Imm, S, E, getContext()));
2634 return MatchOperand_Success;
2640 // The optional operand must be "lsl #N" where N is non-negative.
2641 if (!Parser.getTok().is(AsmToken::Identifier) ||
2642 !Parser.getTok().getIdentifier().equals_lower("lsl")) {
2643 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2644 return MatchOperand_ParseFail;
2650 parseOptionalToken(AsmToken::Hash);
2652 if (Parser.getTok().isNot(AsmToken::Integer)) {
2653 Error(Parser.getTok().getLoc(), "only 'lsl #+N' valid after immediate");
2654 return MatchOperand_ParseFail;
2657 int64_t ShiftAmount = Parser.getTok().getIntVal();
2659 if (ShiftAmount < 0) {
2660 Error(Parser.getTok().getLoc(), "positive shift amount required");
2661 return MatchOperand_ParseFail;
2663 Parser.Lex(); // Eat the number
2665 // Just in case the optional lsl #0 is used for immediates other than zero.
2666 if (ShiftAmount == 0 && Imm != nullptr) {
2667 SMLoc E = Parser.getTok().getLoc();
2668 Operands.push_back(AArch64Operand::CreateImm(Imm, S, E, getContext()));
2669 return MatchOperand_Success;
2672 SMLoc E = Parser.getTok().getLoc();
2673 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2674 S, E, getContext()));
2675 return MatchOperand_Success;
2678 /// parseCondCodeString - Parse a Condition Code string.
2679 AArch64CC::CondCode AArch64AsmParser::parseCondCodeString(StringRef Cond) {
2680 AArch64CC::CondCode CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2681 .Case("eq", AArch64CC::EQ)
2682 .Case("ne", AArch64CC::NE)
2683 .Case("cs", AArch64CC::HS)
2684 .Case("hs", AArch64CC::HS)
2685 .Case("cc", AArch64CC::LO)
2686 .Case("lo", AArch64CC::LO)
2687 .Case("mi", AArch64CC::MI)
2688 .Case("pl", AArch64CC::PL)
2689 .Case("vs", AArch64CC::VS)
2690 .Case("vc", AArch64CC::VC)
2691 .Case("hi", AArch64CC::HI)
2692 .Case("ls", AArch64CC::LS)
2693 .Case("ge", AArch64CC::GE)
2694 .Case("lt", AArch64CC::LT)
2695 .Case("gt", AArch64CC::GT)
2696 .Case("le", AArch64CC::LE)
2697 .Case("al", AArch64CC::AL)
2698 .Case("nv", AArch64CC::NV)
2699 .Default(AArch64CC::Invalid);
2701 if (CC == AArch64CC::Invalid &&
2702 getSTI().getFeatureBits()[AArch64::FeatureSVE])
2703 CC = StringSwitch<AArch64CC::CondCode>(Cond.lower())
2704 .Case("none", AArch64CC::EQ)
2705 .Case("any", AArch64CC::NE)
2706 .Case("nlast", AArch64CC::HS)
2707 .Case("last", AArch64CC::LO)
2708 .Case("first", AArch64CC::MI)
2709 .Case("nfrst", AArch64CC::PL)
2710 .Case("pmore", AArch64CC::HI)
2711 .Case("plast", AArch64CC::LS)
2712 .Case("tcont", AArch64CC::GE)
2713 .Case("tstop", AArch64CC::LT)
2714 .Default(AArch64CC::Invalid);
2719 /// parseCondCode - Parse a Condition Code operand.
2720 bool AArch64AsmParser::parseCondCode(OperandVector &Operands,
2721 bool invertCondCode) {
2722 MCAsmParser &Parser = getParser();
2724 const AsmToken &Tok = Parser.getTok();
2725 assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
2727 StringRef Cond = Tok.getString();
2728 AArch64CC::CondCode CC = parseCondCodeString(Cond);
2729 if (CC == AArch64CC::Invalid)
2730 return TokError("invalid condition code");
2731 Parser.Lex(); // Eat identifier token.
2733 if (invertCondCode) {
2734 if (CC == AArch64CC::AL || CC == AArch64CC::NV)
2735 return TokError("condition codes AL and NV are invalid for this instruction");
2736 CC = AArch64CC::getInvertedCondCode(AArch64CC::CondCode(CC));
2740 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2744 /// tryParseOptionalShift - Some operands take an optional shift argument. Parse
2745 /// them if present.
2746 OperandMatchResultTy
2747 AArch64AsmParser::tryParseOptionalShiftExtend(OperandVector &Operands) {
2748 MCAsmParser &Parser = getParser();
2749 const AsmToken &Tok = Parser.getTok();
2750 std::string LowerID = Tok.getString().lower();
2751 AArch64_AM::ShiftExtendType ShOp =
2752 StringSwitch<AArch64_AM::ShiftExtendType>(LowerID)
2753 .Case("lsl", AArch64_AM::LSL)
2754 .Case("lsr", AArch64_AM::LSR)
2755 .Case("asr", AArch64_AM::ASR)
2756 .Case("ror", AArch64_AM::ROR)
2757 .Case("msl", AArch64_AM::MSL)
2758 .Case("uxtb", AArch64_AM::UXTB)
2759 .Case("uxth", AArch64_AM::UXTH)
2760 .Case("uxtw", AArch64_AM::UXTW)
2761 .Case("uxtx", AArch64_AM::UXTX)
2762 .Case("sxtb", AArch64_AM::SXTB)
2763 .Case("sxth", AArch64_AM::SXTH)
2764 .Case("sxtw", AArch64_AM::SXTW)
2765 .Case("sxtx", AArch64_AM::SXTX)
2766 .Default(AArch64_AM::InvalidShiftExtend);
2768 if (ShOp == AArch64_AM::InvalidShiftExtend)
2769 return MatchOperand_NoMatch;
2771 SMLoc S = Tok.getLoc();
2774 bool Hash = parseOptionalToken(AsmToken::Hash);
2776 if (!Hash && getLexer().isNot(AsmToken::Integer)) {
2777 if (ShOp == AArch64_AM::LSL || ShOp == AArch64_AM::LSR ||
2778 ShOp == AArch64_AM::ASR || ShOp == AArch64_AM::ROR ||
2779 ShOp == AArch64_AM::MSL) {
2780 // We expect a number here.
2781 TokError("expected #imm after shift specifier");
2782 return MatchOperand_ParseFail;
2785 // "extend" type operations don't need an immediate, #0 is implicit.
2786 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2788 AArch64Operand::CreateShiftExtend(ShOp, 0, false, S, E, getContext()));
2789 return MatchOperand_Success;
2792 // Make sure we do actually have a number, identifier or a parenthesized
2794 SMLoc E = Parser.getTok().getLoc();
2795 if (!Parser.getTok().is(AsmToken::Integer) &&
2796 !Parser.getTok().is(AsmToken::LParen) &&
2797 !Parser.getTok().is(AsmToken::Identifier)) {
2798 Error(E, "expected integer shift amount");
2799 return MatchOperand_ParseFail;
2802 const MCExpr *ImmVal;
2803 if (getParser().parseExpression(ImmVal))
2804 return MatchOperand_ParseFail;
2806 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
2808 Error(E, "expected constant '#imm' after shift specifier");
2809 return MatchOperand_ParseFail;
2812 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
2813 Operands.push_back(AArch64Operand::CreateShiftExtend(
2814 ShOp, MCE->getValue(), true, S, E, getContext()));
2815 return MatchOperand_Success;
2818 static const struct Extension {
2820 const FeatureBitset Features;
2821 } ExtensionMap[] = {
2822 {"crc", {AArch64::FeatureCRC}},
2823 {"sm4", {AArch64::FeatureSM4}},
2824 {"sha3", {AArch64::FeatureSHA3}},
2825 {"sha2", {AArch64::FeatureSHA2}},
2826 {"aes", {AArch64::FeatureAES}},
2827 {"crypto", {AArch64::FeatureCrypto}},
2828 {"fp", {AArch64::FeatureFPARMv8}},
2829 {"simd", {AArch64::FeatureNEON}},
2830 {"ras", {AArch64::FeatureRAS}},
2831 {"lse", {AArch64::FeatureLSE}},
2832 {"predres", {AArch64::FeaturePredRes}},
2833 {"ccdp", {AArch64::FeatureCacheDeepPersist}},
2834 {"mte", {AArch64::FeatureMTE}},
2835 {"tlb-rmi", {AArch64::FeatureTLB_RMI}},
2836 {"pan-rwv", {AArch64::FeaturePAN_RWV}},
2837 {"ccpp", {AArch64::FeatureCCPP}},
2838 {"sve", {AArch64::FeatureSVE}},
2839 {"sve2", {AArch64::FeatureSVE2}},
2840 {"sve2-aes", {AArch64::FeatureSVE2AES}},
2841 {"sve2-sm4", {AArch64::FeatureSVE2SM4}},
2842 {"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
2843 {"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
2844 // FIXME: Unsupported extensions
2851 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
2852 if (FBS[AArch64::HasV8_1aOps])
2854 else if (FBS[AArch64::HasV8_2aOps])
2856 else if (FBS[AArch64::HasV8_3aOps])
2858 else if (FBS[AArch64::HasV8_4aOps])
2860 else if (FBS[AArch64::HasV8_5aOps])
2863 auto ext = std::find_if(std::begin(ExtensionMap),
2864 std::end(ExtensionMap),
2865 [&](const Extension& e)
2866 // Use & in case multiple features are enabled
2867 { return (FBS & e.Features) != FeatureBitset(); }
2870 Str += ext != std::end(ExtensionMap) ? ext->Name : "(unknown)";
2874 void AArch64AsmParser::createSysAlias(uint16_t Encoding, OperandVector &Operands,
2876 const uint16_t Op2 = Encoding & 7;
2877 const uint16_t Cm = (Encoding & 0x78) >> 3;
2878 const uint16_t Cn = (Encoding & 0x780) >> 7;
2879 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
2881 const MCExpr *Expr = MCConstantExpr::create(Op1, getContext());
2884 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
2886 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
2888 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
2889 Expr = MCConstantExpr::create(Op2, getContext());
2891 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
2894 /// parseSysAlias - The IC, DC, AT, and TLBI instructions are simple aliases for
2895 /// the SYS instruction. Parse them specially so that we create a SYS MCInst.
2896 bool AArch64AsmParser::parseSysAlias(StringRef Name, SMLoc NameLoc,
2897 OperandVector &Operands) {
2898 if (Name.find('.') != StringRef::npos)
2899 return TokError("invalid operand");
2903 AArch64Operand::CreateToken("sys", false, NameLoc, getContext()));
2905 MCAsmParser &Parser = getParser();
2906 const AsmToken &Tok = Parser.getTok();
2907 StringRef Op = Tok.getString();
2908 SMLoc S = Tok.getLoc();
2910 if (Mnemonic == "ic") {
2911 const AArch64IC::IC *IC = AArch64IC::lookupICByName(Op);
2913 return TokError("invalid operand for IC instruction");
2914 else if (!IC->haveFeatures(getSTI().getFeatureBits())) {
2915 std::string Str("IC " + std::string(IC->Name) + " requires ");
2916 setRequiredFeatureString(IC->getRequiredFeatures(), Str);
2917 return TokError(Str.c_str());
2919 createSysAlias(IC->Encoding, Operands, S);
2920 } else if (Mnemonic == "dc") {
2921 const AArch64DC::DC *DC = AArch64DC::lookupDCByName(Op);
2923 return TokError("invalid operand for DC instruction");
2924 else if (!DC->haveFeatures(getSTI().getFeatureBits())) {
2925 std::string Str("DC " + std::string(DC->Name) + " requires ");
2926 setRequiredFeatureString(DC->getRequiredFeatures(), Str);
2927 return TokError(Str.c_str());
2929 createSysAlias(DC->Encoding, Operands, S);
2930 } else if (Mnemonic == "at") {
2931 const AArch64AT::AT *AT = AArch64AT::lookupATByName(Op);
2933 return TokError("invalid operand for AT instruction");
2934 else if (!AT->haveFeatures(getSTI().getFeatureBits())) {
2935 std::string Str("AT " + std::string(AT->Name) + " requires ");
2936 setRequiredFeatureString(AT->getRequiredFeatures(), Str);
2937 return TokError(Str.c_str());
2939 createSysAlias(AT->Encoding, Operands, S);
2940 } else if (Mnemonic == "tlbi") {
2941 const AArch64TLBI::TLBI *TLBI = AArch64TLBI::lookupTLBIByName(Op);
2943 return TokError("invalid operand for TLBI instruction");
2944 else if (!TLBI->haveFeatures(getSTI().getFeatureBits())) {
2945 std::string Str("TLBI " + std::string(TLBI->Name) + " requires ");
2946 setRequiredFeatureString(TLBI->getRequiredFeatures(), Str);
2947 return TokError(Str.c_str());
2949 createSysAlias(TLBI->Encoding, Operands, S);
2950 } else if (Mnemonic == "cfp" || Mnemonic == "dvp" || Mnemonic == "cpp") {
2951 const AArch64PRCTX::PRCTX *PRCTX = AArch64PRCTX::lookupPRCTXByName(Op);
2953 return TokError("invalid operand for prediction restriction instruction");
2954 else if (!PRCTX->haveFeatures(getSTI().getFeatureBits())) {
2956 Mnemonic.upper() + std::string(PRCTX->Name) + " requires ");
2957 setRequiredFeatureString(PRCTX->getRequiredFeatures(), Str);
2958 return TokError(Str.c_str());
2960 uint16_t PRCTX_Op2 =
2961 Mnemonic == "cfp" ? 4 :
2962 Mnemonic == "dvp" ? 5 :
2963 Mnemonic == "cpp" ? 7 :
2965 assert(PRCTX_Op2 && "Invalid mnemonic for prediction restriction instruction");
2966 createSysAlias(PRCTX->Encoding << 3 | PRCTX_Op2 , Operands, S);
2969 Parser.Lex(); // Eat operand.
2971 bool ExpectRegister = (Op.lower().find("all") == StringRef::npos);
2972 bool HasRegister = false;
2974 // Check for the optional register operand.
2975 if (parseOptionalToken(AsmToken::Comma)) {
2976 if (Tok.isNot(AsmToken::Identifier) || parseRegister(Operands))
2977 return TokError("expected register operand");
2981 if (ExpectRegister && !HasRegister)
2982 return TokError("specified " + Mnemonic + " op requires a register");
2983 else if (!ExpectRegister && HasRegister)
2984 return TokError("specified " + Mnemonic + " op does not use a register");
2986 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
2992 OperandMatchResultTy
2993 AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
2994 MCAsmParser &Parser = getParser();
2995 const AsmToken &Tok = Parser.getTok();
2997 if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) {
2998 TokError("'csync' operand expected");
2999 return MatchOperand_ParseFail;
3000 // Can be either a #imm style literal or an option name
3001 } else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
3002 // Immediate operand.
3003 const MCExpr *ImmVal;
3004 SMLoc ExprLoc = getLoc();
3005 if (getParser().parseExpression(ImmVal))
3006 return MatchOperand_ParseFail;
3007 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3009 Error(ExprLoc, "immediate value expected for barrier operand");
3010 return MatchOperand_ParseFail;
3012 if (MCE->getValue() < 0 || MCE->getValue() > 15) {
3013 Error(ExprLoc, "barrier operand out of range");
3014 return MatchOperand_ParseFail;
3016 auto DB = AArch64DB::lookupDBByEncoding(MCE->getValue());
3017 Operands.push_back(AArch64Operand::CreateBarrier(
3018 MCE->getValue(), DB ? DB->Name : "", ExprLoc, getContext()));
3019 return MatchOperand_Success;
3022 if (Tok.isNot(AsmToken::Identifier)) {
3023 TokError("invalid operand for instruction");
3024 return MatchOperand_ParseFail;
3027 auto TSB = AArch64TSB::lookupTSBByName(Tok.getString());
3028 // The only valid named option for ISB is 'sy'
3029 auto DB = AArch64DB::lookupDBByName(Tok.getString());
3030 if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
3031 TokError("'sy' or #imm operand expected");
3032 return MatchOperand_ParseFail;
3033 // The only valid named option for TSB is 'csync'
3034 } else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) {
3035 TokError("'csync' operand expected");
3036 return MatchOperand_ParseFail;
3037 } else if (!DB && !TSB) {
3038 TokError("invalid barrier option name");
3039 return MatchOperand_ParseFail;
3042 Operands.push_back(AArch64Operand::CreateBarrier(
3043 DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(), getContext()));
3044 Parser.Lex(); // Consume the option
3046 return MatchOperand_Success;
3049 OperandMatchResultTy
3050 AArch64AsmParser::tryParseSysReg(OperandVector &Operands) {
3051 MCAsmParser &Parser = getParser();
3052 const AsmToken &Tok = Parser.getTok();
3054 if (Tok.isNot(AsmToken::Identifier))
3055 return MatchOperand_NoMatch;
3058 auto SysReg = AArch64SysReg::lookupSysRegByName(Tok.getString());
3059 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
3060 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
3061 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
3063 MRSReg = MSRReg = AArch64SysReg::parseGenericRegister(Tok.getString());
3065 auto PState = AArch64PState::lookupPStateByName(Tok.getString());
3066 unsigned PStateImm = -1;
3067 if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
3068 PStateImm = PState->Encoding;
3071 AArch64Operand::CreateSysReg(Tok.getString(), getLoc(), MRSReg, MSRReg,
3072 PStateImm, getContext()));
3073 Parser.Lex(); // Eat identifier
3075 return MatchOperand_Success;
3078 /// tryParseNeonVectorRegister - Parse a vector register operand.
3079 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
3080 MCAsmParser &Parser = getParser();
3081 if (Parser.getTok().isNot(AsmToken::Identifier))
3085 // Check for a vector register specifier first.
3088 OperandMatchResultTy Res =
3089 tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
3090 if (Res != MatchOperand_Success)
3093 const auto &KindRes = parseVectorKind(Kind, RegKind::NeonVector);
3097 unsigned ElementWidth = KindRes->second;
3099 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
3100 S, getLoc(), getContext()));
3102 // If there was an explicit qualifier, that goes on as a literal text
3106 AArch64Operand::CreateToken(Kind, false, S, getContext()));
3108 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
3111 OperandMatchResultTy
3112 AArch64AsmParser::tryParseVectorIndex(OperandVector &Operands) {
3113 SMLoc SIdx = getLoc();
3114 if (parseOptionalToken(AsmToken::LBrac)) {
3115 const MCExpr *ImmVal;
3116 if (getParser().parseExpression(ImmVal))
3117 return MatchOperand_NoMatch;
3118 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal);
3120 TokError("immediate value expected for vector index");
3121 return MatchOperand_ParseFail;;
3126 if (parseToken(AsmToken::RBrac, "']' expected"))
3127 return MatchOperand_ParseFail;;
3129 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->getValue(), SIdx,
3131 return MatchOperand_Success;
3134 return MatchOperand_NoMatch;
3137 // tryParseVectorRegister - Try to parse a vector register name with
3138 // optional kind specifier. If it is a register specifier, eat the token
3140 OperandMatchResultTy
3141 AArch64AsmParser::tryParseVectorRegister(unsigned &Reg, StringRef &Kind,
3142 RegKind MatchKind) {
3143 MCAsmParser &Parser = getParser();
3144 const AsmToken &Tok = Parser.getTok();
3146 if (Tok.isNot(AsmToken::Identifier))
3147 return MatchOperand_NoMatch;
3149 StringRef Name = Tok.getString();
3150 // If there is a kind specifier, it's separated from the register name by
3152 size_t Start = 0, Next = Name.find('.');
3153 StringRef Head = Name.slice(Start, Next);
3154 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
3157 if (Next != StringRef::npos) {
3158 Kind = Name.slice(Next, StringRef::npos);
3159 if (!isValidVectorKind(Kind, MatchKind)) {
3160 TokError("invalid vector kind qualifier");
3161 return MatchOperand_ParseFail;
3164 Parser.Lex(); // Eat the register token.
3167 return MatchOperand_Success;
3170 return MatchOperand_NoMatch;
3173 /// tryParseSVEPredicateVector - Parse a SVE predicate register operand.
3174 OperandMatchResultTy
3175 AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) {
3176 // Check for a SVE predicate register specifier first.
3177 const SMLoc S = getLoc();
3180 auto Res = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
3181 if (Res != MatchOperand_Success)
3184 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEPredicateVector);
3186 return MatchOperand_NoMatch;
3188 unsigned ElementWidth = KindRes->second;
3189 Operands.push_back(AArch64Operand::CreateVectorReg(
3190 RegNum, RegKind::SVEPredicateVector, ElementWidth, S,
3191 getLoc(), getContext()));
3193 // Not all predicates are followed by a '/m' or '/z'.
3194 MCAsmParser &Parser = getParser();
3195 if (Parser.getTok().isNot(AsmToken::Slash))
3196 return MatchOperand_Success;
3198 // But when they do they shouldn't have an element type suffix.
3199 if (!Kind.empty()) {
3200 Error(S, "not expecting size suffix");
3201 return MatchOperand_ParseFail;
3204 // Add a literal slash as operand
3206 AArch64Operand::CreateToken("/" , false, getLoc(), getContext()));
3208 Parser.Lex(); // Eat the slash.
3210 // Zeroing or merging?
3211 auto Pred = Parser.getTok().getString().lower();
3212 if (Pred != "z" && Pred != "m") {
3213 Error(getLoc(), "expecting 'm' or 'z' predication");
3214 return MatchOperand_ParseFail;
3217 // Add zero/merge token.
3218 const char *ZM = Pred == "z" ? "z" : "m";
3220 AArch64Operand::CreateToken(ZM, false, getLoc(), getContext()));
3222 Parser.Lex(); // Eat zero/merge token.
3223 return MatchOperand_Success;
3226 /// parseRegister - Parse a register operand.
3227 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
3228 // Try for a Neon vector register.
3229 if (!tryParseNeonVectorRegister(Operands))
3232 // Otherwise try for a scalar register.
3233 if (tryParseGPROperand<false>(Operands) == MatchOperand_Success)
3239 bool AArch64AsmParser::parseSymbolicImmVal(const MCExpr *&ImmVal) {
3240 MCAsmParser &Parser = getParser();
3241 bool HasELFModifier = false;
3242 AArch64MCExpr::VariantKind RefKind;
3244 if (parseOptionalToken(AsmToken::Colon)) {
3245 HasELFModifier = true;
3247 if (Parser.getTok().isNot(AsmToken::Identifier))
3248 return TokError("expect relocation specifier in operand after ':'");
3250 std::string LowerCase = Parser.getTok().getIdentifier().lower();
3251 RefKind = StringSwitch<AArch64MCExpr::VariantKind>(LowerCase)
3252 .Case("lo12", AArch64MCExpr::VK_LO12)
3253 .Case("abs_g3", AArch64MCExpr::VK_ABS_G3)
3254 .Case("abs_g2", AArch64MCExpr::VK_ABS_G2)
3255 .Case("abs_g2_s", AArch64MCExpr::VK_ABS_G2_S)
3256 .Case("abs_g2_nc", AArch64MCExpr::VK_ABS_G2_NC)
3257 .Case("abs_g1", AArch64MCExpr::VK_ABS_G1)
3258 .Case("abs_g1_s", AArch64MCExpr::VK_ABS_G1_S)
3259 .Case("abs_g1_nc", AArch64MCExpr::VK_ABS_G1_NC)
3260 .Case("abs_g0", AArch64MCExpr::VK_ABS_G0)
3261 .Case("abs_g0_s", AArch64MCExpr::VK_ABS_G0_S)
3262 .Case("abs_g0_nc", AArch64MCExpr::VK_ABS_G0_NC)
3263 .Case("dtprel_g2", AArch64MCExpr::VK_DTPREL_G2)
3264 .Case("dtprel_g1", AArch64MCExpr::VK_DTPREL_G1)
3265 .Case("dtprel_g1_nc", AArch64MCExpr::VK_DTPREL_G1_NC)
3266 .Case("dtprel_g0", AArch64MCExpr::VK_DTPREL_G0)
3267 .Case("dtprel_g0_nc", AArch64MCExpr::VK_DTPREL_G0_NC)
3268 .Case("dtprel_hi12", AArch64MCExpr::VK_DTPREL_HI12)
3269 .Case("dtprel_lo12", AArch64MCExpr::VK_DTPREL_LO12)
3270 .Case("dtprel_lo12_nc", AArch64MCExpr::VK_DTPREL_LO12_NC)
3271 .Case("pg_hi21_nc", AArch64MCExpr::VK_ABS_PAGE_NC)
3272 .Case("tprel_g2", AArch64MCExpr::VK_TPREL_G2)
3273 .Case("tprel_g1", AArch64MCExpr::VK_TPREL_G1)
3274 .Case("tprel_g1_nc", AArch64MCExpr::VK_TPREL_G1_NC)
3275 .Case("tprel_g0", AArch64MCExpr::VK_TPREL_G0)
3276 .Case("tprel_g0_nc", AArch64MCExpr::VK_TPREL_G0_NC)
3277 .Case("tprel_hi12", AArch64MCExpr::VK_TPREL_HI12)
3278 .Case("tprel_lo12", AArch64MCExpr::VK_TPREL_LO12)
3279 .Case("tprel_lo12_nc", AArch64MCExpr::VK_TPREL_LO12_NC)
3280 .Case("tlsdesc_lo12", AArch64MCExpr::VK_TLSDESC_LO12)
3281 .Case("got", AArch64MCExpr::VK_GOT_PAGE)
3282 .Case("got_lo12", AArch64MCExpr::VK_GOT_LO12)
3283 .Case("gottprel", AArch64MCExpr::VK_GOTTPREL_PAGE)
3284 .Case("gottprel_lo12", AArch64MCExpr::VK_GOTTPREL_LO12_NC)
3285 .Case("gottprel_g1", AArch64MCExpr::VK_GOTTPREL_G1)
3286 .Case("gottprel_g0_nc", AArch64MCExpr::VK_GOTTPREL_G0_NC)
3287 .Case("tlsdesc", AArch64MCExpr::VK_TLSDESC_PAGE)
3288 .Case("secrel_lo12", AArch64MCExpr::VK_SECREL_LO12)
3289 .Case("secrel_hi12", AArch64MCExpr::VK_SECREL_HI12)
3290 .Default(AArch64MCExpr::VK_INVALID);
3292 if (RefKind == AArch64MCExpr::VK_INVALID)
3293 return TokError("expect relocation specifier in operand after ':'");
3295 Parser.Lex(); // Eat identifier
3297 if (parseToken(AsmToken::Colon, "expect ':' after relocation specifier"))
3301 if (getParser().parseExpression(ImmVal))
3305 ImmVal = AArch64MCExpr::create(ImmVal, RefKind, getContext());
3310 template <RegKind VectorKind>
3311 OperandMatchResultTy
3312 AArch64AsmParser::tryParseVectorList(OperandVector &Operands,
3314 MCAsmParser &Parser = getParser();
3315 if (!Parser.getTok().is(AsmToken::LCurly))
3316 return MatchOperand_NoMatch;
3318 // Wrapper around parse function
3319 auto ParseVector = [this, &Parser](unsigned &Reg, StringRef &Kind, SMLoc Loc,
3320 bool NoMatchIsError) {
3321 auto RegTok = Parser.getTok();
3322 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
3323 if (ParseRes == MatchOperand_Success) {
3324 if (parseVectorKind(Kind, VectorKind))
3326 llvm_unreachable("Expected a valid vector kind");
3329 if (RegTok.isNot(AsmToken::Identifier) ||
3330 ParseRes == MatchOperand_ParseFail ||
3331 (ParseRes == MatchOperand_NoMatch && NoMatchIsError)) {
3332 Error(Loc, "vector register expected");
3333 return MatchOperand_ParseFail;
3336 return MatchOperand_NoMatch;
3340 auto LCurly = Parser.getTok();
3341 Parser.Lex(); // Eat left bracket token.
3345 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
3347 // Put back the original left bracket if there was no match, so that
3348 // different types of list-operands can be matched (e.g. SVE, Neon).
3349 if (ParseRes == MatchOperand_NoMatch)
3350 Parser.getLexer().UnLex(LCurly);
3352 if (ParseRes != MatchOperand_Success)
3355 int64_t PrevReg = FirstReg;
3358 if (parseOptionalToken(AsmToken::Minus)) {
3359 SMLoc Loc = getLoc();
3363 ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
3364 if (ParseRes != MatchOperand_Success)
3367 // Any Kind suffices must match on all regs in the list.
3368 if (Kind != NextKind) {
3369 Error(Loc, "mismatched register size suffix");
3370 return MatchOperand_ParseFail;
3373 unsigned Space = (PrevReg < Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
3375 if (Space == 0 || Space > 3) {
3376 Error(Loc, "invalid number of vectors");
3377 return MatchOperand_ParseFail;
3383 while (parseOptionalToken(AsmToken::Comma)) {
3384 SMLoc Loc = getLoc();
3387 ParseRes = ParseVector(Reg, NextKind, getLoc(), true);
3388 if (ParseRes != MatchOperand_Success)
3391 // Any Kind suffices must match on all regs in the list.
3392 if (Kind != NextKind) {
3393 Error(Loc, "mismatched register size suffix");
3394 return MatchOperand_ParseFail;
3397 // Registers must be incremental (with wraparound at 31)
3398 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
3399 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32) {
3400 Error(Loc, "registers must be sequential");
3401 return MatchOperand_ParseFail;
3409 if (parseToken(AsmToken::RCurly, "'}' expected"))
3410 return MatchOperand_ParseFail;
3413 Error(S, "invalid number of vectors");
3414 return MatchOperand_ParseFail;
3417 unsigned NumElements = 0;
3418 unsigned ElementWidth = 0;
3419 if (!Kind.empty()) {
3420 if (const auto &VK = parseVectorKind(Kind, VectorKind))
3421 std::tie(NumElements, ElementWidth) = *VK;
3424 Operands.push_back(AArch64Operand::CreateVectorList(
3425 FirstReg, Count, NumElements, ElementWidth, VectorKind, S, getLoc(),
3428 return MatchOperand_Success;
3431 /// parseNeonVectorList - Parse a vector list operand for AdvSIMD instructions.
3432 bool AArch64AsmParser::parseNeonVectorList(OperandVector &Operands) {
3433 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(Operands, true);
3434 if (ParseRes != MatchOperand_Success)
3437 return tryParseVectorIndex(Operands) == MatchOperand_ParseFail;
3440 OperandMatchResultTy
3441 AArch64AsmParser::tryParseGPR64sp0Operand(OperandVector &Operands) {
3442 SMLoc StartLoc = getLoc();
3445 OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
3446 if (Res != MatchOperand_Success)
3449 if (!parseOptionalToken(AsmToken::Comma)) {
3450 Operands.push_back(AArch64Operand::CreateReg(
3451 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3452 return MatchOperand_Success;
3455 parseOptionalToken(AsmToken::Hash);
3457 if (getParser().getTok().isNot(AsmToken::Integer)) {
3458 Error(getLoc(), "index must be absent or #0");
3459 return MatchOperand_ParseFail;
3462 const MCExpr *ImmVal;
3463 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
3464 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
3465 Error(getLoc(), "index must be absent or #0");
3466 return MatchOperand_ParseFail;
3469 Operands.push_back(AArch64Operand::CreateReg(
3470 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3471 return MatchOperand_Success;
3474 template <bool ParseShiftExtend, RegConstraintEqualityTy EqTy>
3475 OperandMatchResultTy
3476 AArch64AsmParser::tryParseGPROperand(OperandVector &Operands) {
3477 SMLoc StartLoc = getLoc();
3480 OperandMatchResultTy Res = tryParseScalarRegister(RegNum);
3481 if (Res != MatchOperand_Success)
3484 // No shift/extend is the default.
3485 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) {
3486 Operands.push_back(AArch64Operand::CreateReg(
3487 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
3488 return MatchOperand_Success;
3495 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
3496 Res = tryParseOptionalShiftExtend(ExtOpnd);
3497 if (Res != MatchOperand_Success)
3500 auto Ext = static_cast<AArch64Operand*>(ExtOpnd.back().get());
3501 Operands.push_back(AArch64Operand::CreateReg(
3502 RegNum, RegKind::Scalar, StartLoc, Ext->getEndLoc(), getContext(), EqTy,
3503 Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
3504 Ext->hasShiftExtendAmount()));
3506 return MatchOperand_Success;
3509 bool AArch64AsmParser::parseOptionalMulOperand(OperandVector &Operands) {
3510 MCAsmParser &Parser = getParser();
3512 // Some SVE instructions have a decoration after the immediate, i.e.
3513 // "mul vl". We parse them here and add tokens, which must be present in the
3514 // asm string in the tablegen instruction.
3515 bool NextIsVL = Parser.getLexer().peekTok().getString().equals_lower("vl");
3516 bool NextIsHash = Parser.getLexer().peekTok().is(AsmToken::Hash);
3517 if (!Parser.getTok().getString().equals_lower("mul") ||
3518 !(NextIsVL || NextIsHash))
3522 AArch64Operand::CreateToken("mul", false, getLoc(), getContext()));
3523 Parser.Lex(); // Eat the "mul"
3527 AArch64Operand::CreateToken("vl", false, getLoc(), getContext()));
3528 Parser.Lex(); // Eat the "vl"
3533 Parser.Lex(); // Eat the #
3536 // Parse immediate operand.
3537 const MCExpr *ImmVal;
3538 if (!Parser.parseExpression(ImmVal))
3539 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
3540 Operands.push_back(AArch64Operand::CreateImm(
3541 MCConstantExpr::create(MCE->getValue(), getContext()), S, getLoc(),
3543 return MatchOperand_Success;
3547 return Error(getLoc(), "expected 'vl' or '#<imm>'");
3550 /// parseOperand - Parse a arm instruction operand. For now this parses the
3551 /// operand regardless of the mnemonic.
3552 bool AArch64AsmParser::parseOperand(OperandVector &Operands, bool isCondCode,
3553 bool invertCondCode) {
3554 MCAsmParser &Parser = getParser();
3556 OperandMatchResultTy ResTy =
3557 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/ true);
3559 // Check if the current operand has a custom associated parser, if so, try to
3560 // custom parse the operand, or fallback to the general approach.
3561 if (ResTy == MatchOperand_Success)
3563 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3564 // there was a match, but an error occurred, in which case, just return that
3565 // the operand parsing failed.
3566 if (ResTy == MatchOperand_ParseFail)
3569 // Nothing custom, so do general case parsing.
3571 switch (getLexer().getKind()) {
3575 if (parseSymbolicImmVal(Expr))
3576 return Error(S, "invalid operand");
3578 SMLoc E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3579 Operands.push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3582 case AsmToken::LBrac: {
3583 SMLoc Loc = Parser.getTok().getLoc();
3584 Operands.push_back(AArch64Operand::CreateToken("[", false, Loc,
3586 Parser.Lex(); // Eat '['
3588 // There's no comma after a '[', so we can parse the next operand
3590 return parseOperand(Operands, false, false);
3592 case AsmToken::LCurly:
3593 return parseNeonVectorList(Operands);
3594 case AsmToken::Identifier: {
3595 // If we're expecting a Condition Code operand, then just parse that.
3597 return parseCondCode(Operands, invertCondCode);
3599 // If it's a register name, parse it.
3600 if (!parseRegister(Operands))
3603 // See if this is a "mul vl" decoration or "mul #<int>" operand used
3604 // by SVE instructions.
3605 if (!parseOptionalMulOperand(Operands))
3608 // This could be an optional "shift" or "extend" operand.
3609 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3610 // We can only continue if no tokens were eaten.
3611 if (GotShift != MatchOperand_NoMatch)
3614 // This was not a register so parse other operands that start with an
3615 // identifier (like labels) as expressions and create them as immediates.
3616 const MCExpr *IdVal;
3618 if (getParser().parseExpression(IdVal))
3620 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3621 Operands.push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3624 case AsmToken::Integer:
3625 case AsmToken::Real:
3626 case AsmToken::Hash: {
3627 // #42 -> immediate.
3630 parseOptionalToken(AsmToken::Hash);
3632 // Parse a negative sign
3633 bool isNegative = false;
3634 if (Parser.getTok().is(AsmToken::Minus)) {
3636 // We need to consume this token only when we have a Real, otherwise
3637 // we let parseSymbolicImmVal take care of it
3638 if (Parser.getLexer().peekTok().is(AsmToken::Real))
3642 // The only Real that should come through here is a literal #0.0 for
3643 // the fcmp[e] r, #0.0 instructions. They expect raw token operands,
3644 // so convert the value.
3645 const AsmToken &Tok = Parser.getTok();
3646 if (Tok.is(AsmToken::Real)) {
3647 APFloat RealVal(APFloat::IEEEdouble(), Tok.getString());
3648 uint64_t IntVal = RealVal.bitcastToAPInt().getZExtValue();
3649 if (Mnemonic != "fcmp" && Mnemonic != "fcmpe" && Mnemonic != "fcmeq" &&
3650 Mnemonic != "fcmge" && Mnemonic != "fcmgt" && Mnemonic != "fcmle" &&
3651 Mnemonic != "fcmlt" && Mnemonic != "fcmne")
3652 return TokError("unexpected floating point literal");
3653 else if (IntVal != 0 || isNegative)
3654 return TokError("expected floating-point constant #0.0");
3655 Parser.Lex(); // Eat the token.
3658 AArch64Operand::CreateToken("#0", false, S, getContext()));
3660 AArch64Operand::CreateToken(".0", false, S, getContext()));
3664 const MCExpr *ImmVal;
3665 if (parseSymbolicImmVal(ImmVal))
3668 E = SMLoc::getFromPointer(getLoc().getPointer() - 1);
3669 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3672 case AsmToken::Equal: {
3673 SMLoc Loc = getLoc();
3674 if (Mnemonic != "ldr") // only parse for ldr pseudo (e.g. ldr r0, =val)
3675 return TokError("unexpected token in operand");
3676 Parser.Lex(); // Eat '='
3677 const MCExpr *SubExprVal;
3678 if (getParser().parseExpression(SubExprVal))
3681 if (Operands.size() < 2 ||
3682 !static_cast<AArch64Operand &>(*Operands[1]).isScalarReg())
3683 return Error(Loc, "Only valid when first operand is register");
3686 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3687 Operands[1]->getReg());
3689 MCContext& Ctx = getContext();
3690 E = SMLoc::getFromPointer(Loc.getPointer() - 1);
3691 // If the op is an imm and can be fit into a mov, then replace ldr with mov.
3692 if (isa<MCConstantExpr>(SubExprVal)) {
3693 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3694 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3695 while(Imm > 0xFFFF && countTrailingZeros(Imm) >= 16) {
3699 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3700 Operands[0] = AArch64Operand::CreateToken("movz", false, Loc, Ctx);
3701 Operands.push_back(AArch64Operand::CreateImm(
3702 MCConstantExpr::create(Imm, Ctx), S, E, Ctx));
3704 Operands.push_back(AArch64Operand::CreateShiftExtend(AArch64_AM::LSL,
3705 ShiftAmt, true, S, E, Ctx));
3708 APInt Simm = APInt(64, Imm << ShiftAmt);
3709 // check if the immediate is an unsigned or signed 32-bit int for W regs
3710 if (!IsXReg && !(Simm.isIntN(32) || Simm.isSignedIntN(32)))
3711 return Error(Loc, "Immediate too large for register");
3713 // If it is a label or an imm that cannot fit in a movz, put it into CP.
3714 const MCExpr *CPLoc =
3715 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
3716 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3722 bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
3723 const MCParsedAsmOperand &Op2) const {
3724 auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
3725 auto &AOp2 = static_cast<const AArch64Operand&>(Op2);
3726 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
3727 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
3728 return MCTargetAsmParser::regsEqual(Op1, Op2);
3730 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
3731 "Testing equality of non-scalar registers not supported");
3733 // Check if a registers match their sub/super register classes.
3734 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
3735 return getXRegFromWReg(Op1.getReg()) == Op2.getReg();
3736 if (AOp1.getRegEqualityTy() == EqualsSubReg)
3737 return getWRegFromXReg(Op1.getReg()) == Op2.getReg();
3738 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
3739 return getXRegFromWReg(Op2.getReg()) == Op1.getReg();
3740 if (AOp2.getRegEqualityTy() == EqualsSubReg)
3741 return getWRegFromXReg(Op2.getReg()) == Op1.getReg();
3746 /// ParseInstruction - Parse an AArch64 instruction mnemonic followed by its
3748 bool AArch64AsmParser::ParseInstruction(ParseInstructionInfo &Info,
3749 StringRef Name, SMLoc NameLoc,
3750 OperandVector &Operands) {
3751 MCAsmParser &Parser = getParser();
3752 Name = StringSwitch<StringRef>(Name.lower())
3753 .Case("beq", "b.eq")
3754 .Case("bne", "b.ne")
3755 .Case("bhs", "b.hs")
3756 .Case("bcs", "b.cs")
3757 .Case("blo", "b.lo")
3758 .Case("bcc", "b.cc")
3759 .Case("bmi", "b.mi")
3760 .Case("bpl", "b.pl")
3761 .Case("bvs", "b.vs")
3762 .Case("bvc", "b.vc")
3763 .Case("bhi", "b.hi")
3764 .Case("bls", "b.ls")
3765 .Case("bge", "b.ge")
3766 .Case("blt", "b.lt")
3767 .Case("bgt", "b.gt")
3768 .Case("ble", "b.le")
3769 .Case("bal", "b.al")
3770 .Case("bnv", "b.nv")
3773 // First check for the AArch64-specific .req directive.
3774 if (Parser.getTok().is(AsmToken::Identifier) &&
3775 Parser.getTok().getIdentifier() == ".req") {
3776 parseDirectiveReq(Name, NameLoc);
3777 // We always return 'error' for this, as we're done with this
3778 // statement and don't need to match the 'instruction."
3782 // Create the leading tokens for the mnemonic, split by '.' characters.
3783 size_t Start = 0, Next = Name.find('.');
3784 StringRef Head = Name.slice(Start, Next);
3786 // IC, DC, AT, TLBI and Prediction invalidation instructions are aliases for
3787 // the SYS instruction.
3788 if (Head == "ic" || Head == "dc" || Head == "at" || Head == "tlbi" ||
3789 Head == "cfp" || Head == "dvp" || Head == "cpp")
3790 return parseSysAlias(Head, NameLoc, Operands);
3793 AArch64Operand::CreateToken(Head, false, NameLoc, getContext()));
3796 // Handle condition codes for a branch mnemonic
3797 if (Head == "b" && Next != StringRef::npos) {
3799 Next = Name.find('.', Start + 1);
3800 Head = Name.slice(Start + 1, Next);
3802 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3803 (Head.data() - Name.data()));
3804 AArch64CC::CondCode CC = parseCondCodeString(Head);
3805 if (CC == AArch64CC::Invalid)
3806 return Error(SuffixLoc, "invalid condition code");
3808 AArch64Operand::CreateToken(".", true, SuffixLoc, getContext()));
3810 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3813 // Add the remaining tokens in the mnemonic.
3814 while (Next != StringRef::npos) {
3816 Next = Name.find('.', Start + 1);
3817 Head = Name.slice(Start, Next);
3818 SMLoc SuffixLoc = SMLoc::getFromPointer(NameLoc.getPointer() +
3819 (Head.data() - Name.data()) + 1);
3821 AArch64Operand::CreateToken(Head, true, SuffixLoc, getContext()));
3824 // Conditional compare instructions have a Condition Code operand, which needs
3825 // to be parsed and an immediate operand created.
3826 bool condCodeFourthOperand =
3827 (Head == "ccmp" || Head == "ccmn" || Head == "fccmp" ||
3828 Head == "fccmpe" || Head == "fcsel" || Head == "csel" ||
3829 Head == "csinc" || Head == "csinv" || Head == "csneg");
3831 // These instructions are aliases to some of the conditional select
3832 // instructions. However, the condition code is inverted in the aliased
3835 // FIXME: Is this the correct way to handle these? Or should the parser
3836 // generate the aliased instructions directly?
3837 bool condCodeSecondOperand = (Head == "cset" || Head == "csetm");
3838 bool condCodeThirdOperand =
3839 (Head == "cinc" || Head == "cinv" || Head == "cneg");
3841 // Read the remaining operands.
3842 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3846 // Parse and remember the operand.
3847 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3848 (N == 3 && condCodeThirdOperand) ||
3849 (N == 2 && condCodeSecondOperand),
3850 condCodeSecondOperand || condCodeThirdOperand)) {
3854 // After successfully parsing some operands there are two special cases to
3855 // consider (i.e. notional operands not separated by commas). Both are due
3856 // to memory specifiers:
3857 // + An RBrac will end an address for load/store/prefetch
3858 // + An '!' will indicate a pre-indexed operation.
3860 // It's someone else's responsibility to make sure these tokens are sane
3861 // in the given context!
3863 SMLoc RLoc = Parser.getTok().getLoc();
3864 if (parseOptionalToken(AsmToken::RBrac))
3866 AArch64Operand::CreateToken("]", false, RLoc, getContext()));
3867 SMLoc ELoc = Parser.getTok().getLoc();
3868 if (parseOptionalToken(AsmToken::Exclaim))
3870 AArch64Operand::CreateToken("!", false, ELoc, getContext()));
3873 } while (parseOptionalToken(AsmToken::Comma));
3876 if (parseToken(AsmToken::EndOfStatement, "unexpected token in argument list"))
3882 static inline bool isMatchingOrAlias(unsigned ZReg, unsigned Reg) {
3883 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
3884 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
3885 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
3886 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
3887 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
3888 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
3889 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
3892 // FIXME: This entire function is a giant hack to provide us with decent
3893 // operand range validation/diagnostics until TableGen/MC can be extended
3894 // to support autogeneration of this kind of validation.
3895 bool AArch64AsmParser::validateInstruction(MCInst &Inst, SMLoc &IDLoc,
3896 SmallVectorImpl<SMLoc> &Loc) {
3897 const MCRegisterInfo *RI = getContext().getRegisterInfo();
3898 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
3900 // A prefix only applies to the instruction following it. Here we extract
3901 // prefix information for the next instruction before validating the current
3902 // one so that in the case of failure we don't erronously continue using the
3904 PrefixInfo Prefix = NextPrefix;
3905 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.TSFlags);
3907 // Before validating the instruction in isolation we run through the rules
3908 // applicable when it follows a prefix instruction.
3909 // NOTE: brk & hlt can be prefixed but require no additional validation.
3910 if (Prefix.isActive() &&
3911 (Inst.getOpcode() != AArch64::BRK) &&
3912 (Inst.getOpcode() != AArch64::HLT)) {
3914 // Prefixed intructions must have a destructive operand.
3915 if ((MCID.TSFlags & AArch64::DestructiveInstTypeMask) ==
3916 AArch64::NotDestructive)
3917 return Error(IDLoc, "instruction is unpredictable when following a"
3918 " movprfx, suggest replacing movprfx with mov");
3920 // Destination operands must match.
3921 if (Inst.getOperand(0).getReg() != Prefix.getDstReg())
3922 return Error(Loc[0], "instruction is unpredictable when following a"
3923 " movprfx writing to a different destination");
3925 // Destination operand must not be used in any other location.
3926 for (unsigned i = 1; i < Inst.getNumOperands(); ++i) {
3927 if (Inst.getOperand(i).isReg() &&
3928 (MCID.getOperandConstraint(i, MCOI::TIED_TO) == -1) &&
3929 isMatchingOrAlias(Prefix.getDstReg(), Inst.getOperand(i).getReg()))
3930 return Error(Loc[0], "instruction is unpredictable when following a"
3931 " movprfx and destination also used as non-destructive"
3935 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
3936 if (Prefix.isPredicated()) {
3939 // Find the instructions general predicate.
3940 for (unsigned i = 1; i < Inst.getNumOperands(); ++i)
3941 if (Inst.getOperand(i).isReg() &&
3942 PPRRegClass.contains(Inst.getOperand(i).getReg())) {
3947 // Instruction must be predicated if the movprfx is predicated.
3949 (MCID.TSFlags & AArch64::ElementSizeMask) == AArch64::ElementSizeNone)
3950 return Error(IDLoc, "instruction is unpredictable when following a"
3951 " predicated movprfx, suggest using unpredicated movprfx");
3953 // Instruction must use same general predicate as the movprfx.
3954 if (Inst.getOperand(PgIdx).getReg() != Prefix.getPgReg())
3955 return Error(IDLoc, "instruction is unpredictable when following a"
3956 " predicated movprfx using a different general predicate");
3958 // Instruction element type must match the movprfx.
3959 if ((MCID.TSFlags & AArch64::ElementSizeMask) != Prefix.getElementSize())
3960 return Error(IDLoc, "instruction is unpredictable when following a"
3961 " predicated movprfx with a different element size");
3965 // Check for indexed addressing modes w/ the base register being the
3966 // same as a destination/source register or pair load where
3967 // the Rt == Rt2. All of those are undefined behaviour.
3968 switch (Inst.getOpcode()) {
3969 case AArch64::LDPSWpre:
3970 case AArch64::LDPWpost:
3971 case AArch64::LDPWpre:
3972 case AArch64::LDPXpost:
3973 case AArch64::LDPXpre: {
3974 unsigned Rt = Inst.getOperand(1).getReg();
3975 unsigned Rt2 = Inst.getOperand(2).getReg();
3976 unsigned Rn = Inst.getOperand(3).getReg();
3977 if (RI->isSubRegisterEq(Rn, Rt))
3978 return Error(Loc[0], "unpredictable LDP instruction, writeback base "
3979 "is also a destination");
3980 if (RI->isSubRegisterEq(Rn, Rt2))
3981 return Error(Loc[1], "unpredictable LDP instruction, writeback base "
3982 "is also a destination");
3985 case AArch64::LDPDi:
3986 case AArch64::LDPQi:
3987 case AArch64::LDPSi:
3988 case AArch64::LDPSWi:
3989 case AArch64::LDPWi:
3990 case AArch64::LDPXi: {
3991 unsigned Rt = Inst.getOperand(0).getReg();
3992 unsigned Rt2 = Inst.getOperand(1).getReg();
3994 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
3997 case AArch64::LDPDpost:
3998 case AArch64::LDPDpre:
3999 case AArch64::LDPQpost:
4000 case AArch64::LDPQpre:
4001 case AArch64::LDPSpost:
4002 case AArch64::LDPSpre:
4003 case AArch64::LDPSWpost: {
4004 unsigned Rt = Inst.getOperand(1).getReg();
4005 unsigned Rt2 = Inst.getOperand(2).getReg();
4007 return Error(Loc[1], "unpredictable LDP instruction, Rt2==Rt");
4010 case AArch64::STPDpost:
4011 case AArch64::STPDpre:
4012 case AArch64::STPQpost:
4013 case AArch64::STPQpre:
4014 case AArch64::STPSpost:
4015 case AArch64::STPSpre:
4016 case AArch64::STPWpost:
4017 case AArch64::STPWpre:
4018 case AArch64::STPXpost:
4019 case AArch64::STPXpre: {
4020 unsigned Rt = Inst.getOperand(1).getReg();
4021 unsigned Rt2 = Inst.getOperand(2).getReg();
4022 unsigned Rn = Inst.getOperand(3).getReg();
4023 if (RI->isSubRegisterEq(Rn, Rt))
4024 return Error(Loc[0], "unpredictable STP instruction, writeback base "
4025 "is also a source");
4026 if (RI->isSubRegisterEq(Rn, Rt2))
4027 return Error(Loc[1], "unpredictable STP instruction, writeback base "
4028 "is also a source");
4031 case AArch64::LDRBBpre:
4032 case AArch64::LDRBpre:
4033 case AArch64::LDRHHpre:
4034 case AArch64::LDRHpre:
4035 case AArch64::LDRSBWpre:
4036 case AArch64::LDRSBXpre:
4037 case AArch64::LDRSHWpre:
4038 case AArch64::LDRSHXpre:
4039 case AArch64::LDRSWpre:
4040 case AArch64::LDRWpre:
4041 case AArch64::LDRXpre:
4042 case AArch64::LDRBBpost:
4043 case AArch64::LDRBpost:
4044 case AArch64::LDRHHpost:
4045 case AArch64::LDRHpost:
4046 case AArch64::LDRSBWpost:
4047 case AArch64::LDRSBXpost:
4048 case AArch64::LDRSHWpost:
4049 case AArch64::LDRSHXpost:
4050 case AArch64::LDRSWpost:
4051 case AArch64::LDRWpost:
4052 case AArch64::LDRXpost: {
4053 unsigned Rt = Inst.getOperand(1).getReg();
4054 unsigned Rn = Inst.getOperand(2).getReg();
4055 if (RI->isSubRegisterEq(Rn, Rt))
4056 return Error(Loc[0], "unpredictable LDR instruction, writeback base "
4057 "is also a source");
4060 case AArch64::STRBBpost:
4061 case AArch64::STRBpost:
4062 case AArch64::STRHHpost:
4063 case AArch64::STRHpost:
4064 case AArch64::STRWpost:
4065 case AArch64::STRXpost:
4066 case AArch64::STRBBpre:
4067 case AArch64::STRBpre:
4068 case AArch64::STRHHpre:
4069 case AArch64::STRHpre:
4070 case AArch64::STRWpre:
4071 case AArch64::STRXpre: {
4072 unsigned Rt = Inst.getOperand(1).getReg();
4073 unsigned Rn = Inst.getOperand(2).getReg();
4074 if (RI->isSubRegisterEq(Rn, Rt))
4075 return Error(Loc[0], "unpredictable STR instruction, writeback base "
4076 "is also a source");
4079 case AArch64::STXRB:
4080 case AArch64::STXRH:
4081 case AArch64::STXRW:
4082 case AArch64::STXRX:
4083 case AArch64::STLXRB:
4084 case AArch64::STLXRH:
4085 case AArch64::STLXRW:
4086 case AArch64::STLXRX: {
4087 unsigned Rs = Inst.getOperand(0).getReg();
4088 unsigned Rt = Inst.getOperand(1).getReg();
4089 unsigned Rn = Inst.getOperand(2).getReg();
4090 if (RI->isSubRegisterEq(Rt, Rs) ||
4091 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4092 return Error(Loc[0],
4093 "unpredictable STXR instruction, status is also a source");
4096 case AArch64::STXPW:
4097 case AArch64::STXPX:
4098 case AArch64::STLXPW:
4099 case AArch64::STLXPX: {
4100 unsigned Rs = Inst.getOperand(0).getReg();
4101 unsigned Rt1 = Inst.getOperand(1).getReg();
4102 unsigned Rt2 = Inst.getOperand(2).getReg();
4103 unsigned Rn = Inst.getOperand(3).getReg();
4104 if (RI->isSubRegisterEq(Rt1, Rs) || RI->isSubRegisterEq(Rt2, Rs) ||
4105 (RI->isSubRegisterEq(Rn, Rs) && Rn != AArch64::SP))
4106 return Error(Loc[0],
4107 "unpredictable STXP instruction, status is also a source");
4113 // Now check immediate ranges. Separate from the above as there is overlap
4114 // in the instructions being checked and this keeps the nested conditionals
4116 switch (Inst.getOpcode()) {
4117 case AArch64::ADDSWri:
4118 case AArch64::ADDSXri:
4119 case AArch64::ADDWri:
4120 case AArch64::ADDXri:
4121 case AArch64::SUBSWri:
4122 case AArch64::SUBSXri:
4123 case AArch64::SUBWri:
4124 case AArch64::SUBXri: {
4125 // Annoyingly we can't do this in the isAddSubImm predicate, so there is
4126 // some slight duplication here.
4127 if (Inst.getOperand(2).isExpr()) {
4128 const MCExpr *Expr = Inst.getOperand(2).getExpr();
4129 AArch64MCExpr::VariantKind ELFRefKind;
4130 MCSymbolRefExpr::VariantKind DarwinRefKind;
4132 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
4134 // Only allow these with ADDXri.
4135 if ((DarwinRefKind == MCSymbolRefExpr::VK_PAGEOFF ||
4136 DarwinRefKind == MCSymbolRefExpr::VK_TLVPPAGEOFF) &&
4137 Inst.getOpcode() == AArch64::ADDXri)
4140 // Only allow these with ADDXri/ADDWri
4141 if ((ELFRefKind == AArch64MCExpr::VK_LO12 ||
4142 ELFRefKind == AArch64MCExpr::VK_DTPREL_HI12 ||
4143 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12 ||
4144 ELFRefKind == AArch64MCExpr::VK_DTPREL_LO12_NC ||
4145 ELFRefKind == AArch64MCExpr::VK_TPREL_HI12 ||
4146 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12 ||
4147 ELFRefKind == AArch64MCExpr::VK_TPREL_LO12_NC ||
4148 ELFRefKind == AArch64MCExpr::VK_TLSDESC_LO12 ||
4149 ELFRefKind == AArch64MCExpr::VK_SECREL_LO12 ||
4150 ELFRefKind == AArch64MCExpr::VK_SECREL_HI12) &&
4151 (Inst.getOpcode() == AArch64::ADDXri ||
4152 Inst.getOpcode() == AArch64::ADDWri))
4155 // Don't allow symbol refs in the immediate field otherwise
4156 // Note: Loc.back() may be Loc[1] or Loc[2] depending on the number of
4157 // operands of the original instruction (i.e. 'add w0, w1, borked' vs
4158 // 'cmp w0, 'borked')
4159 return Error(Loc.back(), "invalid immediate expression");
4161 // We don't validate more complex expressions here
4170 static std::string AArch64MnemonicSpellCheck(StringRef S,
4171 const FeatureBitset &FBS,
4172 unsigned VariantID = 0);
4174 bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
4176 OperandVector &Operands) {
4178 case Match_InvalidTiedOperand: {
4179 RegConstraintEqualityTy EqTy =
4180 static_cast<const AArch64Operand &>(*Operands[ErrorInfo])
4181 .getRegEqualityTy();
4183 case RegConstraintEqualityTy::EqualsSubReg:
4184 return Error(Loc, "operand must be 64-bit form of destination register");
4185 case RegConstraintEqualityTy::EqualsSuperReg:
4186 return Error(Loc, "operand must be 32-bit form of destination register");
4187 case RegConstraintEqualityTy::EqualsReg:
4188 return Error(Loc, "operand must match destination register");
4190 llvm_unreachable("Unknown RegConstraintEqualityTy");
4192 case Match_MissingFeature:
4194 "instruction requires a CPU feature not currently enabled");
4195 case Match_InvalidOperand:
4196 return Error(Loc, "invalid operand for instruction");
4197 case Match_InvalidSuffix:
4198 return Error(Loc, "invalid type suffix for instruction");
4199 case Match_InvalidCondCode:
4200 return Error(Loc, "expected AArch64 condition code");
4201 case Match_AddSubRegExtendSmall:
4203 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
4204 case Match_AddSubRegExtendLarge:
4206 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
4207 case Match_AddSubSecondSource:
4209 "expected compatible register, symbol or integer in range [0, 4095]");
4210 case Match_LogicalSecondSource:
4211 return Error(Loc, "expected compatible register or logical immediate");
4212 case Match_InvalidMovImm32Shift:
4213 return Error(Loc, "expected 'lsl' with optional integer 0 or 16");
4214 case Match_InvalidMovImm64Shift:
4215 return Error(Loc, "expected 'lsl' with optional integer 0, 16, 32 or 48");
4216 case Match_AddSubRegShift32:
4218 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
4219 case Match_AddSubRegShift64:
4221 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
4222 case Match_InvalidFPImm:
4224 "expected compatible register or floating-point constant");
4225 case Match_InvalidMemoryIndexedSImm6:
4226 return Error(Loc, "index must be an integer in range [-32, 31].");
4227 case Match_InvalidMemoryIndexedSImm5:
4228 return Error(Loc, "index must be an integer in range [-16, 15].");
4229 case Match_InvalidMemoryIndexed1SImm4:
4230 return Error(Loc, "index must be an integer in range [-8, 7].");
4231 case Match_InvalidMemoryIndexed2SImm4:
4232 return Error(Loc, "index must be a multiple of 2 in range [-16, 14].");
4233 case Match_InvalidMemoryIndexed3SImm4:
4234 return Error(Loc, "index must be a multiple of 3 in range [-24, 21].");
4235 case Match_InvalidMemoryIndexed4SImm4:
4236 return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
4237 case Match_InvalidMemoryIndexed16SImm4:
4238 return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
4239 case Match_InvalidMemoryIndexed1SImm6:
4240 return Error(Loc, "index must be an integer in range [-32, 31].");
4241 case Match_InvalidMemoryIndexedSImm8:
4242 return Error(Loc, "index must be an integer in range [-128, 127].");
4243 case Match_InvalidMemoryIndexedSImm9:
4244 return Error(Loc, "index must be an integer in range [-256, 255].");
4245 case Match_InvalidMemoryIndexed16SImm9:
4246 return Error(Loc, "index must be a multiple of 16 in range [-4096, 4080].");
4247 case Match_InvalidMemoryIndexed8SImm10:
4248 return Error(Loc, "index must be a multiple of 8 in range [-4096, 4088].");
4249 case Match_InvalidMemoryIndexed4SImm7:
4250 return Error(Loc, "index must be a multiple of 4 in range [-256, 252].");
4251 case Match_InvalidMemoryIndexed8SImm7:
4252 return Error(Loc, "index must be a multiple of 8 in range [-512, 504].");
4253 case Match_InvalidMemoryIndexed16SImm7:
4254 return Error(Loc, "index must be a multiple of 16 in range [-1024, 1008].");
4255 case Match_InvalidMemoryIndexed8UImm5:
4256 return Error(Loc, "index must be a multiple of 8 in range [0, 248].");
4257 case Match_InvalidMemoryIndexed4UImm5:
4258 return Error(Loc, "index must be a multiple of 4 in range [0, 124].");
4259 case Match_InvalidMemoryIndexed2UImm5:
4260 return Error(Loc, "index must be a multiple of 2 in range [0, 62].");
4261 case Match_InvalidMemoryIndexed8UImm6:
4262 return Error(Loc, "index must be a multiple of 8 in range [0, 504].");
4263 case Match_InvalidMemoryIndexed16UImm6:
4264 return Error(Loc, "index must be a multiple of 16 in range [0, 1008].");
4265 case Match_InvalidMemoryIndexed4UImm6:
4266 return Error(Loc, "index must be a multiple of 4 in range [0, 252].");
4267 case Match_InvalidMemoryIndexed2UImm6:
4268 return Error(Loc, "index must be a multiple of 2 in range [0, 126].");
4269 case Match_InvalidMemoryIndexed1UImm6:
4270 return Error(Loc, "index must be in range [0, 63].");
4271 case Match_InvalidMemoryWExtend8:
4273 "expected 'uxtw' or 'sxtw' with optional shift of #0");
4274 case Match_InvalidMemoryWExtend16:
4276 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
4277 case Match_InvalidMemoryWExtend32:
4279 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
4280 case Match_InvalidMemoryWExtend64:
4282 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
4283 case Match_InvalidMemoryWExtend128:
4285 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
4286 case Match_InvalidMemoryXExtend8:
4288 "expected 'lsl' or 'sxtx' with optional shift of #0");
4289 case Match_InvalidMemoryXExtend16:
4291 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
4292 case Match_InvalidMemoryXExtend32:
4294 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
4295 case Match_InvalidMemoryXExtend64:
4297 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
4298 case Match_InvalidMemoryXExtend128:
4300 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
4301 case Match_InvalidMemoryIndexed1:
4302 return Error(Loc, "index must be an integer in range [0, 4095].");
4303 case Match_InvalidMemoryIndexed2:
4304 return Error(Loc, "index must be a multiple of 2 in range [0, 8190].");
4305 case Match_InvalidMemoryIndexed4:
4306 return Error(Loc, "index must be a multiple of 4 in range [0, 16380].");
4307 case Match_InvalidMemoryIndexed8:
4308 return Error(Loc, "index must be a multiple of 8 in range [0, 32760].");
4309 case Match_InvalidMemoryIndexed16:
4310 return Error(Loc, "index must be a multiple of 16 in range [0, 65520].");
4311 case Match_InvalidImm0_1:
4312 return Error(Loc, "immediate must be an integer in range [0, 1].");
4313 case Match_InvalidImm0_7:
4314 return Error(Loc, "immediate must be an integer in range [0, 7].");
4315 case Match_InvalidImm0_15:
4316 return Error(Loc, "immediate must be an integer in range [0, 15].");
4317 case Match_InvalidImm0_31:
4318 return Error(Loc, "immediate must be an integer in range [0, 31].");
4319 case Match_InvalidImm0_63:
4320 return Error(Loc, "immediate must be an integer in range [0, 63].");
4321 case Match_InvalidImm0_127:
4322 return Error(Loc, "immediate must be an integer in range [0, 127].");
4323 case Match_InvalidImm0_255:
4324 return Error(Loc, "immediate must be an integer in range [0, 255].");
4325 case Match_InvalidImm0_65535:
4326 return Error(Loc, "immediate must be an integer in range [0, 65535].");
4327 case Match_InvalidImm1_8:
4328 return Error(Loc, "immediate must be an integer in range [1, 8].");
4329 case Match_InvalidImm1_16:
4330 return Error(Loc, "immediate must be an integer in range [1, 16].");
4331 case Match_InvalidImm1_32:
4332 return Error(Loc, "immediate must be an integer in range [1, 32].");
4333 case Match_InvalidImm1_64:
4334 return Error(Loc, "immediate must be an integer in range [1, 64].");
4335 case Match_InvalidSVEAddSubImm8:
4336 return Error(Loc, "immediate must be an integer in range [0, 255]"
4337 " with a shift amount of 0");
4338 case Match_InvalidSVEAddSubImm16:
4339 case Match_InvalidSVEAddSubImm32:
4340 case Match_InvalidSVEAddSubImm64:
4341 return Error(Loc, "immediate must be an integer in range [0, 255] or a "
4342 "multiple of 256 in range [256, 65280]");
4343 case Match_InvalidSVECpyImm8:
4344 return Error(Loc, "immediate must be an integer in range [-128, 255]"
4345 " with a shift amount of 0");
4346 case Match_InvalidSVECpyImm16:
4347 return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
4348 "multiple of 256 in range [-32768, 65280]");
4349 case Match_InvalidSVECpyImm32:
4350 case Match_InvalidSVECpyImm64:
4351 return Error(Loc, "immediate must be an integer in range [-128, 127] or a "
4352 "multiple of 256 in range [-32768, 32512]");
4353 case Match_InvalidIndexRange1_1:
4354 return Error(Loc, "expected lane specifier '[1]'");
4355 case Match_InvalidIndexRange0_15:
4356 return Error(Loc, "vector lane must be an integer in range [0, 15].");
4357 case Match_InvalidIndexRange0_7:
4358 return Error(Loc, "vector lane must be an integer in range [0, 7].");
4359 case Match_InvalidIndexRange0_3:
4360 return Error(Loc, "vector lane must be an integer in range [0, 3].");
4361 case Match_InvalidIndexRange0_1:
4362 return Error(Loc, "vector lane must be an integer in range [0, 1].");
4363 case Match_InvalidSVEIndexRange0_63:
4364 return Error(Loc, "vector lane must be an integer in range [0, 63].");
4365 case Match_InvalidSVEIndexRange0_31:
4366 return Error(Loc, "vector lane must be an integer in range [0, 31].");
4367 case Match_InvalidSVEIndexRange0_15:
4368 return Error(Loc, "vector lane must be an integer in range [0, 15].");
4369 case Match_InvalidSVEIndexRange0_7:
4370 return Error(Loc, "vector lane must be an integer in range [0, 7].");
4371 case Match_InvalidSVEIndexRange0_3:
4372 return Error(Loc, "vector lane must be an integer in range [0, 3].");
4373 case Match_InvalidLabel:
4374 return Error(Loc, "expected label or encodable integer pc offset");
4376 return Error(Loc, "expected readable system register");
4378 return Error(Loc, "expected writable system register or pstate");
4379 case Match_InvalidComplexRotationEven:
4380 return Error(Loc, "complex rotation must be 0, 90, 180 or 270.");
4381 case Match_InvalidComplexRotationOdd:
4382 return Error(Loc, "complex rotation must be 90 or 270.");
4383 case Match_MnemonicFail: {
4384 std::string Suggestion = AArch64MnemonicSpellCheck(
4385 ((AArch64Operand &)*Operands[0]).getToken(),
4386 ComputeAvailableFeatures(STI->getFeatureBits()));
4387 return Error(Loc, "unrecognized instruction mnemonic" + Suggestion);
4389 case Match_InvalidGPR64shifted8:
4390 return Error(Loc, "register must be x0..x30 or xzr, without shift");
4391 case Match_InvalidGPR64shifted16:
4392 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #1'");
4393 case Match_InvalidGPR64shifted32:
4394 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #2'");
4395 case Match_InvalidGPR64shifted64:
4396 return Error(Loc, "register must be x0..x30 or xzr, with required shift 'lsl #3'");
4397 case Match_InvalidGPR64NoXZRshifted8:
4398 return Error(Loc, "register must be x0..x30 without shift");
4399 case Match_InvalidGPR64NoXZRshifted16:
4400 return Error(Loc, "register must be x0..x30 with required shift 'lsl #1'");
4401 case Match_InvalidGPR64NoXZRshifted32:
4402 return Error(Loc, "register must be x0..x30 with required shift 'lsl #2'");
4403 case Match_InvalidGPR64NoXZRshifted64:
4404 return Error(Loc, "register must be x0..x30 with required shift 'lsl #3'");
4405 case Match_InvalidZPR32UXTW8:
4406 case Match_InvalidZPR32SXTW8:
4407 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
4408 case Match_InvalidZPR32UXTW16:
4409 case Match_InvalidZPR32SXTW16:
4410 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
4411 case Match_InvalidZPR32UXTW32:
4412 case Match_InvalidZPR32SXTW32:
4413 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
4414 case Match_InvalidZPR32UXTW64:
4415 case Match_InvalidZPR32SXTW64:
4416 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
4417 case Match_InvalidZPR64UXTW8:
4418 case Match_InvalidZPR64SXTW8:
4419 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
4420 case Match_InvalidZPR64UXTW16:
4421 case Match_InvalidZPR64SXTW16:
4422 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
4423 case Match_InvalidZPR64UXTW32:
4424 case Match_InvalidZPR64SXTW32:
4425 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
4426 case Match_InvalidZPR64UXTW64:
4427 case Match_InvalidZPR64SXTW64:
4428 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
4429 case Match_InvalidZPR32LSL8:
4430 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s'");
4431 case Match_InvalidZPR32LSL16:
4432 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
4433 case Match_InvalidZPR32LSL32:
4434 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
4435 case Match_InvalidZPR32LSL64:
4436 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
4437 case Match_InvalidZPR64LSL8:
4438 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d'");
4439 case Match_InvalidZPR64LSL16:
4440 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
4441 case Match_InvalidZPR64LSL32:
4442 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
4443 case Match_InvalidZPR64LSL64:
4444 return Error(Loc, "invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
4445 case Match_InvalidZPR0:
4446 return Error(Loc, "expected register without element width suffix");
4447 case Match_InvalidZPR8:
4448 case Match_InvalidZPR16:
4449 case Match_InvalidZPR32:
4450 case Match_InvalidZPR64:
4451 case Match_InvalidZPR128:
4452 return Error(Loc, "invalid element width");
4453 case Match_InvalidZPR_3b8:
4454 return Error(Loc, "Invalid restricted vector register, expected z0.b..z7.b");
4455 case Match_InvalidZPR_3b16:
4456 return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h");
4457 case Match_InvalidZPR_3b32:
4458 return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s");
4459 case Match_InvalidZPR_4b16:
4460 return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h");
4461 case Match_InvalidZPR_4b32:
4462 return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s");
4463 case Match_InvalidZPR_4b64:
4464 return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d");
4465 case Match_InvalidSVEPattern:
4466 return Error(Loc, "invalid predicate pattern");
4467 case Match_InvalidSVEPredicateAnyReg:
4468 case Match_InvalidSVEPredicateBReg:
4469 case Match_InvalidSVEPredicateHReg:
4470 case Match_InvalidSVEPredicateSReg:
4471 case Match_InvalidSVEPredicateDReg:
4472 return Error(Loc, "invalid predicate register.");
4473 case Match_InvalidSVEPredicate3bAnyReg:
4474 return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)");
4475 case Match_InvalidSVEPredicate3bBReg:
4476 return Error(Loc, "invalid restricted predicate register, expected p0.b..p7.b");
4477 case Match_InvalidSVEPredicate3bHReg:
4478 return Error(Loc, "invalid restricted predicate register, expected p0.h..p7.h");
4479 case Match_InvalidSVEPredicate3bSReg:
4480 return Error(Loc, "invalid restricted predicate register, expected p0.s..p7.s");
4481 case Match_InvalidSVEPredicate3bDReg:
4482 return Error(Loc, "invalid restricted predicate register, expected p0.d..p7.d");
4483 case Match_InvalidSVEExactFPImmOperandHalfOne:
4484 return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0.");
4485 case Match_InvalidSVEExactFPImmOperandHalfTwo:
4486 return Error(Loc, "Invalid floating point constant, expected 0.5 or 2.0.");
4487 case Match_InvalidSVEExactFPImmOperandZeroOne:
4488 return Error(Loc, "Invalid floating point constant, expected 0.0 or 1.0.");
4490 llvm_unreachable("unexpected error code!");
4494 static const char *getSubtargetFeatureName(uint64_t Val);
4496 bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
4497 OperandVector &Operands,
4499 uint64_t &ErrorInfo,
4500 bool MatchingInlineAsm) {
4501 assert(!Operands.empty() && "Unexpect empty operand list!");
4502 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[0]);
4503 assert(Op.isToken() && "Leading operand should always be a mnemonic!");
4505 StringRef Tok = Op.getToken();
4506 unsigned NumOperands = Operands.size();
4508 if (NumOperands == 4 && Tok == "lsl") {
4509 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
4510 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
4511 if (Op2.isScalarReg() && Op3.isImm()) {
4512 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
4514 uint64_t Op3Val = Op3CE->getValue();
4515 uint64_t NewOp3Val = 0;
4516 uint64_t NewOp4Val = 0;
4517 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].contains(
4519 NewOp3Val = (32 - Op3Val) & 0x1f;
4520 NewOp4Val = 31 - Op3Val;
4522 NewOp3Val = (64 - Op3Val) & 0x3f;
4523 NewOp4Val = 63 - Op3Val;
4526 const MCExpr *NewOp3 = MCConstantExpr::create(NewOp3Val, getContext());
4527 const MCExpr *NewOp4 = MCConstantExpr::create(NewOp4Val, getContext());
4529 Operands[0] = AArch64Operand::CreateToken(
4530 "ubfm", false, Op.getStartLoc(), getContext());
4531 Operands.push_back(AArch64Operand::CreateImm(
4532 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
4533 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
4534 Op3.getEndLoc(), getContext());
4537 } else if (NumOperands == 4 && Tok == "bfc") {
4538 // FIXME: Horrible hack to handle BFC->BFM alias.
4539 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
4540 AArch64Operand LSBOp = static_cast<AArch64Operand &>(*Operands[2]);
4541 AArch64Operand WidthOp = static_cast<AArch64Operand &>(*Operands[3]);
4543 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
4544 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
4545 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
4547 if (LSBCE && WidthCE) {
4548 uint64_t LSB = LSBCE->getValue();
4549 uint64_t Width = WidthCE->getValue();
4551 uint64_t RegWidth = 0;
4552 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4558 if (LSB >= RegWidth)
4559 return Error(LSBOp.getStartLoc(),
4560 "expected integer in range [0, 31]");
4561 if (Width < 1 || Width > RegWidth)
4562 return Error(WidthOp.getStartLoc(),
4563 "expected integer in range [1, 32]");
4567 ImmR = (32 - LSB) & 0x1f;
4569 ImmR = (64 - LSB) & 0x3f;
4571 uint64_t ImmS = Width - 1;
4573 if (ImmR != 0 && ImmS >= ImmR)
4574 return Error(WidthOp.getStartLoc(),
4575 "requested insert overflows register");
4577 const MCExpr *ImmRExpr = MCConstantExpr::create(ImmR, getContext());
4578 const MCExpr *ImmSExpr = MCConstantExpr::create(ImmS, getContext());
4579 Operands[0] = AArch64Operand::CreateToken(
4580 "bfm", false, Op.getStartLoc(), getContext());
4581 Operands[2] = AArch64Operand::CreateReg(
4582 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
4583 SMLoc(), SMLoc(), getContext());
4584 Operands[3] = AArch64Operand::CreateImm(
4585 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
4586 Operands.emplace_back(
4587 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
4588 WidthOp.getEndLoc(), getContext()));
4591 } else if (NumOperands == 5) {
4592 // FIXME: Horrible hack to handle the BFI -> BFM, SBFIZ->SBFM, and
4593 // UBFIZ -> UBFM aliases.
4594 if (Tok == "bfi" || Tok == "sbfiz" || Tok == "ubfiz") {
4595 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
4596 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
4597 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
4599 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
4600 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
4601 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
4603 if (Op3CE && Op4CE) {
4604 uint64_t Op3Val = Op3CE->getValue();
4605 uint64_t Op4Val = Op4CE->getValue();
4607 uint64_t RegWidth = 0;
4608 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4614 if (Op3Val >= RegWidth)
4615 return Error(Op3.getStartLoc(),
4616 "expected integer in range [0, 31]");
4617 if (Op4Val < 1 || Op4Val > RegWidth)
4618 return Error(Op4.getStartLoc(),
4619 "expected integer in range [1, 32]");
4621 uint64_t NewOp3Val = 0;
4623 NewOp3Val = (32 - Op3Val) & 0x1f;
4625 NewOp3Val = (64 - Op3Val) & 0x3f;
4627 uint64_t NewOp4Val = Op4Val - 1;
4629 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
4630 return Error(Op4.getStartLoc(),
4631 "requested insert overflows register");
4633 const MCExpr *NewOp3 =
4634 MCConstantExpr::create(NewOp3Val, getContext());
4635 const MCExpr *NewOp4 =
4636 MCConstantExpr::create(NewOp4Val, getContext());
4637 Operands[3] = AArch64Operand::CreateImm(
4638 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
4639 Operands[4] = AArch64Operand::CreateImm(
4640 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
4642 Operands[0] = AArch64Operand::CreateToken(
4643 "bfm", false, Op.getStartLoc(), getContext());
4644 else if (Tok == "sbfiz")
4645 Operands[0] = AArch64Operand::CreateToken(
4646 "sbfm", false, Op.getStartLoc(), getContext());
4647 else if (Tok == "ubfiz")
4648 Operands[0] = AArch64Operand::CreateToken(
4649 "ubfm", false, Op.getStartLoc(), getContext());
4651 llvm_unreachable("No valid mnemonic for alias?");
4655 // FIXME: Horrible hack to handle the BFXIL->BFM, SBFX->SBFM, and
4656 // UBFX -> UBFM aliases.
4657 } else if (NumOperands == 5 &&
4658 (Tok == "bfxil" || Tok == "sbfx" || Tok == "ubfx")) {
4659 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
4660 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
4661 AArch64Operand &Op4 = static_cast<AArch64Operand &>(*Operands[4]);
4663 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
4664 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
4665 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
4667 if (Op3CE && Op4CE) {
4668 uint64_t Op3Val = Op3CE->getValue();
4669 uint64_t Op4Val = Op4CE->getValue();
4671 uint64_t RegWidth = 0;
4672 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4678 if (Op3Val >= RegWidth)
4679 return Error(Op3.getStartLoc(),
4680 "expected integer in range [0, 31]");
4681 if (Op4Val < 1 || Op4Val > RegWidth)
4682 return Error(Op4.getStartLoc(),
4683 "expected integer in range [1, 32]");
4685 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
4687 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
4688 return Error(Op4.getStartLoc(),
4689 "requested extract overflows register");
4691 const MCExpr *NewOp4 =
4692 MCConstantExpr::create(NewOp4Val, getContext());
4693 Operands[4] = AArch64Operand::CreateImm(
4694 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
4696 Operands[0] = AArch64Operand::CreateToken(
4697 "bfm", false, Op.getStartLoc(), getContext());
4698 else if (Tok == "sbfx")
4699 Operands[0] = AArch64Operand::CreateToken(
4700 "sbfm", false, Op.getStartLoc(), getContext());
4701 else if (Tok == "ubfx")
4702 Operands[0] = AArch64Operand::CreateToken(
4703 "ubfm", false, Op.getStartLoc(), getContext());
4705 llvm_unreachable("No valid mnemonic for alias?");
4711 // The Cyclone CPU and early successors didn't execute the zero-cycle zeroing
4712 // instruction for FP registers correctly in some rare circumstances. Convert
4713 // it to a safe instruction and warn (because silently changing someone's
4714 // assembly is rude).
4715 if (getSTI().getFeatureBits()[AArch64::FeatureZCZeroingFPWorkaround] &&
4716 NumOperands == 4 && Tok == "movi") {
4717 AArch64Operand &Op1 = static_cast<AArch64Operand &>(*Operands[1]);
4718 AArch64Operand &Op2 = static_cast<AArch64Operand &>(*Operands[2]);
4719 AArch64Operand &Op3 = static_cast<AArch64Operand &>(*Operands[3]);
4720 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
4721 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
4722 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
4723 if (Suffix.lower() == ".2d" &&
4724 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
4725 Warning(IDLoc, "instruction movi.2d with immediate #0 may not function"
4726 " correctly on this CPU, converting to equivalent movi.16b");
4727 // Switch the suffix to .16b.
4728 unsigned Idx = Op1.isToken() ? 1 : 2;
4729 Operands[Idx] = AArch64Operand::CreateToken(".16b", false, IDLoc,
4735 // FIXME: Horrible hack for sxtw and uxtw with Wn src and Xd dst operands.
4736 // InstAlias can't quite handle this since the reg classes aren't
4738 if (NumOperands == 3 && (Tok == "sxtw" || Tok == "uxtw")) {
4739 // The source register can be Wn here, but the matcher expects a
4740 // GPR64. Twiddle it here if necessary.
4741 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
4742 if (Op.isScalarReg()) {
4743 unsigned Reg = getXRegFromWReg(Op.getReg());
4744 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
4745 Op.getStartLoc(), Op.getEndLoc(),
4749 // FIXME: Likewise for sxt[bh] with a Xd dst operand
4750 else if (NumOperands == 3 && (Tok == "sxtb" || Tok == "sxth")) {
4751 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
4752 if (Op.isScalarReg() &&
4753 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4755 // The source register can be Wn here, but the matcher expects a
4756 // GPR64. Twiddle it here if necessary.
4757 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[2]);
4758 if (Op.isScalarReg()) {
4759 unsigned Reg = getXRegFromWReg(Op.getReg());
4760 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
4762 Op.getEndLoc(), getContext());
4766 // FIXME: Likewise for uxt[bh] with a Xd dst operand
4767 else if (NumOperands == 3 && (Tok == "uxtb" || Tok == "uxth")) {
4768 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
4769 if (Op.isScalarReg() &&
4770 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4772 // The source register can be Wn here, but the matcher expects a
4773 // GPR32. Twiddle it here if necessary.
4774 AArch64Operand &Op = static_cast<AArch64Operand &>(*Operands[1]);
4775 if (Op.isScalarReg()) {
4776 unsigned Reg = getWRegFromXReg(Op.getReg());
4777 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
4779 Op.getEndLoc(), getContext());
4785 FeatureBitset MissingFeatures;
4786 // First try to match against the secondary set of tables containing the
4787 // short-form NEON instructions (e.g. "fadd.2s v0, v1, v2").
4788 unsigned MatchResult =
4789 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
4790 MatchingInlineAsm, 1);
4792 // If that fails, try against the alternate table containing long-form NEON:
4793 // "fadd v0.2s, v1.2s, v2.2s"
4794 if (MatchResult != Match_Success) {
4795 // But first, save the short-form match result: we can use it in case the
4796 // long-form match also fails.
4797 auto ShortFormNEONErrorInfo = ErrorInfo;
4798 auto ShortFormNEONMatchResult = MatchResult;
4799 auto ShortFormNEONMissingFeatures = MissingFeatures;
4802 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
4803 MatchingInlineAsm, 0);
4805 // Now, both matches failed, and the long-form match failed on the mnemonic
4806 // suffix token operand. The short-form match failure is probably more
4807 // relevant: use it instead.
4808 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
4809 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
4810 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
4811 MatchResult = ShortFormNEONMatchResult;
4812 ErrorInfo = ShortFormNEONErrorInfo;
4813 MissingFeatures = ShortFormNEONMissingFeatures;
4817 switch (MatchResult) {
4818 case Match_Success: {
4819 // Perform range checking and other semantic validations
4820 SmallVector<SMLoc, 8> OperandLocs;
4821 NumOperands = Operands.size();
4822 for (unsigned i = 1; i < NumOperands; ++i)
4823 OperandLocs.push_back(Operands[i]->getStartLoc());
4824 if (validateInstruction(Inst, IDLoc, OperandLocs))
4828 Out.EmitInstruction(Inst, getSTI());
4831 case Match_MissingFeature: {
4832 assert(MissingFeatures.any() && "Unknown missing feature!");
4833 // Special case the error message for the very common case where only
4834 // a single subtarget feature is missing (neon, e.g.).
4835 std::string Msg = "instruction requires:";
4836 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
4837 if (MissingFeatures[i]) {
4839 Msg += getSubtargetFeatureName(i);
4842 return Error(IDLoc, Msg);
4844 case Match_MnemonicFail:
4845 return showMatchError(IDLoc, MatchResult, ErrorInfo, Operands);
4846 case Match_InvalidOperand: {
4847 SMLoc ErrorLoc = IDLoc;
4849 if (ErrorInfo != ~0ULL) {
4850 if (ErrorInfo >= Operands.size())
4851 return Error(IDLoc, "too few operands for instruction",
4852 SMRange(IDLoc, getTok().getLoc()));
4854 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
4855 if (ErrorLoc == SMLoc())
4858 // If the match failed on a suffix token operand, tweak the diagnostic
4860 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
4861 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
4862 MatchResult = Match_InvalidSuffix;
4864 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
4866 case Match_InvalidTiedOperand:
4867 case Match_InvalidMemoryIndexed1:
4868 case Match_InvalidMemoryIndexed2:
4869 case Match_InvalidMemoryIndexed4:
4870 case Match_InvalidMemoryIndexed8:
4871 case Match_InvalidMemoryIndexed16:
4872 case Match_InvalidCondCode:
4873 case Match_AddSubRegExtendSmall:
4874 case Match_AddSubRegExtendLarge:
4875 case Match_AddSubSecondSource:
4876 case Match_LogicalSecondSource:
4877 case Match_AddSubRegShift32:
4878 case Match_AddSubRegShift64:
4879 case Match_InvalidMovImm32Shift:
4880 case Match_InvalidMovImm64Shift:
4881 case Match_InvalidFPImm:
4882 case Match_InvalidMemoryWExtend8:
4883 case Match_InvalidMemoryWExtend16:
4884 case Match_InvalidMemoryWExtend32:
4885 case Match_InvalidMemoryWExtend64:
4886 case Match_InvalidMemoryWExtend128:
4887 case Match_InvalidMemoryXExtend8:
4888 case Match_InvalidMemoryXExtend16:
4889 case Match_InvalidMemoryXExtend32:
4890 case Match_InvalidMemoryXExtend64:
4891 case Match_InvalidMemoryXExtend128:
4892 case Match_InvalidMemoryIndexed1SImm4:
4893 case Match_InvalidMemoryIndexed2SImm4:
4894 case Match_InvalidMemoryIndexed3SImm4:
4895 case Match_InvalidMemoryIndexed4SImm4:
4896 case Match_InvalidMemoryIndexed1SImm6:
4897 case Match_InvalidMemoryIndexed16SImm4:
4898 case Match_InvalidMemoryIndexed4SImm7:
4899 case Match_InvalidMemoryIndexed8SImm7:
4900 case Match_InvalidMemoryIndexed16SImm7:
4901 case Match_InvalidMemoryIndexed8UImm5:
4902 case Match_InvalidMemoryIndexed4UImm5:
4903 case Match_InvalidMemoryIndexed2UImm5:
4904 case Match_InvalidMemoryIndexed1UImm6:
4905 case Match_InvalidMemoryIndexed2UImm6:
4906 case Match_InvalidMemoryIndexed4UImm6:
4907 case Match_InvalidMemoryIndexed8UImm6:
4908 case Match_InvalidMemoryIndexed16UImm6:
4909 case Match_InvalidMemoryIndexedSImm6:
4910 case Match_InvalidMemoryIndexedSImm5:
4911 case Match_InvalidMemoryIndexedSImm8:
4912 case Match_InvalidMemoryIndexedSImm9:
4913 case Match_InvalidMemoryIndexed16SImm9:
4914 case Match_InvalidMemoryIndexed8SImm10:
4915 case Match_InvalidImm0_1:
4916 case Match_InvalidImm0_7:
4917 case Match_InvalidImm0_15:
4918 case Match_InvalidImm0_31:
4919 case Match_InvalidImm0_63:
4920 case Match_InvalidImm0_127:
4921 case Match_InvalidImm0_255:
4922 case Match_InvalidImm0_65535:
4923 case Match_InvalidImm1_8:
4924 case Match_InvalidImm1_16:
4925 case Match_InvalidImm1_32:
4926 case Match_InvalidImm1_64:
4927 case Match_InvalidSVEAddSubImm8:
4928 case Match_InvalidSVEAddSubImm16:
4929 case Match_InvalidSVEAddSubImm32:
4930 case Match_InvalidSVEAddSubImm64:
4931 case Match_InvalidSVECpyImm8:
4932 case Match_InvalidSVECpyImm16:
4933 case Match_InvalidSVECpyImm32:
4934 case Match_InvalidSVECpyImm64:
4935 case Match_InvalidIndexRange1_1:
4936 case Match_InvalidIndexRange0_15:
4937 case Match_InvalidIndexRange0_7:
4938 case Match_InvalidIndexRange0_3:
4939 case Match_InvalidIndexRange0_1:
4940 case Match_InvalidSVEIndexRange0_63:
4941 case Match_InvalidSVEIndexRange0_31:
4942 case Match_InvalidSVEIndexRange0_15:
4943 case Match_InvalidSVEIndexRange0_7:
4944 case Match_InvalidSVEIndexRange0_3:
4945 case Match_InvalidLabel:
4946 case Match_InvalidComplexRotationEven:
4947 case Match_InvalidComplexRotationOdd:
4948 case Match_InvalidGPR64shifted8:
4949 case Match_InvalidGPR64shifted16:
4950 case Match_InvalidGPR64shifted32:
4951 case Match_InvalidGPR64shifted64:
4952 case Match_InvalidGPR64NoXZRshifted8:
4953 case Match_InvalidGPR64NoXZRshifted16:
4954 case Match_InvalidGPR64NoXZRshifted32:
4955 case Match_InvalidGPR64NoXZRshifted64:
4956 case Match_InvalidZPR32UXTW8:
4957 case Match_InvalidZPR32UXTW16:
4958 case Match_InvalidZPR32UXTW32:
4959 case Match_InvalidZPR32UXTW64:
4960 case Match_InvalidZPR32SXTW8:
4961 case Match_InvalidZPR32SXTW16:
4962 case Match_InvalidZPR32SXTW32:
4963 case Match_InvalidZPR32SXTW64:
4964 case Match_InvalidZPR64UXTW8:
4965 case Match_InvalidZPR64SXTW8:
4966 case Match_InvalidZPR64UXTW16:
4967 case Match_InvalidZPR64SXTW16:
4968 case Match_InvalidZPR64UXTW32:
4969 case Match_InvalidZPR64SXTW32:
4970 case Match_InvalidZPR64UXTW64:
4971 case Match_InvalidZPR64SXTW64:
4972 case Match_InvalidZPR32LSL8:
4973 case Match_InvalidZPR32LSL16:
4974 case Match_InvalidZPR32LSL32:
4975 case Match_InvalidZPR32LSL64:
4976 case Match_InvalidZPR64LSL8:
4977 case Match_InvalidZPR64LSL16:
4978 case Match_InvalidZPR64LSL32:
4979 case Match_InvalidZPR64LSL64:
4980 case Match_InvalidZPR0:
4981 case Match_InvalidZPR8:
4982 case Match_InvalidZPR16:
4983 case Match_InvalidZPR32:
4984 case Match_InvalidZPR64:
4985 case Match_InvalidZPR128:
4986 case Match_InvalidZPR_3b8:
4987 case Match_InvalidZPR_3b16:
4988 case Match_InvalidZPR_3b32:
4989 case Match_InvalidZPR_4b16:
4990 case Match_InvalidZPR_4b32:
4991 case Match_InvalidZPR_4b64:
4992 case Match_InvalidSVEPredicateAnyReg:
4993 case Match_InvalidSVEPattern:
4994 case Match_InvalidSVEPredicateBReg:
4995 case Match_InvalidSVEPredicateHReg:
4996 case Match_InvalidSVEPredicateSReg:
4997 case Match_InvalidSVEPredicateDReg:
4998 case Match_InvalidSVEPredicate3bAnyReg:
4999 case Match_InvalidSVEPredicate3bBReg:
5000 case Match_InvalidSVEPredicate3bHReg:
5001 case Match_InvalidSVEPredicate3bSReg:
5002 case Match_InvalidSVEPredicate3bDReg:
5003 case Match_InvalidSVEExactFPImmOperandHalfOne:
5004 case Match_InvalidSVEExactFPImmOperandHalfTwo:
5005 case Match_InvalidSVEExactFPImmOperandZeroOne:
5008 if (ErrorInfo >= Operands.size())
5009 return Error(IDLoc, "too few operands for instruction", SMRange(IDLoc, (*Operands.back()).getEndLoc()));
5010 // Any time we get here, there's nothing fancy to do. Just get the
5011 // operand SMLoc and display the diagnostic.
5012 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
5013 if (ErrorLoc == SMLoc())
5015 return showMatchError(ErrorLoc, MatchResult, ErrorInfo, Operands);
5019 llvm_unreachable("Implement any new match types added!");
5022 /// ParseDirective parses the arm specific directives
5023 bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
5024 const MCObjectFileInfo::Environment Format =
5025 getContext().getObjectFileInfo()->getObjectFileType();
5026 bool IsMachO = Format == MCObjectFileInfo::IsMachO;
5028 StringRef IDVal = DirectiveID.getIdentifier();
5029 SMLoc Loc = DirectiveID.getLoc();
5030 if (IDVal == ".arch")
5031 parseDirectiveArch(Loc);
5032 else if (IDVal == ".cpu")
5033 parseDirectiveCPU(Loc);
5034 else if (IDVal == ".tlsdesccall")
5035 parseDirectiveTLSDescCall(Loc);
5036 else if (IDVal == ".ltorg" || IDVal == ".pool")
5037 parseDirectiveLtorg(Loc);
5038 else if (IDVal == ".unreq")
5039 parseDirectiveUnreq(Loc);
5040 else if (IDVal == ".inst")
5041 parseDirectiveInst(Loc);
5042 else if (IDVal == ".cfi_negate_ra_state")
5043 parseDirectiveCFINegateRAState();
5044 else if (IDVal == ".cfi_b_key_frame")
5045 parseDirectiveCFIBKeyFrame();
5046 else if (IDVal == ".arch_extension")
5047 parseDirectiveArchExtension(Loc);
5049 if (IDVal == MCLOHDirectiveName())
5050 parseDirectiveLOH(IDVal, Loc);
5058 static void ExpandCryptoAEK(AArch64::ArchKind ArchKind,
5059 SmallVector<StringRef, 4> &RequestedExtensions) {
5060 const bool NoCrypto =
5061 (std::find(RequestedExtensions.begin(), RequestedExtensions.end(),
5062 "nocrypto") != std::end(RequestedExtensions));
5064 (std::find(RequestedExtensions.begin(), RequestedExtensions.end(),
5065 "crypto") != std::end(RequestedExtensions));
5067 if (!NoCrypto && Crypto) {
5070 // Map 'generic' (and others) to sha2 and aes, because
5071 // that was the traditional meaning of crypto.
5072 case AArch64::ArchKind::ARMV8_1A:
5073 case AArch64::ArchKind::ARMV8_2A:
5074 case AArch64::ArchKind::ARMV8_3A:
5075 RequestedExtensions.push_back("sha2");
5076 RequestedExtensions.push_back("aes");
5078 case AArch64::ArchKind::ARMV8_4A:
5079 case AArch64::ArchKind::ARMV8_5A:
5080 RequestedExtensions.push_back("sm4");
5081 RequestedExtensions.push_back("sha3");
5082 RequestedExtensions.push_back("sha2");
5083 RequestedExtensions.push_back("aes");
5086 } else if (NoCrypto) {
5089 // Map 'generic' (and others) to sha2 and aes, because
5090 // that was the traditional meaning of crypto.
5091 case AArch64::ArchKind::ARMV8_1A:
5092 case AArch64::ArchKind::ARMV8_2A:
5093 case AArch64::ArchKind::ARMV8_3A:
5094 RequestedExtensions.push_back("nosha2");
5095 RequestedExtensions.push_back("noaes");
5097 case AArch64::ArchKind::ARMV8_4A:
5098 case AArch64::ArchKind::ARMV8_5A:
5099 RequestedExtensions.push_back("nosm4");
5100 RequestedExtensions.push_back("nosha3");
5101 RequestedExtensions.push_back("nosha2");
5102 RequestedExtensions.push_back("noaes");
5108 /// parseDirectiveArch
5110 bool AArch64AsmParser::parseDirectiveArch(SMLoc L) {
5111 SMLoc ArchLoc = getLoc();
5113 StringRef Arch, ExtensionString;
5114 std::tie(Arch, ExtensionString) =
5115 getParser().parseStringToEndOfStatement().trim().split('+');
5117 AArch64::ArchKind ID = AArch64::parseArch(Arch);
5118 if (ID == AArch64::ArchKind::INVALID)
5119 return Error(ArchLoc, "unknown arch name");
5121 if (parseToken(AsmToken::EndOfStatement))
5124 // Get the architecture and extension features.
5125 std::vector<StringRef> AArch64Features;
5126 AArch64::getArchFeatures(ID, AArch64Features);
5127 AArch64::getExtensionFeatures(AArch64::getDefaultExtensions("generic", ID),
5130 MCSubtargetInfo &STI = copySTI();
5131 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
5132 STI.setDefaultFeatures("generic", join(ArchFeatures.begin(), ArchFeatures.end(), ","));
5134 SmallVector<StringRef, 4> RequestedExtensions;
5135 if (!ExtensionString.empty())
5136 ExtensionString.split(RequestedExtensions, '+');
5138 ExpandCryptoAEK(ID, RequestedExtensions);
5140 FeatureBitset Features = STI.getFeatureBits();
5141 for (auto Name : RequestedExtensions) {
5142 bool EnableFeature = true;
5144 if (Name.startswith_lower("no")) {
5145 EnableFeature = false;
5146 Name = Name.substr(2);
5149 for (const auto &Extension : ExtensionMap) {
5150 if (Extension.Name != Name)
5153 if (Extension.Features.none())
5154 report_fatal_error("unsupported architectural extension: " + Name);
5156 FeatureBitset ToggleFeatures = EnableFeature
5157 ? (~Features & Extension.Features)
5158 : ( Features & Extension.Features);
5159 FeatureBitset Features =
5160 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
5161 setAvailableFeatures(Features);
5168 /// parseDirectiveArchExtension
5169 /// ::= .arch_extension [no]feature
5170 bool AArch64AsmParser::parseDirectiveArchExtension(SMLoc L) {
5171 SMLoc ExtLoc = getLoc();
5173 StringRef Name = getParser().parseStringToEndOfStatement().trim();
5175 if (parseToken(AsmToken::EndOfStatement,
5176 "unexpected token in '.arch_extension' directive"))
5179 bool EnableFeature = true;
5180 if (Name.startswith_lower("no")) {
5181 EnableFeature = false;
5182 Name = Name.substr(2);
5185 MCSubtargetInfo &STI = copySTI();
5186 FeatureBitset Features = STI.getFeatureBits();
5187 for (const auto &Extension : ExtensionMap) {
5188 if (Extension.Name != Name)
5191 if (Extension.Features.none())
5192 return Error(ExtLoc, "unsupported architectural extension: " + Name);
5194 FeatureBitset ToggleFeatures = EnableFeature
5195 ? (~Features & Extension.Features)
5196 : (Features & Extension.Features);
5197 FeatureBitset Features =
5198 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
5199 setAvailableFeatures(Features);
5203 return Error(ExtLoc, "unknown architectural extension: " + Name);
5206 static SMLoc incrementLoc(SMLoc L, int Offset) {
5207 return SMLoc::getFromPointer(L.getPointer() + Offset);
5210 /// parseDirectiveCPU
5212 bool AArch64AsmParser::parseDirectiveCPU(SMLoc L) {
5213 SMLoc CurLoc = getLoc();
5215 StringRef CPU, ExtensionString;
5216 std::tie(CPU, ExtensionString) =
5217 getParser().parseStringToEndOfStatement().trim().split('+');
5219 if (parseToken(AsmToken::EndOfStatement))
5222 SmallVector<StringRef, 4> RequestedExtensions;
5223 if (!ExtensionString.empty())
5224 ExtensionString.split(RequestedExtensions, '+');
5226 // FIXME This is using tablegen data, but should be moved to ARMTargetParser
5227 // once that is tablegen'ed
5228 if (!getSTI().isCPUStringValid(CPU)) {
5229 Error(CurLoc, "unknown CPU name");
5233 MCSubtargetInfo &STI = copySTI();
5234 STI.setDefaultFeatures(CPU, "");
5235 CurLoc = incrementLoc(CurLoc, CPU.size());
5237 ExpandCryptoAEK(llvm::AArch64::getCPUArchKind(CPU), RequestedExtensions);
5239 FeatureBitset Features = STI.getFeatureBits();
5240 for (auto Name : RequestedExtensions) {
5241 // Advance source location past '+'.
5242 CurLoc = incrementLoc(CurLoc, 1);
5244 bool EnableFeature = true;
5246 if (Name.startswith_lower("no")) {
5247 EnableFeature = false;
5248 Name = Name.substr(2);
5251 bool FoundExtension = false;
5252 for (const auto &Extension : ExtensionMap) {
5253 if (Extension.Name != Name)
5256 if (Extension.Features.none())
5257 report_fatal_error("unsupported architectural extension: " + Name);
5259 FeatureBitset ToggleFeatures = EnableFeature
5260 ? (~Features & Extension.Features)
5261 : ( Features & Extension.Features);
5262 FeatureBitset Features =
5263 ComputeAvailableFeatures(STI.ToggleFeature(ToggleFeatures));
5264 setAvailableFeatures(Features);
5265 FoundExtension = true;
5270 if (!FoundExtension)
5271 Error(CurLoc, "unsupported architectural extension");
5273 CurLoc = incrementLoc(CurLoc, Name.size());
5278 /// parseDirectiveInst
5279 /// ::= .inst opcode [, ...]
5280 bool AArch64AsmParser::parseDirectiveInst(SMLoc Loc) {
5281 if (getLexer().is(AsmToken::EndOfStatement))
5282 return Error(Loc, "expected expression following '.inst' directive");
5284 auto parseOp = [&]() -> bool {
5287 if (check(getParser().parseExpression(Expr), L, "expected expression"))
5289 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
5290 if (check(!Value, L, "expected constant expression"))
5292 getTargetStreamer().emitInst(Value->getValue());
5296 if (parseMany(parseOp))
5297 return addErrorSuffix(" in '.inst' directive");
5301 // parseDirectiveTLSDescCall:
5302 // ::= .tlsdesccall symbol
5303 bool AArch64AsmParser::parseDirectiveTLSDescCall(SMLoc L) {
5305 if (check(getParser().parseIdentifier(Name), L,
5306 "expected symbol after directive") ||
5307 parseToken(AsmToken::EndOfStatement))
5310 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5311 const MCExpr *Expr = MCSymbolRefExpr::create(Sym, getContext());
5312 Expr = AArch64MCExpr::create(Expr, AArch64MCExpr::VK_TLSDESC, getContext());
5315 Inst.setOpcode(AArch64::TLSDESCCALL);
5316 Inst.addOperand(MCOperand::createExpr(Expr));
5318 getParser().getStreamer().EmitInstruction(Inst, getSTI());
5322 /// ::= .loh <lohName | lohId> label1, ..., labelN
5323 /// The number of arguments depends on the loh identifier.
5324 bool AArch64AsmParser::parseDirectiveLOH(StringRef IDVal, SMLoc Loc) {
5326 if (getParser().getTok().isNot(AsmToken::Identifier)) {
5327 if (getParser().getTok().isNot(AsmToken::Integer))
5328 return TokError("expected an identifier or a number in directive");
5329 // We successfully get a numeric value for the identifier.
5330 // Check if it is valid.
5331 int64_t Id = getParser().getTok().getIntVal();
5332 if (Id <= -1U && !isValidMCLOHType(Id))
5333 return TokError("invalid numeric identifier in directive");
5334 Kind = (MCLOHType)Id;
5336 StringRef Name = getTok().getIdentifier();
5337 // We successfully parse an identifier.
5338 // Check if it is a recognized one.
5339 int Id = MCLOHNameToId(Name);
5342 return TokError("invalid identifier in directive");
5343 Kind = (MCLOHType)Id;
5345 // Consume the identifier.
5347 // Get the number of arguments of this LOH.
5348 int NbArgs = MCLOHIdToNbArgs(Kind);
5350 assert(NbArgs != -1 && "Invalid number of arguments");
5352 SmallVector<MCSymbol *, 3> Args;
5353 for (int Idx = 0; Idx < NbArgs; ++Idx) {
5355 if (getParser().parseIdentifier(Name))
5356 return TokError("expected identifier in directive");
5357 Args.push_back(getContext().getOrCreateSymbol(Name));
5359 if (Idx + 1 == NbArgs)
5361 if (parseToken(AsmToken::Comma,
5362 "unexpected token in '" + Twine(IDVal) + "' directive"))
5365 if (parseToken(AsmToken::EndOfStatement,
5366 "unexpected token in '" + Twine(IDVal) + "' directive"))
5369 getStreamer().EmitLOHDirective((MCLOHType)Kind, Args);
5373 /// parseDirectiveLtorg
5374 /// ::= .ltorg | .pool
5375 bool AArch64AsmParser::parseDirectiveLtorg(SMLoc L) {
5376 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
5378 getTargetStreamer().emitCurrentConstantPool();
5382 /// parseDirectiveReq
5383 /// ::= name .req registername
5384 bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
5385 MCAsmParser &Parser = getParser();
5386 Parser.Lex(); // Eat the '.req' token.
5387 SMLoc SRegLoc = getLoc();
5388 RegKind RegisterKind = RegKind::Scalar;
5390 OperandMatchResultTy ParseRes = tryParseScalarRegister(RegNum);
5392 if (ParseRes != MatchOperand_Success) {
5394 RegisterKind = RegKind::NeonVector;
5395 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
5397 if (ParseRes == MatchOperand_ParseFail)
5400 if (ParseRes == MatchOperand_Success && !Kind.empty())
5401 return Error(SRegLoc, "vector register without type specifier expected");
5404 if (ParseRes != MatchOperand_Success) {
5406 RegisterKind = RegKind::SVEDataVector;
5408 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
5410 if (ParseRes == MatchOperand_ParseFail)
5413 if (ParseRes == MatchOperand_Success && !Kind.empty())
5414 return Error(SRegLoc,
5415 "sve vector register without type specifier expected");
5418 if (ParseRes != MatchOperand_Success) {
5420 RegisterKind = RegKind::SVEPredicateVector;
5421 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
5423 if (ParseRes == MatchOperand_ParseFail)
5426 if (ParseRes == MatchOperand_Success && !Kind.empty())
5427 return Error(SRegLoc,
5428 "sve predicate register without type specifier expected");
5431 if (ParseRes != MatchOperand_Success)
5432 return Error(SRegLoc, "register name or alias expected");
5434 // Shouldn't be anything else.
5435 if (parseToken(AsmToken::EndOfStatement,
5436 "unexpected input in .req directive"))
5439 auto pair = std::make_pair(RegisterKind, (unsigned) RegNum);
5440 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
5441 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
5446 /// parseDirectiveUneq
5447 /// ::= .unreq registername
5448 bool AArch64AsmParser::parseDirectiveUnreq(SMLoc L) {
5449 MCAsmParser &Parser = getParser();
5450 if (getTok().isNot(AsmToken::Identifier))
5451 return TokError("unexpected input in .unreq directive.");
5452 RegisterReqs.erase(Parser.getTok().getIdentifier().lower());
5453 Parser.Lex(); // Eat the identifier.
5454 if (parseToken(AsmToken::EndOfStatement))
5455 return addErrorSuffix("in '.unreq' directive");
5459 bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
5460 if (parseToken(AsmToken::EndOfStatement, "unexpected token in directive"))
5462 getStreamer().EmitCFINegateRAState();
5466 /// parseDirectiveCFIBKeyFrame
5468 bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
5469 if (parseToken(AsmToken::EndOfStatement,
5470 "unexpected token in '.cfi_b_key_frame'"))
5472 getStreamer().EmitCFIBKeyFrame();
5477 AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
5478 AArch64MCExpr::VariantKind &ELFRefKind,
5479 MCSymbolRefExpr::VariantKind &DarwinRefKind,
5481 ELFRefKind = AArch64MCExpr::VK_INVALID;
5482 DarwinRefKind = MCSymbolRefExpr::VK_None;
5485 if (const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
5486 ELFRefKind = AE->getKind();
5487 Expr = AE->getSubExpr();
5490 const MCSymbolRefExpr *SE = dyn_cast<MCSymbolRefExpr>(Expr);
5492 // It's a simple symbol reference with no addend.
5493 DarwinRefKind = SE->getKind();
5497 // Check that it looks like a symbol + an addend
5499 bool Relocatable = Expr->evaluateAsRelocatable(Res, nullptr, nullptr);
5500 if (!Relocatable || Res.getSymB())
5503 // Treat expressions with an ELFRefKind (like ":abs_g1:3", or
5504 // ":abs_g1:x" where x is constant) as symbolic even if there is no symbol.
5505 if (!Res.getSymA() && ELFRefKind == AArch64MCExpr::VK_INVALID)
5509 DarwinRefKind = Res.getSymA()->getKind();
5510 Addend = Res.getConstant();
5512 // It's some symbol reference + a constant addend, but really
5513 // shouldn't use both Darwin and ELF syntax.
5514 return ELFRefKind == AArch64MCExpr::VK_INVALID ||
5515 DarwinRefKind == MCSymbolRefExpr::VK_None;
5518 /// Force static initialization.
5519 extern "C" void LLVMInitializeAArch64AsmParser() {
5520 RegisterMCAsmParser<AArch64AsmParser> X(getTheAArch64leTarget());
5521 RegisterMCAsmParser<AArch64AsmParser> Y(getTheAArch64beTarget());
5522 RegisterMCAsmParser<AArch64AsmParser> Z(getTheARM64Target());
5523 RegisterMCAsmParser<AArch64AsmParser> W(getTheARM64_32Target());
5524 RegisterMCAsmParser<AArch64AsmParser> V(getTheAArch64_32Target());
5527 #define GET_REGISTER_MATCHER
5528 #define GET_SUBTARGET_FEATURE_NAME
5529 #define GET_MATCHER_IMPLEMENTATION
5530 #define GET_MNEMONIC_SPELL_CHECKER
5531 #include "AArch64GenAsmMatcher.inc"
5533 // Define this matcher function after the auto-generated include so we
5534 // have the match class enum definitions.
5535 unsigned AArch64AsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
5537 AArch64Operand &Op = static_cast<AArch64Operand &>(AsmOp);
5538 // If the kind is a token for a literal immediate, check if our asm
5539 // operand matches. This is for InstAliases which have a fixed-value
5540 // immediate in the syntax.
5541 int64_t ExpectedVal;
5544 return Match_InvalidOperand;
5586 return Match_InvalidOperand;
5587 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Op.getImm());
5589 return Match_InvalidOperand;
5590 if (CE->getValue() == ExpectedVal)
5591 return Match_Success;
5592 return Match_InvalidOperand;
5595 OperandMatchResultTy
5596 AArch64AsmParser::tryParseGPRSeqPair(OperandVector &Operands) {
5600 if (getParser().getTok().isNot(AsmToken::Identifier)) {
5601 Error(S, "expected register");
5602 return MatchOperand_ParseFail;
5606 OperandMatchResultTy Res = tryParseScalarRegister(FirstReg);
5607 if (Res != MatchOperand_Success)
5608 return MatchOperand_ParseFail;
5610 const MCRegisterClass &WRegClass =
5611 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
5612 const MCRegisterClass &XRegClass =
5613 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
5615 bool isXReg = XRegClass.contains(FirstReg),
5616 isWReg = WRegClass.contains(FirstReg);
5617 if (!isXReg && !isWReg) {
5618 Error(S, "expected first even register of a "
5619 "consecutive same-size even/odd register pair");
5620 return MatchOperand_ParseFail;
5623 const MCRegisterInfo *RI = getContext().getRegisterInfo();
5624 unsigned FirstEncoding = RI->getEncodingValue(FirstReg);
5626 if (FirstEncoding & 0x1) {
5627 Error(S, "expected first even register of a "
5628 "consecutive same-size even/odd register pair");
5629 return MatchOperand_ParseFail;
5632 if (getParser().getTok().isNot(AsmToken::Comma)) {
5633 Error(getLoc(), "expected comma");
5634 return MatchOperand_ParseFail;
5641 Res = tryParseScalarRegister(SecondReg);
5642 if (Res != MatchOperand_Success)
5643 return MatchOperand_ParseFail;
5645 if (RI->getEncodingValue(SecondReg) != FirstEncoding + 1 ||
5646 (isXReg && !XRegClass.contains(SecondReg)) ||
5647 (isWReg && !WRegClass.contains(SecondReg))) {
5648 Error(E,"expected second odd register of a "
5649 "consecutive same-size even/odd register pair");
5650 return MatchOperand_ParseFail;
5655 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube64,
5656 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
5658 Pair = RI->getMatchingSuperReg(FirstReg, AArch64::sube32,
5659 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
5662 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
5663 getLoc(), getContext()));
5665 return MatchOperand_Success;
5668 template <bool ParseShiftExtend, bool ParseSuffix>
5669 OperandMatchResultTy
5670 AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
5671 const SMLoc S = getLoc();
5672 // Check for a SVE vector register specifier first.
5676 OperandMatchResultTy Res =
5677 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
5679 if (Res != MatchOperand_Success)
5682 if (ParseSuffix && Kind.empty())
5683 return MatchOperand_NoMatch;
5685 const auto &KindRes = parseVectorKind(Kind, RegKind::SVEDataVector);
5687 return MatchOperand_NoMatch;
5689 unsigned ElementWidth = KindRes->second;
5691 // No shift/extend is the default.
5692 if (!ParseShiftExtend || getParser().getTok().isNot(AsmToken::Comma)) {
5693 Operands.push_back(AArch64Operand::CreateVectorReg(
5694 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
5696 OperandMatchResultTy Res = tryParseVectorIndex(Operands);
5697 if (Res == MatchOperand_ParseFail)
5698 return MatchOperand_ParseFail;
5699 return MatchOperand_Success;
5706 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> ExtOpnd;
5707 Res = tryParseOptionalShiftExtend(ExtOpnd);
5708 if (Res != MatchOperand_Success)
5711 auto Ext = static_cast<AArch64Operand *>(ExtOpnd.back().get());
5712 Operands.push_back(AArch64Operand::CreateVectorReg(
5713 RegNum, RegKind::SVEDataVector, ElementWidth, S, Ext->getEndLoc(),
5714 getContext(), Ext->getShiftExtendType(), Ext->getShiftExtendAmount(),
5715 Ext->hasShiftExtendAmount()));
5717 return MatchOperand_Success;
5720 OperandMatchResultTy
5721 AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) {
5722 MCAsmParser &Parser = getParser();
5724 SMLoc SS = getLoc();
5725 const AsmToken &TokE = Parser.getTok();
5726 bool IsHash = TokE.is(AsmToken::Hash);
5728 if (!IsHash && TokE.isNot(AsmToken::Identifier))
5729 return MatchOperand_NoMatch;
5733 Parser.Lex(); // Eat hash
5735 // Parse the immediate operand.
5736 const MCExpr *ImmVal;
5738 if (Parser.parseExpression(ImmVal))
5739 return MatchOperand_ParseFail;
5741 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
5743 return MatchOperand_ParseFail;
5745 Pattern = MCE->getValue();
5747 // Parse the pattern
5748 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString());
5750 return MatchOperand_NoMatch;
5753 Pattern = Pat->Encoding;
5754 assert(Pattern >= 0 && Pattern < 32);
5758 AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()),
5759 SS, getLoc(), getContext()));
5761 return MatchOperand_Success;