Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -82,7 +82,6 @@ unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind); int tryParseRegister(); int tryMatchVectorRegister(StringRef &Kind, bool expected); - int tryParseSVEDataVectorRegister(const AsmToken &Tok, StringRef &Kind); bool parseRegister(OperandVector &Operands); bool parseSymbolicImmVal(const MCExpr *&ImmVal); bool parseVectorList(OperandVector &Operands); @@ -117,6 +116,8 @@ /// } + OperandMatchResultTy tryParseSVERegister(int &Reg, StringRef &Kind, + RegKind MatchKind); OperandMatchResultTy tryParseOptionalShiftExtend(OperandVector &Operands); OperandMatchResultTy tryParseBarrierOperand(OperandVector &Operands); OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); @@ -2708,30 +2709,37 @@ // tryParseSVEDataVectorRegister - Try to parse a SVE vector register name with // optional kind specifier. If it is a register specifier, eat the token // and return it. -int AArch64AsmParser::tryParseSVEDataVectorRegister(const AsmToken &Tok, - StringRef &Kind) { +OperandMatchResultTy +AArch64AsmParser::tryParseSVERegister(int &Reg, StringRef &Kind, + RegKind MatchKind) { + MCAsmParser &Parser = getParser(); + const AsmToken &Tok = Parser.getTok(); + if (Tok.isNot(AsmToken::Identifier)) - return -1; + return MatchOperand_NoMatch; StringRef Name = Tok.getString(); // If there is a kind specifier, it's separated from the register name by // a '.'. size_t Start = 0, Next = Name.find('.'); StringRef Head = Name.slice(Start, Next); - unsigned RegNum = matchRegisterNameAlias(Head, RegKind::SVEDataVector); + unsigned RegNum = matchRegisterNameAlias(Head, MatchKind); if (RegNum) { if (Next != StringRef::npos) { Kind = Name.slice(Next, StringRef::npos); if (!isValidSVEKind(Kind)) { TokError("invalid sve vector kind qualifier"); - return -1; + return MatchOperand_ParseFail; } } - return RegNum; + Parser.Lex(); // Eat the register token. + + Reg = RegNum; + return MatchOperand_Success; } - return -1; + return MatchOperand_NoMatch; } /// parseRegister - Parse a non-vector register operand. @@ -4291,10 +4299,10 @@ MCAsmParser &Parser = getParser(); Parser.Lex(); // Eat the '.req' token. SMLoc SRegLoc = getLoc(); - unsigned RegNum = tryParseRegister(); + int RegNum = tryParseRegister(); RegKind RegisterKind = RegKind::Scalar; - if (RegNum == static_cast(-1)) { + if (RegNum == -1) { StringRef Kind; RegisterKind = RegKind::NeonVector; RegNum = tryMatchVectorRegister(Kind, false); @@ -4302,18 +4310,21 @@ return Error(SRegLoc, "vector register without type specifier expected"); } - if (RegNum == static_cast(-1)) { + if (RegNum == -1) { StringRef Kind; RegisterKind = RegKind::SVEDataVector; - int RegNumTmp = tryParseSVEDataVectorRegister(Parser.getTok(), Kind); - if (RegNumTmp != -1) - Parser.Lex(); - RegNum = RegNumTmp; - if (!Kind.empty()) - return Error(SRegLoc, "sve vector register without type specifier expected"); + OperandMatchResultTy Res = + tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector); + + if (Res == MatchOperand_ParseFail) + return true; + + if (Res == MatchOperand_Success && !Kind.empty()) + return Error(SRegLoc, + "sve vector register without type specifier expected"); } - if (RegNum == static_cast(-1)) + if (RegNum == -1) return Error(SRegLoc, "register name or alias expected"); // Shouldn't be anything else. @@ -4321,7 +4332,7 @@ "unexpected input in .req directive")) return true; - auto pair = std::make_pair(RegisterKind, RegNum); + auto pair = std::make_pair(RegisterKind, (unsigned) RegNum); if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) Warning(L, "ignoring redefinition of register alias '" + Name + "'"); @@ -4542,16 +4553,16 @@ template OperandMatchResultTy AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) { - MCAsmParser &Parser = getParser(); const SMLoc S = getLoc(); // Check for a SVE vector register specifier first. + int RegNum = -1; StringRef Kind; - int RegNum = tryParseSVEDataVectorRegister(Parser.getTok(), Kind); - if (RegNum == -1) - return MatchOperand_NoMatch; - // Eat the SVE Register Token - Parser.Lex(); + OperandMatchResultTy Res = + tryParseSVERegister(RegNum, Kind, RegKind::SVEDataVector); + + if (Res != MatchOperand_Success) + return Res; if (ParseSuffix && Kind.empty()) return MatchOperand_NoMatch; Index: test/MC/AArch64/SVE/add-diagnostics.s =================================================================== --- test/MC/AArch64/SVE/add-diagnostics.s +++ test/MC/AArch64/SVE/add-diagnostics.s @@ -4,13 +4,16 @@ add z22.h, z10.h, z32.h // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand // CHECK-NEXT: add z22.h, z10.h, z32.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: // Invalid element kind. add z20.h, z2.h, z31.x // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid sve vector kind qualifier // CHECK-NEXT: add z20.h, z2.h, z31.x +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: // Element size specifiers should match. add z27.h, z11.h, z27.b // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand // CHECK-NEXT: add z27.h, z11.h, z27.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: test/MC/AArch64/SVE/sub-diagnostics.s =================================================================== --- test/MC/AArch64/SVE/sub-diagnostics.s +++ test/MC/AArch64/SVE/sub-diagnostics.s @@ -4,13 +4,16 @@ sub z3.h, z26.h, z32.h // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand // CHECK-NEXT: sub z3.h, z26.h, z32.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: // Invalid element kind. sub z4.h, z27.h, z31.x // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid sve vector kind qualifier // CHECK-NEXT: sub z4.h, z27.h, z31.x +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: // Element size specifiers should match. sub z0.h, z8.h, z8.b // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand // CHECK-NEXT: sub z0.h, z8.h, z8.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: