Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LLVM][AArch64][Assembly]: Add FAMINMAX assembly/disasse… #70115

Merged
merged 1 commit into from
Oct 27, 2023

Conversation

hassnaaHamdi
Copy link
Member

@hassnaaHamdi hassnaaHamdi commented Oct 24, 2023

…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

@llvmbot llvmbot added backend:AArch64 mc Machine (object) code labels Oct 24, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 24, 2023

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-backend-aarch64

Author: None (hassnaaHamdi)

Changes

…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


Patch is 42.37 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/70115.diff

17 Files Affected:

  • (modified) llvm/include/llvm/TargetParser/AArch64TargetParser.h (+2)
  • (modified) llvm/lib/Target/AArch64/AArch64.td (+3)
  • (modified) llvm/lib/Target/AArch64/AArch64InstrInfo.td (+11)
  • (modified) llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td (+8)
  • (modified) llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td (+6)
  • (modified) llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (+1)
  • (added) llvm/test/MC/AArch64/FP8/directive-arch-negative.s (+8)
  • (added) llvm/test/MC/AArch64/FP8/directive-arch.s (+8)
  • (added) llvm/test/MC/AArch64/FP8/faminmax-diagnostics.s (+64)
  • (added) llvm/test/MC/AArch64/FP8/faminmax.s (+197)
  • (added) llvm/test/MC/AArch64/FP8_SME2/faminmax-diagnoctics.s (+62)
  • (added) llvm/test/MC/AArch64/FP8_SME2/faminmax.s (+159)
  • (added) llvm/test/MC/AArch64/FP8_SVE2/famax-diagnostics.s (+49)
  • (added) llvm/test/MC/AArch64/FP8_SVE2/famax.s (+88)
  • (added) llvm/test/MC/AArch64/FP8_SVE2/famin-diagnostics.s (+49)
  • (added) llvm/test/MC/AArch64/FP8_SVE2/famin.s (+88)
  • (modified) llvm/unittests/TargetParser/TargetParserTest.cpp (+3)
diff --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index bf14473f133fab7..710bea3540f0938 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -160,6 +160,7 @@ enum ArchExtKind : unsigned {
   AEK_ITE =           56, // FEAT_ITE
   AEK_GCS =           57, // FEAT_GCS
   AEK_FPMR =          58, // FEAT_FPMR
+  AEK_FAMINMAX =      59, // FEAT_FAMINMAX
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
@@ -269,6 +270,7 @@ inline constexpr ExtensionInfo Extensions[] = {
     {"wfxt", AArch64::AEK_NONE, {}, {}, FEAT_WFXT, "+wfxt", 550},
     {"gcs", AArch64::AEK_GCS, "+gcs", "-gcs", FEAT_INIT, "", 0},
     {"fpmr", AArch64::AEK_FPMR, "+fpmr", "-fpmr", FEAT_INIT, "", 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 ced1d4389203653..45cc11b8505774e 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -511,6 +511,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 382d3956f105f8c..528a4d984dd06ca 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -162,6 +162,8 @@ def HasSME2p1        : Predicate<"Subtarget->hasSME2p1()">,
                                  AssemblerPredicateWithAll<(all_of FeatureSME2p1), "sme2p1">;
 def HasFPMR          : Predicate<"Subtarget->hasFPMR()">,
                                  AssemblerPredicateWithAll<(all_of FeatureFPMR), "fpmr">;
+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.
@@ -173,6 +175,10 @@ def HasSVE2orSME
     : Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME()">,
                 AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME),
                 "sve2 or sme">;
+def HasSVE2orSME2
+    : Predicate<"Subtarget->hasSVE2() || Subtarget->hasSME2()">,
+                AssemblerPredicateWithAll<(any_of FeatureSVE2, FeatureSME2),
+                "sve2 or sme2">;
 def HasSVE2p1_or_HasSME
     : Predicate<"Subtarget->hasSVE2p1() || Subtarget->hasSME()">,
                  AssemblerPredicateWithAll<(any_of FeatureSME, FeatureSVE2p1), "sme or sve2p1">;
@@ -9249,6 +9255,11 @@ let Predicates = [HasD128] in {
   }
 }
 
+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"
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 2685f2e3c8108e5..9e6b773dd283882 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -855,3 +855,11 @@ defm BFCLAMP_VG4_4ZZZ: sme2p1_bfclamp_vector_vg4_multi<"bfclamp">;
 defm BFMOPA_MPPZZ_H : sme2p1_fmop_tile_fp16<"bfmopa", 0b1, 0b0, 0b11, ZPR16>;
 defm BFMOPS_MPPZZ_H : sme2p1_fmop_tile_fp16<"bfmops", 0b1, 0b1, 0b11, ZPR16>;
 }
+
+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]
\ No newline at end of file
diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index d599ac4689e5cb3..eba7cfd6bb65e0c 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4002,3 +4002,9 @@ defm UZPQ1_ZZZ : sve2p1_permute_vec_elems_q<0b010, "uzpq1">;
 defm UZPQ2_ZZZ : sve2p1_permute_vec_elems_q<0b011, "uzpq2">;
 defm TBLQ_ZZZ  : sve2p1_tblq<"tblq">;
 } // End HasSVE2p1_or_HasSME2p1
+
+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
\ No newline at end of file
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 6e70deec3f89092..b0a56c861d7500d 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -3639,6 +3639,7 @@ static const struct Extension {
     {"ssbs", {AArch64::FeatureSSBS}},
     {"tme", {AArch64::FeatureTME}},
     {"fpmr", {AArch64::FeatureFPMR}},
+    {"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
new file mode 100644
index 000000000000000..86aeb7546f7d458
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s
@@ -0,0 +1,8 @@
+// RUN: not llvm-mc -triple aarch64 -filetype asm -o - %s 2>&1 | FileCheck %s
+
+.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
new file mode 100644
index 000000000000000..1f3c918946297bb
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8/directive-arch.s
@@ -0,0 +1,8 @@
+// RUN: llvm-mc -triple aarch64 -o - %s 2>&1 | FileCheck %s
+
+.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 000000000000000..724b7eadfb4162a
--- /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 000000000000000..02c3b8f11d6ee6a
--- /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  <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+
+/// 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  <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
+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 <unknown>
+
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 000000000000000..d6de69ec0ba08cf
--- /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]+...
[truncated]

@github-actions
Copy link

github-actions bot commented Oct 24, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Contributor

@CarolineConcatto CarolineConcatto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I have a nit for the tests to be consistent between them.

llvm/test/MC/AArch64/FP8_SVE2/famax-diagnostics.s Outdated Show resolved Hide resolved
…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

Change-Id: I1cfcfa86377b7f1d018b0a6ef7787d571d69dde7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants