Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td =================================================================== --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -3586,4 +3586,8 @@ def UDOT_ZZZ_HtoS : sve2p1_two_way_dot_vv<"udot", 0b1>; def SDOT_ZZZI_HtoS : sve2p1_two_way_dot_vvi<"sdot", 0b0>; def UDOT_ZZZI_HtoS : sve2p1_two_way_dot_vvi<"udot", 0b1>; + +defm SQRSHRN_Z2ZI_StoH : sve2p1_multi_vec_shift_narrow<"sqrshrn", 0b10>; +defm UQRSHRN_Z2ZI_StoH : sve2p1_multi_vec_shift_narrow<"uqrshrn", 0b11>; +defm SQRSHRUN_Z2ZI_StoH : sve2p1_multi_vec_shift_narrow<"sqrshrun", 0b00>; } // End HasSVE2p1_or_HasSME2 Index: llvm/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -8695,3 +8695,29 @@ let Constraints = "$Zda = $_Zda"; let DestructiveInstType = DestructiveOther; } + + +// SVE2 multi-vec shift narrow +class sve2p1_multi_vec_shift_narrow opc, bits<2> tsz> + : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, vecshiftR16:$imm4), + mnemonic, "\t$Zd, $Zn, $imm4", + "", []>, Sched<[]> { + bits<5> Zd; + bits<4> Zn; + bits<4> imm4; + let Inst{31-23} = 0b010001011; + let Inst{22} = tsz{1}; + let Inst{21} = 0b1; + let Inst{20} = tsz{0}; + let Inst{19-16} = imm4; + let Inst{15-14} = 0b00; + let Inst{13-12} = opc; + let Inst{11-10} = 0b10; + let Inst{9-6} = Zn; + let Inst{5} = 0b0; + let Inst{4-0} = Zd; +} + +multiclass sve2p1_multi_vec_shift_narrow opc> { + def : sve2p1_multi_vec_shift_narrow; +} Index: llvm/test/MC/AArch64/SVE2p1/sqrshrn-diagnostics.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/sqrshrn-diagnostics.s @@ -0,0 +1,40 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid vector list + +sqrshrn z0.h, {z0.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sqrshrn z0.h, {z0.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrn z0.h, {z1.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: sqrshrn z0.h, {z1.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffixes + +sqrshrn z0.b, {z0.s-z1.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sqrshrn z0.b, {z0.s-z1.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrn z0.h, {z0.d-z1.d}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sqrshrn z0.h, {z0.d-z1.d}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate + +sqrshrn z0.h, {z0.s-z1.s}, #17 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: sqrshrn z0.h, {z0.s-z1.s}, #17 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrn z0.h, {z0.s-z1.s}, #0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: sqrshrn z0.h, {z0.s-z1.s}, #0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: llvm/test/MC/AArch64/SVE2p1/sqrshrn.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/sqrshrn.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +sqrshrn z0.h, {z0.s-z1.s}, #16 // 01000101-10110000-00101000-00000000 +// CHECK-INST: sqrshrn z0.h, { z0.s, z1.s }, #16 +// CHECK-ENCODING: [0x00,0x28,0xb0,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b02800 + +sqrshrn z21.h, {z10.s-z11.s}, #11 // 01000101-10110101-00101001-01010101 +// CHECK-INST: sqrshrn z21.h, { z10.s, z11.s }, #11 +// CHECK-ENCODING: [0x55,0x29,0xb5,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b52955 + +sqrshrn z23.h, {z12.s-z13.s}, #8 // 01000101-10111000-00101001-10010111 +// CHECK-INST: sqrshrn z23.h, { z12.s, z13.s }, #8 +// CHECK-ENCODING: [0x97,0x29,0xb8,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b82997 + +sqrshrn z31.h, {z30.s-z31.s}, #1 // 01000101-10111111-00101011-11011111 +// CHECK-INST: sqrshrn z31.h, { z30.s, z31.s }, #1 +// CHECK-ENCODING: [0xdf,0x2b,0xbf,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45bf2bdf Index: llvm/test/MC/AArch64/SVE2p1/sqrshrun-diagnostics.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/sqrshrun-diagnostics.s @@ -0,0 +1,40 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid vector list + +sqrshrun z0.h, {z0.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sqrshrun z0.h, {z0.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrun z0.h, {z1.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: sqrshrun z0.h, {z1.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffixes + +sqrshrun z0.b, {z0.s-z1.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sqrshrun z0.b, {z0.s-z1.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrun z0.h, {z0.d-z1.d}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sqrshrun z0.h, {z0.d-z1.d}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate + +sqrshrun z0.h, {z0.s-z1.s}, #17 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: sqrshrun z0.h, {z0.s-z1.s}, #17 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sqrshrun z0.h, {z0.s-z1.s}, #0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: sqrshrun z0.h, {z0.s-z1.s}, #0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: llvm/test/MC/AArch64/SVE2p1/sqrshrun.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/sqrshrun.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +sqrshrun z0.h, {z0.s-z1.s}, #16 // 01000101-10110000-00001000-00000000 +// CHECK-INST: sqrshrun z0.h, { z0.s, z1.s }, #16 +// CHECK-ENCODING: [0x00,0x08,0xb0,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b00800 + +sqrshrun z21.h, {z10.s-z11.s}, #11 // 01000101-10110101-00001001-01010101 +// CHECK-INST: sqrshrun z21.h, { z10.s, z11.s }, #11 +// CHECK-ENCODING: [0x55,0x09,0xb5,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b50955 + +sqrshrun z23.h, {z12.s-z13.s}, #8 // 01000101-10111000-00001001-10010111 +// CHECK-INST: sqrshrun z23.h, { z12.s, z13.s }, #8 +// CHECK-ENCODING: [0x97,0x09,0xb8,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b80997 + +sqrshrun z31.h, {z30.s-z31.s}, #1 // 01000101-10111111-00001011-11011111 +// CHECK-INST: sqrshrun z31.h, { z30.s, z31.s }, #1 +// CHECK-ENCODING: [0xdf,0x0b,0xbf,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45bf0bdf Index: llvm/test/MC/AArch64/SVE2p1/uqrshrn-diagnostics.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/uqrshrn-diagnostics.s @@ -0,0 +1,40 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid vector list + +uqrshrn z0.h, {z0.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: uqrshrn z0.h, {z0.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uqrshrn z0.h, {z1.s-z2.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: uqrshrn z0.h, {z1.s-z2.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffixes + +uqrshrn z0.b, {z0.s-z1.s}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: uqrshrn z0.b, {z0.s-z1.s}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uqrshrn z0.h, {z0.d-z1.d}, #16 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: uqrshrn z0.h, {z0.d-z1.d}, #16 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid immediate + +uqrshrn z0.h, {z0.s-z1.s}, #17 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: uqrshrn z0.h, {z0.s-z1.s}, #17 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +uqrshrn z0.h, {z0.s-z1.s}, #0 +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [1, 16]. +// CHECK-NEXT: uqrshrn z0.h, {z0.s-z1.s}, #0 +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: Index: llvm/test/MC/AArch64/SVE2p1/uqrshrn.s =================================================================== --- /dev/null +++ llvm/test/MC/AArch64/SVE2p1/uqrshrn.s @@ -0,0 +1,38 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2p1 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +uqrshrn z0.h, {z0.s-z1.s}, #16 // 01000101-10110000-00111000-00000000 +// CHECK-INST: uqrshrn z0.h, { z0.s, z1.s }, #16 +// CHECK-ENCODING: [0x00,0x38,0xb0,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b03800 + +uqrshrn z21.h, {z10.s-z11.s}, #11 // 01000101-10110101-00111001-01010101 +// CHECK-INST: uqrshrn z21.h, { z10.s, z11.s }, #11 +// CHECK-ENCODING: [0x55,0x39,0xb5,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b53955 + +uqrshrn z23.h, {z12.s-z13.s}, #8 // 01000101-10111000-00111001-10010111 +// CHECK-INST: uqrshrn z23.h, { z12.s, z13.s }, #8 +// CHECK-ENCODING: [0x97,0x39,0xb8,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45b83997 + +uqrshrn z31.h, {z30.s-z31.s}, #1 // 01000101-10111111-00111011-11011111 +// CHECK-INST: uqrshrn z31.h, { z30.s, z31.s }, #1 +// CHECK-ENCODING: [0xdf,0x3b,0xbf,0x45] +// CHECK-ERROR: instruction requires: sme2 or sve2p1 +// CHECK-UNKNOWN: 45bf3bdf