Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -59,12 +59,14 @@ namespace { +enum class RegKind {Scalar, NeonVector, SVEVector }; + class AArch64AsmParser : public MCTargetAsmParser { private: StringRef Mnemonic; ///< Instruction mnemonic. // Map of register aliases registers via the .req directive. - StringMap> RegisterReqs; + StringMap> RegisterReqs; AArch64TargetStreamer &getTargetStreamer() { MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); @@ -77,6 +79,7 @@ void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S); AArch64CC::CondCode parseCondCodeString(StringRef Cond); bool parseCondCode(OperandVector &Operands, bool invertCondCode); + unsigned matchReqRegisterNameAlias(StringRef Name, RegKind Kind); unsigned matchRegisterNameAlias(StringRef Name, bool isVector); int tryParseRegister(); int tryMatchVectorRegister(StringRef &Kind, bool expected); @@ -194,7 +197,7 @@ struct RegOp { unsigned RegNum; - bool isVector; + RegKind Kind; }; struct VectorListOp { @@ -804,34 +807,38 @@ return SysReg.PStateField != -1U; } - bool isReg() const override { return Kind == k_Register && !Reg.isVector; } - bool isVectorReg() const { return Kind == k_Register && Reg.isVector; } + bool isReg() const override { + return Kind == k_Register && Reg.Kind == RegKind::Scalar; + } + bool isVectorReg() const { + return Kind == k_Register && Reg.Kind == RegKind::NeonVector; + } bool isVectorRegLo() const { - return Kind == k_Register && Reg.isVector && + return Kind == k_Register && Reg.Kind == RegKind::NeonVector && AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains( Reg.RegNum); } bool isGPR32as64() const { - return Kind == k_Register && !Reg.isVector && + return Kind == k_Register && Reg.Kind == RegKind::Scalar && AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum); } bool isWSeqPair() const { - return Kind == k_Register && !Reg.isVector && + return Kind == k_Register && Reg.Kind == RegKind::Scalar && AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains( Reg.RegNum); } bool isXSeqPair() const { - return Kind == k_Register && !Reg.isVector && + return Kind == k_Register && Reg.Kind == RegKind::Scalar && AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains( Reg.RegNum); } bool isGPR64sp0() const { - return Kind == k_Register && !Reg.isVector && + return Kind == k_Register && Reg.Kind == RegKind::Scalar && AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum); } @@ -1564,10 +1571,10 @@ } static std::unique_ptr - CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) { + CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx) { auto Op = make_unique(k_Register, Ctx); Op->Reg.RegNum = RegNum; - Op->Reg.isVector = isVector; + Op->Reg.Kind = Kind; Op->StartLoc = S; Op->EndLoc = E; return Op; @@ -1879,23 +1886,29 @@ return (RegNo == (unsigned)-1); } +unsigned AArch64AsmParser::matchReqRegisterNameAlias(StringRef Name, + RegKind Kind) { + // Check for aliases registered via .req. Canonicalize to lower case. + // That's more consistent since register names are case insensitive, and + // it's how the original entry was passed in from MC/MCParser/AsmParser. + auto Entry = RegisterReqs.find(Name.lower()); + if (Entry == RegisterReqs.end()) + return 0; + // set RegNum if the match is the right kind of register + if (Kind == Entry->getValue().first) + return Entry->getValue().second; + return 0; +} + // Matches a register name or register alias previously defined by '.req' unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name, bool isVector) { unsigned RegNum = isVector ? matchVectorRegName(Name) : MatchRegisterName(Name); + RegKind Kind = isVector ? RegKind::NeonVector : RegKind::Scalar; - if (RegNum == 0) { - // Check for aliases registered via .req. Canonicalize to lower case. - // That's more consistent since register names are case insensitive, and - // it's how the original entry was passed in from MC/MCParser/AsmParser. - auto Entry = RegisterReqs.find(Name.lower()); - if (Entry == RegisterReqs.end()) - return 0; - // set RegNum if the match is the right kind of register - if (isVector == Entry->getValue().first) - RegNum = Entry->getValue().second; - } + if (RegNum == 0) + RegNum = matchReqRegisterNameAlias (Name, Kind); return RegNum; } @@ -2565,6 +2578,7 @@ if (Parser.getTok().isNot(AsmToken::Identifier)) return true; + RegKind RegisterKind = RegKind::NeonVector; SMLoc S = getLoc(); // Check for a vector register specifier first. StringRef Kind; @@ -2572,7 +2586,8 @@ if (Reg == -1) return true; Operands.push_back( - AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext())); + AArch64Operand::CreateReg(Reg, RegisterKind, S, getLoc(), getContext())); + // If there was an explicit qualifier, that goes on as a literal text // operand. if (!Kind.empty()) @@ -2606,7 +2621,7 @@ /// parseRegister - Parse a non-vector register operand. bool AArch64AsmParser::parseRegister(OperandVector &Operands) { SMLoc S = getLoc(); - // Try for a vector register. + // Try for a vector (neon) register. if (!tryParseVectorRegister(Operands)) return false; @@ -2614,8 +2629,8 @@ int64_t Reg = tryParseRegister(); if (Reg == -1) return true; - Operands.push_back( - AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext())); + Operands.push_back(AArch64Operand::CreateReg(Reg, RegKind::Scalar, S, + getLoc(), getContext())); return false; } @@ -2752,7 +2767,8 @@ parseValidVectorKind(Kind, NumElements, ElementKind); Operands.push_back(AArch64Operand::CreateVectorList( - FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext())); + FirstReg, Count, NumElements, ElementKind, S, getLoc(), + getContext())); // If there is an index specifier following the list, parse that too. SMLoc SIdx = getLoc(); @@ -2795,7 +2811,7 @@ if (!parseOptionalToken(AsmToken::Comma)) { Operands.push_back( - AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx)); + AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx)); return MatchOperand_Success; } @@ -2814,7 +2830,7 @@ } Operands.push_back( - AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx)); + AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx)); return MatchOperand_Success; } @@ -3528,8 +3544,8 @@ Operands[0] = AArch64Operand::CreateToken( "bfm", false, Op.getStartLoc(), getContext()); Operands[2] = AArch64Operand::CreateReg( - RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(), - SMLoc(), getContext()); + RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar, + SMLoc(), SMLoc(), getContext()); Operands[3] = AArch64Operand::CreateImm( ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext()); Operands.emplace_back( @@ -3665,8 +3681,9 @@ AArch64Operand &Op = static_cast(*Operands[2]); if (Op.isReg()) { unsigned Reg = getXRegFromWReg(Op.getReg()); - Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), - Op.getEndLoc(), getContext()); + Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, + Op.getStartLoc(), Op.getEndLoc(), + getContext()); } } // FIXME: Likewise for sxt[bh] with a Xd dst operand @@ -3680,7 +3697,8 @@ AArch64Operand &Op = static_cast(*Operands[2]); if (Op.isReg()) { unsigned Reg = getXRegFromWReg(Op.getReg()); - Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), + Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, + Op.getStartLoc(), Op.getEndLoc(), getContext()); } } @@ -3696,7 +3714,8 @@ AArch64Operand &Op = static_cast(*Operands[1]); if (Op.isReg()) { unsigned Reg = getWRegFromXReg(Op.getReg()); - Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(), + Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar, + Op.getStartLoc(), Op.getEndLoc(), getContext()); } } @@ -4157,14 +4176,14 @@ Parser.Lex(); // Eat the '.req' token. SMLoc SRegLoc = getLoc(); unsigned RegNum = tryParseRegister(); - bool IsVector = false; + RegKind RegisterKind = RegKind::Scalar; if (RegNum == static_cast(-1)) { StringRef Kind; + RegisterKind = RegKind::NeonVector; RegNum = tryMatchVectorRegister(Kind, false); if (!Kind.empty()) return Error(SRegLoc, "vector register without type specifier expected"); - IsVector = true; } if (RegNum == static_cast(-1)) @@ -4175,7 +4194,7 @@ "unexpected input in .req directive")) return true; - auto pair = std::make_pair(IsVector, RegNum); + auto pair = std::make_pair(RegisterKind, RegNum); if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair) Warning(L, "ignoring redefinition of register alias '" + Name + "'"); @@ -4386,8 +4405,8 @@ &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]); } - Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(), - getContext())); + Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S, + getLoc(), getContext())); return MatchOperand_Success; }