diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index f754c32e1176d..8516ab2c7dd71 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -923,10 +923,9 @@ class ZPRRegOp : RegisterClass< - "AArch64", +class PPRClass : RegisterClass<"AArch64", [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1 ], 16, - (sequence "P%u", firstreg, lastreg)> { + (sequence "P%u", firstreg, lastreg, step)> { let Size = 16; } @@ -940,6 +939,8 @@ def PPR_p8to15 : PPRClass<8, 15> { let DecoderMethod = "DecodeSimpleRegisterClass"; } +def PPRMul2 : PPRClass<0, 14, 2>; + class PPRAsmOperand : AsmOperandClass { let Name = "SVE" # name # "Reg"; let PredicateMethod = "isSVEPredicateVectorRegOfWidth<" @@ -1098,10 +1099,11 @@ class PPRVectorListMul : PPRVectorList"; + # ElementWidth # + ", AArch64::PPRMul2RegClassID>"; } -let EncoderMethod = "EncodeRegAsMultipleOf<2>", +let EncoderMethod = "EncodeRegMul_MinMax<2, 0, 14>", DecoderMethod = "DecodePPR2Mul2RegisterClass" in { def PP_b_mul_r : RegisterOperand"> { let ParserMatchClass = PPRVectorListMul<8, 2>; @@ -1124,23 +1126,28 @@ let EncoderMethod = "EncodeRegAsMultipleOf<2>", //****************************************************************************** // SVE vector register classes -class ZPRClass : RegisterClass<"AArch64", +class ZPRClass : RegisterClass<"AArch64", [nxv16i8, nxv8i16, nxv4i32, nxv2i64, nxv2f16, nxv4f16, nxv8f16, nxv2bf16, nxv4bf16, nxv8bf16, nxv2f32, nxv4f32, nxv2f64], - 128, (sequence "Z%u", 0, lastreg)> { + 128, (sequence "Z%u", firstreg, lastreg, step)> { let Size = 128; } -def ZPR : ZPRClass<31> { +def ZPRMul2 : ZPRClass<0, 30, 2>; +def ZPRMul4 : ZPRClass<0, 28, 4>; +def ZPRMul2_Lo : ZPRClass<0, 14, 2>; +def ZPRMul2_Hi : ZPRClass<16, 30, 2>; + +def ZPR : ZPRClass<0, 31> { let DecoderMethod = "DecodeSimpleRegisterClass"; } -def ZPR_4b : ZPRClass<15> { // Restricted 4 bit SVE vector register class. +def ZPR_4b : ZPRClass<0, 15> { // Restricted 4 bit SVE vector register class. let DecoderMethod = "DecodeSimpleRegisterClass"; } -def ZPR_3b : ZPRClass<7> { // Restricted 3 bit SVE vector register class. +def ZPR_3b : ZPRClass<0, 7> { // Restricted 3 bit SVE vector register class. let DecoderMethod = "DecodeSimpleRegisterClass"; } @@ -1188,6 +1195,39 @@ def ZPR4b16 : ZPRRegOp<"h", ZPRAsmOp4b16, ElementSizeH, ZPR_4b>; def ZPR4b32 : ZPRRegOp<"s", ZPRAsmOp4b32, ElementSizeS, ZPR_4b>; def ZPR4b64 : ZPRRegOp<"d", ZPRAsmOp4b64, ElementSizeD, ZPR_4b>; +class ZPRMul2_MinToMaxRegOp + : ZPRRegOp { + let EncoderMethod = "EncodeRegMul_MinMax<2," # Min # ", " # Max # ">"; + let DecoderMethod = "DecodeZPRMul2_MinMax<" # Min # ", " # Max # ">"; +} + +def ZPRMul2AsmOp8_Lo : ZPRAsmOperand<"VectorB_Lo", 8, "Mul2_Lo">; +def ZPRMul2AsmOp8_Hi : ZPRAsmOperand<"VectorB_Hi", 8, "Mul2_Hi">; +def ZPRMul2AsmOp16_Lo : ZPRAsmOperand<"VectorH_Lo", 16, "Mul2_Lo">; +def ZPRMul2AsmOp16_Hi : ZPRAsmOperand<"VectorH_Hi", 16, "Mul2_Hi">; +def ZPRMul2AsmOp32_Lo : ZPRAsmOperand<"VectorS_Lo", 32, "Mul2_Lo">; +def ZPRMul2AsmOp32_Hi : ZPRAsmOperand<"VectorS_Hi", 32, "Mul2_Hi">; +def ZPRMul2AsmOp64_Lo : ZPRAsmOperand<"VectorD_Lo", 64, "Mul2_Lo">; +def ZPRMul2AsmOp64_Hi : ZPRAsmOperand<"VectorD_Hi", 64, "Mul2_Hi">; + +def ZPR_K : RegisterClass<"AArch64", [untyped], 128, + (add Z20, Z21, Z22, Z23, Z28, Z29, Z30, Z31)>; + +def ZK : RegisterOperand">{ + let EncoderMethod = "EncodeZK"; + let DecoderMethod = "DecodeZK"; + let ParserMatchClass = ZPRAsmOperand<"Vector_20to23or28to31", 0, "_K">; +} + +def ZPR8Mul2_Lo : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Lo, 0, 14, ElementSizeB, ZPRMul2_Lo>; +def ZPR8Mul2_Hi : ZPRMul2_MinToMaxRegOp<"b", ZPRMul2AsmOp8_Hi, 16, 30, ElementSizeB, ZPRMul2_Hi>; +def ZPR16Mul2_Lo : ZPRMul2_MinToMaxRegOp<"h", ZPRMul2AsmOp16_Lo, 0, 14, ElementSizeH, ZPRMul2_Lo>; +def ZPR16Mul2_Hi : ZPRMul2_MinToMaxRegOp<"h", ZPRMul2AsmOp16_Hi, 16, 30, ElementSizeH, ZPRMul2_Hi>; +def ZPR32Mul2_Lo : ZPRMul2_MinToMaxRegOp<"s", ZPRMul2AsmOp32_Lo, 0, 14, ElementSizeS, ZPRMul2_Lo>; +def ZPR32Mul2_Hi : ZPRMul2_MinToMaxRegOp<"s", ZPRMul2AsmOp32_Hi, 16, 30, ElementSizeS, ZPRMul2_Hi>; +def ZPR64Mul2_Lo : ZPRMul2_MinToMaxRegOp<"d", ZPRMul2AsmOp64_Lo, 0, 14, ElementSizeD, ZPRMul2_Lo>; +def ZPR64Mul2_Hi : ZPRMul2_MinToMaxRegOp<"d", ZPRMul2AsmOp64_Hi, 16, 30, ElementSizeD, ZPRMul2_Hi>; + class FPRasZPR : AsmOperandClass{ let Name = "FPR" # Width # "asZPR"; let PredicateMethod = "isFPRasZPR"; @@ -1327,64 +1367,117 @@ def ZPR4Mul4 : RegisterClass<"AArch64", [untyped], 128, (add (decimate ZSeqQuads let Size = 512; } -class ZPRVectorListMul : ZPRVectorList { - let Name = "SVEVectorListMul" # NumRegs # "x" # ElementWidth; +class ZPRVectorListMul + : ZPRVectorList { + let Name = "SVEVectorList" # NumRegs # "x" # ElementWidth # RegClassSuffix; let DiagnosticType = "Invalid" # Name; let PredicateMethod = - "isTypedVectorListMultiple"; + "isTypedVectorListMultiple"; } -let EncoderMethod = "EncodeRegAsMultipleOf<2>", - DecoderMethod = "DecodeZPR2Mul2RegisterClass" in { +let EncoderMethod = "EncodeRegMul_MinMax<2, 0, 30>", + DecoderMethod = "DecodeZPR2Mul2RegisterClass<0, 30>" in { def ZZ_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<0, 2>; + let ParserMatchClass = ZPRVectorListMul<0, 2, "Mul2">; } def ZZ_b_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<8, 2>; + let ParserMatchClass = ZPRVectorListMul<8, 2, "Mul2">; } def ZZ_h_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<16, 2>; + let ParserMatchClass = ZPRVectorListMul<16, 2, "Mul2">; } def ZZ_s_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<32, 2>; + let ParserMatchClass = ZPRVectorListMul<32, 2, "Mul2">; } def ZZ_d_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<64, 2>; + let ParserMatchClass = ZPRVectorListMul<64, 2, "Mul2">; } def ZZ_q_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<128, 2>; + let ParserMatchClass = ZPRVectorListMul<128, 2, "Mul2">; } } // end let EncoderMethod/DecoderMethod -let EncoderMethod = "EncodeRegAsMultipleOf<4>", +let EncoderMethod = "EncodeRegMul_MinMax<4, 0, 28>", DecoderMethod = "DecodeZPR4Mul4RegisterClass" in { def ZZZZ_b_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<8, 4>; + let ParserMatchClass = ZPRVectorListMul<8, 4, "Mul4">; } def ZZZZ_h_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<16, 4>; + let ParserMatchClass = ZPRVectorListMul<16, 4, "Mul4">; } def ZZZZ_s_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<32, 4>; + let ParserMatchClass = ZPRVectorListMul<32, 4, "Mul4">; } def ZZZZ_d_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<64, 4>; + let ParserMatchClass = ZPRVectorListMul<64, 4, "Mul4">; } def ZZZZ_q_mul_r : RegisterOperand"> { - let ParserMatchClass = ZPRVectorListMul<128, 4>; + let ParserMatchClass = ZPRVectorListMul<128, 4, "Mul4">; } } // end let EncoderMethod/DecoderMethod +// Pairs of consecutive ZPR, starting with an even register, split into +// Lo=0-14 and Hi=16-30. +def ZPR2Mul2_Lo : RegisterClass<"AArch64", [untyped], 128, + (trunc (decimate ZSeqPairs, 2), 8)> { + let Size = 256; +} + +def ZPR2Mul2_Hi : RegisterClass<"AArch64", [untyped], 128, + (trunc (rotr (decimate ZSeqPairs, 2), 8), 8)> { + let Size = 256; +} + +let EncoderMethod = "EncodeRegMul_MinMax<2, 0, 14>", + DecoderMethod = "DecodeZPR2Mul2RegisterClass<0, 16>" in { + def ZZ_b_mul_r_Lo : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<8, 2, "Mul2_Lo">; + } + + def ZZ_h_mul_r_Lo : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<16, 2, "Mul2_Lo">; + } + + def ZZ_s_mul_r_Lo : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<32, 2, "Mul2_Lo">; + } + + def ZZ_d_mul_r_Lo : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<64, 2, "Mul2_Lo">; + } +} + +let EncoderMethod = "EncodeRegMul_MinMax<2, 16, 30>", + DecoderMethod = "DecodeZPR2Mul2RegisterClass<16, 31>" in { + def ZZ_b_mul_r_Hi : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<8, 2, "Mul2_Hi">; + } + + def ZZ_h_mul_r_Hi : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<16, 2, "Mul2_Hi">; + } + + def ZZ_s_mul_r_Hi : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<32, 2, "Mul2_Hi">; + } + + def ZZ_d_mul_r_Hi : RegisterOperand"> { + let ParserMatchClass = ZPRVectorListMul<64, 2, "Mul2_Hi">; + } + } // end let EncoderMethod/DecoderMethod + // SME2 strided multi-vector operands // ZStridedPairs diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index a5165d45893f3..d0d2fda23a580 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1262,6 +1262,9 @@ class AArch64Operand : public MCParsedAsmOperand { case AArch64::ZPRRegClassID: case AArch64::ZPR_3bRegClassID: case AArch64::ZPR_4bRegClassID: + case AArch64::ZPRMul2_LoRegClassID: + case AArch64::ZPRMul2_HiRegClassID: + case AArch64::ZPR_KRegClassID: RK = RegKind::SVEDataVector; break; case AArch64::PPRRegClassID: @@ -1442,13 +1445,13 @@ class AArch64Operand : public MCParsedAsmOperand { } template + unsigned ElementWidth, unsigned RegClass> DiagnosticPredicate isTypedVectorListMultiple() const { bool Res = isTypedVectorList(); if (!Res) return DiagnosticPredicateTy::NoMatch; - if (((VectorList.RegNum - AArch64::Z0) % NumRegs) != 0) + if (!AArch64MCRegisterClasses[RegClass].contains(VectorList.RegNum)) return DiagnosticPredicateTy::NearMatch; return DiagnosticPredicateTy::Match; } @@ -6092,6 +6095,33 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "Invalid restricted vector register, expected z0.s..z15.s"); case Match_InvalidZPR_4b64: return Error(Loc, "Invalid restricted vector register, expected z0.d..z15.d"); + case Match_InvalidZPRMul2_Lo8: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z0.b..z14.b"); + case Match_InvalidZPRMul2_Hi8: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z16.b..z30.b"); + case Match_InvalidZPRMul2_Lo16: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z0.h..z14.h"); + case Match_InvalidZPRMul2_Hi16: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z16.h..z30.h"); + case Match_InvalidZPRMul2_Lo32: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z0.s..z14.s"); + case Match_InvalidZPRMul2_Hi32: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z16.s..z30.s"); + case Match_InvalidZPRMul2_Lo64: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z0.d..z14.d"); + case Match_InvalidZPRMul2_Hi64: + return Error(Loc, "Invalid restricted vector register, expected even " + "register in z16.d..z30.d"); + case Match_InvalidZPR_K0: + return Error(Loc, "invalid restricted vector register, expected register " + "in z20..z23 or z28..z31"); case Match_InvalidSVEPattern: return Error(Loc, "invalid predicate pattern"); case Match_InvalidSVEPPRorPNRAnyReg: @@ -6171,19 +6201,36 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode, return Error(Loc, "operand must be a register in range [w12, w15]"); case Match_InvalidMatrixIndexGPR32_8_11: return Error(Loc, "operand must be a register in range [w8, w11]"); - case Match_InvalidSVEVectorListMul2x8: - case Match_InvalidSVEVectorListMul2x16: - case Match_InvalidSVEVectorListMul2x32: - case Match_InvalidSVEVectorListMul2x64: - case Match_InvalidSVEVectorListMul2x128: + case Match_InvalidSVEVectorList2x8Mul2: + case Match_InvalidSVEVectorList2x16Mul2: + case Match_InvalidSVEVectorList2x32Mul2: + case Match_InvalidSVEVectorList2x64Mul2: + case Match_InvalidSVEVectorList2x128Mul2: return Error(Loc, "Invalid vector list, expected list with 2 consecutive " "SVE vectors, where the first vector is a multiple of 2 " "and with matching element types"); - case Match_InvalidSVEVectorListMul4x8: - case Match_InvalidSVEVectorListMul4x16: - case Match_InvalidSVEVectorListMul4x32: - case Match_InvalidSVEVectorListMul4x64: - case Match_InvalidSVEVectorListMul4x128: + case Match_InvalidSVEVectorList2x8Mul2_Lo: + case Match_InvalidSVEVectorList2x16Mul2_Lo: + case Match_InvalidSVEVectorList2x32Mul2_Lo: + case Match_InvalidSVEVectorList2x64Mul2_Lo: + return Error(Loc, "Invalid vector list, expected list with 2 consecutive " + "SVE vectors in the range z0-z14, where the first vector " + "is a multiple of 2 " + "and with matching element types"); + case Match_InvalidSVEVectorList2x8Mul2_Hi: + case Match_InvalidSVEVectorList2x16Mul2_Hi: + case Match_InvalidSVEVectorList2x32Mul2_Hi: + case Match_InvalidSVEVectorList2x64Mul2_Hi: + return Error(Loc, + "Invalid vector list, expected list with 2 consecutive " + "SVE vectors in the range z16-z30, where the first vector " + "is a multiple of 2 " + "and with matching element types"); + case Match_InvalidSVEVectorList4x8Mul4: + case Match_InvalidSVEVectorList4x16Mul4: + case Match_InvalidSVEVectorList4x32Mul4: + case Match_InvalidSVEVectorList4x64Mul4: + case Match_InvalidSVEVectorList4x128Mul4: return Error(Loc, "Invalid vector list, expected list with 4 consecutive " "SVE vectors, where the first vector is a multiple of 4 " "and with matching element types"); @@ -6776,16 +6823,33 @@ bool AArch64AsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_InvalidMatrixIndexGPR32_12_15: case Match_InvalidMatrixIndexGPR32_8_11: case Match_InvalidLookupTable: - case Match_InvalidSVEVectorListMul2x8: - case Match_InvalidSVEVectorListMul2x16: - case Match_InvalidSVEVectorListMul2x32: - case Match_InvalidSVEVectorListMul2x64: - case Match_InvalidSVEVectorListMul2x128: - case Match_InvalidSVEVectorListMul4x8: - case Match_InvalidSVEVectorListMul4x16: - case Match_InvalidSVEVectorListMul4x32: - case Match_InvalidSVEVectorListMul4x64: - case Match_InvalidSVEVectorListMul4x128: + case Match_InvalidZPRMul2_Lo8: + case Match_InvalidZPRMul2_Hi8: + case Match_InvalidZPRMul2_Lo16: + case Match_InvalidZPRMul2_Hi16: + case Match_InvalidZPRMul2_Lo32: + case Match_InvalidZPRMul2_Hi32: + case Match_InvalidZPRMul2_Lo64: + case Match_InvalidZPRMul2_Hi64: + case Match_InvalidZPR_K0: + case Match_InvalidSVEVectorList2x8Mul2: + case Match_InvalidSVEVectorList2x16Mul2: + case Match_InvalidSVEVectorList2x32Mul2: + case Match_InvalidSVEVectorList2x64Mul2: + case Match_InvalidSVEVectorList2x128Mul2: + case Match_InvalidSVEVectorList4x8Mul4: + case Match_InvalidSVEVectorList4x16Mul4: + case Match_InvalidSVEVectorList4x32Mul4: + case Match_InvalidSVEVectorList4x64Mul4: + case Match_InvalidSVEVectorList4x128Mul4: + case Match_InvalidSVEVectorList2x8Mul2_Lo: + case Match_InvalidSVEVectorList2x16Mul2_Lo: + case Match_InvalidSVEVectorList2x32Mul2_Lo: + case Match_InvalidSVEVectorList2x64Mul2_Lo: + case Match_InvalidSVEVectorList2x8Mul2_Hi: + case Match_InvalidSVEVectorList2x16Mul2_Hi: + case Match_InvalidSVEVectorList2x32Mul2_Hi: + case Match_InvalidSVEVectorList2x64Mul2_Hi: case Match_InvalidSVEVectorListStrided2x8: case Match_InvalidSVEVectorListStrided2x16: case Match_InvalidSVEVectorListStrided2x32: diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index b97f00c993112..4a4b89da71888 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -45,6 +45,13 @@ static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, unsigned RegNo, static DecodeStatus DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); +template +static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const MCDisassembler *Decoder); +static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder); +template static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); @@ -355,13 +362,45 @@ DecodeGPR64x8ClassRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, return Success; } +template +static DecodeStatus DecodeZPRMul2_MinMax(MCInst &Inst, unsigned RegNo, + uint64_t Address, + const MCDisassembler *Decoder) { + unsigned Reg = (RegNo * 2) + Min; + if (Reg < Min || Reg > Max || (Reg & 1)) + return Fail; + unsigned Register = + AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(Reg); + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + +template static DecodeStatus DecodeZPR2Mul2RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { - if (RegNo * 2 > 30) + unsigned Reg = (RegNo * 2) + Min; + if (Reg < Min || Reg > Max || (Reg & 1)) + return Fail; + + unsigned Register = + AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(Reg); + Inst.addOperand(MCOperand::createReg(Register)); + return Success; +} + +// Zk Is the name of the control vector register Z20-Z23 or Z28-Z31, encoded in +// the "K:Zk" fields. Z20-Z23 = 000, 001,010, 011 and Z28-Z31 = 100, 101, 110, +// 111 +static DecodeStatus DecodeZK(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder) { + // RegNo < 4 => Reg is in Z20-Z23 (offset 20) + // RegNo >= 4 => Reg is in Z28-Z31 (offset 24) + unsigned Reg = (RegNo < 4) ? (RegNo + 20) : (RegNo + 24); + if (!(Reg >= 20 && Reg <= 23) && !(Reg >= 28 && Reg <= 31)) return Fail; unsigned Register = - AArch64MCRegisterClasses[AArch64::ZPR2RegClassID].getRegister(RegNo * 2); + AArch64MCRegisterClasses[AArch64::ZPRRegClassID].getRegister(Reg); Inst.addOperand(MCOperand::createReg(Register)); return Success; } diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp index c3e12b6d8024e..85ffb8639dadf 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -191,10 +191,13 @@ class AArch64MCCodeEmitter : public MCCodeEmitter { unsigned fixOneOperandFPComparison(const MCInst &MI, unsigned EncodedValue, const MCSubtargetInfo &STI) const; - template - uint32_t EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const; + template + uint32_t EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + uint32_t EncodeZK(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; uint32_t EncodePNR_p8to15(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; @@ -561,15 +564,31 @@ AArch64MCCodeEmitter::getVecShiftL8OpValue(const MCInst &MI, unsigned OpIdx, return MO.getImm() - 8; } -template +template uint32_t -AArch64MCCodeEmitter::EncodeRegAsMultipleOf(const MCInst &MI, unsigned OpIdx, - SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const { +AArch64MCCodeEmitter::EncodeRegMul_MinMax(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { assert(llvm::isPowerOf2_32(Multiple) && "Multiple is not a power of 2"); auto RegOpnd = MI.getOperand(OpIdx).getReg(); unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd); - return RegVal / Multiple; + assert(RegVal >= Min && RegVal <= Max && (RegVal & (Multiple - 1)) == 0); + return (RegVal - Min) / Multiple; +} + +// Zk Is the name of the control vector register Z20-Z23 or Z28-Z31, encoded in +// the "K:Zk" fields. Z20-Z23 = 000, 001,010, 011 and Z28-Z31 = 100, 101, 110, +// 111 +uint32_t AArch64MCCodeEmitter::EncodeZK(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + auto RegOpnd = MI.getOperand(OpIdx).getReg(); + unsigned RegVal = Ctx.getRegisterInfo()->getEncodingValue(RegOpnd); + // Z28 => RegVal = 28 (28 - 24 = 4) Z28 = 4 + if (RegOpnd > AArch64::Z27) + return (RegVal - 24); + // Z20 => RegVal = 20 (20 -20 = 0) Z20 = 0 + return (RegVal - 20); } uint32_t diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir index 2ffb785680685..f1d1b691fe1aa 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir @@ -57,11 +57,11 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_reg_output - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: $w0 = COPY [[COPY]](s32) ; CHECK-NEXT: RET_ReallyLR implicit $w0 - INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0:gpr32common + INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0:gpr32common %1:_(s32) = COPY %0 $w0 = COPY %1(s32) RET_ReallyLR implicit $w0 @@ -75,12 +75,12 @@ tracksRegLiveness: true body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_mixed_types - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0, {{[0-9]+}} /* regdef:FPR64 */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0, 3342346 /* regdef:FPR64 */, def %1 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1 ; CHECK-NEXT: $d0 = COPY [[COPY1]](s64) ; CHECK-NEXT: RET_ReallyLR implicit $d0 - INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1769482 /* regdef:GPR32common */, def %0:gpr32common, 2621450 /* regdef:FPR64 */, def %1:fpr64 + INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 2490378 /* regdef:GPR32common */, def %0:gpr32common, 3342346 /* regdef:FPR64 */, def %1:fpr64 %3:_(s32) = COPY %0 %4:_(s64) = COPY %1 $d0 = COPY %4(s64) diff --git a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll index 068e194779c15..9f8897575b3d5 100644 --- a/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll +++ b/llvm/test/CodeGen/AArch64/aarch64-sve-asm.ll @@ -13,7 +13,7 @@ define @test_svadd_i8( %Zn, asm "add $0.b, $1.b, $2.b", "=w,w,y"( %Zn, %Zm) @@ -29,7 +29,7 @@ define @test_svsub_i64( %Zn, asm "sub $0.d, $1.d, $2.d", "=w,w,x"( %Zn, %Zm) @@ -45,7 +45,7 @@ define @test_svfmul_f16( %Zn, asm "fmul $0.h, $1.h, $2.h", "=w,w,y"( %Zn, %Zm) @@ -61,7 +61,7 @@ define @test_svfmul_f( %Zn, asm "fmul $0.s, $1.s, $2.s", "=w,w,x"( %Zn, %Zm) @@ -79,7 +79,7 @@ define @test_svfadd_f16( %Pg, asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Upl,w,w"( %Pg, %Zn, %Zm) @@ -95,7 +95,7 @@ define @test_incp( %Pg, ; CHECK-NEXT: [[COPY1:%[0-9]+]]:ppr = COPY $p0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:ppr = COPY [[COPY1]] ; CHECK-NEXT: [[COPY3:%[0-9]+]]:zpr = COPY [[COPY]] - ; CHECK-NEXT: INLINEASM &"incp $0.s, $1", 0 /* attdialect */, 5046282 /* regdef:ZPR */, def %2, 393225 /* reguse:PPR */, [[COPY2]], 2147483657 /* reguse tiedto:$0 */, [[COPY3]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"incp $0.s, $1", 0 /* attdialect */, 5767178 /* regdef:ZPR */, def %2, 458761 /* reguse:PPR */, [[COPY2]], 2147483657 /* reguse tiedto:$0 */, [[COPY3]](tied-def 3) ; CHECK-NEXT: $z0 = COPY %2 ; CHECK-NEXT: RET_ReallyLR implicit $z0 %1 = tail call asm "incp $0.s, $1", "=w,@3Upa,0"( %Pg, %Zn) @@ -113,7 +113,7 @@ define @test_svfadd_f16_Uph_constraint( %P ; CHECK-NEXT: [[COPY3:%[0-9]+]]:ppr_p8to15 = COPY [[COPY2]] ; CHECK-NEXT: [[COPY4:%[0-9]+]]:zpr = COPY [[COPY1]] ; CHECK-NEXT: [[COPY5:%[0-9]+]]:zpr = COPY [[COPY]] - ; CHECK-NEXT: INLINEASM &"fadd $0.h, $1/m, $2.h, $3.h", 0 /* attdialect */, 5046282 /* regdef:ZPR */, def %3, 655369 /* reguse:PPR_p8to15 */, [[COPY3]], 5046281 /* reguse:ZPR */, [[COPY4]], 5046281 /* reguse:ZPR */, [[COPY5]] + ; CHECK-NEXT: INLINEASM &"fadd $0.h, $1/m, $2.h, $3.h", 0 /* attdialect */, 5767178 /* regdef:ZPR */, def %3, 786441 /* reguse:PPR_p8to15 */, [[COPY3]], 5767177 /* reguse:ZPR */, [[COPY4]], 5767177 /* reguse:ZPR */, [[COPY5]] ; CHECK-NEXT: $z0 = COPY %3 ; CHECK-NEXT: RET_ReallyLR implicit $z0 %1 = tail call asm "fadd $0.h, $1/m, $2.h, $3.h", "=w,@3Uph,w,w"( %Pg, %Zn, %Zm) diff --git a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir index 2be7aba2a3df8..ffa7453e48b4f 100644 --- a/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir +++ b/llvm/test/CodeGen/AArch64/emit_fneg_with_non_register_operand.mir @@ -91,10 +91,10 @@ body: | ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[LOADgot:%[0-9]+]]:gpr64common = LOADgot target-flags(aarch64-got) @c ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, [[LDRDui]](tied-def 3) ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY %2 ; CHECK-NEXT: [[LDRDui1:%[0-9]+]]:fpr64 = LDRDui [[LOADgot]], 0 :: (dereferenceable load (s64) from @c) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, [[LDRDui1]](tied-def 3) ; CHECK-NEXT: [[FNEGDr:%[0-9]+]]:fpr64 = FNEGDr %2 ; CHECK-NEXT: nofpexcept FCMPDrr %4, killed [[FNEGDr]], implicit-def $nzcv, implicit $fpcr ; CHECK-NEXT: Bcc 1, %bb.2, implicit $nzcv @@ -111,10 +111,10 @@ body: | %6:gpr64common = LOADgot target-flags(aarch64-got) @c %3:fpr64 = LDRDui %6, 0 :: (dereferenceable load (s64) from @c) - INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, %3(tied-def 3) + INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %2, 2147483657 /* reguse tiedto:$0 */, %3(tied-def 3) %0:fpr64 = COPY %2 %5:fpr64 = LDRDui %6, 0 :: (dereferenceable load (s64) from @c) - INLINEASM &"", 1 /* sideeffect attdialect */, 2621450 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, %5(tied-def 3) + INLINEASM &"", 1 /* sideeffect attdialect */, 3342346 /* regdef:FPR64 */, def %4, 2147483657 /* reguse tiedto:$0 */, %5(tied-def 3) %7:fpr64 = FNEGDr %2 nofpexcept FCMPDrr %4, killed %7, implicit-def $nzcv, implicit $fpcr Bcc 1, %bb.2, implicit $nzcv diff --git a/llvm/test/CodeGen/AArch64/fmlal-loreg.ll b/llvm/test/CodeGen/AArch64/fmlal-loreg.ll index 20737a7318394..31ead890ba8ac 100644 --- a/llvm/test/CodeGen/AArch64/fmlal-loreg.ll +++ b/llvm/test/CodeGen/AArch64/fmlal-loreg.ll @@ -11,8 +11,8 @@ define <4 x float> @test(ptr %lhs_panel, ptr %rhs_panel, <4 x float> %a) { ; CHECK-NEXT: .cfi_def_cfa_offset 16 ; CHECK-NEXT: .cfi_offset b8, -16 ; CHECK-NEXT: fmov x8, d0 -; CHECK-NEXT: ldr q8, [x0] ; CHECK-NEXT: ldr q16, [x1] +; CHECK-NEXT: ldr q8, [x0] ; CHECK-NEXT: lsr x9, x8, #32 ; CHECK-NEXT: //APP ; CHECK-NEXT: nop diff --git a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir index 5dd29cf39c0ea..f8af5b9637017 100644 --- a/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir +++ b/llvm/test/CodeGen/AArch64/peephole-insvigpr.mir @@ -487,7 +487,7 @@ body: | ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY $x0 ; CHECK-NEXT: [[DEF:%[0-9]+]]:gpr64all = IMPLICIT_DEF ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gpr64sp = COPY [[DEF]] - ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 2621450 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] + ; CHECK-NEXT: INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 3342346 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed [[COPY1]] ; CHECK-NEXT: [[MOVIv2d_ns:%[0-9]+]]:fpr128 = MOVIv2d_ns 0 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[MOVIv2d_ns]].dsub ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF @@ -505,7 +505,7 @@ body: | %0:gpr64common = COPY $x0 %2:gpr64all = IMPLICIT_DEF %3:gpr64sp = COPY %2 - INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 2621450 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed %3 + INLINEASM &"ldr ${0:s}, $1", 8 /* mayload attdialect */, 3342346 /* regdef:FPR64 */, def %1, 262158 /* mem:m */, killed %3 %4:fpr128 = MOVIv2d_ns 0 %5:fpr64 = COPY %4.dsub %7:fpr128 = IMPLICIT_DEF