diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 2a857234c7d74..25899ee83f257 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4163,7 +4163,9 @@ defm BFMIN_ZPZZ : sve_fp_2op_p_zds_zeroing_bfloat; defm BFMAX_ZPZZ : sve_fp_2op_p_zds_zeroing_bfloat; } // HasSVEB16B16, UseExperimentalZeroingPseudos - +let Predicates = [HasSVEBFSCALE] in { + def BFSCALE_ZPZZ : sve_fp_2op_p_zds_bfscale<0b1001, "bfscale", DestructiveBinary>; +} // HasSVEBFSCALE //===----------------------------------------------------------------------===// // SME2.1 or SVE2.1 instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index f655526fa81cf..b5665e30b88d7 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -2174,6 +2174,11 @@ multiclass sve_fp_2op_p_zds_bfloat opc, string asm, string Ps, def : SVE_3_Op_Pat(NAME)>; } +class sve_fp_2op_p_zds_bfscale opc, string asm, DestructiveInstTypeEnum flags> +: sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>{ + let DestructiveInstType = flags; +} + multiclass sve_fp_2op_p_zds_zeroing_hsd { def _H_ZERO : PredTwoOpPseudo; def _S_ZERO : PredTwoOpPseudo; diff --git a/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s new file mode 100644 index 0000000000000..9be311df26007 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2/bfscale-diagnostics.s @@ -0,0 +1,43 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve-bfscale 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid element width + +bfscale z31.h, p7/m, z31.h, z31.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfscale z31.h, p7/m, z31.h, z31.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bfscale z31.h, p7/m, z31.b, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfscale z31.h, p7/m, z31.b, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +bfscale z31.d, p7/m, z31.h, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: bfscale z31.d, p7/m, z31.h, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Predicate register out of range + +bfscale z31.h, p8/m, z31.h, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: bfscale z31.h, p8/m, z31.h, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Destination and source register don't match + +bfscale z31.h, p7/m, z20.h, z31.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: bfscale z31.h, p7/m, z20.h, z31.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// ------------------------------------------------------------------------- // +// Using zeroing predicate +bfscale z0.h, p0/z, z0.h, z0.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: bfscale z0.h, p0/z, z0.h, z0.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE2/bfscale.s b/llvm/test/MC/AArch64/SVE2/bfscale.s new file mode 100644 index 0000000000000..c655488ecd8dd --- /dev/null +++ b/llvm/test/MC/AArch64/SVE2/bfscale.s @@ -0,0 +1,50 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-bfscale < %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=+sve,+sve-bfscale < %s \ +// RUN: | llvm-objdump -d --mattr=+sve,+sve-bfscale - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+sve-bfscale < %s \ +// RUN: | llvm-objdump -d --mattr=-sve-bfscale - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+sve-bfscale < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve,+sve-bfscale -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +bfscale z0.h, p0/m, z0.h, z0.h // 01100101-00001001-10000000-00000000 +// CHECK-INST: bfscale z0.h, p0/m, z0.h, z0.h +// CHECK-ENCODING: [0x00,0x80,0x09,0x65] +// CHECK-ERROR: instruction requires: sve-bfscale +// CHECK-UNKNOWN: 65098000 + +bfscale z21.h, p5/m, z21.h, z10.h // 01100101-00001001-10010101-01010101 +// CHECK-INST: bfscale z21.h, p5/m, z21.h, z10.h +// CHECK-ENCODING: [0x55,0x95,0x09,0x65] +// CHECK-ERROR: instruction requires: sve-bfscale +// CHECK-UNKNOWN: 65099555 + +bfscale z31.h, p7/m, z31.h, z31.h // 01100101-00001001-10011111-11111111 +// CHECK-INST: bfscale z31.h, p7/m, z31.h, z31.h +// CHECK-ENCODING: [0xff,0x9f,0x09,0x65] +// CHECK-ERROR: instruction requires: sve-bfscale +// CHECK-UNKNOWN: 65099fff + +// --------------------------------------------------------------------------// +// Test compatibility with MOVPRFX instruction. + +movprfx z23.h, p3/m, z31.h +bfscale z23.h, p3/m, z23.h, z13.h // 01100101-00001001-10001101-10110111 +// CHECK-INST: movprfx z23.h, p3/m, z31.h +// CHECK-INST: bfscale z23.h, p3/m, z23.h, z13.h +// CHECK-ENCODING: [0xb7,0x8d,0x09,0x65] +// CHECK-ERROR: instruction requires: sve-bfscale +// CHECK-UNKNOWN: 65098db7 + +movprfx z23, z31 +bfscale z23.h, p3/m, z23.h, z13.h // 01100101-00001001-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: bfscale z23.h, p3/m, z23.h, z13.h +// CHECK-ENCODING: [0xb7,0x8d,0x09,0x65] +// CHECK-ERROR: instruction requires: sve-bfscale +// CHECK-UNKNOWN: 65098db7 diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s index 767e5dc5a1513..858aaf9d13ecc 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s +++ b/llvm/test/MC/AArch64/SVE2/directive-arch-negative.s @@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d bgrp z21.s, z10.s, z21.s // CHECK: error: instruction requires: sve2-bitperm // CHECK-NEXT: bgrp z21.s, z10.s, z21.s + +.arch armv9-a+sve-bfscale +.arch armv9-a+nosve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: error: instruction requires: sve-bfscale +// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch.s b/llvm/test/MC/AArch64/SVE2/directive-arch.s index 0a921ccf5e4f0..b9710b67f8a1d 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-arch.s +++ b/llvm/test/MC/AArch64/SVE2/directive-arch.s @@ -19,3 +19,7 @@ rax1 z0.d, z0.d, z0.d .arch armv9-a+sve2-bitperm bgrp z21.s, z10.s, z21.s // CHECK: bgrp z21.s, z10.s, z21.s + +.arch armv9-a+sve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s index 6d90f7f057490..bd625d2526269 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s +++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension-negative.s @@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d bgrp z21.s, z10.s, z21.s // CHECK: error: instruction requires: sve2-bitperm // CHECK-NEXT: bgrp z21.s, z10.s, z21.s + +.arch_extension sve-bfscale +.arch_extension nosve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: error: instruction requires: sve-bfscale +// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s index 90f5bec07d542..28d803bf7cc88 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s +++ b/llvm/test/MC/AArch64/SVE2/directive-arch_extension.s @@ -19,3 +19,7 @@ rax1 z0.d, z0.d, z0.d .arch_extension sve2-bitperm bgrp z21.s, z10.s, z21.s // CHECK: bgrp z21.s, z10.s, z21.s + +.arch_extension sve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s b/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s index ed99aa7f00786..45a04a58eac3b 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s +++ b/llvm/test/MC/AArch64/SVE2/directive-cpu-negative.s @@ -29,3 +29,9 @@ rax1 z0.d, z0.d, z0.d bgrp z21.s, z10.s, z21.s // CHECK: error: instruction requires: sve2-bitperm // CHECK-NEXT: bgrp z21.s, z10.s, z21.s + +.cpu generic+sve-bfscale +.cpu generic+nosve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: error: instruction requires: sve-bfscale +// CHECK-NEXT: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file diff --git a/llvm/test/MC/AArch64/SVE2/directive-cpu.s b/llvm/test/MC/AArch64/SVE2/directive-cpu.s index b3cacc46c1ddc..75d2321bf6207 100644 --- a/llvm/test/MC/AArch64/SVE2/directive-cpu.s +++ b/llvm/test/MC/AArch64/SVE2/directive-cpu.s @@ -19,3 +19,7 @@ rax1 z0.d, z0.d, z0.d .cpu generic+sve2-bitperm bgrp z21.s, z10.s, z21.s // CHECK: bgrp z21.s, z10.s, z21.s + +.cpu generic+sve-bfscale +bfscale z0.h, p0/m, z0.h, z0.h +// CHECK: bfscale z0.h, p0/m, z0.h, z0.h \ No newline at end of file