Skip to content

Commit

Permalink
[LLVM][AArch64] Add assembly/disassembly for MUL/BFMUL SME instructio…
Browse files Browse the repository at this point in the history
…ns (#113535)

According to https://developer.arm.com/documentation/ddi0602

Co-authored-by: Momchil-Velikov [email protected]
  • Loading branch information
CarolineConcatto authored Oct 29, 2024
1 parent 7544d3a commit d4197f3
Show file tree
Hide file tree
Showing 6 changed files with 696 additions and 0 deletions.
10 changes: 10 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,11 @@ let Predicates = [HasSME2p2] in {

defm BFMOP4A : sme2_bfmop4as_widening<0, "bfmop4a">;
defm BFMOP4S : sme2_bfmop4as_widening<1, "bfmop4s">;

defm FMUL_2ZZ : sme2_multi2_fmul_sm<"fmul">;
defm FMUL_2Z2Z : sme2_multi2_fmul_mm< "fmul">;
defm FMUL_4ZZ : sme2_multi4_fmul_sm<"fmul">;
defm FMUL_4Z4Z : sme2_multi4_fmul_mm< "fmul">;
} // [HasSME2p2]

let Predicates = [HasSME2p2, HasSMEB16B16] in {
Expand All @@ -1024,3 +1029,8 @@ let Predicates = [HasSME2p2, HasSMEF8F16], Uses = [FPMR, FPCR] in {
let Predicates = [HasSME2p2, HasSMEF16F16] in {
def FTMOPA_M2ZZZI_HtoH : sme_tmopa_16b<0b10001, ZZ_h_mul_r, ZPR16, "ftmopa">;
} // [HasSME2p2, HasSMEF16F16]

let Predicates = [HasSME2, HasSVEBFSCALE] in {
defm BFMUL : sme2_bfmul_single<"bfmul">;
defm BFMUL : sme2_bfmul_multi<"bfmul">;
} //[HasSME2, HasSVEBFSCALE]
110 changes: 110 additions & 0 deletions llvm/lib/Target/AArch64/SMEInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -5225,3 +5225,113 @@ multiclass sme2_bfmop4as_widening<bit S, string mnemonic> {
// Multiple vectors
def _M2Z2Z_S : sme2_bf16_fp32_quarter_tile_outer_product<1, 1, S, mnemonic, ZZ_h_mul_r_Lo, ZZ_h_mul_r_Hi>;
}

class sme2_multi2_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
: I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
mnemonic, "\t$Zd, $Zn, $Zm",
"", []>, Sched<[]> {
bits<4> Zd;
bits<4> Zn;
bits<4> Zm;

let Inst{31-24} = 0b11000001;
let Inst{23-22} = size;
let Inst{21} = 0b1;
let Inst{20-17} = Zm;
let Inst{16-10} = 0b0111010;
let Inst{9-6} = Zn;
let Inst{5} = 0b0;
let Inst{4-1} = Zd;
let Inst{0} = 0b0;
}

multiclass sme2_multi2_fmul_sm<string mnemonic> {
def _H : sme2_multi2_fmul_sm<0b01, mnemonic, ZZ_h_mul_r, ZPR4b16>;
def _S : sme2_multi2_fmul_sm<0b10, mnemonic, ZZ_s_mul_r, ZPR4b32>;
def _D : sme2_multi2_fmul_sm<0b11, mnemonic, ZZ_d_mul_r, ZPR4b64>;
}

class sme2_multi4_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
: I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
mnemonic, "\t$Zd, $Zn, $Zm",
"", []>, Sched<[]> {
bits<3> Zd;
bits<3> Zn;
bits<4> Zm;

let Inst{31-24} = 0b11000001;
let Inst{23-22} = size;
let Inst{21} = 0b1;
let Inst{20-17} = Zm;
let Inst{16-10} = 0b1111010;
let Inst{9-7} = Zn;
let Inst{6-5} = 0b00;
let Inst{4-2} = Zd;
let Inst{1-0} = 0b00;
}

multiclass sme2_multi4_fmul_sm<string mnemonic> {
def _H : sme2_multi4_fmul_sm<0b01, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
def _S : sme2_multi4_fmul_sm<0b10, mnemonic, ZZZZ_s_mul_r, ZPR4b32>;
def _D : sme2_multi4_fmul_sm<0b11, mnemonic, ZZZZ_d_mul_r, ZPR4b64>;
}

multiclass sme2_bfmul_single<string mnemonic> {
def _2ZZ : sme2_multi2_fmul_sm<0b00, mnemonic, ZZ_h_mul_r, ZPR4b16>;
def _4ZZ : sme2_multi4_fmul_sm<0b00, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
}

class sme2_multi2_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
: I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
mnemonic, "\t$Zd, $Zn, $Zm",
"", []>, Sched<[]> {
bits<4> Zd;
bits<4> Zn;
bits<4> Zm;

let Inst{31-24} = 0b11000001;
let Inst{23-22} = size;
let Inst{21} = 0b1;
let Inst{20-17} = Zm;
let Inst{16-10} = 0b0111001;
let Inst{9-6} = Zn;
let Inst{5} = 0b0;
let Inst{4-1} = Zd;
let Inst{0} = 0b0;
}

multiclass sme2_multi2_fmul_mm<string mnemonic> {
def _H : sme2_multi2_fmul_mm<0b01, mnemonic, ZZ_h_mul_r>;
def _S : sme2_multi2_fmul_mm<0b10, mnemonic, ZZ_s_mul_r>;
def _D : sme2_multi2_fmul_mm<0b11, mnemonic, ZZ_d_mul_r>;
}

class sme2_multi4_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
: I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
mnemonic, "\t$Zd, $Zn, $Zm",
"", []>, Sched<[]> {
bits<3> Zd;
bits<3> Zn;
bits<3> Zm;

let Inst{31-24} = 0b11000001;
let Inst{23-22} = size;
let Inst{21} = 0b1;
let Inst{20-18} = Zm;
let Inst{17-10} = 0b01111001;
let Inst{9-7} = Zn;
let Inst{6-5} = 0b00;
let Inst{4-2} = Zd;
let Inst{1-0} = 0b00;
}

multiclass sme2_multi4_fmul_mm<string mnemonic> {
def _H : sme2_multi4_fmul_mm<0b01, mnemonic, ZZZZ_h_mul_r>;
def _S : sme2_multi4_fmul_mm<0b10, mnemonic, ZZZZ_s_mul_r>;
def _D : sme2_multi4_fmul_mm<0b11, mnemonic, ZZZZ_d_mul_r>;
}

multiclass sme2_bfmul_multi<string mnemonic> {
def _2Z2Z : sme2_multi2_fmul_mm<0b00, mnemonic, ZZ_h_mul_r>;
def _4Z4Z : sme2_multi4_fmul_mm<0b00, mnemonic, ZZZZ_h_mul_r>;
}
111 changes: 111 additions & 0 deletions llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// RUN: not llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale 2>&1 < %s| FileCheck %s

// Multiple and single, 2 regs

bfmul {z0.s-z1.s}, {z0.h-z1.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z1.h-z2.h}, {z0.h-z1.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types

bfmul {z0.h-z2.h}, {z0.h-z1.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z0.s-z1.s}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z1.h-z2.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types

bfmul {z0.h-z1.h}, {z0.h-z2.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h

bfmul {z0.h-z1.h}, {z0.h-z1.h}, z16.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h

// Multiple and single, 4 regs

bfmul {z0.s-z3.s}, {z0.h-z3.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z1.h-z4.h}, {z0.h-z3.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types

bfmul {z0.h-z4.h}, {z0.h-z3.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors

bfmul {z0.h-z3.h}, {z0.s-z3.s}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z3.h}, {z1.h-z4.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types

bfmul {z0.h-z3.h}, {z0.h-z4.h}, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors

bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h

bfmul {z0.h-z3.h}, {z0.h-z3.h}, z16.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h

// Multiple, 2 regs

bfmul {z0.s-z1.s}, {z0.h-z1.h}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z1.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types

bfmul {z0.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z0.s-z1.s}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z1.h-z2.h}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types

bfmul {z0.h-z1.h}, {z0.h-z2.h}, {z0.h-z1.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.s-z1.s}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z1.h-z2.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types

bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z2.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

// Multiple, 4 regs

bfmul {z0.s-z3.s}, {z0.h-z3.h}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z1.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types

bfmul {z0.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors

bfmul {z0.h-z3.h}, {z0.s-z3.s}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z3.h}, {z1.h-z4.h}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types

bfmul {z0.h-z3.h}, {z0.h-z4.h}, {z0.h-z3.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors

bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.s-z3.s}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction

bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z1.h-z4.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types

bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z4.h}
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
92 changes: 92 additions & 0 deletions llvm/test/MC/AArch64/SME2/bfmul.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %s \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-ERROR
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2,+sve-bfscale < %s \
// RUN: | llvm-objdump -d --mattr=+sme2,+sve-bfscale - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2,+sve-bfscale < %s \
// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
// Disassemble encoding and check the re-encoding (-show-encoding) matches.
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %s \
// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale -disassemble -show-encoding \
// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST

// Multiple and single, 2 regs

bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.h // 11000001-00100000-11101000-00000000
// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, z0.h
// CHECK-ENCODING: [0x00,0xe8,0x20,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c120e800 <unknown>

bfmul {z20.h-z21.h}, {z10.h-z11.h}, z10.h // 11000001-00110100-11101001-01010100
// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, z10.h
// CHECK-ENCODING: [0x54,0xe9,0x34,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c134e954 <unknown>

bfmul {z30.h-z31.h}, {z30.h-z31.h}, z15.h // 11000001-00111110-11101011-11011110
// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, z15.h
// CHECK-ENCODING: [0xde,0xeb,0x3e,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c13eebde <unknown>

// Multiple and single, 4 regs

bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.h // 11000001-00100001-11101000-00000000
// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, z0.h
// CHECK-ENCODING: [0x00,0xe8,0x21,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c121e800 <unknown>

bfmul {z20.h-z23.h}, {z8.h-z11.h}, z10.h // 11000001-00110101-11101001-00010100
// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, z10.h
// CHECK-ENCODING: [0x14,0xe9,0x35,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c135e914 <unknown>

bfmul {z28.h-z31.h}, {z28.h-z31.h}, z15.h // 11000001-00111111-11101011-10011100
// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, z15.h
// CHECK-ENCODING: [0x9c,0xeb,0x3f,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c13feb9c <unknown>

// Multiple, 2 regs
bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h} // 11000001-00100000-11100100-00000000
// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, { z0.h, z1.h }
// CHECK-ENCODING: [0x00,0xe4,0x20,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c120e400 <unknown>

bfmul {z20.h-z21.h}, {z10.h-z11.h}, {z20.h-z21.h} // 11000001-00110100-11100101-01010100
// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, { z20.h, z21.h }
// CHECK-ENCODING: [0x54,0xe5,0x34,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c134e554 <unknown>

bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h} // 11000001-00111110-11100111-11011110
// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, { z30.h, z31.h }
// CHECK-ENCODING: [0xde,0xe7,0x3e,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c13ee7de <unknown>

// Multiple, 4 regs

bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-00100001-11100100-00000000
// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h }
// CHECK-ENCODING: [0x00,0xe4,0x21,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c121e400 <unknown>

bfmul {z20.h-z23.h}, {z8.h-z11.h}, {z20.h-z23.h} // 11000001-00110101-11100101-00010100
// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, { z20.h - z23.h }
// CHECK-ENCODING: [0x14,0xe5,0x35,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c135e514 <unknown>

bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-00111101-11100111-10011100
// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h }
// CHECK-ENCODING: [0x9c,0xe7,0x3d,0xc1]
// CHECK-ERROR: instruction requires: sme2 sve-bfscale
// CHECK-UNKNOWN: c13de79c <unknown>
Loading

0 comments on commit d4197f3

Please sign in to comment.