From 7b33faaf38a49787b209cfa514bfda5e20d1fc40 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Tue, 17 Jul 2018 15:41:58 +0000 Subject: [PATCH] [AArch64][SVE]: Integer multiply-add/subtract instructions. This patch adds support for the following instructions: MLA mul-add, writing addend (Zda = Zda + Zn * Zm) MLS mul-sub, writing addend (Zda = Zda + -Zn * Zm) MAD mul-add, writing multiplicant (Zdn = Za + Zdn * Zm) MSB mul-sub, writing multiplicant (Zdn = Za + -Zdn * Zm) llvm-svn: 337293 --- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td | 5 ++ llvm/lib/Target/AArch64/SVEInstrFormats.td | 64 ++++++++++++++++++++++++++ llvm/test/MC/AArch64/SVE/mad-diagnostics.s | 19 ++++++++ llvm/test/MC/AArch64/SVE/mad.s | 32 +++++++++++++ llvm/test/MC/AArch64/SVE/mla-diagnostics.s | 19 ++++++++ llvm/test/MC/AArch64/SVE/mla.s | 32 +++++++++++++ llvm/test/MC/AArch64/SVE/mls-diagnostics.s | 19 ++++++++ llvm/test/MC/AArch64/SVE/mls.s | 32 +++++++++++++ llvm/test/MC/AArch64/SVE/msb-diagnostics.s | 19 ++++++++ llvm/test/MC/AArch64/SVE/msb.s | 32 +++++++++++++ 10 files changed, 273 insertions(+) create mode 100644 llvm/test/MC/AArch64/SVE/mad-diagnostics.s create mode 100644 llvm/test/MC/AArch64/SVE/mad.s create mode 100644 llvm/test/MC/AArch64/SVE/mla-diagnostics.s create mode 100644 llvm/test/MC/AArch64/SVE/mla.s create mode 100644 llvm/test/MC/AArch64/SVE/mls-diagnostics.s create mode 100644 llvm/test/MC/AArch64/SVE/mls.s create mode 100644 llvm/test/MC/AArch64/SVE/msb-diagnostics.s create mode 100644 llvm/test/MC/AArch64/SVE/msb.s diff --git a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td index 60114f7..42c3df3 100644 --- a/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -48,6 +48,11 @@ let Predicates = [HasSVE] in { defm SQSUB_ZI : sve_int_arith_imm0<0b110, "sqsub">; defm UQSUB_ZI : sve_int_arith_imm0<0b111, "uqsub">; + defm MAD_ZPmZZ : sve_int_mladdsub_vvv_pred<0b0, "mad">; + defm MSB_ZPmZZ : sve_int_mladdsub_vvv_pred<0b1, "msb">; + defm MLA_ZPmZZ : sve_int_mlas_vvv_pred<0b0, "mla">; + defm MLS_ZPmZZ : sve_int_mlas_vvv_pred<0b1, "mls">; + defm ORR_ZI : sve_int_log_imm<0b00, "orr", "orn">; defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon">; defm AND_ZI : sve_int_log_imm<0b10, "and", "bic">; diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td index 3939744..fced9d0 100644 --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -1381,6 +1381,70 @@ multiclass sve_int_bin_pred_arit_1 opc, string asm> { } //===----------------------------------------------------------------------===// +// SVE Integer Multiply-Add Group +//===----------------------------------------------------------------------===// + +class sve_int_mladdsub_vvv_pred sz8_64, bits<1> opc, string asm, + ZPRRegOp zprty> +: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za), + asm, "\t$Zdn, $Pg/m, $Zm, $Za", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Zdn; + bits<5> Za; + bits<5> Zm; + let Inst{31-24} = 0b00000100; + let Inst{23-22} = sz8_64; + let Inst{21} = 0b0; + let Inst{20-16} = Zm; + let Inst{15-14} = 0b11; + let Inst{13} = opc; + let Inst{12-10} = Pg; + let Inst{9-5} = Za; + let Inst{4-0} = Zdn; + + let Constraints = "$Zdn = $_Zdn"; +} + +multiclass sve_int_mladdsub_vvv_pred opc, string asm> { + def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>; + def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>; + def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>; + def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>; +} + +class sve_int_mlas_vvv_pred sz8_64, bits<1> opc, string asm, + ZPRRegOp zprty> +: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm), + asm, "\t$Zda, $Pg/m, $Zn, $Zm", + "", + []>, Sched<[]> { + bits<3> Pg; + bits<5> Zda; + bits<5> Zm; + bits<5> Zn; + let Inst{31-24} = 0b00000100; + let Inst{23-22} = sz8_64; + let Inst{21} = 0b0; + let Inst{20-16} = Zm; + let Inst{15-14} = 0b01; + let Inst{13} = opc; + let Inst{12-10} = Pg; + let Inst{9-5} = Zn; + let Inst{4-0} = Zda; + + let Constraints = "$Zda = $_Zda"; +} + +multiclass sve_int_mlas_vvv_pred opc, string asm> { + def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>; + def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>; + def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>; + def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>; +} + +//===----------------------------------------------------------------------===// // SVE Integer Arithmetic - Unary Predicated Group //===----------------------------------------------------------------------===// diff --git a/llvm/test/MC/AArch64/SVE/mad-diagnostics.s b/llvm/test/MC/AArch64/SVE/mad-diagnostics.s new file mode 100644 index 0000000..e320933 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mad-diagnostics.s @@ -0,0 +1,19 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +mad z0.h, p8/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: mad z0.h, p8/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid element width + +mad z0.s, p7/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: mad z0.s, p7/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE/mad.s b/llvm/test/MC/AArch64/SVE/mad.s new file mode 100644 index 0000000..3a5d81e --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mad.s @@ -0,0 +1,32 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %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=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +mad z0.b, p7/m, z1.b, z31.b +// CHECK-INST: mad z0.b, p7/m, z1.b, z31.b +// CHECK-ENCODING: [0xe0,0xdf,0x01,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 df 01 04 + +mad z0.h, p7/m, z1.h, z31.h +// CHECK-INST: mad z0.h, p7/m, z1.h, z31.h +// CHECK-ENCODING: [0xe0,0xdf,0x41,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 df 41 04 + +mad z0.s, p7/m, z1.s, z31.s +// CHECK-INST: mad z0.s, p7/m, z1.s, z31.s +// CHECK-ENCODING: [0xe0,0xdf,0x81,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 df 81 04 + +mad z0.d, p7/m, z1.d, z31.d +// CHECK-INST: mad z0.d, p7/m, z1.d, z31.d +// CHECK-ENCODING: [0xe0,0xdf,0xc1,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 df c1 04 diff --git a/llvm/test/MC/AArch64/SVE/mla-diagnostics.s b/llvm/test/MC/AArch64/SVE/mla-diagnostics.s new file mode 100644 index 0000000..03cb471 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mla-diagnostics.s @@ -0,0 +1,19 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +mla z0.h, p8/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: mla z0.h, p8/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid element width + +mla z0.s, p7/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: mla z0.s, p7/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE/mla.s b/llvm/test/MC/AArch64/SVE/mla.s new file mode 100644 index 0000000..4911e6a --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mla.s @@ -0,0 +1,32 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %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=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +mla z0.b, p7/m, z1.b, z31.b +// CHECK-INST: mla z0.b, p7/m, z1.b, z31.b +// CHECK-ENCODING: [0x20,0x5c,0x1f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 5c 1f 04 + +mla z0.h, p7/m, z1.h, z31.h +// CHECK-INST: mla z0.h, p7/m, z1.h, z31.h +// CHECK-ENCODING: [0x20,0x5c,0x5f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 5c 5f 04 + +mla z0.s, p7/m, z1.s, z31.s +// CHECK-INST: mla z0.s, p7/m, z1.s, z31.s +// CHECK-ENCODING: [0x20,0x5c,0x9f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 5c 9f 04 + +mla z0.d, p7/m, z1.d, z31.d +// CHECK-INST: mla z0.d, p7/m, z1.d, z31.d +// CHECK-ENCODING: [0x20,0x5c,0xdf,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 5c df 04 diff --git a/llvm/test/MC/AArch64/SVE/mls-diagnostics.s b/llvm/test/MC/AArch64/SVE/mls-diagnostics.s new file mode 100644 index 0000000..711518c --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mls-diagnostics.s @@ -0,0 +1,19 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +mls z0.h, p8/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: mls z0.h, p8/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid element width + +mls z0.s, p7/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: mls z0.s, p7/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE/mls.s b/llvm/test/MC/AArch64/SVE/mls.s new file mode 100644 index 0000000..8c088fd --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/mls.s @@ -0,0 +1,32 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %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=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +mls z0.b, p7/m, z1.b, z31.b +// CHECK-INST: mls z0.b, p7/m, z1.b, z31.b +// CHECK-ENCODING: [0x20,0x7c,0x1f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 7c 1f 04 + +mls z0.h, p7/m, z1.h, z31.h +// CHECK-INST: mls z0.h, p7/m, z1.h, z31.h +// CHECK-ENCODING: [0x20,0x7c,0x5f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 7c 5f 04 + +mls z0.s, p7/m, z1.s, z31.s +// CHECK-INST: mls z0.s, p7/m, z1.s, z31.s +// CHECK-ENCODING: [0x20,0x7c,0x9f,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 7c 9f 04 + +mls z0.d, p7/m, z1.d, z31.d +// CHECK-INST: mls z0.d, p7/m, z1.d, z31.d +// CHECK-ENCODING: [0x20,0x7c,0xdf,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: 20 7c df 04 diff --git a/llvm/test/MC/AArch64/SVE/msb-diagnostics.s b/llvm/test/MC/AArch64/SVE/msb-diagnostics.s new file mode 100644 index 0000000..a2bde87 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/msb-diagnostics.s @@ -0,0 +1,19 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +msb z0.h, p8/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: msb z0.h, p8/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid element width + +msb z0.s, p7/m, z1.h, z2.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: msb z0.s, p7/m, z1.h, z2.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SVE/msb.s b/llvm/test/MC/AArch64/SVE/msb.s new file mode 100644 index 0000000..048f321 --- /dev/null +++ b/llvm/test/MC/AArch64/SVE/msb.s @@ -0,0 +1,32 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve < %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=+sve < %s \ +// RUN: | llvm-objdump -d -mattr=+sve - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN + +msb z0.b, p7/m, z1.b, z31.b +// CHECK-INST: msb z0.b, p7/m, z1.b, z31.b +// CHECK-ENCODING: [0xe0,0xff,0x01,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 ff 01 04 + +msb z0.h, p7/m, z1.h, z31.h +// CHECK-INST: msb z0.h, p7/m, z1.h, z31.h +// CHECK-ENCODING: [0xe0,0xff,0x41,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 ff 41 04 + +msb z0.s, p7/m, z1.s, z31.s +// CHECK-INST: msb z0.s, p7/m, z1.s, z31.s +// CHECK-ENCODING: [0xe0,0xff,0x81,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 ff 81 04 + +msb z0.d, p7/m, z1.d, z31.d +// CHECK-INST: msb z0.d, p7/m, z1.d, z31.d +// CHECK-ENCODING: [0xe0,0xff,0xc1,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 ff c1 04 -- 2.7.4