llvm.org GIT mirror llvm / c5e08cf
[AArch64][SVE] Asm: Replace 'IsVector' by 'RegKind' in AArch64AsmParser (NFC) Patch [2/5] in a series to add assembler/disassembler support for AArch64 SVE unpredicated ADD/SUB instructions. This change is a non functional change that adds RegKind as an alternative to 'isVector' to prepare it for newer types (SVE data vectors and predicate vectors) that will be added in next patches (where the SVE data vector is added as part of this patch set) Patch by Sander De Smalen. Reviewed by: rengolin Differential Revision: https://reviews.llvm.org/D39088 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317569 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 1 year, 11 months ago
2 changed file(s) with 71 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
459459 // assmebler matching.
460460 def VectorReg64AsmOperand : AsmOperandClass {
461461 let Name = "VectorReg64";
462 let PredicateMethod = "isVectorReg";
462 let PredicateMethod = "isNeonVectorReg";
463463 }
464464 def VectorReg128AsmOperand : AsmOperandClass {
465465 let Name = "VectorReg128";
466 let PredicateMethod = "isVectorReg";
466 let PredicateMethod = "isNeonVectorReg";
467467 }
468468
469469 def V64 : RegisterOperand {
474474 let ParserMatchClass = VectorReg128AsmOperand;
475475 }
476476
477 def VectorRegLoAsmOperand : AsmOperandClass { let Name = "VectorRegLo"; }
477 def VectorRegLoAsmOperand : AsmOperandClass {
478 let Name = "VectorRegLo";
479 let PredicateMethod = "isNeonVectorRegLo";
480 }
478481 def V128_lo : RegisterOperand {
479482 let ParserMatchClass = VectorRegLoAsmOperand;
480483 }
5858
5959 namespace {
6060
61 enum class RegKind {Scalar, NeonVector};
62
6163 class AArch64AsmParser : public MCTargetAsmParser {
6264 private:
6365 StringRef Mnemonic; ///< Instruction mnemonic.
6466
6567 // Map of register aliases registers via the .req directive.
66 StringMapbool, unsigned>> RegisterReqs;
68 StringMapRegKind, unsigned>> RegisterReqs;
6769
6870 AArch64TargetStreamer &getTargetStreamer() {
6971 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
7678 void createSysAlias(uint16_t Encoding, OperandVector &Operands, SMLoc S);
7779 AArch64CC::CondCode parseCondCodeString(StringRef Cond);
7880 bool parseCondCode(OperandVector &Operands, bool invertCondCode);
79 unsigned matchRegisterNameAlias(StringRef Name, bool isVector);
81 unsigned matchRegisterNameAlias(StringRef Name, RegKind Kind);
8082 int tryParseRegister();
8183 int tryMatchVectorRegister(StringRef &Kind, bool expected);
8284 bool parseRegister(OperandVector &Operands);
125127 OperandMatchResultTy tryParseFPImm(OperandVector &Operands);
126128 OperandMatchResultTy tryParseAddSubImm(OperandVector &Operands);
127129 OperandMatchResultTy tryParseGPR64sp0Operand(OperandVector &Operands);
128 bool tryParseVectorRegister(OperandVector &Operands);
130 bool tryParseNeonVectorRegister(OperandVector &Operands);
129131 OperandMatchResultTy tryParseGPRSeqPair(OperandVector &Operands);
130132
131133 public:
193195
194196 struct RegOp {
195197 unsigned RegNum;
196 bool isVector;
198 RegKind Kind;
197199 };
198200
199201 struct VectorListOp {
803805 return SysReg.PStateField != -1U;
804806 }
805807
806 bool isReg() const override { return Kind == k_Register && !Reg.isVector; }
807 bool isVectorReg() const { return Kind == k_Register && Reg.isVector; }
808
809 bool isVectorRegLo() const {
810 return Kind == k_Register && Reg.isVector &&
808 bool isReg() const override {
809 return Kind == k_Register && Reg.Kind == RegKind::Scalar;
810 }
811
812 bool isNeonVectorReg() const {
813 return Kind == k_Register && Reg.Kind == RegKind::NeonVector;
814 }
815
816 bool isNeonVectorRegLo() const {
817 return Kind == k_Register && Reg.Kind == RegKind::NeonVector &&
811818 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
812819 Reg.RegNum);
813820 }
814821
815822 bool isGPR32as64() const {
816 return Kind == k_Register && !Reg.isVector &&
823 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
817824 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(Reg.RegNum);
818825 }
819826
820827 bool isWSeqPair() const {
821 return Kind == k_Register && !Reg.isVector &&
828 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
822829 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
823830 Reg.RegNum);
824831 }
825832
826833 bool isXSeqPair() const {
827 return Kind == k_Register && !Reg.isVector &&
834 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
828835 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
829836 Reg.RegNum);
830837 }
831838
832839 bool isGPR64sp0() const {
833 return Kind == k_Register && !Reg.isVector &&
840 return Kind == k_Register && Reg.Kind == RegKind::Scalar &&
834841 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(Reg.RegNum);
835842 }
836843
15631570 }
15641571
15651572 static std::unique_ptr
1566 CreateReg(unsigned RegNum, bool isVector, SMLoc S, SMLoc E, MCContext &Ctx) {
1573 CreateReg(unsigned RegNum, RegKind Kind, SMLoc S, SMLoc E, MCContext &Ctx) {
15671574 auto Op = make_unique(k_Register, Ctx);
15681575 Op->Reg.RegNum = RegNum;
1569 Op->Reg.isVector = isVector;
1576 Op->Reg.Kind = Kind;
15701577 Op->StartLoc = S;
15711578 Op->EndLoc = E;
15721579 return Op;
17901797
17911798 /// }
17921799
1793 static unsigned matchVectorRegName(StringRef Name) {
1800 static unsigned MatchNeonVectorRegName(StringRef Name) {
17941801 return StringSwitch(Name.lower())
17951802 .Case("v0", AArch64::Q0)
17961803 .Case("v1", AArch64::Q1)
18801887
18811888 // Matches a register name or register alias previously defined by '.req'
18821889 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1883 bool isVector) {
1884 unsigned RegNum = isVector ? matchVectorRegName(Name)
1885 : MatchRegisterName(Name);
1886
1887 if (RegNum == 0) {
1890 RegKind Kind) {
1891 unsigned RegNum;
1892 switch (Kind) {
1893 case RegKind::Scalar:
1894 RegNum = MatchRegisterName(Name);
1895 break;
1896 case RegKind::NeonVector:
1897 RegNum = MatchNeonVectorRegName(Name);
1898 break;
1899 }
1900
1901 if (!RegNum) {
18881902 // Check for aliases registered via .req. Canonicalize to lower case.
18891903 // That's more consistent since register names are case insensitive, and
18901904 // it's how the original entry was passed in from MC/MCParser/AsmParser.
18911905 auto Entry = RegisterReqs.find(Name.lower());
18921906 if (Entry == RegisterReqs.end())
18931907 return 0;
1908
18941909 // set RegNum if the match is the right kind of register
1895 if (isVector == Entry->getValue().first)
1910 if (Kind == Entry->getValue().first)
18961911 RegNum = Entry->getValue().second;
18971912 }
18981913 return RegNum;
19081923 return -1;
19091924
19101925 std::string lowerCase = Tok.getString().lower();
1911 unsigned RegNum = matchRegisterNameAlias(lowerCase, false);
1926 unsigned RegNum = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
19121927 // Also handle a few aliases of registers.
19131928 if (RegNum == 0)
19141929 RegNum = StringSwitch(lowerCase)
19391954 // a '.'.
19401955 size_t Start = 0, Next = Name.find('.');
19411956 StringRef Head = Name.slice(Start, Next);
1942 unsigned RegNum = matchRegisterNameAlias(Head, true);
1957 unsigned RegNum = matchRegisterNameAlias(Head, RegKind::NeonVector);
19431958
19441959 if (RegNum) {
19451960 if (Next != StringRef::npos) {
25582573 return MatchOperand_Success;
25592574 }
25602575
2561 /// tryParseVectorRegister - Parse a vector register operand.
2562 bool AArch64AsmParser::tryParseVectorRegister(OperandVector &Operands) {
2576 /// tryParseNeonVectorRegister - Parse a vector register operand.
2577 bool AArch64AsmParser::tryParseNeonVectorRegister(OperandVector &Operands) {
25632578 MCAsmParser &Parser = getParser();
25642579 if (Parser.getTok().isNot(AsmToken::Identifier))
25652580 return true;
25712586 if (Reg == -1)
25722587 return true;
25732588 Operands.push_back(
2574 AArch64Operand::CreateReg(Reg, true, S, getLoc(), getContext()));
2589 AArch64Operand::CreateReg(Reg, RegKind::NeonVector, S, getLoc(),
2590 getContext()));
2591
25752592 // If there was an explicit qualifier, that goes on as a literal text
25762593 // operand.
25772594 if (!Kind.empty())
26052622 /// parseRegister - Parse a non-vector register operand.
26062623 bool AArch64AsmParser::parseRegister(OperandVector &Operands) {
26072624 SMLoc S = getLoc();
2608 // Try for a vector register.
2609 if (!tryParseVectorRegister(Operands))
2625 // Try for a vector (neon) register.
2626 if (!tryParseNeonVectorRegister(Operands))
26102627 return false;
26112628
26122629 // Try for a scalar register.
26132630 int64_t Reg = tryParseRegister();
26142631 if (Reg == -1)
26152632 return true;
2616 Operands.push_back(
2617 AArch64Operand::CreateReg(Reg, false, S, getLoc(), getContext()));
2633 Operands.push_back(AArch64Operand::CreateReg(Reg, RegKind::Scalar, S,
2634 getLoc(), getContext()));
26182635
26192636 return false;
26202637 }
27822799 if (!Tok.is(AsmToken::Identifier))
27832800 return MatchOperand_NoMatch;
27842801
2785 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), false);
2802 unsigned RegNum = matchRegisterNameAlias(Tok.getString().lower(), RegKind::Scalar);
27862803
27872804 MCContext &Ctx = getContext();
27882805 const MCRegisterInfo *RI = Ctx.getRegisterInfo();
27942811
27952812 if (!parseOptionalToken(AsmToken::Comma)) {
27962813 Operands.push_back(
2797 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2814 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx));
27982815 return MatchOperand_Success;
27992816 }
28002817
28132830 }
28142831
28152832 Operands.push_back(
2816 AArch64Operand::CreateReg(RegNum, false, S, getLoc(), Ctx));
2833 AArch64Operand::CreateReg(RegNum, RegKind::Scalar, S, getLoc(), Ctx));
28172834 return MatchOperand_Success;
28182835 }
28192836
35283545 Operands[0] = AArch64Operand::CreateToken(
35293546 "bfm", false, Op.getStartLoc(), getContext());
35303547 Operands[2] = AArch64Operand::CreateReg(
3531 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, false, SMLoc(),
3532 SMLoc(), getContext());
3548 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
3549 SMLoc(), SMLoc(), getContext());
35333550 Operands[3] = AArch64Operand::CreateImm(
35343551 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
35353552 Operands.emplace_back(
36653682 AArch64Operand &Op = static_cast(*Operands[2]);
36663683 if (Op.isReg()) {
36673684 unsigned Reg = getXRegFromWReg(Op.getReg());
3668 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3669 Op.getEndLoc(), getContext());
3685 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3686 Op.getStartLoc(), Op.getEndLoc(),
3687 getContext());
36703688 }
36713689 }
36723690 // FIXME: Likewise for sxt[bh] with a Xd dst operand
36803698 AArch64Operand &Op = static_cast(*Operands[2]);
36813699 if (Op.isReg()) {
36823700 unsigned Reg = getXRegFromWReg(Op.getReg());
3683 Operands[2] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3701 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3702 Op.getStartLoc(),
36843703 Op.getEndLoc(), getContext());
36853704 }
36863705 }
36963715 AArch64Operand &Op = static_cast(*Operands[1]);
36973716 if (Op.isReg()) {
36983717 unsigned Reg = getWRegFromXReg(Op.getReg());
3699 Operands[1] = AArch64Operand::CreateReg(Reg, false, Op.getStartLoc(),
3718 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
3719 Op.getStartLoc(),
37003720 Op.getEndLoc(), getContext());
37013721 }
37023722 }
41574177 Parser.Lex(); // Eat the '.req' token.
41584178 SMLoc SRegLoc = getLoc();
41594179 unsigned RegNum = tryParseRegister();
4160 bool IsVector = false;
4180 RegKind RegisterKind = RegKind::Scalar;
41614181
41624182 if (RegNum == static_cast(-1)) {
41634183 StringRef Kind;
4184 RegisterKind = RegKind::NeonVector;
41644185 RegNum = tryMatchVectorRegister(Kind, false);
41654186 if (!Kind.empty())
41664187 return Error(SRegLoc, "vector register without type specifier expected");
4167 IsVector = true;
41684188 }
41694189
41704190 if (RegNum == static_cast(-1))
41754195 "unexpected input in .req directive"))
41764196 return true;
41774197
4178 auto pair = std::make_pair(IsVector, RegNum);
4198 auto pair = std::make_pair(RegisterKind, RegNum);
41794199 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
41804200 Warning(L, "ignoring redefinition of register alias '" + Name + "'");
41814201
43874407 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
43884408 }
43894409
4390 Operands.push_back(AArch64Operand::CreateReg(Pair, false, S, getLoc(),
4391 getContext()));
4410 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
4411 getLoc(), getContext()));
43924412
43934413 return MatchOperand_Success;
43944414 }