[ARM] Add v8.1a "Rounding Double Multiply Add/Subtract" extension
authorVladimir Sukharev <vladimir.sukharev@arm.com>
Thu, 26 Mar 2015 18:29:02 +0000 (18:29 +0000)
committerVladimir Sukharev <vladimir.sukharev@arm.com>
Thu, 26 Mar 2015 18:29:02 +0000 (18:29 +0000)
Reviewers: t.p.northover

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D8503

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233301 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrNEON.td
test/CodeGen/ARM/neon-v8.1a.ll [new file with mode: 0644]
test/MC/ARM/basic-arm-instructions-v8.1a.s [new file with mode: 0644]
test/MC/Disassembler/ARM/armv8.1a.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/invalid-armv8.1a.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/invalid-thumbv8.1a.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/thumb-v8.1a.txt [new file with mode: 0644]

index e9e8b8fa6201bfac9a79cc456d7921c21af3ea7b..c3984cae2db2beb7e9a7f4572f693d2a5e22e668 100644 (file)
@@ -226,6 +226,8 @@ def HasCrypto        : Predicate<"Subtarget->hasCrypto()">,
                                  AssemblerPredicate<"FeatureCrypto", "crypto">;
 def HasCRC           : Predicate<"Subtarget->hasCRC()">,
                                  AssemblerPredicate<"FeatureCRC", "crc">;
+def HasV8_1a         : Predicate<"Subtarget->hasV8_1a()">,
+                                 AssemblerPredicate<"FeatureV8_1a", "v8.1a">;
 def HasFP16          : Predicate<"Subtarget->hasFP16()">,
                                  AssemblerPredicate<"FeatureFP16","half-float">;
 def HasDivide        : Predicate<"Subtarget->hasDivide()">,
index 655fc812f00ec3f811243d0f9df2ff908888cdfe..a6a07a8f02ebde0417f6c7d0c81d470f2f0b89a4 100644 (file)
@@ -2790,7 +2790,7 @@ class N3VDMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                                                      imm:$lane)))))))]>;
 class N3VDMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                     string OpcodeStr, string Dt,
-                    ValueType Ty, SDNode MulOp, SDNode ShOp>
+                    ValueType Ty, SDPatternOperator MulOp, SDPatternOperator ShOp>
   : N3VLane16<0, 1, op21_20, op11_8, 1, 0,
         (outs DPR:$Vd),
         (ins DPR:$src1, DPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
@@ -2826,7 +2826,7 @@ class N3VQMulOpSL<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
 class N3VQMulOpSL16<bits<2> op21_20, bits<4> op11_8, InstrItinClass itin,
                     string OpcodeStr, string Dt,
                     ValueType ResTy, ValueType OpTy,
-                    SDNode MulOp, SDNode ShOp>
+                    SDPatternOperator MulOp, SDPatternOperator ShOp>
   : N3VLane16<1, 1, op21_20, op11_8, 1, 0,
         (outs QPR:$Vd),
         (ins QPR:$src1, QPR:$Vn, DPR_8:$Vm, VectorIndex16:$lane),
@@ -3674,7 +3674,7 @@ multiclass N3VMulOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 multiclass N3VMulOpSL_HS<bits<4> op11_8,
                          InstrItinClass itinD16, InstrItinClass itinD32,
                          InstrItinClass itinQ16, InstrItinClass itinQ32,
-                         string OpcodeStr, string Dt, SDNode ShOp> {
+                         string OpcodeStr, string Dt, SDPatternOperator ShOp> {
   def v4i16 : N3VDMulOpSL16<0b01, op11_8, itinD16,
                             OpcodeStr, !strconcat(Dt, "16"), v4i16, mul, ShOp>;
   def v2i32 : N3VDMulOpSL<0b10, op11_8, itinD32,
@@ -3711,27 +3711,38 @@ multiclass N3VIntOp_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
 }
 
 // Neon 3-argument intrinsics,
-//   element sizes of 8, 16 and 32 bits:
-multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
-                       InstrItinClass itinD, InstrItinClass itinQ,
+//   element sizes of 16 and 32 bits:
+multiclass N3VInt3_HS<bit op24, bit op23, bits<4> op11_8, bit op4,
+                       InstrItinClass itinD16, InstrItinClass itinD32,
+                       InstrItinClass itinQ16, InstrItinClass itinQ32,
                        string OpcodeStr, string Dt, SDPatternOperator IntOp> {
   // 64-bit vector types.
-  def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD,
-                       OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
-  def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD,
+  def v4i16 : N3VDInt3<op24, op23, 0b01, op11_8, op4, itinD16,
                        OpcodeStr, !strconcat(Dt, "16"), v4i16, v4i16, IntOp>;
-  def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD,
+  def v2i32 : N3VDInt3<op24, op23, 0b10, op11_8, op4, itinD32,
                        OpcodeStr, !strconcat(Dt, "32"), v2i32, v2i32, IntOp>;
 
   // 128-bit vector types.
-  def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ,
-                       OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
-  def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ,
+  def v8i16 : N3VQInt3<op24, op23, 0b01, op11_8, op4, itinQ16,
                        OpcodeStr, !strconcat(Dt, "16"), v8i16, v8i16, IntOp>;
-  def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ,
+  def v4i32 : N3VQInt3<op24, op23, 0b10, op11_8, op4, itinQ32,
                        OpcodeStr, !strconcat(Dt, "32"), v4i32, v4i32, IntOp>;
 }
 
+//   element sizes of 8, 16 and 32 bits:
+multiclass N3VInt3_QHS<bit op24, bit op23, bits<4> op11_8, bit op4,
+                       InstrItinClass itinD16, InstrItinClass itinD32,
+                       InstrItinClass itinQ16, InstrItinClass itinQ32,
+                       string OpcodeStr, string Dt, SDPatternOperator IntOp>
+           :N3VInt3_HS <op24, op23, op11_8, op4, itinD16, itinD32,
+                        itinQ16, itinQ32, OpcodeStr, Dt, IntOp>{
+  // 64-bit vector types.
+  def v8i8  : N3VDInt3<op24, op23, 0b00, op11_8, op4, itinD16,
+                       OpcodeStr, !strconcat(Dt, "8"), v8i8, v8i8, IntOp>;
+  // 128-bit vector types.
+  def v16i8 : N3VQInt3<op24, op23, 0b00, op11_8, op4, itinQ16,
+                       OpcodeStr, !strconcat(Dt, "8"), v16i8, v16i8, IntOp>;
+}
 
 // Neon Long Multiply-Op vector operations,
 //   element sizes of 8, 16 and 32 bits:
@@ -4305,6 +4316,147 @@ defm VMLALu   : N3VLMulOp_QHS<1,1,0b1000,0, IIC_VMACi16D, IIC_VMACi32D,
 defm VMLALsls : N3VLMulOpSL_HS<0, 0b0010, "vmlal", "s", NEONvmulls, add>;
 defm VMLALslu : N3VLMulOpSL_HS<1, 0b0010, "vmlal", "u", NEONvmullu, add>;
 
+let Predicates = [HasNEON, HasV8_1a] in {
+  // v8.1a Neon Rounding Double Multiply-Op vector operations,
+  // VQRDMLAH : Vector Saturating Rounding Doubling Multiply Accumulate Long
+  //            (Q += D * D)
+  defm VQRDMLAH : N3VInt3_HS<1, 0, 0b1011, 1, IIC_VMACi16D, IIC_VMACi32D,
+                             IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",
+                             null_frag>;
+  def : Pat<(v4i16 (int_arm_neon_vqadds
+                     (v4i16 DPR:$src1),
+                     (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn),
+                                                   (v4i16 DPR:$Vm))))),
+            (v4i16 (VQRDMLAHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
+  def : Pat<(v2i32 (int_arm_neon_vqadds
+                     (v2i32 DPR:$src1),
+                     (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn),
+                                                   (v2i32 DPR:$Vm))))),
+            (v2i32 (VQRDMLAHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
+  def : Pat<(v8i16 (int_arm_neon_vqadds
+                     (v8i16 QPR:$src1),
+                     (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn),
+                                                   (v8i16 QPR:$Vm))))),
+            (v8i16 (VQRDMLAHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
+  def : Pat<(v4i32 (int_arm_neon_vqadds
+                     (v4i32 QPR:$src1),
+                     (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn),
+                                                   (v4i32 QPR:$Vm))))),
+            (v4i32 (VQRDMLAHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
+
+  defm VQRDMLAHsl : N3VMulOpSL_HS<0b1110, IIC_VMACi16D, IIC_VMACi32D,
+                                  IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlah", "s",
+                                  null_frag>;
+  def : Pat<(v4i16 (int_arm_neon_vqadds
+                     (v4i16 DPR:$src1),
+                     (v4i16 (int_arm_neon_vqrdmulh
+                              (v4i16 DPR:$Vn),
+                              (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
+                                                   imm:$lane)))))),
+            (v4i16 (VQRDMLAHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm,
+                                    imm:$lane))>;
+  def : Pat<(v2i32 (int_arm_neon_vqadds
+                     (v2i32 DPR:$src1),
+                     (v2i32 (int_arm_neon_vqrdmulh
+                              (v2i32 DPR:$Vn),
+                              (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
+                                                   imm:$lane)))))),
+            (v2i32 (VQRDMLAHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm,
+                                    imm:$lane))>;
+  def : Pat<(v8i16 (int_arm_neon_vqadds
+                     (v8i16 QPR:$src1),
+                     (v8i16 (int_arm_neon_vqrdmulh
+                              (v8i16 QPR:$src2),
+                              (v8i16 (NEONvduplane (v8i16 QPR:$src3),
+                                                   imm:$lane)))))),
+            (v8i16 (VQRDMLAHslv8i16 (v8i16 QPR:$src1),
+                                    (v8i16 QPR:$src2),
+                                    (v4i16 (EXTRACT_SUBREG
+                                             QPR:$src3,
+                                             (DSubReg_i16_reg imm:$lane))),
+                                    (SubReg_i16_lane imm:$lane)))>;
+  def : Pat<(v4i32 (int_arm_neon_vqadds
+                     (v4i32 QPR:$src1),
+                     (v4i32 (int_arm_neon_vqrdmulh 
+                              (v4i32 QPR:$src2),
+                              (v4i32 (NEONvduplane (v4i32 QPR:$src3), 
+                                                   imm:$lane)))))),
+            (v4i32 (VQRDMLAHslv4i32 (v4i32 QPR:$src1),
+                                    (v4i32 QPR:$src2),
+                                    (v2i32 (EXTRACT_SUBREG
+                                             QPR:$src3,
+                                             (DSubReg_i32_reg imm:$lane))),
+                                    (SubReg_i32_lane imm:$lane)))>;
+
+  //   VQRDMLSH : Vector Saturating Rounding Doubling Multiply Subtract Long
+  //              (Q -= D * D)
+  defm VQRDMLSH : N3VInt3_HS<1, 0, 0b1100, 1, IIC_VMACi16D, IIC_VMACi32D,
+                             IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",
+                             null_frag>;
+  def : Pat<(v4i16 (int_arm_neon_vqsubs
+                     (v4i16 DPR:$src1),
+                     (v4i16 (int_arm_neon_vqrdmulh (v4i16 DPR:$Vn),
+                                                   (v4i16 DPR:$Vm))))),
+            (v4i16 (VQRDMLSHv4i16 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
+  def : Pat<(v2i32 (int_arm_neon_vqsubs
+                     (v2i32 DPR:$src1),
+                     (v2i32 (int_arm_neon_vqrdmulh (v2i32 DPR:$Vn),
+                                                   (v2i32 DPR:$Vm))))),
+            (v2i32 (VQRDMLSHv2i32 DPR:$src1, DPR:$Vn, DPR:$Vm))>;
+  def : Pat<(v8i16 (int_arm_neon_vqsubs
+                     (v8i16 QPR:$src1),
+                     (v8i16 (int_arm_neon_vqrdmulh (v8i16 QPR:$Vn),
+                                                   (v8i16 QPR:$Vm))))),
+            (v8i16 (VQRDMLSHv8i16 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
+  def : Pat<(v4i32 (int_arm_neon_vqsubs
+                     (v4i32 QPR:$src1),
+                     (v4i32 (int_arm_neon_vqrdmulh (v4i32 QPR:$Vn),
+                                                   (v4i32 QPR:$Vm))))),
+            (v4i32 (VQRDMLSHv4i32 QPR:$src1, QPR:$Vn, QPR:$Vm))>;
+
+  defm VQRDMLSHsl : N3VMulOpSL_HS<0b1111, IIC_VMACi16D, IIC_VMACi32D,
+                                  IIC_VMACi16Q, IIC_VMACi32Q, "vqrdmlsh", "s",
+                                  null_frag>;
+  def : Pat<(v4i16 (int_arm_neon_vqsubs
+                     (v4i16 DPR:$src1),
+                     (v4i16 (int_arm_neon_vqrdmulh
+                              (v4i16 DPR:$Vn),
+                              (v4i16 (NEONvduplane (v4i16 DPR_8:$Vm),
+                                                   imm:$lane)))))),
+            (v4i16 (VQRDMLSHslv4i16 DPR:$src1, DPR:$Vn, DPR_8:$Vm, imm:$lane))>;
+  def : Pat<(v2i32 (int_arm_neon_vqsubs
+                     (v2i32 DPR:$src1),
+                     (v2i32 (int_arm_neon_vqrdmulh
+                              (v2i32 DPR:$Vn),
+                              (v2i32 (NEONvduplane (v2i32 DPR_VFP2:$Vm),
+                                                   imm:$lane)))))),
+            (v2i32 (VQRDMLSHslv2i32 DPR:$src1, DPR:$Vn, DPR_VFP2:$Vm, 
+                                    imm:$lane))>;
+  def : Pat<(v8i16 (int_arm_neon_vqsubs
+                     (v8i16 QPR:$src1),
+                     (v8i16 (int_arm_neon_vqrdmulh
+                              (v8i16 QPR:$src2),
+                              (v8i16 (NEONvduplane (v8i16 QPR:$src3), 
+                                                   imm:$lane)))))),
+            (v8i16 (VQRDMLSHslv8i16 (v8i16 QPR:$src1),
+                                    (v8i16 QPR:$src2),
+                                    (v4i16 (EXTRACT_SUBREG 
+                                             QPR:$src3,
+                                             (DSubReg_i16_reg imm:$lane))),
+                                    (SubReg_i16_lane imm:$lane)))>;
+  def : Pat<(v4i32 (int_arm_neon_vqsubs
+                     (v4i32 QPR:$src1),
+                     (v4i32 (int_arm_neon_vqrdmulh
+                              (v4i32 QPR:$src2),
+                              (v4i32 (NEONvduplane (v4i32 QPR:$src3),
+                                                    imm:$lane)))))),
+            (v4i32 (VQRDMLSHslv4i32 (v4i32 QPR:$src1),
+                                    (v4i32 QPR:$src2),
+                                    (v2i32 (EXTRACT_SUBREG 
+                                             QPR:$src3,
+                                             (DSubReg_i32_reg imm:$lane))),
+                                    (SubReg_i32_lane imm:$lane)))>;
+}
 //   VQDMLAL  : Vector Saturating Doubling Multiply Accumulate Long (Q += D * D)
 defm VQDMLAL  : N3VLInt3_HS<0, 1, 0b1001, 0, IIC_VMACi16D, IIC_VMACi32D,
                             "vqdmlal", "s", null_frag>;
diff --git a/test/CodeGen/ARM/neon-v8.1a.ll b/test/CodeGen/ARM/neon-v8.1a.ll
new file mode 100644 (file)
index 0000000..9125913
--- /dev/null
@@ -0,0 +1,166 @@
+; RUN: llc < %s -mtriple=armv8 -mattr=+v8.1a | FileCheck %s
+
+;-----------------------------------------------------------------------------
+; RDMA Vector
+
+declare <4 x i16> @llvm.arm.neon.vqrdmulh.v4i16(<4 x i16>, <4 x i16>)
+declare <8 x i16> @llvm.arm.neon.vqrdmulh.v8i16(<8 x i16>, <8 x i16>)
+declare <2 x i32> @llvm.arm.neon.vqrdmulh.v2i32(<2 x i32>, <2 x i32>)
+declare <4 x i32> @llvm.arm.neon.vqrdmulh.v4i32(<4 x i32>, <4 x i32>)
+
+declare <4 x i16> @llvm.arm.neon.vqadds.v4i16(<4 x i16>, <4 x i16>)
+declare <8 x i16> @llvm.arm.neon.vqadds.v8i16(<8 x i16>, <8 x i16>)
+declare <2 x i32> @llvm.arm.neon.vqadds.v2i32(<2 x i32>, <2 x i32>)
+declare <4 x i32> @llvm.arm.neon.vqadds.v4i32(<4 x i32>, <4 x i32>)
+
+declare <4 x i16> @llvm.arm.neon.vqsubs.v4i16(<4 x i16>, <4 x i16>)
+declare <8 x i16> @llvm.arm.neon.vqsubs.v8i16(<8 x i16>, <8 x i16>)
+declare <2 x i32> @llvm.arm.neon.vqsubs.v2i32(<2 x i32>, <2 x i32>)
+declare <4 x i32> @llvm.arm.neon.vqsubs.v4i32(<4 x i32>, <4 x i32>)
+
+define <4 x i16> @test_vqrdmlah_v4i16(<4 x i16> %acc, <4 x i16> %mhs, <4 x i16> %rhs) {
+; CHECK-LABEL: test_vqrdmlah_v4i16:
+   %prod = call <4 x i16> @llvm.arm.neon.vqrdmulh.v4i16(<4 x i16> %mhs,  <4 x i16> %rhs)
+   %retval =  call <4 x i16> @llvm.arm.neon.vqadds.v4i16(<4 x i16> %acc,  <4 x i16> %prod)
+; CHECK: vqrdmlah.s16 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+   ret <4 x i16> %retval
+}
+
+define <8 x i16> @test_vqrdmlah_v8i16(<8 x i16> %acc, <8 x i16> %mhs, <8 x i16> %rhs) {
+; CHECK-LABEL: test_vqrdmlah_v8i16:
+   %prod = call <8 x i16> @llvm.arm.neon.vqrdmulh.v8i16(<8 x i16> %mhs, <8 x i16> %rhs)
+   %retval =  call <8 x i16> @llvm.arm.neon.vqadds.v8i16(<8 x i16> %acc, <8 x i16> %prod)
+; CHECK: vqrdmlah.s16 {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
+   ret <8 x i16> %retval
+}
+
+define <2 x i32> @test_vqrdmlah_v2i32(<2 x i32> %acc, <2 x i32> %mhs, <2 x i32> %rhs) {
+; CHECK-LABEL: test_vqrdmlah_v2i32:
+   %prod = call <2 x i32> @llvm.arm.neon.vqrdmulh.v2i32(<2 x i32> %mhs, <2 x i32> %rhs)
+   %retval =  call <2 x i32> @llvm.arm.neon.vqadds.v2i32(<2 x i32> %acc, <2 x i32> %prod)
+; CHECK: vqrdmlah.s32 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+   ret <2 x i32> %retval
+}
+
+define <4 x i32> @test_vqrdmlah_v4i32(<4 x i32> %acc, <4 x i32> %mhs, <4 x i32> %rhs) {
+; CHECK-LABEL: test_vqrdmlah_v4i32:
+   %prod = call <4 x i32> @llvm.arm.neon.vqrdmulh.v4i32(<4 x i32> %mhs, <4 x i32> %rhs)
+   %retval =  call <4 x i32> @llvm.arm.neon.vqadds.v4i32(<4 x i32> %acc, <4 x i32> %prod)
+; CHECK: vqrdmlah.s32 {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
+   ret <4 x i32> %retval
+}
+
+define <4 x i16> @test_vqrdmlsh_v4i16(<4 x i16> %acc, <4 x i16> %mhs, <4 x i16> %rhs) {
+; CHECK-LABEL: test_vqrdmlsh_v4i16:
+   %prod = call <4 x i16> @llvm.arm.neon.vqrdmulh.v4i16(<4 x i16> %mhs,  <4 x i16> %rhs)
+   %retval =  call <4 x i16> @llvm.arm.neon.vqsubs.v4i16(<4 x i16> %acc, <4 x i16> %prod)
+; CHECK: vqrdmlsh.s16 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+   ret <4 x i16> %retval
+}
+
+define <8 x i16> @test_vqrdmlsh_v8i16(<8 x i16> %acc, <8 x i16> %mhs, <8 x i16> %rhs) {
+; CHECK-LABEL: test_vqrdmlsh_v8i16:
+   %prod = call <8 x i16> @llvm.arm.neon.vqrdmulh.v8i16(<8 x i16> %mhs, <8 x i16> %rhs)
+   %retval =  call <8 x i16> @llvm.arm.neon.vqsubs.v8i16(<8 x i16> %acc, <8 x i16> %prod)
+; CHECK: vqrdmlsh.s16 {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
+   ret <8 x i16> %retval
+}
+
+define <2 x i32> @test_vqrdmlsh_v2i32(<2 x i32> %acc, <2 x i32> %mhs, <2 x i32> %rhs) {
+; CHECK-LABEL: test_vqrdmlsh_v2i32:
+   %prod = call <2 x i32> @llvm.arm.neon.vqrdmulh.v2i32(<2 x i32> %mhs, <2 x i32> %rhs)
+   %retval =  call <2 x i32> @llvm.arm.neon.vqsubs.v2i32(<2 x i32> %acc, <2 x i32> %prod)
+; CHECK: vqrdmlsh.s32 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}
+   ret <2 x i32> %retval
+}
+
+define <4 x i32> @test_vqrdmlsh_v4i32(<4 x i32> %acc, <4 x i32> %mhs, <4 x i32> %rhs) {
+; CHECK-LABEL: test_vqrdmlsh_v4i32:
+   %prod = call <4 x i32> @llvm.arm.neon.vqrdmulh.v4i32(<4 x i32> %mhs, <4 x i32> %rhs)
+   %retval =  call <4 x i32> @llvm.arm.neon.vqsubs.v4i32(<4 x i32> %acc, <4 x i32> %prod)
+; CHECK: vqrdmlsh.s32 {{q[0-9]+}}, {{q[0-9]+}}, {{q[0-9]+}}
+   ret <4 x i32> %retval
+}
+
+;-----------------------------------------------------------------------------
+; RDMA Scalar
+
+define <4 x i16> @test_vqrdmlah_lane_s16(<4 x i16> %acc, <4 x i16> %x, <4 x i16> %v) {
+; CHECK-LABEL: test_vqrdmlah_lane_s16:
+entry:
+  %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
+  %prod = call <4 x i16> @llvm.arm.neon.vqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)
+  %retval =  call <4 x i16> @llvm.arm.neon.vqadds.v4i16(<4 x i16> %acc, <4 x i16> %prod)
+; CHECK: vqrdmlah.s16 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}[3]
+  ret <4 x i16> %retval
+}
+
+define <8 x i16> @test_vqrdmlahq_lane_s16(<8 x i16> %acc, <8 x i16> %x, <4 x i16> %v) {
+; CHECK-LABEL: test_vqrdmlahq_lane_s16:
+entry:
+  %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
+  %prod = call <8 x i16> @llvm.arm.neon.vqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)
+  %retval =  call <8 x i16> @llvm.arm.neon.vqadds.v8i16(<8 x i16> %acc, <8 x i16> %prod)
+; CHECK: vqrdmlah.s16 {{q[0-9]+}}, {{q[0-9]+}}, {{d[0-9]+}}[2]
+  ret <8 x i16> %retval
+}
+
+define <2 x i32> @test_vqrdmlah_lane_s32(<2 x i32> %acc, <2 x i32> %x, <2 x i32> %v) {
+; CHECK-LABEL: test_vqrdmlah_lane_s32:
+entry:
+  %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> <i32 1, i32 1>
+  %prod = tail call <2 x i32> @llvm.arm.neon.vqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)
+  %retval =  call <2 x i32> @llvm.arm.neon.vqadds.v2i32(<2 x i32> %acc, <2 x i32> %prod)
+; CHECK: vqrdmlah.s32 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}[1]
+  ret <2 x i32> %retval
+}
+
+define <4 x i32> @test_vqrdmlahq_lane_s32(<4 x i32> %acc,<4 x i32> %x, <2 x i32> %v) {
+; CHECK-LABEL: test_vqrdmlahq_lane_s32:
+entry:
+  %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <4 x i32> zeroinitializer
+  %prod = tail call <4 x i32> @llvm.arm.neon.vqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)
+  %retval =  call <4 x i32> @llvm.arm.neon.vqadds.v4i32(<4 x i32> %acc, <4 x i32> %prod)
+; CHECK: vqrdmlah.s32 {{q[0-9]+}}, {{q[0-9]+}}, {{d[0-9]+}}[0]
+  ret <4 x i32> %retval
+}
+
+define <4 x i16> @test_vqrdmlsh_lane_s16(<4 x i16> %acc, <4 x i16> %x, <4 x i16> %v) {
+; CHECK-LABEL: test_vqrdmlsh_lane_s16:
+entry:
+  %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <4 x i32> <i32 3, i32 3, i32 3, i32 3>
+  %prod = call <4 x i16> @llvm.arm.neon.vqrdmulh.v4i16(<4 x i16> %x, <4 x i16> %shuffle)
+  %retval =  call <4 x i16> @llvm.arm.neon.vqsubs.v4i16(<4 x i16> %acc, <4 x i16> %prod)
+; CHECK: vqrdmlsh.s16 {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}[3]
+  ret <4 x i16> %retval
+}
+
+define <8 x i16> @test_vqrdmlshq_lane_s16(<8 x i16> %acc, <8 x i16> %x, <4 x i16> %v) {
+; CHECK-LABEL: test_vqrdmlshq_lane_s16:
+entry:
+  %shuffle = shufflevector <4 x i16> %v, <4 x i16> undef, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>
+  %prod = call <8 x i16> @llvm.arm.neon.vqrdmulh.v8i16(<8 x i16> %x, <8 x i16> %shuffle)
+  %retval =  call <8 x i16> @llvm.arm.neon.vqsubs.v8i16(<8 x i16> %acc, <8 x i16> %prod)
+; CHECK: vqrdmlsh.s16 {{q[0-9]+}}, {{q[0-9]+}}, {{d[0-9]+}}[2]
+  ret <8 x i16> %retval
+}
+
+define <2 x i32> @test_vqrdmlsh_lane_s32(<2 x i32> %acc, <2 x i32> %x, <2 x i32> %v) {
+; CHECK-LABEL: test_vqrdmlsh_lane_s32:
+entry:
+  %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <2 x i32> <i32 1, i32 1>
+  %prod = tail call <2 x i32> @llvm.arm.neon.vqrdmulh.v2i32(<2 x i32> %x, <2 x i32> %shuffle)
+  %retval =  call <2 x i32> @llvm.arm.neon.vqsubs.v2i32(<2 x i32> %acc, <2 x i32> %prod)
+; CHECK: vqrdmlsh.s32  {{d[0-9]+}}, {{d[0-9]+}}, {{d[0-9]+}}[1]
+  ret <2 x i32> %retval
+}
+
+define <4 x i32> @test_vqrdmlshq_lane_s32(<4 x i32> %acc,<4 x i32> %x, <2 x i32> %v) {
+; CHECK-LABEL: test_vqrdmlshq_lane_s32:
+entry:
+  %shuffle = shufflevector <2 x i32> %v, <2 x i32> undef, <4 x i32> zeroinitializer
+  %prod = tail call <4 x i32> @llvm.arm.neon.vqrdmulh.v4i32(<4 x i32> %x, <4 x i32> %shuffle)
+  %retval =  call <4 x i32> @llvm.arm.neon.vqsubs.v4i32(<4 x i32> %acc, <4 x i32> %prod)
+; CHECK: vqrdmlsh.s32 {{q[0-9]+}}, {{q[0-9]+}}, {{d[0-9]+}}[0]
+  ret <4 x i32> %retval
+}
diff --git a/test/MC/ARM/basic-arm-instructions-v8.1a.s b/test/MC/ARM/basic-arm-instructions-v8.1a.s
new file mode 100644 (file)
index 0000000..261e628
--- /dev/null
@@ -0,0 +1,174 @@
+//RUN: not llvm-mc -triple thumb-none-linux-gnu -mattr=+v8.1a -mattr=neon -show-encoding < %s 2>%t | FileCheck %s --check-prefix=CHECK-V81aTHUMB
+//RUN: FileCheck --check-prefix=CHECK-ERROR <%t %s
+//RUN: not llvm-mc -triple arm-none-linux-gnu -mattr=+v8.1a -mattr=neon -show-encoding < %s 2>%t | FileCheck %s --check-prefix=CHECK-V81aARM
+//RUN: FileCheck --check-prefix=CHECK-ERROR <%t %s
+
+//RUN: not llvm-mc -triple thumb-none-linux-gnu -mattr=+v8 -mattr=neon -show-encoding < %s 2>1 |& FileCheck %s --check-prefix=CHECK-V8
+//RUN: not llvm-mc -triple arm-none-linux-gnu -mattr=+v8 -mattr=neon -show-encoding < %s 2>1 |& FileCheck %s --check-prefix=CHECK-V8
+
+
+  .text
+//CHECK-V8THUMB: .text
+
+  vqrdmlah.i8   q0, q1, q2
+  vqrdmlah.u16  d0, d1, d2
+  vqrdmlsh.f32  q3, q4, q5
+  vqrdmlsh.f64  d3, d5, d5
+
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlah.i8   q0, q1, q2
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlah.u16  d0, d1, d2
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlsh.f32  q3, q4, q5
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlsh.f64  d3, d5, d5
+//CHECK-ERROR:           ^
+//CHECK-V8: error: invalid operand for instruction
+//CHECK-V8:   vqrdmlah.i8   q0, q1, q2
+//CHECK-V8:           ^
+//CHECK-V8: error: invalid operand for instruction
+//CHECK-V8:   vqrdmlah.u16  d0, d1, d2
+//CHECK-V8:           ^
+//CHECK-V8: error: invalid operand for instruction
+//CHECK-V8:   vqrdmlsh.f32  q3, q4, q5
+//CHECK-V8:           ^
+//CHECK-V8: error: invalid operand for instruction
+//CHECK-V8   vqrdmlsh.f64  d3, d5, d5
+//CHECK-V8:           ^
+
+  vqrdmlah.s16    d0, d1, d2
+//CHECK-V81aARM:   vqrdmlah.s16  d0, d1, d2      @ encoding: [0x12,0x0b,0x11,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s16  d0, d1, d2      @ encoding: [0x11,0xff,0x12,0x0b]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s16    d0, d1, d2
+//CHECK-V8:  ^
+
+  vqrdmlah.s32  d0, d1, d2
+//CHECK-V81aARM:   vqrdmlah.s32  d0, d1, d2      @ encoding: [0x12,0x0b,0x21,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s32  d0, d1, d2      @ encoding: [0x21,0xff,0x12,0x0b]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s32  d0, d1, d2
+//CHECK-V8:  ^
+
+  vqrdmlah.s16  q0, q1, q2
+//CHECK-V81aARM:   vqrdmlah.s16  q0, q1, q2      @ encoding: [0x54,0x0b,0x12,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s16  q0, q1, q2      @ encoding: [0x12,0xff,0x54,0x0b]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s16  q0, q1, q2
+//CHECK-V8:  ^
+
+  vqrdmlah.s32  q2, q3, q0
+//CHECK-V81aARM:   vqrdmlah.s32  q2, q3, q0      @ encoding: [0x50,0x4b,0x26,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s32  q2, q3, q0      @ encoding: [0x26,0xff,0x50,0x4b]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s32  q2, q3, q0
+//CHECK-V8:  ^
+
+
+  vqrdmlsh.s16  d7, d6, d5
+//CHECK-V81aARM:   vqrdmlsh.s16  d7, d6, d5      @ encoding: [0x15,0x7c,0x16,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s16  d7, d6, d5      @ encoding: [0x16,0xff,0x15,0x7c]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s16  d7, d6, d5
+//CHECK-V8:  ^
+
+  vqrdmlsh.s32  d0, d1, d2
+//CHECK-V81aARM:   vqrdmlsh.s32  d0, d1, d2      @ encoding: [0x12,0x0c,0x21,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s32  d0, d1, d2      @ encoding: [0x21,0xff,0x12,0x0c]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s32  d0, d1, d2
+//CHECK-V8:  ^
+
+  vqrdmlsh.s16  q0, q1, q2
+//CHECK-V81aARM:   vqrdmlsh.s16  q0, q1, q2      @ encoding: [0x54,0x0c,0x12,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s16  q0, q1, q2      @ encoding: [0x12,0xff,0x54,0x0c]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s16  q0, q1, q2
+//CHECK-V8:  ^
+
+  vqrdmlsh.s32    q3, q4, q5
+//CHECK-V81aARM:   vqrdmlsh.s32  q3, q4, q5      @ encoding: [0x5a,0x6c,0x28,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s32  q3, q4, q5      @ encoding: [0x28,0xff,0x5a,0x6c]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s32  q3, q4, q5
+//CHECK-V8:  ^
+
+
+  vqrdmlah.i8   q0, q1, d9[7]
+  vqrdmlah.u16  d0, d1, d2[3]
+  vqrdmlsh.f32  q3, q4, d5[1]
+  vqrdmlsh.f64  d3, d5, d5[0]
+
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlah.i8   q0, q1, d9[7]
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlah.u16  d0, d1, d2[3]
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlsh.f32  q3, q4, d5[1]
+//CHECK-ERROR:           ^
+//CHECK-ERROR: error: invalid operand for instruction
+//CHECK-ERROR:   vqrdmlsh.f64  d3, d5, d5[0]
+//CHECK-ERROR:           ^
+
+  vqrdmlah.s16  d0, d1, d2[0]
+//CHECK-V81aARM:   vqrdmlah.s16 d0, d1, d2[0]    @ encoding: [0x42,0x0e,0x91,0xf2]
+//CHECK-V81aTHUMB: vqrdmlah.s16  d0, d1, d2[0]   @ encoding: [0x91,0xef,0x42,0x0e]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s16  d0, d1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlah.s32  d0, d1, d2[0]
+//CHECK-V81aARM:   vqrdmlah.s32 d0, d1, d2[0]    @ encoding: [0x42,0x0e,0xa1,0xf2]
+//CHECK-V81aTHUMB: vqrdmlah.s32  d0, d1, d2[0]   @ encoding: [0xa1,0xef,0x42,0x0e]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s32  d0, d1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlah.s16  q0, q1, d2[0]
+//CHECK-V81aARM:   vqrdmlah.s16  q0, q1, d2[0]   @ encoding: [0x42,0x0e,0x92,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s16  q0, q1, d2[0]   @ encoding: [0x92,0xff,0x42,0x0e]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s16  q0, q1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlah.s32  q0, q1, d2[0]
+//CHECK-V81aARM:   vqrdmlah.s32  q0, q1, d2[0]   @ encoding: [0x42,0x0e,0xa2,0xf3]
+//CHECK-V81aTHUMB: vqrdmlah.s32  q0, q1, d2[0]   @ encoding: [0xa2,0xff,0x42,0x0e]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlah.s32  q0, q1, d2[0]
+//CHECK-V8:  ^
+
+
+  vqrdmlsh.s16  d0, d1, d2[0]
+//CHECK-V81aARM:   vqrdmlsh.s16 d0, d1, d2[0]    @ encoding: [0x42,0x0f,0x91,0xf2]
+//CHECK-V81aTHUMB: vqrdmlsh.s16  d0, d1, d2[0]   @ encoding: [0x91,0xef,0x42,0x0f]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s16  d0, d1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlsh.s32  d0, d1, d2[0]
+//CHECK-V81aARM:   vqrdmlsh.s32 d0, d1, d2[0]    @ encoding: [0x42,0x0f,0xa1,0xf2]
+//CHECK-V81aTHUMB: vqrdmlsh.s32  d0, d1, d2[0]   @ encoding: [0xa1,0xef,0x42,0x0f]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s32  d0, d1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlsh.s16  q0, q1, d2[0]
+//CHECK-V81aARM:   vqrdmlsh.s16 q0, q1, d2[0]    @ encoding: [0x42,0x0f,0x92,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s16  q0, q1, d2[0]   @ encoding: [0x92,0xff,0x42,0x0f]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s16  q0, q1, d2[0]
+//CHECK-V8:  ^
+
+  vqrdmlsh.s32  q0, q1, d2[0]
+//CHECK-V81aARM:   vqrdmlsh.s32 q0, q1, d2[0]    @ encoding: [0x42,0x0f,0xa2,0xf3]
+//CHECK-V81aTHUMB: vqrdmlsh.s32  q0, q1, d2[0]   @ encoding: [0xa2,0xff,0x42,0x0f]
+//CHECK-V8: error: instruction requires: v8.1a
+//CHECK-V8:  vqrdmlsh.s32  q0, q1, d2[0]
+//CHECK-V8:  ^
diff --git a/test/MC/Disassembler/ARM/armv8.1a.txt b/test/MC/Disassembler/ARM/armv8.1a.txt
new file mode 100644 (file)
index 0000000..de0c89e
--- /dev/null
@@ -0,0 +1,36 @@
+# RUN: llvm-mc -triple armv8 -mattr=+v8.1a  --disassemble < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V81a
+# RUN: not llvm-mc -triple armv8 -mattr=+v8 --disassemble < %s 2>&1 | FileCheck %s --check-prefix=CHECK-V8
+
+[0x54,0x0b,0x12,0xf3]
+[0x12,0x0b,0x21,0xf3]
+[0x54,0x0c,0x12,0xf3]
+[0x12,0x0c,0x21,0xf3]
+# CHECK-V81a:  vqrdmlah.s16  q0, q1, q2
+# CHECK-V81a:  vqrdmlah.s32  d0, d1, d2
+# CHECK-V81a:  vqrdmlsh.s16  q0, q1, q2
+# CHECK-V81a:  vqrdmlsh.s32  d0, d1, d2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x54,0x0b,0x12,0xf3]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x12,0x0b,0x21,0xf3]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x54,0x0c,0x12,0xf3]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x12,0x0c,0x21,0xf3]
+
+[0x42,0x0e,0x92,0xf3]
+[0x42,0x0e,0xa1,0xf2]
+[0x42,0x0f,0x92,0xf3]
+[0x42,0x0f,0xa1,0xf2]
+# CHECK-V81a:  vqrdmlah.s16 q0, q1, d2[0]
+# CHECK-V81a:  vqrdmlah.s32 d0, d1, d2[0]
+# CHECK-V81a:  vqrdmlsh.s16 q0, q1, d2[0]
+# CHECK-V81a:  vqrdmlsh.s32 d0, d1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x42,0x0e,0x92,0xf3]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x42,0x0e,0xa1,0xf2]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x42,0x0f,0x92,0xf3]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x42,0x0f,0xa1,0xf2]
diff --git a/test/MC/Disassembler/ARM/invalid-armv8.1a.txt b/test/MC/Disassembler/ARM/invalid-armv8.1a.txt
new file mode 100644 (file)
index 0000000..1a9f275
--- /dev/null
@@ -0,0 +1,83 @@
+# RUN: not llvm-mc -triple armv8 -mattr=+v8.1a --disassemble < %s 2>&1 | FileCheck %s
+
+# Check, if sizes 00 and 11 are undefined for RDMA
+[0x12,0x0b,0x01,0xf3] # vqrdmlah.s8   d0, d1, d2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x12,0x0b,0x01,0xf3] # vqrdmlah.s8   d0, d1, d2
+# CHECK-NEXT:  ^
+
+[0x12,0x0b,0x31,0xf3] # vqrdmlah.s64  d0, d1, d2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x12,0x0b,0x31,0xf3] # vqrdmlah.s64  d0, d1, d2
+# CHECK-NEXT:  ^
+
+[0x54,0x0b,0x02,0xf3] # vqrdmlah.s8   q0, q1, q2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x54,0x0b,0x02,0xf3] # vqrdmlah.s8   q0, q1, q2
+# CHECK-NEXT:  ^
+
+[0x54,0x0b,0x32,0xf3] # vqrdmlah.s64  q2, q3, q0
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x54,0x0b,0x32,0xf3] # vqrdmlah.s64  q2, q3, q0
+# CHECK-NEXT:  ^
+
+[0x15,0x7c,0x06,0xf3] # vqrdmlsh.s8   d0, d1, d2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x15,0x7c,0x06,0xf3] # vqrdmlsh.s8   d0, d1, d2
+# CHECK-NEXT:  ^
+
+[0x15,0x7c,0x36,0xf3] # vqrdmlsh.s64  d0, d1, d2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x15,0x7c,0x36,0xf3] # vqrdmlsh.s64  d0, d1, d2
+# CHECK-NEXT:  ^
+
+[0x54,0x0c,0x02,0xf3] # vqrdmlsh.s8   q0, q1, q2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x54,0x0c,0x02,0xf3] # vqrdmlsh.s8   q0, q1, q2
+# CHECK-NEXT:  ^
+
+[0x54,0x0c,0x32,0xf3] # vqrdmlsh.s64  q0, q1, q2
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x54,0x0c,0x32,0xf3] # vqrdmlsh.s64  q0, q1, q2
+# CHECK-NEXT:  ^
+
+[0x42,0x0e,0x81,0xf2] # vqrdmlah.s8   d0, d1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0e,0x81,0xf2] # vqrdmlah.s8   d0, d1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0e,0xb1,0xf2] # vqrdmlah.s64  d0, d1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0e,0xb1,0xf2] # vqrdmlah.s64  d0, d1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0e,0x82,0xf3] # vqrdmlah.s8   q0, q1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0e,0x82,0xf3] # vqrdmlah.s8   q0, q1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0e,0xb2,0xf3] # vqrdmlah.s64  q0, q1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0e,0xb2,0xf3] # vqrdmlah.s64  q0, q1, d2[0]
+# CHECK-NEXT:  ^
+
+
+[0x42,0x0f,0x81,0xf2] # vqrdmlsh.s8   d0, d1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0f,0x81,0xf2] # vqrdmlsh.s8   d0, d1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0f,0xb1,0xf2] # vqrdmlsh.s64  d0, d1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0f,0xb1,0xf2] # vqrdmlsh.s64  d0, d1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0f,0x82,0xf3] # vqrdmlsh.s8   q0, q1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0f,0x82,0xf3] # vqrdmlsh.s8   q0, q1, d2[0]
+# CHECK-NEXT:  ^
+
+[0x42,0x0f,0xb2,0xf3] # vqrdmlsh.s64  q0, q1, d2[0]
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x42,0x0f,0xb2,0xf3] # vqrdmlsh.s64  q0, q1, d2[0]
+# CHECK-NEXT:  ^
diff --git a/test/MC/Disassembler/ARM/invalid-thumbv8.1a.txt b/test/MC/Disassembler/ARM/invalid-thumbv8.1a.txt
new file mode 100644 (file)
index 0000000..555b8c3
--- /dev/null
@@ -0,0 +1,72 @@
+# RUN: not llvm-mc -triple thumbv8 -mattr=+v8.1a --disassemble < %s 2>&1 | FileCheck %s
+
+# Check, if sizes 00 and 11 are undefined for RDMA
+[0x01,0xff,0x12,0x0b] # vqrdmlah.s8   d0, d1, d2
+[0x31,0xff,0x12,0x0b] # vqrdmlah.s64  d0, d1, d2
+[0x02,0xff,0x54,0x0b] # vqrdmlah.s8   q0, q1, q2
+[0x06,0xff,0x50,0x4b] # vqrdmlah.s64  q2, q3, q0
+
+[0x01,0xff,0x12,0x0c] # vqrdmlsh.s8   d0, d1, d2
+[0x31,0xff,0x12,0x0c] # vqrdmlsh.s64  d0, d1, d2
+[0x02,0xff,0x54,0x0c] # vqrdmlsh.s8   q0, q1, q2
+[0x32,0xff,0x54,0x0c] # vqrdmlsh.s64  q0, q1, q2
+
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x01,0xff,0x12,0x0b] # vqrdmlah.s8   d0, d1, d2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x31,0xff,0x12,0x0b] # vqrdmlah.s64  d0, d1, d2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x02,0xff,0x54,0x0b] # vqrdmlah.s8   q0, q1, q2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x06,0xff,0x50,0x4b] # vqrdmlah.s64  q2, q3, q0
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x01,0xff,0x12,0x0c] # vqrdmlsh.s8   d0, d1, d2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x31,0xff,0x12,0x0c] # vqrdmlsh.s64  d0, d1, d2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x02,0xff,0x54,0x0c] # vqrdmlsh.s8   q0, q1, q2
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x32,0xff,0x54,0x0c] # vqrdmlsh.s64  q0, q1, q2
+# CHECK-NEXT:  ^
+
+[0x81,0xef,0x42,0x0e] # vqrdmlah.s8   d0, d1, d2[0]
+[0xb1,0xef,0x42,0x0e] # vqrdmlah.s64  d0, d1, d2[0]
+[0x82,0xff,0x42,0x0e] # vqrdmlah.s8   q0, q1, d2[0]
+[0xb2,0xff,0x42,0x0e] # vqrdmlah.s64  q0, q1, d2[0]
+
+[0x81,0xef,0x42,0x0f] # vqrdmlsh.s8   d0, d1, d2[0]
+[0xb1,0xef,0x42,0x0f] # vqrdmlsh.s64  d0, d1, d2[0]
+[0x82,0xff,0x42,0x0f] # vqrdmlsh.s8   q0, q1, d2[0]
+[0xb2,0xff,0x42,0x0f] # vqrdmlsh.s64  q0, q1, d2[0]
+
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x81,0xef,0x42,0x0e] # vqrdmlah.s8   d0, d1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0xb1,0xef,0x42,0x0e] # vqrdmlah.s64  d0, d1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x82,0xff,0x42,0x0e] # vqrdmlah.s8   q0, q1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0xb2,0xff,0x42,0x0e] # vqrdmlah.s64  q0, q1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x81,0xef,0x42,0x0f] # vqrdmlsh.s8   d0, d1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0xb1,0xef,0x42,0x0f] # vqrdmlsh.s64  d0, d1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0x82,0xff,0x42,0x0f] # vqrdmlsh.s8   q0, q1, d2[0]
+# CHECK-NEXT:  ^
+# CHECK:      warning: invalid instruction encoding
+# CHECK-NEXT: [0xb2,0xff,0x42,0x0f] # vqrdmlsh.s64  q0, q1, d2[0]
+# CHECK-NEXT:  ^
diff --git a/test/MC/Disassembler/ARM/thumb-v8.1a.txt b/test/MC/Disassembler/ARM/thumb-v8.1a.txt
new file mode 100644 (file)
index 0000000..bb0f1dc
--- /dev/null
@@ -0,0 +1,98 @@
+# RUN: llvm-mc -triple thumbv8 -mattr=+v8.1a  --disassemble < %s |& FileCheck %s --check-prefix=CHECK-V81a
+# RUN: not llvm-mc -triple thumbv8 -mattr=+v8 --disassemble < %s |& FileCheck %s --check-prefix=CHECK-V8
+
+[0x11,0xff,0x12,0x0b]
+# CHECK-V81a: vqrdmlah.s16  d0, d1, d2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x11,0xff,0x12,0x0b]
+# CHECK-V8: ^
+
+[0x21,0xff,0x12,0x0b]
+# CHECK-V81a: vqrdmlah.s32  d0, d1, d2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x21,0xff,0x12,0x0b]
+# CHECK-V8: ^
+
+[0x12,0xff,0x54,0x0b]
+# CHECK-V81a: vqrdmlah.s16  q0, q1, q2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x12,0xff,0x54,0x0b]
+# CHECK-V8: ^
+
+[0x26,0xff,0x50,0x4b]
+# CHECK-V81a: vqrdmlah.s32  q2, q3, q0
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x26,0xff,0x50,0x4b]
+# CHECK-V8: ^
+
+[0x16,0xff,0x15,0x7c]
+# CHECK-V81a: vqrdmlsh.s16  d7, d6, d5
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x16,0xff,0x15,0x7c]
+# CHECK-V8: ^
+
+[0x21,0xff,0x12,0x0c]
+# CHECK-V81a: vqrdmlsh.s32  d0, d1, d2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x21,0xff,0x12,0x0c]
+# CHECK-V8: ^
+
+[0x12,0xff,0x54,0x0c]
+# CHECK-V81a: vqrdmlsh.s16  q0, q1, q2
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x12,0xff,0x54,0x0c]
+# CHECK-V8: ^
+
+[0x28,0xff,0x5a,0x6c]
+# CHECK-V81a: vqrdmlsh.s32  q3, q4, q5
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x28,0xff,0x5a,0x6c]
+# CHECK-V8: ^
+
+[0x91,0xef,0x42,0x0e]
+# CHECK-V81a: vqrdmlah.s16  d0, d1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x91,0xef,0x42,0x0e]
+# CHECK-V8: ^
+
+[0xa1,0xef,0x42,0x0e]
+# CHECK-V81a: vqrdmlah.s32  d0, d1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0xa1,0xef,0x42,0x0e]
+# CHECK-V8: ^
+
+[0x92,0xff,0x42,0x0e]
+# CHECK-V81a: vqrdmlah.s16  q0, q1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x92,0xff,0x42,0x0e]
+# CHECK-V8: ^
+
+[0xa2,0xff,0x42,0x0e]
+# CHECK-V81a: vqrdmlah.s32  q0, q1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0xa2,0xff,0x42,0x0e]
+# CHECK-V8: ^
+
+[0x91,0xef,0x42,0x0f]
+# CHECK-V81a: vqrdmlsh.s16  d0, d1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x91,0xef,0x42,0x0f]
+# CHECK-V8: ^
+
+[0xa1,0xef,0x42,0x0f]
+# CHECK-V81a: vqrdmlsh.s32  d0, d1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0xa1,0xef,0x42,0x0f]
+# CHECK-V8: ^
+
+[0x92,0xff,0x42,0x0f]
+# CHECK-V81a: vqrdmlsh.s16  q0, q1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0x92,0xff,0x42,0x0f]
+# CHECK-V8: ^
+
+[0xa2,0xff,0x42,0x0f]
+# CHECK-V81a: vqrdmlsh.s32  q0, q1, d2[0]
+# CHECK-V8: warning: invalid instruction encoding
+# CHECK-V8: [0xa2,0xff,0x42,0x0f]
+# CHECK-V8: ^