From b23426ee0eb4b51b87147de3e376bc49960b7f35 Mon Sep 17 00:00:00 2001 From: hassnaaHamdi Date: Fri, 27 Oct 2023 12:13:46 +0100 Subject: [PATCH] =?UTF-8?q?[LLVM][AArch64][Assembly]:=20Add=20FAMINMAX=20a?= =?UTF-8?q?ssembly/disasse=E2=80=A6=20(#70115)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …mbly. This patch adds the feature flag FAMINMAX and the assembly/disassembly for the following instructions of NEON, SVE2 and SME2: * NEON: - FAMIN - FAMAX * SVE2: - FAMIN_ZPmZ - FAMAX_ZPmZ * SME2: - FAMAX_2Z2Z - FAMIN_2Z2Z - FAMAX_4Z4Z - FAMIN_4Z4Z That is according to this documentation: https://developer.arm.com/documentation/ddi0602/2023-09 Co-authored-by: Caroline Concatto --- .../llvm/TargetParser/AArch64TargetParser.h | 2 + llvm/lib/Target/AArch64/AArch64.td | 3 + llvm/lib/Target/AArch64/AArch64InstrInfo.td | 8 + .../lib/Target/AArch64/AArch64SMEInstrInfo.td | 7 + .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 8 +- .../AArch64/AsmParser/AArch64AsmParser.cpp | 1 + .../MC/AArch64/FP8/directive-arch-negative.s | 7 + llvm/test/MC/AArch64/FP8/directive-arch.s | 6 + .../MC/AArch64/FP8/faminmax-diagnostics.s | 64 ++++++ llvm/test/MC/AArch64/FP8/faminmax.s | 197 ++++++++++++++++++ .../AArch64/FP8_SME2/faminmax-diagnoctics.s | 62 ++++++ llvm/test/MC/AArch64/FP8_SME2/faminmax.s | 159 ++++++++++++++ .../AArch64/FP8_SVE2/faminmax-diagnostics.s | 99 +++++++++ llvm/test/MC/AArch64/FP8_SVE2/faminmax.s | 145 +++++++++++++ .../TargetParser/TargetParserTest.cpp | 4 +- 15 files changed, 770 insertions(+), 2 deletions(-) create mode 100644 llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s create mode 100644 llvm/test/MC/AArch64/FP8/faminmax.s create mode 100644 llvm/test/MC/AArch64/FP8_SME2/faminmax-diagnoctics.s create mode 100644 llvm/test/MC/AArch64/FP8_SME2/faminmax.s create mode 100644 llvm/test/MC/AArch64/FP8_SVE2/faminmax-diagnostics.s create mode 100644 llvm/test/MC/AArch64/FP8_SVE2/faminmax.s diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h index 8ff29477942519..232b3d6a6dbb1c 100644 --- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h +++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h @@ -161,6 +161,7 @@ enum ArchExtKind : unsigned { AEK_GCS = 57, // FEAT_GCS AEK_FPMR = 58, // FEAT_FPMR AEK_FP8 = 59, // FEAT_FP8 + AEK_FAMINMAX = 60, // FEAT_FAMINMAX AEK_NUM_EXTENSIONS }; using ExtensionBitset = Bitset; @@ -271,6 +272,7 @@ inline constexpr ExtensionInfo Extensions[] = { {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0}, {"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 0}, {"fp8", AArch64::AEK_FP8, "+fp8", "-fp8", FEAT_INIT, "+fpmr", 0}, + {"faminmax", AArch64::AEK_FAMINMAX, "+faminmax", "-faminmax", FEAT_INIT, "", 0}, // Special cases {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority}, }; diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index 0c0fa82ffe93cc..8fd9358c9f9c7a 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -514,6 +514,9 @@ def FeatureSME2 : SubtargetFeature<"sme2", "HasSME2", "true", def FeatureSME2p1 : SubtargetFeature<"sme2p1", "HasSME2p1", "true", "Enable Scalable Matrix Extension 2.1 (FEAT_SME2p1) instructions", [FeatureSME2]>; +def FeatureFAMINMAX: SubtargetFeature<"faminmax", "HasFAMINMAX", "true", + "Enable FAMIN and FAMAX instructions (FEAT_FAMINMAX)">; + def FeatureAppleA7SysReg : SubtargetFeature<"apple-a7-sysreg", "HasAppleA7SysReg", "true", "Apple A7 (the CPU formerly known as Cyclone)">; diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 6f616b27984357..97c5e89a29a972 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -164,6 +164,8 @@ def HasFPMR : Predicate<"Subtarget->hasFPMR()">, AssemblerPredicateWithAll<(all_of FeatureFPMR), "fpmr">; def HasFP8 : Predicate<"Subtarget->hasFP8()">, AssemblerPredicateWithAll<(all_of FeatureFP8), "fp8">; +def HasFAMINMAX : Predicate<"Subtarget->hasFAMINMAX()">, + AssemblerPredicateWithAll<(all_of FeatureFAMINMAX), "faminmax">; // A subset of SVE(2) instructions are legal in Streaming SVE execution mode, // they should be enabled if either has been specified. @@ -9265,6 +9267,12 @@ let Predicates = [HasFP8] in { defm FSCALE : SIMDThreeSameVectorFP<0b1, 0b1, 0b111, "fscale", null_frag>; } // End let Predicates = [HasFP8] +let Predicates = [HasFAMINMAX] in { + defm FAMAX : SIMDThreeSameVectorFP<0b0, 0b1, 0b011, "famax", null_frag>; + defm FAMIN : SIMDThreeSameVectorFP<0b1, 0b1, 0b011, "famin", null_frag>; +} // End let Predicates = [HasFAMAXMIN] + + include "AArch64InstrAtomics.td" include "AArch64SVEInstrInfo.td" include "AArch64SMEInstrInfo.td" diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td index cdc79ec3ae344a..f55b84b02f8516 100644 --- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -878,3 +878,10 @@ defm FSCALE_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"fscale", 0b001100 } // [HasSME2, HasFP8] +let Predicates = [HasSME2, HasFAMINMAX] in { +defm FAMAX_2Z2Z : sme2_fp_sve_destructive_vector_vg2_multi<"famax", 0b0010100>; +defm FAMIN_2Z2Z : sme2_fp_sve_destructive_vector_vg2_multi<"famin", 0b0010101>; + +defm FAMAX_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"famax", 0b0010100>; +defm FAMIN_4Z4Z : sme2_fp_sve_destructive_vector_vg4_multi<"famin", 0b0010101>; +} //[HasSME2, HasFAMINMAX] diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 002d5d28fcf8d5..1a586765d58b3c 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -4022,4 +4022,10 @@ defm FCVTN_Z2Z_HtoB : sve2_fp8_down_cvt_single<0b00, "fcvtn", ZZ_h_mul_r>; defm FCVTNB_Z2Z_StoB : sve2_fp8_down_cvt_single<0b01, "fcvtnb", ZZ_s_mul_r>; defm BFCVTN_Z2Z_HtoB : sve2_fp8_down_cvt_single<0b10, "bfcvtn", ZZ_h_mul_r>; defm FCVTNT_Z2Z_StoB : sve2_fp8_down_cvt_single<0b11, "fcvtnt", ZZ_s_mul_r>; -} // End HasSVE2orSME2, HasFP8 \ No newline at end of file +} // End HasSVE2orSME2, HasFP8 + +let Predicates = [HasSVE2orSME2, HasFAMINMAX] in { +// FP8 Arithmetic - Predicated Group +defm FAMIN_ZPmZ : sve_fp_2op_p_zds<0b1111, "famin", "", null_frag, DestructiveOther>; +defm FAMAX_ZPmZ : sve_fp_2op_p_zds<0b1110, "famax", "", null_frag, DestructiveOther>; +} // End HasSVE2orSME2, HasFAMINMAX diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 36e34fdc07e7cc..35abe3563eb81a 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -3640,6 +3640,7 @@ static const struct Extension { {"tme", {AArch64::FeatureTME}}, {"fpmr", {AArch64::FeatureFPMR}}, {"fp8", {AArch64::FeatureFP8}}, + {"faminmax", {AArch64::FeatureFAMINMAX}}, }; static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) { diff --git a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s index cf48416d29d8a2..86525ff68134c9 100644 --- a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s +++ b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s @@ -5,3 +5,10 @@ bf1cvtl v0.8h, v0.8b // CHECK: error: instruction requires: fp8 // CHECK: bf1cvtl v0.8h, v0.8b + +.arch armv9-a+faminmax +.arch armv9-a+nofaminmax +famax v31.4h, v31.4h, v31.4h +// CHECK: error: instruction requires: faminmax +// CHECK: famax v31.4h, v31.4h, v31.4h + diff --git a/llvm/test/MC/AArch64/FP8/directive-arch.s b/llvm/test/MC/AArch64/FP8/directive-arch.s index 8857d4f0bfbe42..e3f0a94c2ff9a3 100644 --- a/llvm/test/MC/AArch64/FP8/directive-arch.s +++ b/llvm/test/MC/AArch64/FP8/directive-arch.s @@ -5,3 +5,9 @@ bf1cvtl v0.8h, v0.8b // CHECK: bf1cvtl v0.8h, v0.8b .arch armv9-a+nofp8 +.arch armv9-a+faminmax +famax v31.4h, v31.4h, v31.4h +// CHECK: famax v31.4h, v31.4h, v31.4h + +.arch armv9-a+nofaminmax + diff --git a/llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s b/llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s new file mode 100644 index 00000000000000..724b7eadfb4162 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s @@ -0,0 +1,64 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Element size extension incorrect + +famax v0.16s, v0.4s, v0.4s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: famax v0.16s, v0.4s, v0.4s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax v0.4h, v0.4s, v0.4s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax v0.4h, v0.4s, v0.4s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax v0.8h, v0.8s, v0.8s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: famax v0.8h, v0.8s, v0.8s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax v0.2s, v0.2h, v0.2h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax v0.2s, v0.2h, v0.2h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax v0.4s, v31.4h, v0.4h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax v0.4s, v31.4h, v0.4h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax v0.2d, v31.2h, v0.2h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax v0.2d, v31.2h, v0.2h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.16s, v0.4s, v0.4s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: famin v0.16s, v0.4s, v0.4s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.4h, v0.4s, v0.4s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin v0.4h, v0.4s, v0.4s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.8h, v0.8s, v0.8s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier +// CHECK-NEXT: famin v0.8h, v0.8s, v0.8s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.2s, v0.2h, v0.2h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin v0.2s, v0.2h, v0.2h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.4s, v31.4h, v0.4h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin v0.4s, v31.4h, v0.4h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin v0.2d, v31.2h, v0.2h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin v0.2d, v31.2h, v0.2h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/FP8/faminmax.s b/llvm/test/MC/AArch64/FP8/faminmax.s new file mode 100644 index 00000000000000..02c3b8f11d6ee6 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8/faminmax.s @@ -0,0 +1,197 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax < %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=+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=+faminmax - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=-faminmax - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+faminmax < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+faminmax -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +/// FAMAX instructions. +famax v31.4h, v31.4h, v31.4h +// CHECK-INST: famax v31.4h, v31.4h, v31.4h +// CHECK-ENCODING: [0xff,0x1f,0xdf,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0edf1fff + +famax v31.4h, v0.4h, v31.4h +// CHECK-INST: famax v31.4h, v0.4h, v31.4h +// CHECK-ENCODING: [0x1f,0x1c,0xdf,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0edf1c1f + +famax v0.4h, v0.4h, v0.4h +// CHECK-INST: famax v0.4h, v0.4h, v0.4h +// CHECK-ENCODING: [0x00,0x1c,0xc0,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0ec01c00 + +famax v31.8h, v31.8h, v31.8h +// CHECK-INST: famax v31.8h, v31.8h, v31.8h +// CHECK-ENCODING: [0xff,0x1f,0xdf,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4edf1fff + +famax v31.8h, v31.8h, v0.8h +// CHECK-INST: famax v31.8h, v31.8h, v0.8h +// CHECK-ENCODING: [0xff,0x1f,0xc0,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ec01fff + +famax v0.8h, v0.8h, v0.8h +// CHECK-INST: famax v0.8h, v0.8h, v0.8h +// CHECK-ENCODING: [0x00,0x1c,0xc0,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ec01c00 + +famax v31.2s, v31.2s, v31.2s +// CHECK-INST: famax v31.2s, v31.2s, v31.2s +// CHECK-ENCODING: [0xff,0xdf,0xbf,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0ebfdfff + +famax v31.2s, v0.2s, v0.2s +// CHECK-INST: famax v31.2s, v0.2s, v0.2s +// CHECK-ENCODING: [0x1f,0xdc,0xa0,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0ea0dc1f + +famax v0.2s, v0.2s, v0.2s +// CHECK-INST: famax v0.2s, v0.2s, v0.2s +// CHECK-ENCODING: [0x00,0xdc,0xa0,0x0e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 0ea0dc00 + +famax v31.4s, v31.4s, v31.4s +// CHECK-INST: famax v31.4s, v31.4s, v31.4s +// CHECK-ENCODING: [0xff,0xdf,0xbf,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ebfdfff + +famax v0.4s, v31.4s, v31.4s +// CHECK-INST: famax v0.4s, v31.4s, v31.4s +// CHECK-ENCODING: [0xe0,0xdf,0xbf,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ebfdfe0 + +famax v0.4s, v0.4s, v0.4s +// CHECK-INST: famax v0.4s, v0.4s, v0.4s +// CHECK-ENCODING: [0x00,0xdc,0xa0,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ea0dc00 + +famax v31.2d, v31.2d, v31.2d +// CHECK-INST: famax v31.2d, v31.2d, v31.2d +// CHECK-ENCODING: [0xff,0xdf,0xff,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4effdfff + +famax v0.2d, v0.2d, v31.2d +// CHECK-INST: famax v0.2d, v0.2d, v31.2d +// CHECK-ENCODING: [0x00,0xdc,0xff,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4effdc00 + +famax v0.2d, v0.2d, v0.2d +// CHECK-INST: famax v0.2d, v0.2d, v0.2d +// CHECK-ENCODING: [0x00,0xdc,0xe0,0x4e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 4ee0dc00 + + +/// FAMIN instructions. +famin v31.4h, v31.4h, v31.4h +// CHECK-INST: famin v31.4h, v31.4h, v31.4h +// CHECK-ENCODING: [0xff,0x1f,0xdf,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2edf1fff + +famin v31.4h, v0.4h, v31.4h +// CHECK-INST: famin v31.4h, v0.4h, v31.4h +// CHECK-ENCODING: [0x1f,0x1c,0xdf,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2edf1c1f + +famin v0.4h, v0.4h, v0.4h +// CHECK-INST: famin v0.4h, v0.4h, v0.4h +// CHECK-ENCODING: [0x00,0x1c,0xc0,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2ec01c00 + +famin v31.8h, v31.8h, v31.8h +// CHECK-INST: famin v31.8h, v31.8h, v31.8h +// CHECK-ENCODING: [0xff,0x1f,0xdf,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6edf1fff + +famin v31.8h, v31.8h, v0.8h +// CHECK-INST: famin v31.8h, v31.8h, v0.8h +// CHECK-ENCODING: [0xff,0x1f,0xc0,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ec01fff + +famin v0.8h, v0.8h, v0.8h +// CHECK-INST: famin v0.8h, v0.8h, v0.8h +// CHECK-ENCODING: [0x00,0x1c,0xc0,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ec01c00 + +famin v31.2s, v31.2s, v31.2s +// CHECK-INST: famin v31.2s, v31.2s, v31.2s +// CHECK-ENCODING: [0xff,0xdf,0xbf,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2ebfdfff + +famin v31.2s, v0.2s, v0.2s +// CHECK-INST: famin v31.2s, v0.2s, v0.2s +// CHECK-ENCODING: [0x1f,0xdc,0xa0,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2ea0dc1f + +famin v0.2s, v0.2s, v0.2s +// CHECK-INST: famin v0.2s, v0.2s, v0.2s +// CHECK-ENCODING: [0x00,0xdc,0xa0,0x2e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 2ea0dc00 + +famin v31.4s, v31.4s, v31.4s +// CHECK-INST: famin v31.4s, v31.4s, v31.4s +// CHECK-ENCODING: [0xff,0xdf,0xbf,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ebfdfff + +famin v0.4s, v31.4s, v31.4s +// CHECK-INST: famin v0.4s, v31.4s, v31.4s +// CHECK-ENCODING: [0xe0,0xdf,0xbf,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ebfdfe0 + +famin v0.4s, v0.4s, v0.4s +// CHECK-INST: famin v0.4s, v0.4s, v0.4s +// CHECK-ENCODING: [0x00,0xdc,0xa0,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ea0dc00 + +famin v31.2d, v31.2d, v31.2d +// CHECK-INST: famin v31.2d, v31.2d, v31.2d +// CHECK-ENCODING: [0xff,0xdf,0xff,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6effdfff + +famin v0.2d, v0.2d, v31.2d +// CHECK-INST: famin v0.2d, v0.2d, v31.2d +// CHECK-ENCODING: [0x00,0xdc,0xff,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6effdc00 + +famin v0.2d, v0.2d, v0.2d +// CHECK-INST: famin v0.2d, v0.2d, v0.2d +// CHECK-ENCODING: [0x00,0xdc,0xe0,0x6e] +// CHECK-ERROR: instruction requires: faminmax +// CHECK-UNKNOWN: 6ee0dc00 + diff --git a/llvm/test/MC/AArch64/FP8_SME2/faminmax-diagnoctics.s b/llvm/test/MC/AArch64/FP8_SME2/faminmax-diagnoctics.s new file mode 100644 index 00000000000000..d6de69ec0ba08c --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SME2/faminmax-diagnoctics.s @@ -0,0 +1,62 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+faminmax 2>&1 < %s| FileCheck %s + +// --------------------------------------------------------------------------// +// Incorrect operand + +famax {z0.h-z1.h}, {z0.d-z1.d}, {z0.s-z1.s} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax {z0.h-z1.h}, {z0.d-z1.d}, {z0.s-z1.s} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax {z28.s-z31.s}, {z28.h-z31.h}, {z28.d-z31.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax {z28.s-z31.s}, {z28.h-z31.h}, {z28.d-z31.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin {z0.h-z1.h}, {z0.s-z1.s}, {z0.s-z1.s} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin {z0.h-z1.h}, {z0.s-z1.s}, {z0.s-z1.s} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Incorrect range of vectors + +famax {z1.d-z0.d}, {z0.d-z1.d}, {z0.d-z1.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: famax {z1.d-z0.d}, {z0.d-z1.d}, {z0.d-z1.d} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax {z0.h-z3.h}, {z1.h-z4.h}, {z0.h-z3.h} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: famax {z0.h-z3.h}, {z1.h-z4.h}, {z0.h-z3.h} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax {z0.h-z3.h}, {z0.h-z3.h}, {z2.h-z5.h} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: famax {z0.h-z3.h}, {z0.h-z3.h}, {z2.h-z5.h} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax {z3.h-z6.h}, {z0.h-z3.h}, {z0.h-z3.h} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: famax {z3.h-z6.h}, {z0.h-z3.h}, {z0.h-z3.h} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin {z30.h-z31.h}, {z31.h-z0.h}, {z0.h-z1.h} +// 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: famin {z30.h-z31.h}, {z31.h-z0.h}, {z0.h-z1.h} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin {z29.d-z0.d}, {z0.d-z3.d}, {z0.d-z3.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: famin {z29.d-z0.d}, {z0.d-z3.d}, {z0.d-z3.d} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin {z0.d-z3.d}, {z30.d-z1.d}, {z0.d-z3.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: famin {z0.d-z3.d}, {z30.d-z1.d}, {z0.d-z3.d} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin {z0.d-z3.d}, {z0.d-z3.d}, {z28.d-z30.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin {z0.d-z3.d}, {z0.d-z3.d}, {z28.d-z30.d} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: \ No newline at end of file diff --git a/llvm/test/MC/AArch64/FP8_SME2/faminmax.s b/llvm/test/MC/AArch64/FP8_SME2/faminmax.s new file mode 100644 index 00000000000000..c2b2ab057bceec --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SME2/faminmax.s @@ -0,0 +1,159 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+faminmax < %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,+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2,+faminmax - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2,+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=-faminmax - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+faminmax < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2,+faminmax -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// FAMAX +famax {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h} // 11000001-01100000-10110001-01000000 +// CHECK-INST: famax { z0.h, z1.h }, { z0.h, z1.h }, { z0.h, z1.h } +// CHECK-ENCODING: [0x40,0xb1,0x60,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c160b140 + +famax {z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h} // 11000001-01111110-10110001-01011110 +// CHECK-INST: famax { z30.h, z31.h }, { z30.h, z31.h }, { z30.h, z31.h } +// CHECK-ENCODING: [0x5e,0xb1,0x7e,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c17eb15e + +famax {z0.s-z1.s}, {z0.s-z1.s}, {z0.s-z1.s} // 11000001-10100000-10110001-01000000 +// CHECK-INST: famax { z0.s, z1.s }, { z0.s, z1.s }, { z0.s, z1.s } +// CHECK-ENCODING: [0x40,0xb1,0xa0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1a0b140 + +famax {z30.s-z31.s}, {z30.s-z31.s}, {z30.s-z31.s} // 11000001-10111110-10110001-01011110 +// CHECK-INST: famax { z30.s, z31.s }, { z30.s, z31.s }, { z30.s, z31.s } +// CHECK-ENCODING: [0x5e,0xb1,0xbe,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1beb15e + +famax {z0.d-z1.d}, {z0.d-z1.d}, {z0.d-z1.d} // 11000001-11100000-10110001-01000000 +// CHECK-INST: famax { z0.d, z1.d }, { z0.d, z1.d }, { z0.d, z1.d } +// CHECK-ENCODING: [0x40,0xb1,0xe0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1e0b140 + +famax {z30.d-z31.d}, {z30.d-z31.d}, {z30.d-z31.d} // 11000001-11111110-10110001-01011110 +// CHECK-INST: famax { z30.d, z31.d }, { z30.d, z31.d }, { z30.d, z31.d } +// CHECK-ENCODING: [0x5e,0xb1,0xfe,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1feb15e + +famax {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-01100000-10111001-01000000 +// CHECK-INST: famax { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h } +// CHECK-ENCODING: [0x40,0xb9,0x60,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c160b940 + +famax {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-01111100-10111001-01011100 +// CHECK-INST: famax { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h } +// CHECK-ENCODING: [0x5c,0xb9,0x7c,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c17cb95c + +famax {z0.s-z3.s}, {z0.s-z3.s}, {z0.s-z3.s} // 11000001-10100000-10111001-01000000 +// CHECK-INST: famax { z0.s - z3.s }, { z0.s - z3.s }, { z0.s - z3.s } +// CHECK-ENCODING: [0x40,0xb9,0xa0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1a0b940 + +famax {z28.s-z31.s}, {z28.s-z31.s}, {z28.s-z31.s} // 11000001-10111100-10111001-01011100 +// CHECK-INST: famax { z28.s - z31.s }, { z28.s - z31.s }, { z28.s - z31.s } +// CHECK-ENCODING: [0x5c,0xb9,0xbc,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1bcb95c + +famax {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-01100000-10111001-01000000 +// CHECK-INST: famax { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h } +// CHECK-ENCODING: [0x40,0xb9,0x60,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c160b940 + +famax {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-01111100-10111001-01011100 +// CHECK-INST: famax { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h } +// CHECK-ENCODING: [0x5c,0xb9,0x7c,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c17cb95c + +// FAMIN +famin {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h} // 11000001-01100000-10110001-01000001 +// CHECK-INST: famin { z0.h, z1.h }, { z0.h, z1.h }, { z0.h, z1.h } +// CHECK-ENCODING: [0x41,0xb1,0x60,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c160b141 + +famin {z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h} // 11000001-01111110-10110001-01011111 +// CHECK-INST: famin { z30.h, z31.h }, { z30.h, z31.h }, { z30.h, z31.h } +// CHECK-ENCODING: [0x5f,0xb1,0x7e,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c17eb15f + +famin {z0.s-z1.s}, {z0.s-z1.s}, {z0.s-z1.s} // 11000001-10100000-10110001-01000001 +// CHECK-INST: famin { z0.s, z1.s }, { z0.s, z1.s }, { z0.s, z1.s } +// CHECK-ENCODING: [0x41,0xb1,0xa0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1a0b141 + +famin {z30.s-z31.s}, {z30.s-z31.s}, {z30.s-z31.s} // 11000001-10111110-10110001-01011111 +// CHECK-INST: famin { z30.s, z31.s }, { z30.s, z31.s }, { z30.s, z31.s } +// CHECK-ENCODING: [0x5f,0xb1,0xbe,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1beb15f + +famin {z0.d-z1.d}, {z0.d-z1.d}, {z0.d-z1.d} // 11000001-11100000-10110001-01000001 +// CHECK-INST: famin { z0.d, z1.d }, { z0.d, z1.d }, { z0.d, z1.d } +// CHECK-ENCODING: [0x41,0xb1,0xe0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1e0b141 + +famin {z30.d-z31.d}, {z30.d-z31.d}, {z30.d-z31.d} // 11000001-11111110-10110001-01011111 +// CHECK-INST: famin { z30.d, z31.d }, { z30.d, z31.d }, { z30.d, z31.d } +// CHECK-ENCODING: [0x5f,0xb1,0xfe,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1feb15f + +famin {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-01100000-10111001-01000001 +// CHECK-INST: famin { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h } +// CHECK-ENCODING: [0x41,0xb9,0x60,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c160b941 + +famin {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-01111100-10111001-01011101 +// CHECK-INST: famin { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h } +// CHECK-ENCODING: [0x5d,0xb9,0x7c,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c17cb95d + +famin {z0.s-z3.s}, {z0.s-z3.s}, {z0.s-z3.s} // 11000001-10100000-10111001-01000001 +// CHECK-INST: famin { z0.s - z3.s }, { z0.s - z3.s }, { z0.s - z3.s } +// CHECK-ENCODING: [0x41,0xb9,0xa0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1a0b941 + +famin {z28.s-z31.s}, {z28.s-z31.s}, {z28.s-z31.s} // 11000001-10111100-10111001-01011101 +// CHECK-INST: famin { z28.s - z31.s }, { z28.s - z31.s }, { z28.s - z31.s } +// CHECK-ENCODING: [0x5d,0xb9,0xbc,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1bcb95d + +famin {z0.d-z3.d}, {z0.d-z3.d}, {z0.d-z3.d} // 11000001-11100000-10111001-01000001 +// CHECK-INST: famin { z0.d - z3.d }, { z0.d - z3.d }, { z0.d - z3.d } +// CHECK-ENCODING: [0x41,0xb9,0xe0,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1e0b941 + +famin {z28.d-z31.d}, {z28.d-z31.d}, {z28.d-z31.d} // 11000001-11111100-10111001-01011101 +// CHECK-INST: famin { z28.d - z31.d }, { z28.d - z31.d }, { z28.d - z31.d } +// CHECK-ENCODING: [0x5d,0xb9,0xfc,0xc1] +// CHECK-ERROR: instruction requires: faminmax sme2 +// CHECK-UNKNOWN: c1fcb95d diff --git a/llvm/test/MC/AArch64/FP8_SVE2/faminmax-diagnostics.s b/llvm/test/MC/AArch64/FP8_SVE2/faminmax-diagnostics.s new file mode 100644 index 00000000000000..e5d8b246b148b3 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/faminmax-diagnostics.s @@ -0,0 +1,99 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2,+faminmax 2>&1 < %s | FileCheck %s +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+faminmax 2>&1 < %s | FileCheck %s + +// FAMIN: +// Invalid predicate register + +famin z0.h, p8/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: famin z0.h, p8/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin z31.s, p7/z, z31.s, z30.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin z31.s, p7/z, z31.s, z30.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffix + +famin z23.h, p3/m, z23.h, z13.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: famin z23.h, p3/m, z23.h, z13.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin z23.b, p3/m, z23.d, z13.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: famin z23.b, p3/m, z23.d, z13.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Z register out of range + +famin z31.s, p7/z, z31.s, z32.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin z31.s, p7/z, z31.s, z32.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famin z0.d, p0/m, z0.d, z35.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famin z0.d, p0/m, z0.d, z35.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z20, z31 +famin z23.h, p3/m, z23.h, z13.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx writing to a different destination +// CHECK-NEXT: famin z23.h, p3/m, z23.h, z13.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// FMAX: +// Invalid predicate register + +famax z0.h, p8/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix) +// CHECK-NEXT: famax z0.h, p8/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax z31.s, p7/z, z31.s, z30.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax z31.s, p7/z, z31.s, z30.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid vector suffix + +famax z23.h, p3/m, z23.h, z13.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: famax z23.h, p3/m, z23.h, z13.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax z23.b, p3/m, z23.d, z13.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: famax z23.b, p3/m, z23.d, z13.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Z register out of range + +famax z31.s, p7/z, z31.s, z32.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax z31.s, p7/z, z31.s, z32.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +famax z0.d, p0/m, z0.d, z35.d +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: famax z0.d, p0/m, z0.d, z35.d +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Negative tests for instructions that are incompatible with movprfx + +movprfx z20, z31 +famax z23.h, p3/m, z23.h, z13.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx writing to a different destination +// CHECK-NEXT: famax z23.h, p3/m, z23.h, z13.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: \ No newline at end of file diff --git a/llvm/test/MC/AArch64/FP8_SVE2/faminmax.s b/llvm/test/MC/AArch64/FP8_SVE2/faminmax.s new file mode 100644 index 00000000000000..3f931b05da8368 --- /dev/null +++ b/llvm/test/MC/AArch64/FP8_SVE2/faminmax.s @@ -0,0 +1,145 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2,+faminmax < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+faminmax < %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=+sve2,+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=+sve2,+faminmax - | FileCheck %s --check-prefix=CHECK-INST + +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2,+faminmax < %s \ +// RUN: | llvm-objdump -d --mattr=-faminmax - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +// Disassemble encoding and check the re-encoding (-show-encoding) matches. +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2,+faminmax < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sve2,+faminmax -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + +// FAMIN + +famin z0.h, p0/m, z0.h, z1.h // 01100101-01001111-10000000-00100000 +// CHECK-INST: famin z0.h, p0/m, z0.h, z1.h +// CHECK-ENCODING: [0x20,0x80,0x4f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654f8020 + +movprfx z23, z31 +famin z23.h, p3/m, z23.h, z13.h // 01100101-01001111-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famin z23.h, p3/m, z23.h, z13.h +// CHECK-ENCODING: [0xb7,0x8d,0x4f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654f8db7 + +famin z31.h, p7/m, z31.h, z30.h // 01100101-01001111-10011111-11011111 +// CHECK-INST: famin z31.h, p7/m, z31.h, z30.h +// CHECK-ENCODING: [0xdf,0x9f,0x4f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654f9fdf + +famin z0.s, p0/m, z0.s, z1.s // 01100101-10001111-10000000-00100000 +// CHECK-INST: famin z0.s, p0/m, z0.s, z1.s +// CHECK-ENCODING: [0x20,0x80,0x8f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658f8020 + +movprfx z23, z31 +famin z23.s, p3/m, z23.s, z13.s // 01100101-10001111-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famin z23.s, p3/m, z23.s, z13.s +// CHECK-ENCODING: [0xb7,0x8d,0x8f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658f8db7 + +famin z31.s, p7/m, z31.s, z30.s // 01100101-10001111-10011111-11011111 +// CHECK-INST: famin z31.s, p7/m, z31.s, z30.s +// CHECK-ENCODING: [0xdf,0x9f,0x8f,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658f9fdf + +famin z0.d, p0/m, z0.d, z1.d // 01100101-11001111-10000000-00100000 +// CHECK-INST: famin z0.d, p0/m, z0.d, z1.d +// CHECK-ENCODING: [0x20,0x80,0xcf,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65cf8020 + +movprfx z23, z31 +famin z23.d, p3/m, z23.d, z13.d // 01100101-11001111-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famin z23.d, p3/m, z23.d, z13.d +// CHECK-ENCODING: [0xb7,0x8d,0xcf,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65cf8db7 + +famin z31.d, p7/m, z31.d, z30.d // 01100101-11001111-10011111-11011111 +// CHECK-INST: famin z31.d, p7/m, z31.d, z30.d +// CHECK-ENCODING: [0xdf,0x9f,0xcf,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65cf9fdf + + +// FAMAX + +famax z0.h, p0/m, z0.h, z1.h // 01100101-01001110-10000000-00100000 +// CHECK-INST: famax z0.h, p0/m, z0.h, z1.h +// CHECK-ENCODING: [0x20,0x80,0x4e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654e8020 + +movprfx z23, z31 +famax z23.h, p3/m, z23.h, z13.h // 01100101-01001110-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famax z23.h, p3/m, z23.h, z13.h +// CHECK-ENCODING: [0xb7,0x8d,0x4e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654e8db7 + +famax z31.h, p7/m, z31.h, z30.h // 01100101-01001110-10011111-11011111 +// CHECK-INST: famax z31.h, p7/m, z31.h, z30.h +// CHECK-ENCODING: [0xdf,0x9f,0x4e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 654e9fdf + +famax z0.s, p0/m, z0.s, z1.s // 01100101-10001110-10000000-00100000 +// CHECK-INST: famax z0.s, p0/m, z0.s, z1.s +// CHECK-ENCODING: [0x20,0x80,0x8e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658e8020 + +movprfx z23, z31 +famax z23.s, p3/m, z23.s, z13.s // 01100101-10001110-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famax z23.s, p3/m, z23.s, z13.s +// CHECK-ENCODING: [0xb7,0x8d,0x8e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658e8db7 + +famax z31.s, p7/m, z31.s, z30.s // 01100101-10001110-10011111-11011111 +// CHECK-INST: famax z31.s, p7/m, z31.s, z30.s +// CHECK-ENCODING: [0xdf,0x9f,0x8e,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 658e9fdf + +famax z0.d, p0/m, z0.d, z1.d // 01100101-11001110-10000000-00100000 +// CHECK-INST: famax z0.d, p0/m, z0.d, z1.d +// CHECK-ENCODING: [0x20,0x80,0xce,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65ce8020 + +movprfx z23, z31 +famax z23.d, p3/m, z23.d, z13.d // 01100101-11001110-10001101-10110111 +// CHECK-INST: movprfx z23, z31 +// CHECK-INST: famax z23.d, p3/m, z23.d, z13.d +// CHECK-ENCODING: [0xb7,0x8d,0xce,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65ce8db7 + +famax z31.d, p7/m, z31.d, z30.d // 01100101-11001110-10011111-11011111 +// CHECK-INST: famax z31.d, p7/m, z31.d, z30.d +// CHECK-ENCODING: [0xdf,0x9f,0xce,0x65] +// CHECK-ERROR: instruction requires: faminmax sve2 or sme2 +// CHECK-UNKNOWN: 65ce9fdf \ No newline at end of file diff --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp index b662fbe3457cb2..45f39a66ea8b34 100644 --- a/llvm/unittests/TargetParser/TargetParserTest.cpp +++ b/llvm/unittests/TargetParser/TargetParserTest.cpp @@ -1732,7 +1732,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { AArch64::AEK_RCPC3, AArch64::AEK_THE, AArch64::AEK_D128, AArch64::AEK_LSE128, AArch64::AEK_SPECRES2, AArch64::AEK_RASv2, AArch64::AEK_ITE, AArch64::AEK_GCS, AArch64::AEK_FPMR, - AArch64::AEK_FP8}; + AArch64::AEK_FP8, AArch64::AEK_FAMINMAX}; std::vector Features; @@ -1806,6 +1806,7 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) { EXPECT_TRUE(llvm::is_contained(Features, "+gcs")); EXPECT_TRUE(llvm::is_contained(Features, "+fpmr")); EXPECT_TRUE(llvm::is_contained(Features, "+fp8")); + EXPECT_TRUE(llvm::is_contained(Features, "+faminmax")); // Assuming we listed every extension above, this should produce the same // result. (note that AEK_NONE doesn't have a name so it won't be in the @@ -1931,6 +1932,7 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"gcs", "nogcs", "+gcs", "-gcs"}, {"fpmr", "nofpmr", "+fpmr", "-fpmr"}, {"fp8", "nofp8", "+fp8", "-fp8"}, + {"faminmax", "nofaminmax", "+faminmax", "-faminmax"}, }; for (unsigned i = 0; i < std::size(ArchExt); i++) {