diff --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td index 56ff7b0d3a280..47c4c6c39565f 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td +++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td @@ -8528,28 +8528,28 @@ multiclass SIMDTableLookup { def : SIMDTableLookupAlias(NAME#"v8i8One"), - V64, VecListOne128>; + V64, VecListOneConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Two"), - V64, VecListTwo128>; + V64, VecListTwoConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Three"), - V64, VecListThree128>; + V64, VecListThreeConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Four"), - V64, VecListFour128>; + V64, VecListFourConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8One"), - V128, VecListOne128>; + V128, VecListOneConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Two"), - V128, VecListTwo128>; + V128, VecListTwoConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Three"), - V128, VecListThree128>; + V128, VecListThreeConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Four"), - V128, VecListFour128>; + V128, VecListFourConsecutive128>; } multiclass SIMDTableLookupTied { @@ -8572,28 +8572,28 @@ multiclass SIMDTableLookupTied { def : SIMDTableLookupAlias(NAME#"v8i8One"), - V64, VecListOne128>; + V64, VecListOneConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Two"), - V64, VecListTwo128>; + V64, VecListTwoConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Three"), - V64, VecListThree128>; + V64, VecListThreeConsecutive128>; def : SIMDTableLookupAlias(NAME#"v8i8Four"), - V64, VecListFour128>; + V64, VecListFourConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8One"), - V128, VecListOne128>; + V128, VecListOneConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Two"), - V128, VecListTwo128>; + V128, VecListTwoConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Three"), - V128, VecListThree128>; + V128, VecListThreeConsecutive128>; def : SIMDTableLookupAlias(NAME#"v16i8Four"), - V128, VecListFour128>; + V128, VecListFourConsecutive128>; } //---------------------------------------------------------------------------- diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index 4fec120391f01..dd4f2549929f8 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -646,7 +646,7 @@ class TypedVecListRegOperand # eltsize # "'>">; multiclass VectorList { - // With implicit types (probably on instruction instead). E.g. { v0, v1 } + // With implicit types (probably on instruction instead). E.g. { v0, v1 } or {v0, v2, v4}. def _64AsmOperand : AsmOperandClass { let Name = NAME # "64"; let PredicateMethod = "isImplicitlyTypedVectorList"; @@ -667,6 +667,17 @@ multiclass VectorList { let ParserMatchClass = !cast(NAME # "_128AsmOperand"); } + // With implicit types (probably on instruction instead), consecutive registers. E.g. { v0, v1, v2 } + def _Consecutive128AsmOperand : AsmOperandClass { + let Name = NAME # "Consecutive128"; + let PredicateMethod = "isImplicitlyTypedVectorList"; + let RenderMethod = "addVectorListOperands"; + } + + def "Consecutive128" : RegisterOperand { + let ParserMatchClass = !cast(NAME # "_Consecutive128AsmOperand"); + } + // 64-bit register lists with explicit type. // { v0.8b, v1.8b } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 93c85ba62f90e..2fd0027251f4b 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -1445,11 +1445,12 @@ class AArch64Operand : public MCParsedAsmOperand { /// Is this a vector list with the type implicit (presumably attached to the /// instruction itself)? - template + template bool isImplicitlyTypedVectorList() const { return Kind == k_VectorList && VectorList.Count == NumRegs && VectorList.NumElements == 0 && - VectorList.RegisterKind == VectorKind; + VectorList.RegisterKind == VectorKind && + (!IsConsecutive || (VectorList.Stride == 1)); } template + template void addVectorListOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); + assert((!IsConsecutive || (getVectorListStride() == 1)) && + "Expected consecutive registers"); static const unsigned FirstRegs[][5] = { /* DReg */ { AArch64::Q0, AArch64::D0, AArch64::D0_D1, diff --git a/llvm/test/MC/AArch64/neon-diagnostics.s b/llvm/test/MC/AArch64/neon-diagnostics.s index 6863a89bbe189..2610f4acf383b 100644 --- a/llvm/test/MC/AArch64/neon-diagnostics.s +++ b/llvm/test/MC/AArch64/neon-diagnostics.s @@ -6914,6 +6914,9 @@ tbl v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b tbl v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b + tbl v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b + tbl.8b v0, {v2, v4, v6, v8}, v10 + tbl.16b v0, {v2, v4, v6, v8}, v10 // CHECK-ERROR: error: invalid operand for instruction // CHECK-ERROR: tbl v0.8b, {v1.8b}, v2.8b @@ -6930,12 +6933,24 @@ // CHECK-ERROR: error: invalid number of vectors // CHECK-ERROR: tbl v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b // CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbl v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbl.8b v0, {v2, v4, v6, v8}, v10 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbl.16b v0, {v2, v4, v6, v8}, v10 +// CHECK-ERROR: ^ tbx v0.8b, {v1.8b}, v2.8b tbx v0.8b, {v1.8b, v2.8b}, v2.8b tbx v0.8b, {v1.8b, v2.8b, v3.8b}, v2.8b tbx v0.8b, {v1.8b, v2.8b, v3.8b, v4.8b}, v2.8b tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b + tbx v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b + tbx.8b v0, {v2, v4, v6, v8}, v10 + tbx.16b v0, {v2, v4, v6, v8}, v10 // CHECK-ERROR: error: invalid operand for instruction // CHECK-ERROR: tbx v0.8b, {v1.8b}, v2.8b @@ -6952,6 +6967,15 @@ // CHECK-ERROR: error: invalid number of vectors // CHECK-ERROR: tbx v0.8b, {v1.16b, v2.16b, v3.16b, v4.16b, v5.16b}, v2.8b // CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbx v0.8b, {v2.16b, v4.16b, v6.16b, v8.16b}, v10.8b +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbx.8b v0, {v2, v4, v6, v8}, v10 +// CHECK-ERROR: ^ +// CHECK-ERROR: error: invalid operand for instruction +// CHECK-ERROR: tbx.16b v0, {v2, v4, v6, v8}, v10 +// CHECK-ERROR: ^ //---------------------------------------------------------------------- // Scalar Floating-point Convert To Lower Precision Narrow, Rounding To