Skip to content

Commit e714683

Browse files
committed
[AArch64] Armv8.6-A Mat Mul SVE Assembly
This patch upstreams support for the Armv8.6-a Matrix Multiplication Extension. A summary of the features can be found here: https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-architecture-developments-armv8-6-a This patch includes: - Assembly support for AArch64 Scalable Vector Instructions (in line with the Scalable Vector Extension - SVE) This is part of a patch series, starting with BFloat16 support and the other components in the armv8.6a extension (in previous patches linked in phabricator) Based on work by: - Luke Geeson - Oliver Stannard - Luke Cheeseman Reviewers: t.p.northover, rengolin, c-rhodes Reviewed By: c-rhodes Subscribers: c-rhodes, ostannard, tschuett, kristof.beyls, hiraditya, danielkiss, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77873
1 parent 7da1905 commit e714683

9 files changed

+807
-0
lines changed

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -511,6 +511,7 @@ def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
511511
def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
512512
def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
513513
def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
514+
def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;
514515

515516
def simm4s1 : Operand<i64>, ImmLeaf<i64,
516517
[{ return Imm >=-8 && Imm <= 7; }]> {
@@ -544,6 +545,12 @@ def simm4s16 : Operand<i64>, ImmLeaf<i64,
544545
let ParserMatchClass = SImm4s16Operand;
545546
let DecoderMethod = "DecodeSImm<4>";
546547
}
548+
def simm4s32 : Operand<i64>, ImmLeaf<i64,
549+
[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }]> {
550+
let PrintMethod = "printImmScale<32>";
551+
let ParserMatchClass = SImm4s32Operand;
552+
let DecoderMethod = "DecodeSImm<4>";
553+
}
547554

548555
def Imm1_8Operand : AsmImmRange<1, 8>;
549556
def Imm1_16Operand : AsmImmRange<1, 16>;

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,6 +1769,37 @@ multiclass sve_prefetch<SDPatternOperator prefetch, ValueType PredTy, Instructio
17691769

17701770
}
17711771

1772+
let Predicates = [HasSVE, HasMatMulInt8] in {
1773+
def SMMLA_ZZZ : sve_int_matmul<0b00, "smmla">;
1774+
def UMMLA_ZZZ : sve_int_matmul<0b11, "ummla">;
1775+
def USMMLA_ZZZ : sve_int_matmul<0b10, "usmmla">;
1776+
def USDOT_ZZZ : sve_int_dot_mixed<"usdot">;
1777+
def USDOT_ZZZI : sve_int_dot_mixed_indexed<0, "usdot">;
1778+
def SUDOT_ZZZI : sve_int_dot_mixed_indexed<1, "sudot">;
1779+
}
1780+
1781+
let Predicates = [HasSVE, HasMatMulFP32] in {
1782+
def FMMLA_ZZZ_S : sve_fp_matrix_mla<0, "fmmla", ZPR32>;
1783+
}
1784+
1785+
let Predicates = [HasSVE, HasMatMulFP64] in {
1786+
def FMMLA_ZZZ_D : sve_fp_matrix_mla<1, "fmmla", ZPR64>;
1787+
defm LD1RO_B_IMM : sve_mem_ldor_si<0b00, "ld1rob", Z_b, ZPR8>;
1788+
defm LD1RO_H_IMM : sve_mem_ldor_si<0b01, "ld1roh", Z_h, ZPR16>;
1789+
defm LD1RO_W_IMM : sve_mem_ldor_si<0b10, "ld1row", Z_s, ZPR32>;
1790+
defm LD1RO_D_IMM : sve_mem_ldor_si<0b11, "ld1rod", Z_d, ZPR64>;
1791+
defm LD1RO_B : sve_mem_ldor_ss<0b00, "ld1rob", Z_b, ZPR8, GPR64NoXZRshifted8>;
1792+
defm LD1RO_H : sve_mem_ldor_ss<0b01, "ld1roh", Z_h, ZPR16, GPR64NoXZRshifted16>;
1793+
defm LD1RO_W : sve_mem_ldor_ss<0b10, "ld1row", Z_s, ZPR32, GPR64NoXZRshifted32>;
1794+
defm LD1RO_D : sve_mem_ldor_ss<0b11, "ld1rod", Z_d, ZPR64, GPR64NoXZRshifted64>;
1795+
def ZIP1_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b00, 0, "zip1">;
1796+
def ZIP2_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b00, 1, "zip2">;
1797+
def UZP1_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b01, 0, "uzp1">;
1798+
def UZP2_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b01, 1, "uzp2">;
1799+
def TRN1_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b11, 0, "trn1">;
1800+
def TRN2_ZZZ_128 : sve_int_perm_bin_perm_128_zz<0b11, 1, "trn2">;
1801+
}
1802+
17721803
let Predicates = [HasSVE2] in {
17731804
// SVE2 integer multiply-add (indexed)
17741805
defm MLA_ZZZI : sve2_int_mla_by_indexed_elem<0b01, 0b0, "mla", int_aarch64_sve_mla_lane>;

llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4256,6 +4256,8 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
42564256
return Error(Loc, "index must be a multiple of 4 in range [-32, 28].");
42574257
case Match_InvalidMemoryIndexed16SImm4:
42584258
return Error(Loc, "index must be a multiple of 16 in range [-128, 112].");
4259+
case Match_InvalidMemoryIndexed32SImm4:
4260+
return Error(Loc, "index must be a multiple of 32 in range [-256, 224].");
42594261
case Match_InvalidMemoryIndexed1SImm6:
42604262
return Error(Loc, "index must be an integer in range [-32, 31].");
42614263
case Match_InvalidMemoryIndexedSImm8:
@@ -4915,6 +4917,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
49154917
case Match_InvalidMemoryIndexed4SImm4:
49164918
case Match_InvalidMemoryIndexed1SImm6:
49174919
case Match_InvalidMemoryIndexed16SImm4:
4920+
case Match_InvalidMemoryIndexed32SImm4:
49184921
case Match_InvalidMemoryIndexed4SImm7:
49194922
case Match_InvalidMemoryIndexed8SImm7:
49204923
case Match_InvalidMemoryIndexed16SImm7:

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7548,6 +7548,181 @@ class sve_bfloat_convert<bit N, string asm>
75487548
let ElementSize = ElementSizeS;
75497549
}
75507550

7551+
//===----------------------------------------------------------------------===//
7552+
// SVE Integer Matrix Multiply Group
7553+
//===----------------------------------------------------------------------===//
7554+
7555+
class sve_int_matmul<bits<2> uns, string asm>
7556+
: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
7557+
"\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
7558+
bits<5> Zda;
7559+
bits<5> Zn;
7560+
bits<5> Zm;
7561+
let Inst{31-24} = 0b01000101;
7562+
let Inst{23-22} = uns;
7563+
let Inst{21} = 0;
7564+
let Inst{20-16} = Zm;
7565+
let Inst{15-10} = 0b100110;
7566+
let Inst{9-5} = Zn;
7567+
let Inst{4-0} = Zda;
7568+
7569+
let Constraints = "$Zda = $_Zda";
7570+
let DestructiveInstType = DestructiveOther;
7571+
let ElementSize = ZPR32.ElementSize;
7572+
}
7573+
7574+
//===----------------------------------------------------------------------===//
7575+
// SVE Integer Dot Product Mixed Sign Group
7576+
//===----------------------------------------------------------------------===//
7577+
7578+
class sve_int_dot_mixed<string asm>
7579+
: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
7580+
"\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
7581+
bits<5> Zda;
7582+
bits<5> Zn;
7583+
bits<5> Zm;
7584+
let Inst{31-21} = 0b01000100100;
7585+
let Inst{20-16} = Zm;
7586+
let Inst{15-10} = 0b011110;
7587+
let Inst{9-5} = Zn;
7588+
let Inst{4-0} = Zda;
7589+
7590+
let Constraints = "$Zda = $_Zda";
7591+
let DestructiveInstType = DestructiveOther;
7592+
let ElementSize = ZPR32.ElementSize;
7593+
}
7594+
7595+
//===----------------------------------------------------------------------===//
7596+
// SVE Integer Dot Product Mixed Sign - Indexed Group
7597+
//===----------------------------------------------------------------------===//
7598+
7599+
class sve_int_dot_mixed_indexed<bit U, string asm>
7600+
: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS:$idx),
7601+
asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
7602+
bits<5> Zda;
7603+
bits<5> Zn;
7604+
bits<3> Zm;
7605+
bits<2> idx;
7606+
let Inst{31-21} = 0b01000100101;
7607+
let Inst{20-19} = idx;
7608+
let Inst{18-16} = Zm;
7609+
let Inst{15-11} = 0b00011;
7610+
let Inst{10} = U;
7611+
let Inst{9-5} = Zn;
7612+
let Inst{4-0} = Zda;
7613+
7614+
let Constraints = "$Zda = $_Zda";
7615+
let DestructiveInstType = DestructiveOther;
7616+
let ElementSize = ZPR32.ElementSize;
7617+
}
7618+
7619+
//===----------------------------------------------------------------------===//
7620+
// SVE Floating Point Matrix Multiply Accumulate Group
7621+
//===----------------------------------------------------------------------===//
7622+
7623+
class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
7624+
: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
7625+
asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
7626+
bits<5> Zda;
7627+
bits<5> Zn;
7628+
bits<5> Zm;
7629+
let Inst{31-23} = 0b011001001;
7630+
let Inst{22} = sz;
7631+
let Inst{21} = 1;
7632+
let Inst{20-16} = Zm;
7633+
let Inst{15-10} = 0b111001;
7634+
let Inst{9-5} = Zn;
7635+
let Inst{4-0} = Zda;
7636+
7637+
let Constraints = "$Zda = $_Zda";
7638+
let DestructiveInstType = DestructiveOther;
7639+
let ElementSize = zprty.ElementSize;
7640+
}
7641+
7642+
//===----------------------------------------------------------------------===//
7643+
// SVE Memory - Contiguous Load And Replicate 256-bit Group
7644+
//===----------------------------------------------------------------------===//
7645+
7646+
class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
7647+
: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
7648+
asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7649+
bits<5> Zt;
7650+
bits<5> Rn;
7651+
bits<3> Pg;
7652+
bits<4> imm4;
7653+
let Inst{31-25} = 0b1010010;
7654+
let Inst{24-23} = sz;
7655+
let Inst{22-20} = 0b010;
7656+
let Inst{19-16} = imm4;
7657+
let Inst{15-13} = 0b001;
7658+
let Inst{12-10} = Pg;
7659+
let Inst{9-5} = Rn;
7660+
let Inst{4-0} = Zt;
7661+
7662+
let mayLoad = 1;
7663+
}
7664+
7665+
multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
7666+
ZPRRegOp zprty> {
7667+
def NAME : sve_mem_ldor_si<sz, asm, listty>;
7668+
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7669+
(!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7670+
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7671+
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7672+
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7673+
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
7674+
}
7675+
7676+
class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
7677+
RegisterOperand gprty>
7678+
: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7679+
asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7680+
bits<5> Zt;
7681+
bits<3> Pg;
7682+
bits<5> Rn;
7683+
bits<5> Rm;
7684+
let Inst{31-25} = 0b1010010;
7685+
let Inst{24-23} = sz;
7686+
let Inst{22-21} = 0b01;
7687+
let Inst{20-16} = Rm;
7688+
let Inst{15-13} = 0;
7689+
let Inst{12-10} = Pg;
7690+
let Inst{9-5} = Rn;
7691+
let Inst{4-0} = Zt;
7692+
7693+
let mayLoad = 1;
7694+
}
7695+
7696+
multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
7697+
ZPRRegOp zprty, RegisterOperand gprty> {
7698+
def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
7699+
7700+
def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7701+
(!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7702+
}
7703+
7704+
//===----------------------------------------------------------------------===//
7705+
// SVE Interleave 128-bit Elements Group
7706+
//===----------------------------------------------------------------------===//
7707+
7708+
class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
7709+
: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
7710+
asm, "\t$Zd, $Zn, $Zm",
7711+
"",
7712+
[]>, Sched<[]> {
7713+
bits<5> Zd;
7714+
bits<5> Zm;
7715+
bits<5> Zn;
7716+
let Inst{31-21} = 0b00000101101;
7717+
let Inst{20-16} = Zm;
7718+
let Inst{15-13} = 0b000;
7719+
let Inst{12-11} = opc;
7720+
let Inst{10} = P;
7721+
let Inst{9-5} = Zn;
7722+
let Inst{4-0} = Zd;
7723+
}
7724+
7725+
75517726
/// Addressing modes
75527727
def am_sve_indexed_s4 :ComplexPattern<i64, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
75537728
def am_sve_indexed_s6 :ComplexPattern<i64, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+f32mm,+f64mm 2>&1 < %s | FileCheck %s
2+
3+
// --------------------------------------------------------------------------//
4+
// FMMLA (SVE)
5+
6+
// Invalid element size
7+
8+
fmmla z0.h, z1.h, z2.h
9+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
10+
11+
// Mis-matched element size
12+
13+
fmmla z0.d, z1.s, z2.s
14+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
15+
fmmla z0.s, z1.d, z2.s
16+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
17+
fmmla z0.s, z1.s, z2.d
18+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
19+
20+
21+
// --------------------------------------------------------------------------//
22+
// LD1RO (SVE, scalar plus immediate)
23+
24+
// Immediate too high (>224)
25+
ld1rob { z0.b }, p1/z, [x2, #256]
26+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
27+
ld1roh { z0.h }, p1/z, [x2, #256]
28+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
29+
ld1row { z0.s }, p1/z, [x2, #256]
30+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
31+
ld1rod { z0.d }, p1/z, [x2, #256]
32+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
33+
34+
// Immediate too low (<-256)
35+
ld1rob { z0.b }, p1/z, [x2, #-288]
36+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
37+
ld1roh { z0.h }, p1/z, [x2, #-288]
38+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
39+
ld1row { z0.s }, p1/z, [x2, #-288]
40+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
41+
ld1rod { z0.d }, p1/z, [x2, #-288]
42+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
43+
44+
// Immediate not a multiple of 32
45+
ld1rob { z0.b }, p1/z, [x2, #16]
46+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
47+
ld1roh { z0.h }, p1/z, [x2, #16]
48+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
49+
ld1row { z0.s }, p1/z, [x2, #16]
50+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
51+
ld1rod { z0.d }, p1/z, [x2, #16]
52+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: index must be a multiple of 32 in range [-256, 224].
53+
54+
// Prediate register too high
55+
ld1rob { z0.b }, p8/z, [x2]
56+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
57+
ld1roh { z0.h }, p8/z, [x2]
58+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
59+
ld1row { z0.s }, p8/z, [x2]
60+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
61+
ld1rod { z0.d }, p8/z, [x2]
62+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
63+
64+
65+
// --------------------------------------------------------------------------//
66+
// LD1RO (SVE, scalar plus scalar)
67+
68+
// Shift amount not matched to data width
69+
ld1rob { z0.b }, p1/z, [x2, x3, lsl #1]
70+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 without shift
71+
ld1roh { z0.h }, p1/z, [x2, x3, lsl #0]
72+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #1'
73+
ld1row { z0.s }, p1/z, [x2, x3, lsl #3]
74+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #2'
75+
ld1rod { z0.d }, p1/z, [x2, x3, lsl #2]
76+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: register must be x0..x30 with required shift 'lsl #3'
77+
78+
// Prediate register too high
79+
ld1rob { z0.b }, p8/z, [x2, x3, lsl #0]
80+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
81+
ld1roh { z0.h }, p8/z, [x2, x3, lsl #1]
82+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
83+
ld1row { z0.s }, p8/z, [x2, x3, lsl #2]
84+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
85+
ld1rod { z0.d }, p8/z, [x2, x3, lsl #3]
86+
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+f32mm < %s \
2+
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
3+
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve,+i8mm,+f64mm < %s 2>&1 \
4+
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
5+
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+f32mm < %s \
6+
// RUN: | llvm-objdump -d --mattr=+sve,+f32mm - | FileCheck %s --check-prefix=CHECK-INST
7+
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve,+f32mm < %s \
8+
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
9+
10+
// --------------------------------------------------------------------------//
11+
// FMMLA (SVE)
12+
13+
fmmla z0.s, z1.s, z2.s
14+
// CHECK-INST: fmmla z0.s, z1.s, z2.s
15+
// CHECK-ENCODING: [0x20,0xe4,0xa2,0x64]
16+
// CHECK-ERROR: instruction requires: f32mm
17+
// CHECK-UNKNOWN: 20 e4 a2 64 <unknown>

0 commit comments

Comments
 (0)