diff --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h index 4c88448e6a128..419de9d86b916 100644 --- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h +++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h @@ -167,12 +167,6 @@ class ParseStatus { } }; -enum class DiagnosticPredicateTy { - Match, - NearMatch, - NoMatch, -}; - // When an operand is parsed, the assembler will try to iterate through a set of // possible operand classes that the operand might match and call the // corresponding PredicateMethod to determine that. @@ -198,21 +192,24 @@ enum class DiagnosticPredicateTy { // This is a light-weight alternative to the 'NearMissInfo' approach // below which collects *all* possible diagnostics. This alternative // is optional and fully backward compatible with existing -// PredicateMethods that return a 'bool' (match or no match). +// PredicateMethods that return a 'bool' (match or near match). struct DiagnosticPredicate { - DiagnosticPredicateTy Type; - - explicit DiagnosticPredicate(bool Match) - : Type(Match ? DiagnosticPredicateTy::Match - : DiagnosticPredicateTy::NearMatch) {} - DiagnosticPredicate(DiagnosticPredicateTy T) : Type(T) {} - DiagnosticPredicate(const DiagnosticPredicate &) = default; - DiagnosticPredicate& operator=(const DiagnosticPredicate &) = default; - - operator bool() const { return Type == DiagnosticPredicateTy::Match; } - bool isMatch() const { return Type == DiagnosticPredicateTy::Match; } - bool isNearMatch() const { return Type == DiagnosticPredicateTy::NearMatch; } - bool isNoMatch() const { return Type == DiagnosticPredicateTy::NoMatch; } + enum PredicateTy { + Match, // Matches + NearMatch, // Close Match: use Specific Diagnostic + NoMatch, // No Match: use `InvalidOperand` + } Predicate; + + constexpr DiagnosticPredicate(PredicateTy T) : Predicate(T) {} + + explicit constexpr DiagnosticPredicate(bool Matches) + : Predicate(Matches ? Match : NearMatch) {} + + explicit operator bool() const { return Predicate == Match; } + + constexpr bool isMatch() const { return Predicate == Match; } + constexpr bool isNearMatch() const { return Predicate == NearMatch; } + constexpr bool isNoMatch() const { return Predicate == NoMatch; } }; // When matching of an assembly instruction fails, there may be multiple diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 335b46b76688f..11fb746042e98 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -814,7 +814,9 @@ class AArch64Operand : public MCParsedAsmOperand { return (Val >= 0 && Val < 64); } - template bool isSImm() const { return isSImmScaled(); } + template bool isSImm() const { + return bool(isSImmScaled()); + } template DiagnosticPredicate isSImmScaled() const { return isImmScaled(true); @@ -824,7 +826,7 @@ class AArch64Operand : public MCParsedAsmOperand { DiagnosticPredicate isUImmScaled() const { if (IsRange && isImmRange() && (getLastImmVal() != getFirstImmVal() + Offset)) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; return isImmScaled(false); } @@ -833,7 +835,7 @@ class AArch64Operand : public MCParsedAsmOperand { DiagnosticPredicate isImmScaled(bool Signed) const { if ((!isImm() && !isImmRange()) || (isImm() && IsRange) || (isImmRange() && !IsRange)) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; int64_t Val; if (isImmRange()) @@ -841,7 +843,7 @@ class AArch64Operand : public MCParsedAsmOperand { else { const MCConstantExpr *MCE = dyn_cast(getImm()); if (!MCE) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; Val = MCE->getValue(); } @@ -856,33 +858,33 @@ class AArch64Operand : public MCParsedAsmOperand { } if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } DiagnosticPredicate isSVEPattern() const { if (!isImm()) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; auto *MCE = dyn_cast(getImm()); if (!MCE) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; int64_t Val = MCE->getValue(); if (Val >= 0 && Val < 32) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NearMatch; } DiagnosticPredicate isSVEVecLenSpecifier() const { if (!isImm()) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; auto *MCE = dyn_cast(getImm()); if (!MCE) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; int64_t Val = MCE->getValue(); if (Val >= 0 && Val <= 1) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NearMatch; } bool isSymbolicUImm12Offset(const MCExpr *Expr) const { @@ -1057,7 +1059,7 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isSVECpyImm() const { if (!isShiftedImm() && (!isImm() || !isa(getImm()))) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; bool IsByte = std::is_same>::value || std::is_same::value; @@ -1065,9 +1067,9 @@ class AArch64Operand : public MCParsedAsmOperand { if (!(IsByte && ShiftedImm->second) && AArch64_AM::isSVECpyImm(uint64_t(ShiftedImm->first) << ShiftedImm->second)) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } // Unsigned value in the range 0 to 255. For element widths of @@ -1075,7 +1077,7 @@ class AArch64Operand : public MCParsedAsmOperand { // range 0 to 65280. template DiagnosticPredicate isSVEAddSubImm() const { if (!isShiftedImm() && (!isImm() || !isa(getImm()))) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; bool IsByte = std::is_same>::value || std::is_same::value; @@ -1083,15 +1085,15 @@ class AArch64Operand : public MCParsedAsmOperand { if (!(IsByte && ShiftedImm->second) && AArch64_AM::isSVEAddSubImm(ShiftedImm->first << ShiftedImm->second)) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template DiagnosticPredicate isSVEPreferredLogicalImm() const { if (isLogicalImm() && !isSVECpyImm()) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NoMatch; } bool isCondCode() const { return Kind == k_CondCode; } @@ -1319,48 +1321,48 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isSVEPredicateVectorRegOfWidth() const { if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateVector) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (isSVEVectorReg() && (Reg.ElementWidth == ElementWidth)) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template DiagnosticPredicate isSVEPredicateOrPredicateAsCounterRegOfWidth() const { if (Kind != k_Register || (Reg.Kind != RegKind::SVEPredicateAsCounter && Reg.Kind != RegKind::SVEPredicateVector)) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if ((isSVEPredicateAsCounterReg() || isSVEPredicateVectorRegOfWidth()) && Reg.ElementWidth == ElementWidth) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template DiagnosticPredicate isSVEPredicateAsCounterRegOfWidth() const { if (Kind != k_Register || Reg.Kind != RegKind::SVEPredicateAsCounter) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (isSVEPredicateAsCounterReg() && (Reg.ElementWidth == ElementWidth)) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template DiagnosticPredicate isSVEDataVectorRegOfWidth() const { if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (isSVEVectorReg() && Reg.ElementWidth == ElementWidth) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template (); if (!VectorMatch.isMatch()) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; // Give a more specific diagnostic when the user has explicitly typed in // a shift-amount that does not match what is expected, but for which @@ -1378,12 +1380,12 @@ class AArch64Operand : public MCParsedAsmOperand { if (!MatchShift && (ShiftExtendTy == AArch64_AM::UXTW || ShiftExtendTy == AArch64_AM::SXTW) && !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (MatchShift && ShiftExtendTy == getShiftExtendType()) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } bool isGPR32as64() const { @@ -1420,15 +1422,17 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isComplexRotation() const { - if (!isImm()) return DiagnosticPredicateTy::NoMatch; + if (!isImm()) + return DiagnosticPredicate::NoMatch; const MCConstantExpr *CE = dyn_cast(getImm()); - if (!CE) return DiagnosticPredicateTy::NoMatch; + if (!CE) + return DiagnosticPredicate::NoMatch; uint64_t Value = CE->getValue(); if (Value % Angle == Remainder && Value <= 270) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NearMatch; } template bool isGPR64() const { @@ -1439,12 +1443,12 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isGPR64WithShiftExtend() const { if (Kind != k_Register || Reg.Kind != RegKind::Scalar) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (isGPR64() && getShiftExtendType() == AArch64_AM::LSL && getShiftExtendAmount() == Log2_32(ExtWidth / 8)) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NearMatch; } /// Is this a vector list with the type implicit (presumably attached to the @@ -1479,10 +1483,10 @@ class AArch64Operand : public MCParsedAsmOperand { bool Res = isTypedVectorList(); if (!Res) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (!AArch64MCRegisterClasses[RegClass].contains(VectorList.RegNum)) - return DiagnosticPredicateTy::NearMatch; - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::NearMatch; + return DiagnosticPredicate::Match; } template (); if (!Res) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if ((VectorList.RegNum < (AArch64::Z0 + Stride)) || ((VectorList.RegNum >= AArch64::Z16) && (VectorList.RegNum < (AArch64::Z16 + Stride)))) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NoMatch; } template DiagnosticPredicate isVectorIndex() const { if (Kind != k_VectorIndex) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (VectorIndex.Val >= Min && VectorIndex.Val <= Max) - return DiagnosticPredicateTy::Match; - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::Match; + return DiagnosticPredicate::NearMatch; } bool isToken() const override { return Kind == k_Token; } @@ -1531,7 +1535,7 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isExactFPImm() const { if (Kind != k_FPImm) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (getFPImmIsExact()) { // Lookup the immediate from table of supported immediates. @@ -1546,19 +1550,19 @@ class AArch64Operand : public MCParsedAsmOperand { llvm_unreachable("FP immediate is not exact"); if (getFPImm().bitwiseIsEqual(RealVal)) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; } - return DiagnosticPredicateTy::NearMatch; + return DiagnosticPredicate::NearMatch; } template DiagnosticPredicate isExactFPImm() const { - DiagnosticPredicate Res = DiagnosticPredicateTy::NoMatch; + DiagnosticPredicate Res = DiagnosticPredicate::NoMatch; if ((Res = isExactFPImm())) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; if ((Res = isExactFPImm())) - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::Match; return Res; } @@ -1741,12 +1745,12 @@ class AArch64Operand : public MCParsedAsmOperand { template DiagnosticPredicate isMatrixRegOperand() const { if (!isMatrix()) - return DiagnosticPredicateTy::NoMatch; + return DiagnosticPredicate::NoMatch; if (getMatrixKind() != Kind || !AArch64MCRegisterClasses[RegClass].contains(getMatrixReg()) || EltSize != getMatrixElementWidth()) - return DiagnosticPredicateTy::NearMatch; - return DiagnosticPredicateTy::Match; + return DiagnosticPredicate::NearMatch; + return DiagnosticPredicate::Match; } bool isPAuthPCRelLabel16Operand() const {