[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