Skip to content

Commit

Permalink
[AArch64][SVE] Asm: Support for saturing ADD/SUB instructions.
Browse files Browse the repository at this point in the history
The variants added are:
    signed Saturating ADD/SUB (immediate)  e.g. sqadd z0.h, z0.h, #42
  unsigned Saturating ADD/SUB (immediate)  e.g. uqadd z0.h, z0.h, #42
    signed Saturating ADD/SUB (vectors)    e.g. sqadd z0.h, z0.h, z1.h
  unsigned Saturating ADD/SUB (vectors)    e.g. uqadd z0.h, z0.h, z1.h

llvm-svn: 336186
  • Loading branch information
sdesmalen-arm committed Jul 3, 2018
1 parent 226e611 commit 7fc8543
Show file tree
Hide file tree
Showing 9 changed files with 828 additions and 0 deletions.
8 changes: 8 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Expand Up @@ -14,6 +14,10 @@
let Predicates = [HasSVE] in {
defm ADD_ZZZ : sve_int_bin_cons_arit_0<0b000, "add">;
defm SUB_ZZZ : sve_int_bin_cons_arit_0<0b001, "sub">;
defm SQADD_ZZZ : sve_int_bin_cons_arit_0<0b100, "sqadd">;
defm UQADD_ZZZ : sve_int_bin_cons_arit_0<0b101, "uqadd">;
defm SQSUB_ZZZ : sve_int_bin_cons_arit_0<0b110, "sqsub">;
defm UQSUB_ZZZ : sve_int_bin_cons_arit_0<0b111, "uqsub">;

def AND_ZZZ : sve_int_bin_cons_log<0b00, "and">;
def ORR_ZZZ : sve_int_bin_cons_log<0b01, "orr">;
Expand All @@ -30,6 +34,10 @@ let Predicates = [HasSVE] in {

defm ADD_ZI : sve_int_arith_imm0<0b000, "add">;
defm SUB_ZI : sve_int_arith_imm0<0b001, "sub">;
defm SQADD_ZI : sve_int_arith_imm0<0b100, "sqadd">;
defm UQADD_ZI : sve_int_arith_imm0<0b101, "uqadd">;
defm SQSUB_ZI : sve_int_arith_imm0<0b110, "sqsub">;
defm UQSUB_ZI : sve_int_arith_imm0<0b111, "uqsub">;

defm ORR_ZI : sve_int_log_imm<0b00, "orr", "orn">;
defm EOR_ZI : sve_int_log_imm<0b01, "eor", "eon">;
Expand Down
88 changes: 88 additions & 0 deletions llvm/test/MC/AArch64/SVE/sqadd-diagnostics.s
@@ -0,0 +1,88 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s

// Register z32 does not exist.
sqadd z22.h, z10.h, z32.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: sqadd z22.h, z10.h, z32.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Invalid element kind.
sqadd z20.h, z2.h, z31.x
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: sqadd z20.h, z2.h, z31.x
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Element size specifiers should match.
sqadd z27.h, z11.h, z27.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: sqadd z27.h, z11.h, z27.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid immediates

sqadd z0.b, z0.b, #0, lsl #8 // #0, lsl #8 is not valid for .b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqadd z0.b, z0.b, #0, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.b, z0.b, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqadd z0.b, z0.b, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.b, z0.b, #1, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqadd z0.b, z0.b, #1, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.b, z0.b, #256
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqadd z0.b, z0.b, #256
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.h, z0.h, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.h, z0.h, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.h, z0.h, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.h, z0.h, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.h, z0.h, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.h, z0.h, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.s, z0.s, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.s, z0.s, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.s, z0.s, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.s, z0.s, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.s, z0.s, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.s, z0.s, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.d, z0.d, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.d, z0.d, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.d, z0.d, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.d, z0.d, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqadd z0.d, z0.d, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqadd z0.d, z0.d, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
117 changes: 117 additions & 0 deletions llvm/test/MC/AArch64/SVE/sqadd.s
@@ -0,0 +1,117 @@
// 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


sqadd z0.b, z0.b, z0.b
// CHECK-INST: sqadd z0.b, z0.b, z0.b
// CHECK-ENCODING: [0x00,0x10,0x20,0x04]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 10 20 04 <unknown>

sqadd z0.h, z0.h, z0.h
// CHECK-INST: sqadd z0.h, z0.h, z0.h
// CHECK-ENCODING: [0x00,0x10,0x60,0x04]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 10 60 04 <unknown>

sqadd z0.s, z0.s, z0.s
// CHECK-INST: sqadd z0.s, z0.s, z0.s
// CHECK-ENCODING: [0x00,0x10,0xa0,0x04]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 10 a0 04 <unknown>

sqadd z0.d, z0.d, z0.d
// CHECK-INST: sqadd z0.d, z0.d, z0.d
// CHECK-ENCODING: [0x00,0x10,0xe0,0x04]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 10 e0 04 <unknown>

sqadd z0.b, z0.b, #0
// CHECK-INST: sqadd z0.b, z0.b, #0
// CHECK-ENCODING: [0x00,0xc0,0x24,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 c0 24 25 <unknown>

sqadd z31.b, z31.b, #255
// CHECK-INST: sqadd z31.b, z31.b, #255
// CHECK-ENCODING: [0xff,0xdf,0x24,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff df 24 25 <unknown>

sqadd z0.h, z0.h, #0
// CHECK-INST: sqadd z0.h, z0.h, #0
// CHECK-ENCODING: [0x00,0xc0,0x64,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 c0 64 25 <unknown>

sqadd z0.h, z0.h, #0, lsl #8
// CHECK-INST: sqadd z0.h, z0.h, #0, lsl #8
// CHECK-ENCODING: [0x00,0xe0,0x64,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 e0 64 25 <unknown>

sqadd z31.h, z31.h, #255, lsl #8
// CHECK-INST: sqadd z31.h, z31.h, #65280
// CHECK-ENCODING: [0xff,0xff,0x64,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff 64 25 <unknown>

sqadd z31.h, z31.h, #65280
// CHECK-INST: sqadd z31.h, z31.h, #65280
// CHECK-ENCODING: [0xff,0xff,0x64,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff 64 25 <unknown>

sqadd z0.s, z0.s, #0
// CHECK-INST: sqadd z0.s, z0.s, #0
// CHECK-ENCODING: [0x00,0xc0,0xa4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 c0 a4 25 <unknown>

sqadd z0.s, z0.s, #0, lsl #8
// CHECK-INST: sqadd z0.s, z0.s, #0, lsl #8
// CHECK-ENCODING: [0x00,0xe0,0xa4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 e0 a4 25 <unknown>

sqadd z31.s, z31.s, #255, lsl #8
// CHECK-INST: sqadd z31.s, z31.s, #65280
// CHECK-ENCODING: [0xff,0xff,0xa4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff a4 25 <unknown>

sqadd z31.s, z31.s, #65280
// CHECK-INST: sqadd z31.s, z31.s, #65280
// CHECK-ENCODING: [0xff,0xff,0xa4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff a4 25 <unknown>

sqadd z0.d, z0.d, #0
// CHECK-INST: sqadd z0.d, z0.d, #0
// CHECK-ENCODING: [0x00,0xc0,0xe4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 c0 e4 25 <unknown>

sqadd z0.d, z0.d, #0, lsl #8
// CHECK-INST: sqadd z0.d, z0.d, #0, lsl #8
// CHECK-ENCODING: [0x00,0xe0,0xe4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: 00 e0 e4 25 <unknown>

sqadd z31.d, z31.d, #255, lsl #8
// CHECK-INST: sqadd z31.d, z31.d, #65280
// CHECK-ENCODING: [0xff,0xff,0xe4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff e4 25 <unknown>

sqadd z31.d, z31.d, #65280
// CHECK-INST: sqadd z31.d, z31.d, #65280
// CHECK-ENCODING: [0xff,0xff,0xe4,0x25]
// CHECK-ERROR: instruction requires: sve
// CHECK-UNKNOWN: ff ff e4 25 <unknown>
88 changes: 88 additions & 0 deletions llvm/test/MC/AArch64/SVE/sqsub-diagnostics.s
@@ -0,0 +1,88 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve 2>&1 < %s| FileCheck %s

// Register z32 does not exist.
sqsub z22.h, z10.h, z32.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand
// CHECK-NEXT: sqsub z22.h, z10.h, z32.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Invalid element kind.
sqsub z20.h, z2.h, z31.x
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid vector kind qualifier
// CHECK-NEXT: sqsub z20.h, z2.h, z31.x
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

// Element size specifiers should match.
sqsub z27.h, z11.h, z27.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: sqsub z27.h, z11.h, z27.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid immediates

sqsub z0.b, z0.b, #0, lsl #8 // #0, lsl #8 is not valid for .b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqsub z0.b, z0.b, #0, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.b, z0.b, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqsub z0.b, z0.b, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.b, z0.b, #1, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqsub z0.b, z0.b, #1, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.b, z0.b, #256
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] with a shift amount of 0
// CHECK-NEXT: sqsub z0.b, z0.b, #256
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.h, z0.h, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.h, z0.h, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.h, z0.h, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.h, z0.h, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.h, z0.h, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.h, z0.h, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.s, z0.s, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.s, z0.s, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.s, z0.s, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.s, z0.s, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.s, z0.s, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.s, z0.s, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.d, z0.d, #-1
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.d, z0.d, #-1
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.d, z0.d, #256, lsl #8
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.d, z0.d, #256, lsl #8
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

sqsub z0.d, z0.d, #65536
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 255] or a multiple of 256 in range [256, 65280]
// CHECK-NEXT: sqsub z0.d, z0.d, #65536
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

0 comments on commit 7fc8543

Please sign in to comment.