From: Lucas Prates Date: Thu, 12 Nov 2020 10:54:28 +0000 (+0000) Subject: [AArch64] Add a GPR64x8 register class X-Git-Tag: llvmorg-13-init~3103 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=97c006aabb6c831d68204bcb4aad8670af695618;p=platform%2Fupstream%2Fllvm.git [AArch64] Add a GPR64x8 register class This adds a GPR64x8 register class that will be needed as the data operand to the LD64B/ST64B family of instructions in the v8.7-A Accelerator Extension, which load or store a contiguous range of eight x-regs. It has to be its own register class so that register allocation will have visibility of the full set of registers actually read/written by the instructions, which will be needed when we add intrinsics and/or inline asm access to this piece of architecture. Patch written by Simon Tatham. Reviewed By: ostannard Differential Revision: https://reviews.llvm.org/D91774 --- diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 54b351f..28d1988 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -711,6 +711,32 @@ def XSeqPairClassOperand : //===----- END: v8.1a atomic CASP register operands -----------------------===// +//===----------------------------------------------------------------------===// +// Armv8.7a accelerator extension register operands: 8 consecutive GPRs +// starting with an even one + +let Namespace = "AArch64" in { + foreach i = 0-7 in + def "x8sub_"#i : SubRegIndex<64, !mul(64, i)>; +} + +def Tuples8X : RegisterTuples< + !foreach(i, [0,1,2,3,4,5,6,7], !cast("x8sub_"#i)), + !foreach(i, [0,1,2,3,4,5,6,7], (trunc (decimate (rotl GPR64, i), 2), 12))>; + +def GPR64x8Class : RegisterClass<"AArch64", [i64], 64, (trunc Tuples8X, 12)>; +def GPR64x8AsmOp : AsmOperandClass { + let Name = "GPR64x8"; + let ParserMethod = "tryParseGPR64x8"; + let RenderMethod = "addRegOperands"; +} +def GPR64x8 : RegisterOperand { + let ParserMatchClass = GPR64x8AsmOp; + let PrintMethod = "printGPR64x8"; +} + +//===----- END: v8.7a accelerator extension register operands -------------===// + // SVE predicate registers def P0 : AArch64Reg<0, "p0">, DwarfRegNum<[48]>; def P1 : AArch64Reg<1, "p1">, DwarfRegNum<[49]>; diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 6a251f0..10ab483 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -257,6 +257,7 @@ private: OperandMatchResultTy tryParseVectorList(OperandVector &Operands, bool ExpectMatch = false); OperandMatchResultTy tryParseSVEPattern(OperandVector &Operands); + OperandMatchResultTy tryParseGPR64x8(OperandVector &Operands); public: enum AArch64MatchResultTy { @@ -1170,6 +1171,12 @@ public: AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(Reg.RegNum); } + bool isGPR64x8() const { + return Kind == k_Register && Reg.Kind == RegKind::Scalar && + AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains( + Reg.RegNum); + } + bool isWSeqPair() const { return Kind == k_Register && Reg.Kind == RegKind::Scalar && AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains( @@ -6291,3 +6298,26 @@ AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) { return MatchOperand_Success; } + +OperandMatchResultTy +AArch64AsmParser::tryParseGPR64x8(OperandVector &Operands) { + SMLoc SS = getLoc(); + + unsigned XReg; + if (tryParseScalarRegister(XReg) != MatchOperand_Success) + return MatchOperand_NoMatch; + + MCContext &ctx = getContext(); + const MCRegisterInfo *RI = ctx.getRegisterInfo(); + int X8Reg = RI->getMatchingSuperReg( + XReg, AArch64::x8sub_0, + &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]); + if (!X8Reg) { + Error(SS, "expected an even-numbered x-register in the range [x0,x22]"); + return MatchOperand_ParseFail; + } + + Operands.push_back( + AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx)); + return MatchOperand_Success; +} diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index e1a96ce..a9a3843 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -62,6 +62,10 @@ static DecodeStatus DecodeGPR64commonRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder); static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); @@ -457,6 +461,34 @@ static DecodeStatus DecodeGPR64RegisterClass(MCInst &Inst, unsigned RegNo, return Success; } +static const unsigned GPR64x8DecoderTable[] = { + AArch64::X0_X1_X2_X3_X4_X5_X6_X7, + AArch64::X2_X3_X4_X5_X6_X7_X8_X9, + AArch64::X4_X5_X6_X7_X8_X9_X10_X11, + AArch64::X6_X7_X8_X9_X10_X11_X12_X13, + AArch64::X8_X9_X10_X11_X12_X13_X14_X15, + AArch64::X10_X11_X12_X13_X14_X15_X16_X17, + AArch64::X12_X13_X14_X15_X16_X17_X18_X19, + AArch64::X14_X15_X16_X17_X18_X19_X20_X21, + AArch64::X16_X17_X18_X19_X20_X21_X22_X23, + AArch64::X18_X19_X20_X21_X22_X23_X24_X25, + AArch64::X20_X21_X22_X23_X24_X25_X26_X27, +}; + +static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst, + unsigned RegNo, + uint64_t Address, + const void *Decoder) { + if (RegNo > 22) + return Fail; + if (RegNo & 1) + return Fail; + + unsigned Register = GPR64x8DecoderTable[RegNo >> 1]; + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + static DecodeStatus DecodeGPR64spRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const void *Decoder) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp index 501817f..340120d 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1644,3 +1644,10 @@ void AArch64InstPrinter::printGPR64as32(const MCInst *MI, unsigned OpNum, unsigned Reg = MI->getOperand(OpNum).getReg(); O << getRegisterName(getWRegFromXReg(Reg)); } + +void AArch64InstPrinter::printGPR64x8(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned Reg = MI->getOperand(OpNum).getReg(); + O << getRegisterName(MRI.getSubReg(Reg, AArch64::x8sub_0)); +} diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h index 21b7d4b..4be885e 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -190,6 +190,8 @@ protected: const MCSubtargetInfo &STI, raw_ostream &O); void printGPR64as32(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printGPR64x8(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); template void printZPRasFPR(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O);