Skip to content

Commit

Permalink
[AArch64][SVE2] Asm: support SVE2 Crypto Extensions Group
Browse files Browse the repository at this point in the history
Summary:
Patch adds support for the following instructions:

SVE2 crypto constructive binary operations:
    * SM4EKEY, RAX1

SVE2 crypto destructive binary operations:
    * AESE, AESD, SM4E

SVE2 crypto unary operations:
    * AESMC, AESIMC

AESE, AESD, AESMC and AESIMC are enabled with +sve2-aes.  SM4E and
SM4EKEY are enabled with +sve2-sm4. RAX1 is enabled with +sve2-sha3.

The specification can be found here:
https://developer.arm.com/docs/ddi0602/latest

Reviewed By: SjoerdMeijer

Differential Revision: https://reviews.llvm.org/D62307

llvm-svn: 361797
  • Loading branch information
c-rhodes committed May 28, 2019
1 parent c4ed601 commit 8e91dd7
Show file tree
Hide file tree
Showing 16 changed files with 485 additions and 0 deletions.
20 changes: 20 additions & 0 deletions llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
Expand Up @@ -1298,6 +1298,14 @@ let Predicates = [HasSVE2] in {
}

let Predicates = [HasSVE2AES] in {
// SVE2 crypto destructive binary operations
def AESE_ZZZ_B : sve2_crypto_des_bin_op<0b00, "aese", ZPR8>;
def AESD_ZZZ_B : sve2_crypto_des_bin_op<0b01, "aesd", ZPR8>;

// SVE2 crypto unary operations
def AESMC_ZZ_B : sve2_crypto_unary_op<0b0, "aesmc">;
def AESIMC_ZZ_B : sve2_crypto_unary_op<0b1, "aesimc">;

// PMULLB and PMULLT instructions which operate with 64-bit source and
// 128-bit destination elements are enabled with crypto extensions, similar
// to NEON PMULL2 instruction.
Expand All @@ -1307,6 +1315,18 @@ let Predicates = [HasSVE2AES] in {
ZPR128, ZPR64, ZPR64>;
}

let Predicates = [HasSVE2SM4] in {
// SVE2 crypto constructive binary operations
def SM4EKEY_ZZZ_S : sve2_crypto_cons_bin_op<0b0, "sm4ekey", ZPR32>;
// SVE2 crypto destructive binary operations
def SM4E_ZZZ_S : sve2_crypto_des_bin_op<0b10, "sm4e", ZPR32>;
}

let Predicates = [HasSVE2SHA3] in {
// SVE2 crypto constructive binary operations
def RAX1_ZZZ_D : sve2_crypto_cons_bin_op<0b1, "rax1", ZPR64>;
}

let Predicates = [HasSVE2BitPerm] in {
// SVE2 bitwise permute
defm BEXT_ZZZ : sve2_misc_bitwise<0b1100, "bext">;
Expand Down
51 changes: 51 additions & 0 deletions llvm/lib/Target/AArch64/SVEInstrFormats.td
Expand Up @@ -5286,3 +5286,54 @@ multiclass sve2_hist_gen_vector<string asm> {
def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
}

//===----------------------------------------------------------------------===//
// SVE2 Crypto Extensions Group
//===----------------------------------------------------------------------===//

class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
asm, "\t$Zd, $Zn, $Zm",
"",
[]>, Sched<[]> {
bits<5> Zd;
bits<5> Zn;
bits<5> Zm;
let Inst{31-21} = 0b01000101001;
let Inst{20-16} = Zm;
let Inst{15-11} = 0b11110;
let Inst{10} = opc;
let Inst{9-5} = Zn;
let Inst{4-0} = Zd;
}

class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
asm, "\t$Zdn, $_Zdn, $Zm",
"",
[]>, Sched<[]> {
bits<5> Zdn;
bits<5> Zm;
let Inst{31-17} = 0b010001010010001;
let Inst{16} = opc{1};
let Inst{15-11} = 0b11100;
let Inst{10} = opc{0};
let Inst{9-5} = Zm;
let Inst{4-0} = Zdn;

let Constraints = "$Zdn = $_Zdn";
}

class sve2_crypto_unary_op<bit opc, string asm>
: I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn),
asm, "\t$Zdn, $_Zdn",
"",
[]>, Sched<[]> {
bits<5> Zdn;
let Inst{31-11} = 0b010001010010000011100;
let Inst{10} = opc;
let Inst{9-5} = 0b00000;
let Inst{4-0} = Zdn;

let Constraints = "$Zdn = $_Zdn";
}
45 changes: 45 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesd-diagnostics.s
@@ -0,0 +1,45 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// Source and Destination Registers must match

aesd z0.b, z1.b, z2.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
// CHECK-NEXT: aesd z0.b, z1.b, z2.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid element width

aesd z0.h, z0.h, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesd z0.h, z0.h, z0.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesd z0.s, z0.s, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesd z0.s, z0.s, z0.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesd z0.d, z0.d, z0.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesd z0.d, z0.d, z0.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Negative tests for instructions that are incompatible with movprfx

movprfx z0.b, p0/z, z7.b
aesd z0.b, z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesd z0.b, z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

movprfx z0, z7
aesd z0.b, z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesd z0.b, z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
15 changes: 15 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesd.s
@@ -0,0 +1,15 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes < %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=+sve2-aes < %s \
// RUN: | llvm-objdump -d -mattr=+sve2-aes - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2-aes < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN


aesd z0.b, z0.b, z31.b
// CHECK-INST: aesd z0.b, z0.b, z31.b
// CHECK-ENCODING: [0xe0,0xe7,0x22,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: e0 e7 22 45 <unknown>
45 changes: 45 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aese-diagnostics.s
@@ -0,0 +1,45 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// Source and Destination Registers must match

aese z0.b, z1.b, z2.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
// CHECK-NEXT: aese z0.b, z1.b, z2.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid element width

aese z0.h, z0.h, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aese z0.h, z0.h, z0.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aese z0.s, z0.s, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aese z0.s, z0.s, z0.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aese z0.d, z0.d, z0.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aese z0.d, z0.d, z0.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Negative tests for instructions that are incompatible with movprfx

movprfx z0.b, p0/z, z7.b
aese z0.b, z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aese z0.b, z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

movprfx z0, z7
aese z0.b, z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aese z0.b, z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
15 changes: 15 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aese.s
@@ -0,0 +1,15 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes < %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=+sve2-aes < %s \
// RUN: | llvm-objdump -d -mattr=+sve2-aes - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2-aes < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN


aese z0.b, z0.b, z31.b
// CHECK-INST: aese z0.b, z0.b, z31.b
// CHECK-ENCODING: [0xe0,0xe3,0x22,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: e0 e3 22 45 <unknown>
45 changes: 45 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesimc-diagnostics.s
@@ -0,0 +1,45 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// Source and Destination Registers must match

aesimc z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
// CHECK-NEXT: aesimc z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid element width

aesimc z0.h, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesimc z0.h, z0.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesimc z0.s, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesimc z0.s, z0.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesimc z0.d, z0.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesimc z0.d, z0.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Negative tests for instructions that are incompatible with movprfx

movprfx z0.b, p0/z, z7.b
aesimc z0.b, z0.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesimc z0.b, z0.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

movprfx z0, z7
aesimc z0.b, z0.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesimc z0.b, z0.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
21 changes: 21 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesimc.s
@@ -0,0 +1,21 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes < %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=+sve2-aes < %s \
// RUN: | llvm-objdump -d -mattr=+sve2-aes - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2-aes < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN


aesimc z0.b, z0.b
// CHECK-INST: aesimc z0.b, z0.b
// CHECK-ENCODING: [0x00,0xe4,0x20,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: 00 e4 20 45 <unknown>

aesimc z31.b, z31.b
// CHECK-INST: aesimc z31.b, z31.b
// CHECK-ENCODING: [0x1f,0xe4,0x20,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: 1f e4 20 45 <unknown>
45 changes: 45 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesmc-diagnostics.s
@@ -0,0 +1,45 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// Source and Destination Registers must match

aesmc z0.b, z1.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register
// CHECK-NEXT: aesmc z0.b, z1.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Invalid element width

aesmc z0.h, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesmc z0.h, z0.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesmc z0.s, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesmc z0.s, z0.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

aesmc z0.d, z0.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: aesmc z0.d, z0.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Negative tests for instructions that are incompatible with movprfx

movprfx z0.b, p0/z, z7.b
aesmc z0.b, z0.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesmc z0.b, z0.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

movprfx z0, z7
aesmc z0.b, z0.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: aesmc z0.b, z0.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
21 changes: 21 additions & 0 deletions llvm/test/MC/AArch64/SVE2/aesmc.s
@@ -0,0 +1,21 @@
// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-aes < %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=+sve2-aes < %s \
// RUN: | llvm-objdump -d -mattr=+sve2-aes - | FileCheck %s --check-prefix=CHECK-INST
// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sve2-aes < %s \
// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN


aesmc z0.b, z0.b
// CHECK-INST: aesmc z0.b, z0.b
// CHECK-ENCODING: [0x00,0xe0,0x20,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: 00 e0 20 45 <unknown>

aesmc z31.b, z31.b
// CHECK-INST: aesmc z31.b, z31.b
// CHECK-ENCODING: [0x1f,0xe0,0x20,0x45]
// CHECK-ERROR: instruction requires: sve2-aes
// CHECK-UNKNOWN: 1f e0 20 45 <unknown>
36 changes: 36 additions & 0 deletions llvm/test/MC/AArch64/SVE2/rax1-diagnostics.s
@@ -0,0 +1,36 @@
// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sve2-sha3 2>&1 < %s| FileCheck %s


// --------------------------------------------------------------------------//
// Invalid element width

rax1 z0.b, z0.b, z0.b
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: rax1 z0.b, z0.b, z0.b
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

rax1 z0.h, z0.h, z0.h
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: rax1 z0.h, z0.h, z0.h
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

rax1 z0.s, z0.s, z0.s
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
// CHECK-NEXT: rax1 z0.s, z0.s, z0.s
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:


// --------------------------------------------------------------------------//
// Negative tests for instructions that are incompatible with movprfx

movprfx z0.d, p0/z, z7.d
rax1 z0.d, z1.d, z2.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: rax1 z0.d, z1.d, z2.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

movprfx z0, z7
rax1 z0.d, z1.d, z2.d
// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a movprfx, suggest replacing movprfx with mov
// CHECK-NEXT: rax1 z0.d, z1.d, z2.d
// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:

0 comments on commit 8e91dd7

Please sign in to comment.