From f600b10dd2ad647c3757a6e2647de41b14b9cd43 Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Wed, 18 Jul 2018 09:17:29 +0000 Subject: [PATCH] [AArch64][SVE] Asm: Integer divide instructions. This patch adds the following predicated instructions: UDIV Unsigned divide active elements UDIVR Unsigned divide active elements, reverse form. SDIV Signed divide active elements SDIVR Signed divide active elements, reverse form. e.g. udiv z0.s, p0/m, z0.s, z1.s (unsigned divide active elements in z0 by z1, store result in z0) sdivr z0.s, p0/m, z0.s, z1.s (signed divide active elements in z1 by z0, store result in z0) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337369 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64SVEInstrInfo.td | 5 ++++ lib/Target/AArch64/SVEInstrFormats.td | 6 +++++ test/MC/AArch64/SVE/sdiv-diagnostics.s | 33 +++++++++++++++++++++++ test/MC/AArch64/SVE/sdiv.s | 20 ++++++++++++++ test/MC/AArch64/SVE/sdivr-diagnostics.s | 33 +++++++++++++++++++++++ test/MC/AArch64/SVE/sdivr.s | 20 ++++++++++++++ test/MC/AArch64/SVE/udiv-diagnostics.s | 33 +++++++++++++++++++++++ test/MC/AArch64/SVE/udiv.s | 20 ++++++++++++++ test/MC/AArch64/SVE/udivr-diagnostics.s | 33 +++++++++++++++++++++++ test/MC/AArch64/SVE/udivr.s | 20 ++++++++++++++ 10 files changed, 223 insertions(+) create mode 100644 test/MC/AArch64/SVE/sdiv-diagnostics.s create mode 100644 test/MC/AArch64/SVE/sdiv.s create mode 100644 test/MC/AArch64/SVE/sdivr-diagnostics.s create mode 100644 test/MC/AArch64/SVE/sdivr.s create mode 100644 test/MC/AArch64/SVE/udiv-diagnostics.s create mode 100644 test/MC/AArch64/SVE/udiv.s create mode 100644 test/MC/AArch64/SVE/udivr-diagnostics.s create mode 100644 test/MC/AArch64/SVE/udivr.s diff --git a/lib/Target/AArch64/AArch64SVEInstrInfo.td b/lib/Target/AArch64/AArch64SVEInstrInfo.td index 52b19dd133a..b37c6967727 100644 --- a/lib/Target/AArch64/AArch64SVEInstrInfo.td +++ b/lib/Target/AArch64/AArch64SVEInstrInfo.td @@ -67,6 +67,11 @@ let Predicates = [HasSVE] in { defm SMULH_ZPmZ : sve_int_bin_pred_arit_2<0b010, "smulh">; defm UMULH_ZPmZ : sve_int_bin_pred_arit_2<0b011, "umulh">; + defm SDIV_ZPmZ : sve_int_bin_pred_arit_2_div<0b100, "sdiv">; + defm UDIV_ZPmZ : sve_int_bin_pred_arit_2_div<0b101, "udiv">; + defm SDIVR_ZPmZ : sve_int_bin_pred_arit_2_div<0b110, "sdivr">; + defm UDIVR_ZPmZ : sve_int_bin_pred_arit_2_div<0b111, "udivr">; + defm SXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b000, "sxtb">; defm UXTB_ZPmZ : sve_int_un_pred_arit_0_h<0b001, "uxtb">; defm SXTH_ZPmZ : sve_int_un_pred_arit_0_w<0b010, "sxth">; diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index 783d85c7c1a..c759950daa7 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -1387,6 +1387,12 @@ multiclass sve_int_bin_pred_arit_2 opc, string asm> { def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>; } +// Special case for divides which are not defined for 8b/16b elements. +multiclass sve_int_bin_pred_arit_2_div opc, string asm> { + def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>; + def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>; +} + //===----------------------------------------------------------------------===// // SVE Integer Multiply-Add Group //===----------------------------------------------------------------------===// diff --git a/test/MC/AArch64/SVE/sdiv-diagnostics.s b/test/MC/AArch64/SVE/sdiv-diagnostics.s new file mode 100644 index 00000000000..038b268b8a0 --- /dev/null +++ b/test/MC/AArch64/SVE/sdiv-diagnostics.s @@ -0,0 +1,33 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid element size + +sdiv z0.b, p7/m, z0.b, z1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdiv z0.b, p7/m, z0.b, z1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdiv z0.h, p7/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdiv z0.h, p7/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +sdiv z0.s, p7/m, z1.s, z2.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: sdiv z0.s, p7/m, z1.s, z2.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +sdiv z0.s, p8/m, z0.s, z1.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: sdiv z0.s, p8/m, z0.s, z1.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/sdiv.s b/test/MC/AArch64/SVE/sdiv.s new file mode 100644 index 00000000000..565e9f63cfa --- /dev/null +++ b/test/MC/AArch64/SVE/sdiv.s @@ -0,0 +1,20 @@ +// 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 + +sdiv z0.s, p7/m, z0.s, z31.s +// CHECK-INST: sdiv z0.s, p7/m, z0.s, z31.s +// CHECK-ENCODING: [0xe0,0x1f,0x94,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f 94 04 + +sdiv z0.d, p7/m, z0.d, z31.d +// CHECK-INST: sdiv z0.d, p7/m, z0.d, z31.d +// CHECK-ENCODING: [0xe0,0x1f,0xd4,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f d4 04 diff --git a/test/MC/AArch64/SVE/sdivr-diagnostics.s b/test/MC/AArch64/SVE/sdivr-diagnostics.s new file mode 100644 index 00000000000..6a109d0f093 --- /dev/null +++ b/test/MC/AArch64/SVE/sdivr-diagnostics.s @@ -0,0 +1,33 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid element size + +sdivr z0.b, p7/m, z0.b, z1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdivr z0.b, p7/m, z0.b, z1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sdivr z0.h, p7/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: sdivr z0.h, p7/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +sdivr z0.s, p7/m, z1.s, z2.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: sdivr z0.s, p7/m, z1.s, z2.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +sdivr z0.s, p8/m, z0.s, z1.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: sdivr z0.s, p8/m, z0.s, z1.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/sdivr.s b/test/MC/AArch64/SVE/sdivr.s new file mode 100644 index 00000000000..02c8a3052c0 --- /dev/null +++ b/test/MC/AArch64/SVE/sdivr.s @@ -0,0 +1,20 @@ +// 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 + +sdivr z0.s, p7/m, z0.s, z31.s +// CHECK-INST: sdivr z0.s, p7/m, z0.s, z31.s +// CHECK-ENCODING: [0xe0,0x1f,0x96,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f 96 04 + +sdivr z0.d, p7/m, z0.d, z31.d +// CHECK-INST: sdivr z0.d, p7/m, z0.d, z31.d +// CHECK-ENCODING: [0xe0,0x1f,0xd6,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f d6 04 diff --git a/test/MC/AArch64/SVE/udiv-diagnostics.s b/test/MC/AArch64/SVE/udiv-diagnostics.s new file mode 100644 index 00000000000..8a5f6ec2b73 --- /dev/null +++ b/test/MC/AArch64/SVE/udiv-diagnostics.s @@ -0,0 +1,33 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid element size + +udiv z0.b, p7/m, z0.b, z1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udiv z0.b, p7/m, z0.b, z1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udiv z0.h, p7/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udiv z0.h, p7/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +udiv z0.s, p7/m, z1.s, z2.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: udiv z0.s, p7/m, z1.s, z2.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +udiv z0.s, p8/m, z0.s, z1.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: udiv z0.s, p8/m, z0.s, z1.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/udiv.s b/test/MC/AArch64/SVE/udiv.s new file mode 100644 index 00000000000..7ad8a73cb09 --- /dev/null +++ b/test/MC/AArch64/SVE/udiv.s @@ -0,0 +1,20 @@ +// 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 + +udiv z0.s, p7/m, z0.s, z31.s +// CHECK-INST: udiv z0.s, p7/m, z0.s, z31.s +// CHECK-ENCODING: [0xe0,0x1f,0x95,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f 95 04 + +udiv z0.d, p7/m, z0.d, z31.d +// CHECK-INST: udiv z0.d, p7/m, z0.d, z31.d +// CHECK-ENCODING: [0xe0,0x1f,0xd5,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f d5 04 diff --git a/test/MC/AArch64/SVE/udivr-diagnostics.s b/test/MC/AArch64/SVE/udivr-diagnostics.s new file mode 100644 index 00000000000..07628682e72 --- /dev/null +++ b/test/MC/AArch64/SVE/udivr-diagnostics.s @@ -0,0 +1,33 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s + + +// ------------------------------------------------------------------------- // +// Invalid element size + +udivr z0.b, p7/m, z0.b, z1.b +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udivr z0.b, p7/m, z0.b, z1.b +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +udivr z0.h, p7/m, z0.h, z1.h +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width +// CHECK-NEXT: udivr z0.h, p7/m, z0.h, z1.h +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Tied operands must match + +udivr z0.s, p7/m, z1.s, z2.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register +// CHECK-NEXT: udivr z0.s, p7/m, z1.s, z2.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + + +// ------------------------------------------------------------------------- // +// Invalid predicate + +udivr z0.s, p8/m, z0.s, z1.s +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: restricted predicate has range [0, 7]. +// CHECK-NEXT: udivr z0.s, p8/m, z0.s, z1.s +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/test/MC/AArch64/SVE/udivr.s b/test/MC/AArch64/SVE/udivr.s new file mode 100644 index 00000000000..f09b7f49b8c --- /dev/null +++ b/test/MC/AArch64/SVE/udivr.s @@ -0,0 +1,20 @@ +// 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 + +udivr z0.s, p7/m, z0.s, z31.s +// CHECK-INST: udivr z0.s, p7/m, z0.s, z31.s +// CHECK-ENCODING: [0xe0,0x1f,0x97,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f 97 04 + +udivr z0.d, p7/m, z0.d, z31.d +// CHECK-INST: udivr z0.d, p7/m, z0.d, z31.d +// CHECK-ENCODING: [0xe0,0x1f,0xd7,0x04] +// CHECK-ERROR: instruction requires: sve +// CHECK-UNKNOWN: e0 1f d7 04 -- 2.50.1