[llvm] 6477b41 - [llvm][AArch64][Assembly]: Add FP8FMA assembly and disassembly. (#70134)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 1 06:03:05 PDT 2023


Author: hassnaaHamdi
Date: 2023-11-01T13:03:00Z
New Revision: 6477b41a0b56919c42f44c3499ed32720101b43b

URL: https://github.com/llvm/llvm-project/commit/6477b41a0b56919c42f44c3499ed32720101b43b
DIFF: https://github.com/llvm/llvm-project/commit/6477b41a0b56919c42f44c3499ed32720101b43b.diff

LOG: [llvm][AArch64][Assembly]: Add FP8FMA  assembly and disassembly. (#70134)

This patch adds the feature flag FP8FMA and the assembly/disassembly
for the following instructions of NEON and SVE2:
  * NEON: 
    - FMLALBlane
    - FMLALTlane
    - FMLALLBBlane
    - FMLALLBTlane
    - FMLALLTBlane
    - FMLALLTTlane
    - FMLALB
    - FMLALT
    - FMLALLB
    - FMLALLBT
    - FMLALLTB
    - FMLALLTT
  * SVE2:
    - FMLALB_ZZZI
    - FMLALT_ZZZI
    - FMLALB_ZZZ 
    - FMLALT_ZZZ 
    - FMLALLBB_ZZZI 
    - FMLALLBT_ZZZI 
    - FMLALLTB_ZZZI 
    - FMLALLTT_ZZZI 
    - FMLALLBB_ZZZ 
    - FMLALLBT_ZZZ 
    - FMLALLTB_ZZZ 
    - FMLALLTT_ZZZ

That is according to this documentation:
https://developer.arm.com/documentation/ddi0602/2023-09

Added: 
    llvm/test/MC/AArch64/FP8/mla-diagnostic.s
    llvm/test/MC/AArch64/FP8/mla.s
    llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s
    llvm/test/MC/AArch64/FP8_SVE2/fmlal.s
    llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s
    llvm/test/MC/AArch64/FP8_SVE2/fmlall.s

Modified: 
    llvm/include/llvm/TargetParser/AArch64TargetParser.h
    llvm/include/llvm/TargetParser/SubtargetFeature.h
    llvm/lib/Target/AArch64/AArch64.td
    llvm/lib/Target/AArch64/AArch64InstrFormats.td
    llvm/lib/Target/AArch64/AArch64InstrInfo.td
    llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
    llvm/lib/Target/AArch64/AArch64RegisterInfo.td
    llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
    llvm/lib/Target/AArch64/AArch64SchedA64FX.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
    llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
    llvm/lib/Target/AArch64/SVEInstrFormats.td
    llvm/test/MC/AArch64/FP8/directive-arch-negative.s
    llvm/test/MC/AArch64/FP8/directive-arch.s
    llvm/unittests/TargetParser/TargetParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/TargetParser/AArch64TargetParser.h b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
index 232b3d6a6dbb1c4..d1a3c94bc18eda5 100644
--- a/llvm/include/llvm/TargetParser/AArch64TargetParser.h
+++ b/llvm/include/llvm/TargetParser/AArch64TargetParser.h
@@ -162,6 +162,8 @@ enum ArchExtKind : unsigned {
   AEK_FPMR =          58, // FEAT_FPMR
   AEK_FP8 =           59, // FEAT_FP8
   AEK_FAMINMAX =      60, // FEAT_FAMINMAX
+  AEK_FP8FMA =        61, // FEAT_FP8FMA
+  AEK_SSVE_FP8FMA =   62, // FEAT_SSVE_FP8FMA
   AEK_NUM_EXTENSIONS
 };
 using ExtensionBitset = Bitset<AEK_NUM_EXTENSIONS>;
@@ -273,6 +275,8 @@ inline constexpr ExtensionInfo Extensions[] = {
     {"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},
+    {"fp8fma", AArch64::AEK_FP8FMA, "+fp8fma", "-fp8fma", FEAT_INIT, "+fpmr", 0},
+    {"ssve-fp8fma", AArch64::AEK_SSVE_FP8FMA, "+ssve-fp8fma", "-ssve-fp8fma", FEAT_INIT, "+sme2", 0},
     // Special cases
     {"none", AArch64::AEK_NONE, {}, {}, FEAT_INIT, "", ExtensionInfo::MaxFMVPriority},
 };

diff  --git a/llvm/include/llvm/TargetParser/SubtargetFeature.h b/llvm/include/llvm/TargetParser/SubtargetFeature.h
index e4dddfb78effbcd..2e1f00dad2df365 100644
--- a/llvm/include/llvm/TargetParser/SubtargetFeature.h
+++ b/llvm/include/llvm/TargetParser/SubtargetFeature.h
@@ -31,7 +31,7 @@ namespace llvm {
 class raw_ostream;
 class Triple;
 
-const unsigned MAX_SUBTARGET_WORDS = 4;
+const unsigned MAX_SUBTARGET_WORDS = 5;
 const unsigned MAX_SUBTARGET_FEATURES = MAX_SUBTARGET_WORDS * 64;
 
 /// Container class for subtarget features.

diff  --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 8fd9358c9f9c7a0..d3d4bd84f1e984e 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -517,6 +517,12 @@ def FeatureSME2p1 : SubtargetFeature<"sme2p1", "HasSME2p1", "true",
 def FeatureFAMINMAX: SubtargetFeature<"faminmax", "HasFAMINMAX", "true",
    "Enable FAMIN and FAMAX instructions (FEAT_FAMINMAX)">;
 
+def FeatureFP8FMA : SubtargetFeature<"fp8fma", "HasFP8FMA", "true",
+  "Enable fp8 multiply-add instructions (FEAT_FP8FMA)">;
+
+def FeatureSSVE_FP8FMA : SubtargetFeature<"ssve-fp8fma", "HasSSVE_FP8FMA", "true",
+  "Enable SVE2 fp8 multiply-add instructions (FEAT_SSVE_FP8FMA)", [FeatureSME2]>;
+
 def FeatureAppleA7SysReg  : SubtargetFeature<"apple-a7-sysreg", "HasAppleA7SysReg", "true",
   "Apple A7 (the CPU formerly known as Cyclone)">;
 
@@ -747,7 +753,7 @@ let F = [HasSVE2p1, HasSVE2p1_or_HasSME2, HasSVE2p1_or_HasSME2p1] in
 def SVE2p1Unsupported : AArch64Unsupported;
 
 def SVE2Unsupported : AArch64Unsupported {
-  let F = !listconcat([HasSVE2, HasSVE2orSME,
+  let F = !listconcat([HasSVE2, HasSVE2orSME, HasSSVE_FP8FMA,
                        HasSVE2AES, HasSVE2SHA3, HasSVE2SM4, HasSVE2BitPerm],
                        SVE2p1Unsupported.F);
 }
@@ -761,7 +767,7 @@ let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1] in
 def SME2p1Unsupported : AArch64Unsupported;
 
 def SME2Unsupported : AArch64Unsupported {
-  let F = !listconcat([HasSME2, HasSVE2p1_or_HasSME2],
+  let F = !listconcat([HasSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA],
                       SME2p1Unsupported.F);
 }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrFormats.td b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
index a48bf77a774b75c..152e3b4c7407dbf 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrFormats.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrFormats.td
@@ -6055,6 +6055,15 @@ multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,
                                          v4f32, v8f16, OpNode>;
 }
 
+multiclass SIMDThreeSameVectorMLA<bit Q, string asm>{
+  def v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b",
+                                         V128, v8f16, v16i8, null_frag>;
+}
+
+multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm>{
+  def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b",
+                                         V128, v4f32, v16i8, null_frag>;
+}
 
 // FP8 assembly/disassembly classes
 
@@ -8521,6 +8530,31 @@ class BF16ToSinglePrecision<string asm>
 }
 } // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 0
 
+//----------------------------------------------------------------------------
+class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc,
+                                    string asm, string dst_kind,
+                                    RegisterOperand RegType,
+                                    RegisterOperand RegType_lo>
+  : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc,
+                        RegType, RegType, RegType_lo, VectorIndexB,
+                        asm, "", dst_kind, ".16b", ".b", []> {
+
+  // idx = H:L:M
+  bits<4> idx;
+  let Inst{11}    = idx{3};
+  let Inst{21-19} = idx{2-0};
+}
+
+multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm> {
+  def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h",
+                                            V128, V128_0to7>;
+}
+
+multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm> {
+  def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s",
+                                            V128, V128_0to7>;
+}
+
 //----------------------------------------------------------------------------
 // Armv8.6 Matrix Multiply Extension
 //----------------------------------------------------------------------------

diff  --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index d262c8bbe485ac7..20f872dfc17b297 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -166,6 +166,13 @@ def HasFP8           : Predicate<"Subtarget->hasFP8()">,
                                  AssemblerPredicateWithAll<(all_of FeatureFP8), "fp8">;
 def HasFAMINMAX      : Predicate<"Subtarget->hasFAMINMAX()">,
                                  AssemblerPredicateWithAll<(all_of FeatureFAMINMAX), "faminmax">;
+def HasFP8FMA        : Predicate<"Subtarget->hasFP8FMA()">,
+                                 AssemblerPredicateWithAll<(all_of FeatureFP8FMA), "fp8fma">;
+def HasSSVE_FP8FMA   : Predicate<"Subtarget->SSVE_FP8FMA() || "
+                                 "(Subtarget->hasSVE2() && Subtarget->hasFP8FMA())">,
+                                 AssemblerPredicateWithAll<(any_of FeatureSSVE_FP8FMA,
+                                                           (all_of FeatureSVE2, FeatureFP8FMA)),
+                                                           "ssve-fp8fma or (sve2 and fp8fma)">;
 
 // A subset of SVE(2) instructions are legal in Streaming SVE execution mode,
 // they should be enabled if either has been specified.
@@ -9286,6 +9293,21 @@ let Predicates = [HasFAMINMAX] in {
  defm FAMIN : SIMDThreeSameVectorFP<0b1, 0b1, 0b011, "famin", null_frag>;
 } // End let Predicates = [HasFAMAXMIN]
 
+let Predicates = [HasFP8FMA] in {
+ defm FMLALBlane : SIMDThreeSameVectorMLAIndex<0b0, "fmlalb">;
+ defm FMLALTlane : SIMDThreeSameVectorMLAIndex<0b1, "fmlalt">;
+ defm FMLALLBBlane : SIMDThreeSameVectorMLALIndex<0b0, 0b00, "fmlallbb">;
+ defm FMLALLBTlane : SIMDThreeSameVectorMLALIndex<0b0, 0b01, "fmlallbt">;
+ defm FMLALLTBlane : SIMDThreeSameVectorMLALIndex<0b1, 0b00, "fmlalltb">;
+ defm FMLALLTTlane : SIMDThreeSameVectorMLALIndex<0b1, 0b01, "fmlalltt">;
+
+ defm FMLALB : SIMDThreeSameVectorMLA<0b0, "fmlalb">;
+ defm FMLALT : SIMDThreeSameVectorMLA<0b1, "fmlalt">;
+ defm FMLALLBB : SIMDThreeSameVectorMLAL<0b0, 0b00, "fmlallbb">;
+ defm FMLALLBT : SIMDThreeSameVectorMLAL<0b0, 0b01, "fmlallbt">;
+ defm FMLALLTB : SIMDThreeSameVectorMLAL<0b1, 0b00, "fmlalltb">;
+ defm FMLALLTT : SIMDThreeSameVectorMLAL<0b1, 0b01, "fmlalltt">;
+} // End let Predicates = [HasFP8FMA]
 
 include "AArch64InstrAtomics.td"
 include "AArch64SVEInstrInfo.td"

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index cc5384613f1ab38..1a730a0b955d3d1 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -981,6 +981,8 @@ unsigned AArch64RegisterInfo::getRegPressureLimit(const TargetRegisterClass *RC,
   case AArch64::FPR64_loRegClassID:
   case AArch64::FPR16_loRegClassID:
     return 16;
+  case AArch64::FPR128_0to7RegClassID:
+    return 8;
   }
 }
 

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index eb26591908fd79c..497c143584d48d4 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -467,6 +467,13 @@ def FPR128_lo : RegisterClass<"AArch64",
                                v8bf16],
                               128, (trunc FPR128, 16)>;
 
+// The lower 8 vector registers.  Some instructions can only take registers
+// in this range.
+def FPR128_0to7 : RegisterClass<"AArch64",
+                                [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16,
+                                 v8bf16],
+                                128, (trunc FPR128, 8)>;
+
 // Pairs, triples, and quads of 64-bit vector registers.
 def DSeqPairs : RegisterTuples<[dsub0, dsub1], [(rotl FPR64, 0), (rotl FPR64, 1)]>;
 def DSeqTriples : RegisterTuples<[dsub0, dsub1, dsub2],
@@ -534,6 +541,15 @@ def V128_lo : RegisterOperand<FPR128_lo, "printVRegOperand"> {
   let ParserMatchClass = VectorRegLoAsmOperand;
 }
 
+def VectorReg0to7AsmOperand : AsmOperandClass {
+  let Name = "VectorReg0to7";
+  let PredicateMethod = "isNeonVectorReg0to7";
+}
+
+def V128_0to7 : RegisterOperand<FPR128_0to7, "printVRegOperand"> {
+  let ParserMatchClass = VectorReg0to7AsmOperand;
+}
+
 class TypedVecListAsmOperand<int count, string vecty, int lanes, int eltsize>
     : AsmOperandClass {
   let Name = "TypedVectorList" # count # "_" # lanes # eltsize;

diff  --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
index 3faa06f995e5beb..abe07dc0ce3270c 100644
--- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -4045,3 +4045,22 @@ let Predicates = [HasSVE2orSME2, HasFAMINMAX] in {
 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
+
+let Predicates = [HasSSVE_FP8FMA] in {
+// FP8 Widening Multiply-Add Long - Indexed Group
+def FMLALB_ZZZI : sve2_fp8_mla_long_by_indexed_elem<0b0, "fmlalb">;
+def FMLALT_ZZZI : sve2_fp8_mla_long_by_indexed_elem<0b1, "fmlalt">;
+// FP8 Widening Multiply-Add Long Group
+def FMLALB_ZZZ : sve2_fp8_mla<0b100, ZPR16, "fmlalb">;
+def FMLALT_ZZZ : sve2_fp8_mla<0b101, ZPR16, "fmlalt">;
+// FP8 Widening Multiply-Add Long Long - Indexed Group
+def FMLALLBB_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b00, "fmlallbb">;
+def FMLALLBT_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b01, "fmlallbt">;
+def FMLALLTB_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b10, "fmlalltb">;
+def FMLALLTT_ZZZI : sve2_fp8_mla_long_long_by_indexed_elem<0b11, "fmlalltt">;
+// FP8 Widening Multiply-Add Long Long Group
+def FMLALLBB_ZZZ : sve2_fp8_mla<0b000, ZPR32, "fmlallbb">;
+def FMLALLBT_ZZZ : sve2_fp8_mla<0b001, ZPR32, "fmlallbt">;
+def FMLALLTB_ZZZ : sve2_fp8_mla<0b010, ZPR32, "fmlalltb">;
+def FMLALLTT_ZZZ : sve2_fp8_mla<0b011, ZPR32, "fmlalltt">;
+} // End HasSSVE_FP8FMA

diff  --git a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
index f3e844dc5b270d1..1de0e8291ef12d9 100644
--- a/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
+++ b/llvm/lib/Target/AArch64/AArch64SchedA64FX.td
@@ -23,7 +23,7 @@ def A64FXModel : SchedMachineModel {
   list<Predicate> UnsupportedFeatures =
     [HasSVE2, HasSVE2AES, HasSVE2SM4, HasSVE2SHA3, HasSVE2BitPerm, HasPAuth,
      HasSVE2orSME, HasMTE, HasMatMulInt8, HasBF16, HasSME2, HasSME2p1, HasSVE2p1,
-     HasSVE2p1_or_HasSME2p1, HasSMEF16F16];
+     HasSVE2p1_or_HasSME2p1, HasSMEF16F16, HasSSVE_FP8FMA];
 
   let FullInstRWOverlapCheck = 0;
 }

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 35abe3563eb81ab..afecff1303666e1 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -1223,6 +1223,12 @@ class AArch64Operand : public MCParsedAsmOperand {
                 Reg.RegNum));
   }
 
+  bool isNeonVectorReg0to7() const {
+    return Kind == k_Register && Reg.Kind == RegKind::NeonVector &&
+           (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
+               Reg.RegNum));
+  }
+
   bool isMatrix() const { return Kind == k_MatrixRegister; }
   bool isMatrixTileList() const { return Kind == k_MatrixTileList; }
 
@@ -1766,6 +1772,11 @@ class AArch64Operand : public MCParsedAsmOperand {
     Inst.addOperand(MCOperand::createReg(getReg()));
   }
 
+  void addVectorReg0to7Operands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::createReg(getReg()));
+  }
+
   enum VecListIndexType {
     VecListIdx_DReg = 0,
     VecListIdx_QReg = 1,
@@ -2598,31 +2609,31 @@ static std::optional<std::pair<int, int>> parseVectorKind(StringRef Suffix,
 
   switch (VectorKind) {
   case RegKind::NeonVector:
-    Res =
-        StringSwitch<std::pair<int, int>>(Suffix.lower())
-            .Case("", {0, 0})
-            .Case(".1d", {1, 64})
-            .Case(".1q", {1, 128})
-            // '.2h' needed for fp16 scalar pairwise reductions
-            .Case(".2h", {2, 16})
-            .Case(".2s", {2, 32})
-            .Case(".2d", {2, 64})
-            // '.4b' is another special case for the ARMv8.2a dot product
-            // operand
-            .Case(".4b", {4, 8})
-            .Case(".4h", {4, 16})
-            .Case(".4s", {4, 32})
-            .Case(".8b", {8, 8})
-            .Case(".8h", {8, 16})
-            .Case(".16b", {16, 8})
-            // Accept the width neutral ones, too, for verbose syntax. If those
-            // aren't used in the right places, the token operand won't match so
-            // all will work out.
-            .Case(".b", {0, 8})
-            .Case(".h", {0, 16})
-            .Case(".s", {0, 32})
-            .Case(".d", {0, 64})
-            .Default({-1, -1});
+    Res = StringSwitch<std::pair<int, int>>(Suffix.lower())
+              .Case("", {0, 0})
+              .Case(".1d", {1, 64})
+              .Case(".1q", {1, 128})
+              // '.2h' needed for fp16 scalar pairwise reductions
+              .Case(".2h", {2, 16})
+              .Case(".2b", {2, 8})
+              .Case(".2s", {2, 32})
+              .Case(".2d", {2, 64})
+              // '.4b' is another special case for the ARMv8.2a dot product
+              // operand
+              .Case(".4b", {4, 8})
+              .Case(".4h", {4, 16})
+              .Case(".4s", {4, 32})
+              .Case(".8b", {8, 8})
+              .Case(".8h", {8, 16})
+              .Case(".16b", {16, 8})
+              // Accept the width neutral ones, too, for verbose syntax. If
+              // those aren't used in the right places, the token operand won't
+              // match so all will work out.
+              .Case(".b", {0, 8})
+              .Case(".h", {0, 16})
+              .Case(".s", {0, 32})
+              .Case(".d", {0, 64})
+              .Default({-1, -1});
     break;
   case RegKind::SVEPredicateAsCounter:
   case RegKind::SVEPredicateVector:
@@ -3641,6 +3652,8 @@ static const struct Extension {
     {"fpmr", {AArch64::FeatureFPMR}},
     {"fp8", {AArch64::FeatureFP8}},
     {"faminmax", {AArch64::FeatureFAMINMAX}},
+    {"fp8fma", {AArch64::FeatureFP8FMA}},
+    {"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
 };
 
 static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {

diff  --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
index df817f62f99fbf7..cf2d3879292d196 100644
--- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
+++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp
@@ -44,6 +44,9 @@ static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, unsigned RegNo,
 static DecodeStatus DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo,
                                                  uint64_t Address,
                                                  const MCDisassembler *Decoder);
+static DecodeStatus
+DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,
+                               const MCDisassembler *Decoder);
 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Address,
                                              const MCDisassembler *Decoder);
@@ -437,6 +440,14 @@ DecodeFPR128_loRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
   return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
 }
 
+static DecodeStatus
+DecodeFPR128_0to7RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr,
+                               const MCDisassembler *Decoder) {
+  if (RegNo > 7)
+    return Fail;
+  return DecodeFPR128RegisterClass(Inst, RegNo, Addr, Decoder);
+}
+
 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, unsigned RegNo,
                                              uint64_t Addr,
                                              const MCDisassembler *Decoder) {

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
index b956cd4782b7943..21f9f6437e4fe91 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64RegisterBankInfo.cpp
@@ -245,9 +245,10 @@ AArch64RegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC,
   case AArch64::FPR32_with_hsub_in_FPR16_loRegClassID:
   case AArch64::FPR32RegClassID:
   case AArch64::FPR64RegClassID:
-  case AArch64::FPR64_loRegClassID:
   case AArch64::FPR128RegClassID:
+  case AArch64::FPR64_loRegClassID:
   case AArch64::FPR128_loRegClassID:
+  case AArch64::FPR128_0to7RegClassID:
   case AArch64::DDRegClassID:
   case AArch64::DDDRegClassID:
   case AArch64::DDDDRegClassID:

diff  --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td
index ff641a85f844045..20ccd61219039c7 100644
--- a/llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -10121,4 +10121,75 @@ class sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic,
 
 multiclass sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic, RegisterOperand src> {
   def NAME : sve2_fp8_down_cvt_single<opc, mnemonic, ZPR8, src>;
-}
\ No newline at end of file
+}
+
+// FP8 Widening Multiply-Add Long - Indexed Group
+class sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic>
+    : I<(outs ZPR16:$Zda),
+      (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
+      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
+      "", []>, Sched<[]>{
+  bits<5> Zda;
+  bits<5> Zn;
+  bits<3> Zm;
+  bits<4> imm4;
+  let Inst{31-24} = 0b01100100;
+  let Inst{23}    = T;
+  let Inst{22-21} = 0b01;
+  let Inst{20-19} = imm4{3-2};
+  let Inst{18-16} = Zm;
+  let Inst{15-12} = 0b0101;
+  let Inst{11-10} = imm4{1-0};
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zda;
+  let Constraints = "$Zda = $_Zda";
+  let DestructiveInstType = DestructiveOther;
+  let ElementSize         = ZPR16.ElementSize;
+}
+
+// FP8 Widening Multiply-Add (Long)/(Long Long) Group
+class sve2_fp8_mla<bits<3>opc, ZPRRegOp dst_ty, string mnemonic>
+    : I<(outs dst_ty:$Zda),
+      (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
+      mnemonic, "\t$Zda, $Zn, $Zm",
+      "", []>, Sched<[]>{
+  bits<5> Zda;
+  bits<5> Zn;
+  bits<5> Zm;
+  let Inst{31-24} = 0b01100100;
+  let Inst{23}    = opc{2};
+  let Inst{22-21} = 0b01;
+  let Inst{20-16} = Zm;
+  let Inst{15-14} = 0b10;
+  let Inst{13-12} = opc{1-0};
+  let Inst{11-10} = 0b10;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zda;
+  let Constraints = "$Zda = $_Zda";
+  let DestructiveInstType = DestructiveOther;
+  let ElementSize         = dst_ty.ElementSize;
+}
+
+// FP8 Widening Multiply-Add Long Long - Indexed Group
+class sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic>
+    : I<(outs ZPR32:$Zda),
+      (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
+      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
+      "", []>, Sched<[]>{
+  bits<5> Zda;
+  bits<5> Zn;
+  bits<3> Zm;
+  bits<4> imm4;
+  let Inst{31-24} = 0b01100100;
+  let Inst{23-22} = TT;
+  let Inst{21}    = 0b1;
+  let Inst{20-19} = imm4{3-2};
+  let Inst{18-16} = Zm;
+  let Inst{15-12} = 0b1100;
+  let Inst{11-10} = imm4{1-0};
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zda;
+  let Constraints = "$Zda = $_Zda";
+  let DestructiveInstType = DestructiveOther;
+  let ElementSize         = ZPR32.ElementSize;
+}

diff  --git a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s
index 86525ff68134c91..7a45f25fa052de9 100644
--- a/llvm/test/MC/AArch64/FP8/directive-arch-negative.s
+++ b/llvm/test/MC/AArch64/FP8/directive-arch-negative.s
@@ -12,3 +12,14 @@ famax  v31.4h, v31.4h, v31.4h
 // CHECK: error: instruction requires: faminmax
 // CHECK: famax  v31.4h, v31.4h, v31.4h
 
+.arch armv9-a+fp8fma
+.arch armv9-a+nofp8fma
+fmlalb  v0.8h, v0.16b, v0.16b
+// CHECK: error: instruction requires: fp8fma
+// CHECK: fmlalb  v0.8h, v0.16b, v0.16b
+
+.arch armv9-a+ssve-fp8fma
+.arch armv9-a+nossve-fp8fma
+fmlalb  z23.h, z13.b, z0.b[7]
+// CHECK: error: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK: fmlalb  z23.h, z13.b, z0.b[7]

diff  --git a/llvm/test/MC/AArch64/FP8/directive-arch.s b/llvm/test/MC/AArch64/FP8/directive-arch.s
index e3f0a94c2ff9a37..f3627f537b92df7 100644
--- a/llvm/test/MC/AArch64/FP8/directive-arch.s
+++ b/llvm/test/MC/AArch64/FP8/directive-arch.s
@@ -3,11 +3,19 @@
 .arch armv9-a+fp8
 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
 
+.arch armv9-a+fp8fma
+fmlalb  v0.8h, v0.16b, v0.16b
+// CHECK: fmlalb  v0.8h, v0.16b, v0.16b
+.arch armv9-a+nofp8fma
+
+.arch armv9-a+ssve-fp8fma
+fmlalb z23.h, z13.b, z0.b[7]
+// CHECK: fmlalb z23.h, z13.b, z0.b[7]
+.arch armv9-a+nossve-fp8fma

diff  --git a/llvm/test/MC/AArch64/FP8/mla-diagnostic.s b/llvm/test/MC/AArch64/FP8/mla-diagnostic.s
new file mode 100644
index 000000000000000..91a23a3d73e0caf
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8/mla-diagnostic.s
@@ -0,0 +1,85 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=fp8fma 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Element size extension incorrect
+fmlalb  v0.8h, v0.8b, v0.8b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalb  v0.8h, v0.8b, v0.8b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt  v31.8h, v31.16b, v31.16h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
+// CHECK-NEXT: fmlalt  v31.8h, v31.16b, v31.16h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbb  v0.4s, v0, v31
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlallbb  v0.4s, v0, v31
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbt  v31.4b, v31.16b, v0.16b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlallbt  v31.4b, v31.16b, v0.16b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltb  v31.b, v31.16b, v0.16b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalltb  v31.b, v31.16b, v0.16b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltt  v0.4s, v0.16b, v31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalltt  v0.4s, v0.16b, v31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt  v31.8s, v31.16b, v31.16b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
+// CHECK-NEXT: fmlalt  v31.8s, v31.16b, v31.16b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+
+//--------------------------------------------------------------------------//
+// Last Register range is between 0-7
+
+fmlalltb  v0.4s, v31.16b, v8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalltb  v0.4s, v31.16b, v8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}$
+
+fmlalt  v31.8h, v0.16b, v8.b[15]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalt  v31.8h, v0.16b, v8.b[15]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:$
+
+
+// --------------------------------------------------------------------------//
+// Out of range index
+fmlalb  v31.8h, v0.16b, v0.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalb  v31.8h, v0.16b, v0.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt  v31.8h, v0.16b, v0.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalt  v31.8h, v0.16b, v0.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbb  v31.4s, v0.16b, v7.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlallbb  v31.4s, v0.16b, v7.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltt  v31.4s, v0.16b, v7.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalltt  v31.4s, v0.16b, v7.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltb  v0.4s, v31.16b, v7.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalltb  v0.4s, v31.16b, v7.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}
+
+fmlallbt  v0.4s, v31.16b, v0.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlallbt  v0.4s, v31.16b, v0.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/FP8/mla.s b/llvm/test/MC/AArch64/FP8/mla.s
new file mode 100644
index 000000000000000..b3b6f1eb1806211
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8/mla.s
@@ -0,0 +1,98 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fp8fma < %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=+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=+fp8fma - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=-fp8fma - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+fp8fma < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+fp8fma -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+/// VECTOR
+// MLA
+fmlalb  v0.8h, v0.16b, v0.16b
+// CHECK-INST: fmlalb  v0.8h, v0.16b, v0.16b
+// CHECK-ENCODING: [0x00,0xfc,0xc0,0x0e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 0ec0fc00 <unknown>
+
+fmlalt  v31.8h, v31.16b, v31.16b
+// CHECK-INST: fmlalt  v31.8h, v31.16b, v31.16b
+// CHECK-ENCODING: [0xff,0xff,0xdf,0x4e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 4edfffff <unknown>
+
+
+// MLALL
+fmlallbb  v0.4s, v0.16b, v31.16b
+// CHECK-INST: fmlallbb  v0.4s, v0.16b, v31.16b
+// CHECK-ENCODING: [0x00,0xc4,0x1f,0x0e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 0e1fc400 <unknown>
+
+fmlallbt  v31.4s, v31.16b, v0.16b
+// CHECK-INST: fmlallbt  v31.4s, v31.16b, v0.16b
+// CHECK-ENCODING: [0xff,0xc7,0x40,0x0e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 0e40c7ff <unknown>
+
+fmlalltb  v31.4s, v31.16b, v0.16b
+// CHECK-INST: fmlalltb  v31.4s, v31.16b, v0.16b
+// CHECK-ENCODING: [0xff,0xc7,0x00,0x4e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 4e00c7ff <unknown>
+
+fmlalltt  v0.4s, v0.16b, v31.16b
+// CHECK-INST: fmlalltt  v0.4s, v0.16b, v31.16b
+// CHECK-ENCODING: [0x00,0xc4,0x5f,0x4e]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 4e5fc400 <unknown>
+
+fmlalltt v31.4s, v31.16b, v31.16b  // 01001110-01011111-11000111-11111111
+// CHECK-INST: fmlalltt v31.4s, v31.16b, v31.16b
+// CHECK-ENCODING: [0xff,0xc7,0x5f,0x4e]
+// CHECK-ERROR: instruction requires: fp8
+// CHECK-UNKNOWN: 4e5fc7ff <unknown>
+
+//INDEXED
+// MLA
+fmlalb  v31.8h, v0.16b, v0.b[0]
+// CHECK-INST: fmlalb  v31.8h, v0.16b, v0.b[0]
+// CHECK-ENCODING: [0x1f,0x00,0xc0,0x0f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 0fc0001f <unknown>
+
+fmlalt  v31.8h, v0.16b, v0.b[15]
+// CHECK-INST: fmlalt  v31.8h, v0.16b, v0.b[15]
+// CHECK-ENCODING: [0x1f,0x08,0xf8,0x4f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 4ff8081f <unknown>
+
+// MLALL
+fmlallbb  v31.4s, v0.16b, v7.b[0]
+// CHECK-INST: fmlallbb  v31.4s, v0.16b, v7.b[0]
+// CHECK-ENCODING: [0x1f,0x80,0x07,0x2f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 2f07801f <unknown>
+
+fmlalltt  v31.4s, v0.16b, v7.b[0]
+// CHECK-INST: fmlalltt  v31.4s, v0.16b, v7.b[0]
+// CHECK-ENCODING: [0x1f,0x80,0x47,0x6f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 6f47801f <unknown>
+
+fmlalltb  v0.4s, v31.16b, v7.b[15]
+// CHECK-INST: fmlalltb  v0.4s, v31.16b, v7.b[15]
+// CHECK-ENCODING: [0xe0,0x8b,0x3f,0x6f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 6f3f8be0 <unknown>
+
+fmlallbt  v0.4s, v31.16b, v0.b[15]
+// CHECK-INST: fmlallbt  v0.4s, v31.16b, v0.b[15]
+// CHECK-ENCODING: [0xe0,0x8b,0x78,0x2f]
+// CHECK-ERROR: instruction requires: fp8fma
+// CHECK-UNKNOWN: 2f788be0 <unknown>

diff  --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s
new file mode 100644
index 000000000000000..627ec0f044bb999
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlal-diagnostics.s
@@ -0,0 +1,64 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// z register out of range for index
+fmlalb z0.h, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalb z0.h, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt z0.h, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalt z0.h, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Index out of bounds
+
+fmlalb z0.h, z1.b, z7.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalb z0.h, z1.b, z7.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt z0.h, z1.b, z7.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalt z0.h, z1.b, z7.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+fmlalb z0.h, z1.h, z2.h[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalb z0.h, z1.h, z2.h[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalb z0.h, z1.h, z2.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalb  z0.h, z1.h, z2.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt z0.s, z1.b, z2.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalt z0.s, z1.b, z2.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalt z0.s, z1.b, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalt  z0.s, z1.b, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.b, p0/z, z0.b
+fmlalb  z0.h, z1.b, z7.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: fmlalb  z0.h, z1.b, z7.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z29.b, p0/z, z7.b
+fmlalt  z29.h, z30.b, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: fmlalt  z29.h, z30.b, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s
new file mode 100644
index 000000000000000..b567364b0788563
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlal.s
@@ -0,0 +1,114 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma < %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,+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=+sve2,+fp8fma --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2,+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=-fp8fma --no-print-imm-hex - | 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,+fp8fma < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sve2,+fp8fma -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+//
+// FMLALB instructions
+//
+// fmlalb - indexed
+
+fmlalb  z0.h, z0.b, z0.b[0]  // 01100100-00100000-01010000-00000000
+// CHECK-INST: fmlalb  z0.h, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0x50,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64205000 <unknown>
+
+movprfx z23, z31
+fmlalb  z23.h, z13.b, z0.b[7]  // 01100100-00101000-01011101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalb  z23.h, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0x5d,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64285db7 <unknown>
+
+fmlalb  z31.h, z31.b, z7.b[15]  // 01100100-00111111-01011111-11111111
+// CHECK-INST: fmlalb  z31.h, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0x5f,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643f5fff <unknown>
+
+
+// fmlalb - group
+
+fmlalb  z0.h, z0.b, z0.b  // 01100100-10100000-10001000-00000000
+// CHECK-INST: fmlalb  z0.h, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0x88,0xa0,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a08800 <unknown>
+
+movprfx z23, z31
+fmlalb  z23.h, z13.b, z8.b  // 01100100-10101000-10001001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalb  z23.h, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0x89,0xa8,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a889b7 <unknown>
+
+fmlalb  z31.h, z31.b, z31.b  // 01100100-10111111-10001011-11111111
+// CHECK-INST: fmlalb  z31.h, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0x8b,0xbf,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64bf8bff <unknown>
+
+
+//
+// FMLALT instructions
+//
+// fmlalt - indexed
+
+fmlalt  z0.h, z0.b, z0.b[0]  // 01100100-10100000-01010000-00000000
+// CHECK-INST: fmlalt  z0.h, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0x50,0xa0,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a05000 <unknown>
+
+movprfx z23, z31
+fmlalt  z23.h, z13.b, z0.b[7]  // 01100100-10101000-01011101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalt  z23.h, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0x5d,0xa8,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a85db7 <unknown>
+
+fmlalt  z31.h, z31.b, z7.b[15]  // 01100100-10111111-01011111-11111111
+// CHECK-INST: fmlalt  z31.h, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0x5f,0xbf,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64bf5fff <unknown>
+
+
+// fmlalt - group
+
+fmlalt  z0.h, z0.b, z0.b  // 01100100-10100000-10011000-00000000
+// CHECK-INST: fmlalt  z0.h, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0x98,0xa0,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a09800 <unknown>
+
+movprfx z23, z31
+fmlalt  z23.h, z13.b, z8.b  // 01100100-10101000-10011001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalt  z23.h, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0x99,0xa8,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a899b7 <unknown>
+
+fmlalt  z31.h, z31.b, z31.b  // 01100100-10111111-10011011-11111111
+// CHECK-INST: fmlalt  z31.h, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0x9b,0xbf,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64bf9bff <unknown>

diff  --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s
new file mode 100644
index 000000000000000..7a8a299b8756daf
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlall-diagnostics.s
@@ -0,0 +1,85 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma  2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// z register out of range for index
+
+fmlallbb z0.s, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlallbb z0.s, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbt z0.s, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlallbt z0.s, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltb z0.s, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalltb z0.s, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltt z0.s, z1.b, z8.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: fmlalltt z0.s, z1.b, z8.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Index out of bounds
+
+fmlallbb z0.s, z1.b, z7.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlallbb z0.s, z1.b, z7.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbt z0.s, z1.b, z7.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlallbt z0.s, z1.b, z7.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltb z0.s, z1.b, z7.b[-1]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalltb z0.s, z1.b, z7.b[-1]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltt z0.s, z1.b, z7.b[16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 15].
+// CHECK-NEXT: fmlalltt z0.s, z1.b, z7.b[16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid element width
+
+fmlallbb z0.h, z1.b, z2.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlallbb z0.h, z1.b, z2.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlallbt z0.h, z1.b, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlallbt  z0.h, z1.b, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltb z0.s, z1.h, z2.h[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalltb z0.s, z1.h, z2.h[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+fmlalltt z0.s, z1.h, z2.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: fmlalltt  z0.s, z1.h, z2.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Negative tests for instructions that are incompatible with movprfx
+
+movprfx z0.s, p0/z, z0.s
+fmlallbb  z0.s, z1.b, z7.b[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: fmlallbb  z0.s, z1.b, z7.b[0]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+movprfx z29.s, p0/z, z7.s
+fmlalltt  z29.s, z30.b, z31.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: fmlalltt  z29.s, z30.b, z31.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

diff  --git a/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s b/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s
new file mode 100644
index 000000000000000..319e664172da658
--- /dev/null
+++ b/llvm/test/MC/AArch64/FP8_SVE2/fmlall.s
@@ -0,0 +1,222 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+ssve-fp8fma < %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,+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=+sve2,+fp8fma --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2,+fp8fma < %s \
+// RUN:        | llvm-objdump -d --mattr=-sve2 --no-print-imm-hex - | 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,+fp8fma < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sve2,+fp8fma -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+//
+// FMLALLBB instructions
+//
+// fmlallbb - indexed
+
+fmlallbb z0.s, z0.b, z0.b[0]  // 01100100-00100000-11000000-00000000
+// CHECK-INST: fmlallbb z0.s, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0xc0,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6420c000 <unknown>
+
+movprfx z23, z31
+fmlallbb z23.s, z13.b, z0.b[7]  // 01100100-00101000-11001101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlallbb z23.s, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0xcd,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6428cdb7 <unknown>
+
+fmlallbb z31.s, z31.b, z7.b[15]  // 01100100-00111111-11001111-11111111
+// CHECK-INST: fmlallbb z31.s, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0xcf,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643fcfff <unknown>
+
+//
+// FMLALLBB instructions
+//
+// fmlallbb - group
+
+fmlallbb z0.s, z0.b, z0.b  // 01100100-00100000-10001000-00000000
+// CHECK-INST: fmlallbb z0.s, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0x88,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64208800 <unknown>
+
+movprfx z23, z31
+fmlallbb z23.s, z13.b, z8.b  // 01100100-00101000-10001001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlallbb z23.s, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0x89,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 642889b7 <unknown>
+
+fmlallbb z31.s, z31.b, z31.b  // 01100100-00111111-10001011-11111111
+// CHECK-INST: fmlallbb z31.s, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0x8b,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643f8bff <unknown>
+
+//--------------------------------------------//
+//
+// FMLALLBT instructions
+//
+// fmlallbt - indexed
+
+fmlallbt z0.s, z0.b, z0.b[0]  // 01100100-01100000-11000000-00000000
+// CHECK-INST: fmlallbt z0.s, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0xc0,0x60,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6460c000 <unknown>
+
+movprfx z23, z31
+fmlallbt z23.s, z13.b, z0.b[7]  // 01100100-01101000-11001101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlallbt z23.s, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0xcd,0x68,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6468cdb7 <unknown>
+
+fmlallbt z31.s, z31.b, z7.b[15]  // 01100100-01111111-11001111-11111111
+// CHECK-INST: fmlallbt z31.s, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0xcf,0x7f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 647fcfff <unknown>
+
+//
+// FMLALLBT instructions
+//
+// fmlallbt - group
+
+fmlallbt z0.s, z0.b, z0.b  // 01100100-00100000-10011000-00000000
+// CHECK-INST: fmlallbt z0.s, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0x98,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64209800 <unknown>
+
+movprfx z23, z31
+fmlallbt z23.s, z13.b, z8.b  // 01100100-00101000-10011001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlallbt z23.s, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0x99,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 642899b7 <unknown>
+
+fmlallbt z31.s, z31.b, z31.b  // 01100100-00111111-10011011-11111111
+// CHECK-INST: fmlallbt z31.s, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0x9b,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643f9bff <unknown>
+
+//--------------------------------------------//
+//
+// FMLALLTB instructions
+//
+// fmlalltb - indexed
+
+fmlalltb z0.s, z0.b, z0.b[0]  // 01100100-10100000-11000000-00000000
+// CHECK-INST: fmlalltb z0.s, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0xc0,0xa0,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a0c000 <unknown>
+
+movprfx z23, z31
+fmlalltb z23.s, z13.b, z0.b[7]  // 01100100-10101000-11001101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalltb z23.s, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0xcd,0xa8,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64a8cdb7 <unknown>
+
+fmlalltb z31.s, z31.b, z7.b[15]  // 01100100-10111111-11001111-11111111
+// CHECK-INST: fmlalltb z31.s, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0xcf,0xbf,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64bfcfff <unknown>
+
+//
+// FMLALLTB instructions
+//
+// fmlalltb - group
+
+fmlalltb z0.s, z0.b, z0.b  // 01100100-00100000-10101000-00000000
+// CHECK-INST: fmlalltb z0.s, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0xa8,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6420a800 <unknown>
+
+movprfx z23, z31
+fmlalltb z23.s, z13.b, z8.b  // 01100100-00101000-10101001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalltb z23.s, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xa9,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6428a9b7 <unknown>
+
+fmlalltb z31.s, z31.b, z31.b  // 01100100-00111111-10101011-11111111
+// CHECK-INST: fmlalltb z31.s, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0xab,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643fabff <unknown>
+
+
+//--------------------------------------------//
+//
+// FMLALLTT instructions
+//
+// fmlalltt - indexed
+
+fmlalltt z0.s, z0.b, z0.b[0]  // 01100100-11100000-11000000-00000000
+// CHECK-INST: fmlalltt z0.s, z0.b, z0.b[0]
+// CHECK-ENCODING: [0x00,0xc0,0xe0,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64e0c000 <unknown>
+
+movprfx z23, z31
+fmlalltt z23.s, z13.b, z0.b[7]  // 01100100-11101000-11001101-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalltt z23.s, z13.b, z0.b[7]
+// CHECK-ENCODING: [0xb7,0xcd,0xe8,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64e8cdb7 <unknown>
+
+fmlalltt z31.s, z31.b, z7.b[15]  // 01100100-11111111-11001111-11111111
+// CHECK-INST: fmlalltt z31.s, z31.b, z7.b[15]
+// CHECK-ENCODING: [0xff,0xcf,0xff,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 64ffcfff <unknown>
+
+
+//
+// FMLALLTT instructions
+//
+// fmlalltt - group
+
+fmlalltt z0.s, z0.b, z0.b  // 01100100-00100000-10111000-00000000
+// CHECK-INST: fmlalltt z0.s, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0xb8,0x20,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6420b800 <unknown>
+
+movprfx z23, z31
+fmlalltt z23.s, z13.b, z8.b  // 01100100-00101000-10111001-10110111
+// CHECK-INST:  movprfx z23, z31
+// CHECK-INST: fmlalltt z23.s, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xb9,0x28,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 6428b9b7 <unknown>
+
+fmlalltt z31.s, z31.b, z31.b  // 01100100-00111111-10111011-11111111
+// CHECK-INST: fmlalltt z31.s, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0xbb,0x3f,0x64]
+// CHECK-ERROR: instruction requires: ssve-fp8fma or (sve2 and fp8fma)
+// CHECK-UNKNOWN: 643fbbff <unknown>

diff  --git a/llvm/unittests/TargetParser/TargetParserTest.cpp b/llvm/unittests/TargetParser/TargetParserTest.cpp
index 45f39a66ea8b343..3c6d463fee25989 100644
--- a/llvm/unittests/TargetParser/TargetParserTest.cpp
+++ b/llvm/unittests/TargetParser/TargetParserTest.cpp
@@ -1713,26 +1713,27 @@ TEST(TargetParserTest, testAArch64Extension) {
 
 TEST(TargetParserTest, AArch64ExtensionFeatures) {
   std::vector<uint64_t> Extensions = {
-      AArch64::AEK_CRC,     AArch64::AEK_LSE,       AArch64::AEK_RDM,
-      AArch64::AEK_CRYPTO,  AArch64::AEK_SM4,       AArch64::AEK_SHA3,
-      AArch64::AEK_SHA2,    AArch64::AEK_AES,       AArch64::AEK_DOTPROD,
-      AArch64::AEK_FP,      AArch64::AEK_SIMD,      AArch64::AEK_FP16,
-      AArch64::AEK_FP16FML, AArch64::AEK_PROFILE,   AArch64::AEK_RAS,
-      AArch64::AEK_SVE,     AArch64::AEK_SVE2,      AArch64::AEK_SVE2AES,
-      AArch64::AEK_SVE2SM4, AArch64::AEK_SVE2SHA3,  AArch64::AEK_SVE2BITPERM,
-      AArch64::AEK_RCPC,    AArch64::AEK_RAND,      AArch64::AEK_MTE,
-      AArch64::AEK_SSBS,    AArch64::AEK_SB,        AArch64::AEK_PREDRES,
-      AArch64::AEK_BF16,    AArch64::AEK_I8MM,      AArch64::AEK_F32MM,
-      AArch64::AEK_F64MM,   AArch64::AEK_TME,       AArch64::AEK_LS64,
-      AArch64::AEK_BRBE,    AArch64::AEK_PAUTH,     AArch64::AEK_FLAGM,
-      AArch64::AEK_SME,     AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
-      AArch64::AEK_SME2,    AArch64::AEK_HBC,       AArch64::AEK_MOPS,
-      AArch64::AEK_PERFMON, AArch64::AEK_SVE2p1,    AArch64::AEK_SME2p1,
-      AArch64::AEK_B16B16,  AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
-      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_FAMINMAX};
+      AArch64::AEK_CRC,        AArch64::AEK_LSE,       AArch64::AEK_RDM,
+      AArch64::AEK_CRYPTO,     AArch64::AEK_SM4,       AArch64::AEK_SHA3,
+      AArch64::AEK_SHA2,       AArch64::AEK_AES,       AArch64::AEK_DOTPROD,
+      AArch64::AEK_FP,         AArch64::AEK_SIMD,      AArch64::AEK_FP16,
+      AArch64::AEK_FP16FML,    AArch64::AEK_PROFILE,   AArch64::AEK_RAS,
+      AArch64::AEK_SVE,        AArch64::AEK_SVE2,      AArch64::AEK_SVE2AES,
+      AArch64::AEK_SVE2SM4,    AArch64::AEK_SVE2SHA3,  AArch64::AEK_SVE2BITPERM,
+      AArch64::AEK_RCPC,       AArch64::AEK_RAND,      AArch64::AEK_MTE,
+      AArch64::AEK_SSBS,       AArch64::AEK_SB,        AArch64::AEK_PREDRES,
+      AArch64::AEK_BF16,       AArch64::AEK_I8MM,      AArch64::AEK_F32MM,
+      AArch64::AEK_F64MM,      AArch64::AEK_TME,       AArch64::AEK_LS64,
+      AArch64::AEK_BRBE,       AArch64::AEK_PAUTH,     AArch64::AEK_FLAGM,
+      AArch64::AEK_SME,        AArch64::AEK_SMEF64F64, AArch64::AEK_SMEI16I64,
+      AArch64::AEK_SME2,       AArch64::AEK_HBC,       AArch64::AEK_MOPS,
+      AArch64::AEK_PERFMON,    AArch64::AEK_SVE2p1,    AArch64::AEK_SME2p1,
+      AArch64::AEK_B16B16,     AArch64::AEK_SMEF16F16, AArch64::AEK_CSSC,
+      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_FAMINMAX,  AArch64::AEK_FP8FMA,
+      AArch64::AEK_SSVE_FP8FMA};
 
   std::vector<StringRef> Features;
 
@@ -1807,6 +1808,8 @@ TEST(TargetParserTest, AArch64ExtensionFeatures) {
   EXPECT_TRUE(llvm::is_contained(Features, "+fpmr"));
   EXPECT_TRUE(llvm::is_contained(Features, "+fp8"));
   EXPECT_TRUE(llvm::is_contained(Features, "+faminmax"));
+  EXPECT_TRUE(llvm::is_contained(Features, "+fp8fma"));
+  EXPECT_TRUE(llvm::is_contained(Features, "+ssve-fp8fma"));
 
   // 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
@@ -1933,6 +1936,8 @@ TEST(TargetParserTest, AArch64ArchExtFeature) {
       {"fpmr", "nofpmr", "+fpmr", "-fpmr"},
       {"fp8", "nofp8", "+fp8", "-fp8"},
       {"faminmax", "nofaminmax", "+faminmax", "-faminmax"},
+      {"fp8fma", "nofp8fma", "+fp8fma", "-fp8fma"},
+      {"ssve-fp8fma", "nossve-fp8fma", "+ssve-fp8fma", "-ssve-fp8fma"},
   };
 
   for (unsigned i = 0; i < std::size(ArchExt); i++) {


        


More information about the llvm-commits mailing list