@@ -59,7 +59,12 @@ using namespace llvm;
59
59
60
60
namespace {
61
61
62
- enum class RegKind {Scalar, NeonVector, SVEDataVector};
62
+ enum class RegKind {
63
+ Scalar,
64
+ NeonVector,
65
+ SVEDataVector,
66
+ SVEPredicateVector
67
+ };
63
68
64
69
class AArch64AsmParser : public MCTargetAsmParser {
65
70
private:
@@ -134,6 +139,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
134
139
OperandMatchResultTy tryParseGPRSeqPair (OperandVector &Operands);
135
140
template <bool ParseSuffix>
136
141
OperandMatchResultTy tryParseSVEDataVector (OperandVector &Operands);
142
+ OperandMatchResultTy tryParseSVEPredicateVector (OperandVector &Operands);
137
143
138
144
public:
139
145
enum AArch64MatchResultTy {
@@ -826,14 +832,26 @@ class AArch64Operand : public MCParsedAsmOperand {
826
832
Reg.RegNum );
827
833
}
828
834
829
- template <unsigned Class = AArch64::ZPRRegClassID>
830
- bool isSVEDataVectorReg () const {
831
- return (Kind == k_Register && Reg.Kind == RegKind::SVEDataVector) &&
835
+ template <unsigned Class> bool isSVEVectorReg () const {
836
+ RegKind RK;
837
+ switch (Class) {
838
+ case AArch64::ZPRRegClassID:
839
+ RK = RegKind::SVEDataVector;
840
+ break ;
841
+ case AArch64::PPRRegClassID:
842
+ RK = RegKind::SVEPredicateVector;
843
+ break ;
844
+ default :
845
+ llvm_unreachable (" Unsupport register class" );
846
+ }
847
+
848
+ return (Kind == k_Register && Reg.Kind == RK) &&
832
849
AArch64MCRegisterClasses[Class].contains (getReg ());
833
850
}
834
851
835
- template <int ElementWidth> bool isSVEDataVectorRegOfWidth () const {
836
- return isSVEDataVectorReg () &&
852
+ template <int ElementWidth, unsigned Class>
853
+ bool isSVEVectorRegOfWidth () const {
854
+ return isSVEVectorReg<Class>() &&
837
855
(ElementWidth == -1 || Reg.ElementWidth == ElementWidth);
838
856
}
839
857
@@ -1926,6 +1944,27 @@ static unsigned matchSVEDataVectorRegName(StringRef Name) {
1926
1944
.Default (0 );
1927
1945
}
1928
1946
1947
+ static unsigned matchSVEPredicateVectorRegName (StringRef Name) {
1948
+ return StringSwitch<unsigned >(Name.lower ())
1949
+ .Case (" p0" , AArch64::P0)
1950
+ .Case (" p1" , AArch64::P1)
1951
+ .Case (" p2" , AArch64::P2)
1952
+ .Case (" p3" , AArch64::P3)
1953
+ .Case (" p4" , AArch64::P4)
1954
+ .Case (" p5" , AArch64::P5)
1955
+ .Case (" p6" , AArch64::P6)
1956
+ .Case (" p7" , AArch64::P7)
1957
+ .Case (" p8" , AArch64::P8)
1958
+ .Case (" p9" , AArch64::P9)
1959
+ .Case (" p10" , AArch64::P10)
1960
+ .Case (" p11" , AArch64::P11)
1961
+ .Case (" p12" , AArch64::P12)
1962
+ .Case (" p13" , AArch64::P13)
1963
+ .Case (" p14" , AArch64::P14)
1964
+ .Case (" p15" , AArch64::P15)
1965
+ .Default (0 );
1966
+ }
1967
+
1929
1968
static bool isValidSVEKind (StringRef Name) {
1930
1969
return StringSwitch<bool >(Name.lower ())
1931
1970
.Case (" .b" , true )
@@ -1936,8 +1975,8 @@ static bool isValidSVEKind(StringRef Name) {
1936
1975
.Default (false );
1937
1976
}
1938
1977
1939
- static bool isSVEDataVectorRegister (StringRef Name) {
1940
- return Name[0 ] == ' z' ;
1978
+ static bool isSVERegister (StringRef Name) {
1979
+ return Name[0 ] == ' z' || Name[ 0 ] == ' p ' ;
1941
1980
}
1942
1981
1943
1982
static void parseValidVectorKind (StringRef Name, unsigned &NumElements,
@@ -1980,6 +2019,9 @@ unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1980
2019
case RegKind::SVEDataVector:
1981
2020
RegNum = matchSVEDataVectorRegName (Name);
1982
2021
break ;
2022
+ case RegKind::SVEPredicateVector:
2023
+ RegNum = matchSVEPredicateVectorRegName (Name);
2024
+ break ;
1983
2025
}
1984
2026
1985
2027
if (!RegNum) {
@@ -2007,7 +2049,7 @@ int AArch64AsmParser::tryParseRegister() {
2007
2049
return -1 ;
2008
2050
2009
2051
std::string lowerCase = Tok.getString ().lower ();
2010
- if (isSVEDataVectorRegister (lowerCase))
2052
+ if (isSVERegister (lowerCase))
2011
2053
return -1 ;
2012
2054
2013
2055
unsigned RegNum = matchRegisterNameAlias (lowerCase, RegKind::Scalar);
@@ -2742,6 +2784,36 @@ AArch64AsmParser::tryParseSVERegister(int &Reg, StringRef &Kind,
2742
2784
return MatchOperand_NoMatch;
2743
2785
}
2744
2786
2787
+ // / tryParseSVEPredicateVector - Parse a SVE predicate register operand.
2788
+ OperandMatchResultTy
2789
+ AArch64AsmParser::tryParseSVEPredicateVector (OperandVector &Operands) {
2790
+ // Check for a SVE predicate register specifier first.
2791
+ const SMLoc S = getLoc ();
2792
+ StringRef Kind;
2793
+ int RegNum = -1 ;
2794
+ auto Res = tryParseSVERegister (RegNum, Kind, RegKind::SVEPredicateVector);
2795
+ if (Res != MatchOperand_Success)
2796
+ return Res;
2797
+
2798
+ unsigned ElementWidth = StringSwitch<unsigned >(Kind.lower ())
2799
+ .Case (" " , -1 )
2800
+ .Case (" .b" , 8 )
2801
+ .Case (" .h" , 16 )
2802
+ .Case (" .s" , 32 )
2803
+ .Case (" .d" , 64 )
2804
+ .Case (" .q" , 128 )
2805
+ .Default (0 );
2806
+
2807
+ if (!ElementWidth)
2808
+ return MatchOperand_NoMatch;
2809
+
2810
+ Operands.push_back (
2811
+ AArch64Operand::CreateReg (RegNum, RegKind::SVEPredicateVector,
2812
+ ElementWidth, S, getLoc (), getContext ()));
2813
+
2814
+ return MatchOperand_Success;
2815
+ }
2816
+
2745
2817
// / parseRegister - Parse a non-vector register operand.
2746
2818
bool AArch64AsmParser::parseRegister (OperandVector &Operands) {
2747
2819
SMLoc S = getLoc ();
@@ -3575,6 +3647,12 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
3575
3647
ComputeAvailableFeatures (STI->getFeatureBits ()));
3576
3648
return Error (Loc, " unrecognized instruction mnemonic" + Suggestion);
3577
3649
}
3650
+ case Match_InvalidSVEPredicateAnyReg:
3651
+ case Match_InvalidSVEPredicateBReg:
3652
+ case Match_InvalidSVEPredicateHReg:
3653
+ case Match_InvalidSVEPredicateSReg:
3654
+ case Match_InvalidSVEPredicateDReg:
3655
+ return Error (Loc, " invalid predicate register." );
3578
3656
default :
3579
3657
llvm_unreachable (" unexpected error code!" );
3580
3658
}
@@ -3999,6 +4077,11 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3999
4077
case Match_InvalidLabel:
4000
4078
case Match_InvalidComplexRotationEven:
4001
4079
case Match_InvalidComplexRotationOdd:
4080
+ case Match_InvalidSVEPredicateAnyReg:
4081
+ case Match_InvalidSVEPredicateBReg:
4082
+ case Match_InvalidSVEPredicateHReg:
4083
+ case Match_InvalidSVEPredicateSReg:
4084
+ case Match_InvalidSVEPredicateDReg:
4002
4085
case Match_MSR:
4003
4086
case Match_MRS: {
4004
4087
if (ErrorInfo >= Operands.size ())
@@ -4349,6 +4432,20 @@ bool AArch64AsmParser::parseDirectiveReq(StringRef Name, SMLoc L) {
4349
4432
" sve vector register without type specifier expected" );
4350
4433
}
4351
4434
4435
+ if (RegNum == -1 ) {
4436
+ StringRef Kind;
4437
+ RegisterKind = RegKind::SVEPredicateVector;
4438
+ OperandMatchResultTy Res =
4439
+ tryParseSVERegister (RegNum, Kind, RegKind::SVEPredicateVector);
4440
+
4441
+ if (Res == MatchOperand_ParseFail)
4442
+ return true ;
4443
+
4444
+ if (Res == MatchOperand_Success && !Kind.empty ())
4445
+ return Error (SRegLoc,
4446
+ " sve predicate register without type specifier expected" );
4447
+ }
4448
+
4352
4449
if (RegNum == -1 )
4353
4450
return Error (SRegLoc, " register name or alias expected" );
4354
4451
0 commit comments