From dc837e3f1f39aaff0f7c566602d03203d4b94fe4 Mon Sep 17 00:00:00 2001 From: Oliver Stannard Date: Thu, 27 Sep 2018 14:01:40 +0000 Subject: [PATCH] [AArch64][v8.5A] Add Armv8.5-A random number instructions This adds two new system registers, used to generate random numbers. This is an optional extension to v8.5-A, and will be controlled by the "+rng" modifier of the -march= and -mcpu= options. Patch by Pablo Barrio! Differential revision: https://reviews.llvm.org/D52481 llvm-svn: 343217 --- .../llvm/Support/AArch64TargetParser.def | 1 + llvm/include/llvm/Support/TargetParser.h | 1 + llvm/lib/Target/AArch64/AArch64.td | 3 +++ llvm/lib/Target/AArch64/AArch64Subtarget.h | 2 ++ .../lib/Target/AArch64/AArch64SystemOperands.td | 7 +++++++ llvm/test/MC/AArch64/armv8.5a-rand-error.s | 17 +++++++++++++++++ llvm/test/MC/AArch64/armv8.5a-rand.s | 14 ++++++++++++++ .../MC/Disassembler/AArch64/armv8.5a-rand.txt | 12 ++++++++++++ llvm/unittests/Support/TargetParserTest.cpp | 3 ++- 9 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 llvm/test/MC/AArch64/armv8.5a-rand-error.s create mode 100644 llvm/test/MC/AArch64/armv8.5a-rand.s create mode 100644 llvm/test/MC/Disassembler/AArch64/armv8.5a-rand.txt diff --git a/llvm/include/llvm/Support/AArch64TargetParser.def b/llvm/include/llvm/Support/AArch64TargetParser.def index 7ca4efa9ab40..625d7a42f43d 100644 --- a/llvm/include/llvm/Support/AArch64TargetParser.def +++ b/llvm/include/llvm/Support/AArch64TargetParser.def @@ -70,6 +70,7 @@ AARCH64_ARCH_EXT_NAME("profile", AArch64::AEK_PROFILE, "+spe", "-spe") AARCH64_ARCH_EXT_NAME("ras", AArch64::AEK_RAS, "+ras", "-ras") AARCH64_ARCH_EXT_NAME("sve", AArch64::AEK_SVE, "+sve", "-sve") AARCH64_ARCH_EXT_NAME("rcpc", AArch64::AEK_RCPC, "+rcpc", "-rcpc") +AARCH64_ARCH_EXT_NAME("rng", AArch64::AEK_RAND, "+rand", "-rand") #undef AARCH64_ARCH_EXT_NAME #ifndef AARCH64_CPU_NAME diff --git a/llvm/include/llvm/Support/TargetParser.h b/llvm/include/llvm/Support/TargetParser.h index f216213a4805..51ff9207c250 100644 --- a/llvm/include/llvm/Support/TargetParser.h +++ b/llvm/include/llvm/Support/TargetParser.h @@ -180,6 +180,7 @@ enum ArchExtKind : unsigned { AEK_SHA2 = 1 << 15, AEK_AES = 1 << 16, AEK_FP16FML = 1 << 17, + AEK_RAND = 1 << 18, }; StringRef getCanonicalArchName(StringRef Arch); diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td index c6a41d4ce554..ceeebc92d04c 100644 --- a/llvm/lib/Target/AArch64/AArch64.td +++ b/llvm/lib/Target/AArch64/AArch64.td @@ -220,6 +220,9 @@ def FeaturePredCtrl : SubtargetFeature<"predctrl", "HasPredCtrl", "true", def FeatureCacheDeepPersist : SubtargetFeature<"ccdp", "HasCCDP", "true", "Enable Cache Clean to Point of Deep Persistence" >; +def FeatureRandGen : SubtargetFeature<"rand", "HasRandGen", + "true", "Enable Random Number generation instructions" >; + //===----------------------------------------------------------------------===// // Architectures. // diff --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h index d0be93ec79e7..07055f269c9d 100644 --- a/llvm/lib/Target/AArch64/AArch64Subtarget.h +++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h @@ -100,6 +100,7 @@ protected: bool HasSpecCtrl = false; bool HasPredCtrl = false; bool HasCCDP = false; + bool HasRandGen = false; // HasZeroCycleRegMove - Has zero-cycle register mov instructions. bool HasZeroCycleRegMove = false; @@ -318,6 +319,7 @@ public: bool hasSpecCtrl() { return HasSpecCtrl; } bool hasPredCtrl() { return HasPredCtrl; } bool hasCCDP() { return HasCCDP; } + bool hasRandGen() { return HasRandGen; } bool isLittleEndian() const { return IsLittle; } diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td index c6d29acd9f19..f0f309878bd5 100644 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -614,6 +614,13 @@ def : ROSysReg<"ERRIDR_EL1", 0b11, 0b000, 0b0101, 0b0011, 0b000>; def : ROSysReg<"ERXFR_EL1", 0b11, 0b000, 0b0101, 0b0100, 0b000>; } +// v8.5a "random number" registers +// Op0 Op1 CRn CRm Op2 +let Requires = [{ {AArch64::FeatureRandGen} }] in { +def : ROSysReg<"RNDR", 0b11, 0b011, 0b0010, 0b0100, 0b000>; +def : ROSysReg<"RNDRRS", 0b11, 0b011, 0b0010, 0b0100, 0b001>; +} + //===---------------------- // Write-only regs //===---------------------- diff --git a/llvm/test/MC/AArch64/armv8.5a-rand-error.s b/llvm/test/MC/AArch64/armv8.5a-rand-error.s new file mode 100644 index 000000000000..c4cca8a87b2a --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.5a-rand-error.s @@ -0,0 +1,17 @@ +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+rand < %s 2>&1| FileCheck %s + +mrs rndr +mrs rndrrs + +// CHECK: invalid operand for instruction +// CHECK-NEXT: rndr +// CHECK: invalid operand for instruction +// CHECK-NEXT: rndrrs + +mrs rndr, x0 +mrs rndrrs, x1 + +// CHECK: invalid operand for instruction +// CHECK-NEXT: rndr +// CHECK: invalid operand for instruction +// CHECK-NEXT: rndrrs diff --git a/llvm/test/MC/AArch64/armv8.5a-rand.s b/llvm/test/MC/AArch64/armv8.5a-rand.s new file mode 100644 index 000000000000..770990b437e4 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.5a-rand.s @@ -0,0 +1,14 @@ +// RUN: llvm-mc -triple aarch64 -show-encoding -mattr=+rand < %s | FileCheck %s +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=+v8.5a < %s 2>&1 | FileCheck %s --check-prefix=NORAND +// RUN: not llvm-mc -triple aarch64 -show-encoding -mattr=-rand < %s 2>&1 | FileCheck %s --check-prefix=NORAND + +mrs x0, rndr +mrs x1, rndrrs + +// CHECK: mrs x0, RNDR // encoding: [0x00,0x24,0x3b,0xd5] +// CHECK: mrs x1, RNDRRS // encoding: [0x21,0x24,0x3b,0xd5] + +// NORAND: expected readable system register +// NORAND-NEXT: rndr +// NORAND: expected readable system register +// NORAND-NEXT: rndrrs diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.5a-rand.txt b/llvm/test/MC/Disassembler/AArch64/armv8.5a-rand.txt new file mode 100644 index 000000000000..712ed019789d --- /dev/null +++ b/llvm/test/MC/Disassembler/AArch64/armv8.5a-rand.txt @@ -0,0 +1,12 @@ +# RUN: llvm-mc -triple=aarch64 -mattr=+rand -disassemble < %s | FileCheck %s +# RUN: llvm-mc -triple=aarch64 -mattr=+v8.5a -disassemble < %s | FileCheck %s --check-prefix=NORAND +# RUN: llvm-mc -triple=aarch64 -mattr=-rand -disassemble < %s | FileCheck %s --check-prefix=NORAND + +[0x00,0x24,0x3b,0xd5] +[0x21,0x24,0x3b,0xd5] + +# CHECK: mrs x0, RNDR +# CHECK: mrs x1, RNDRRS + +# NORAND: mrs x0, S3_3_C2_C4_0 +# NORAND: mrs x1, S3_3_C2_C4_1 diff --git a/llvm/unittests/Support/TargetParserTest.cpp b/llvm/unittests/Support/TargetParserTest.cpp index d4996fa8e22c..f67d84ebd1c6 100644 --- a/llvm/unittests/Support/TargetParserTest.cpp +++ b/llvm/unittests/Support/TargetParserTest.cpp @@ -967,7 +967,8 @@ TEST(TargetParserTest, AArch64ArchExtFeature) { {"rdm", "nordm", "+rdm", "-rdm"}, {"sve", "nosve", "+sve", "-sve"}, {"dotprod", "nodotprod", "+dotprod", "-dotprod"}, - {"rcpc", "norcpc", "+rcpc", "-rcpc" }}; + {"rcpc", "norcpc", "+rcpc", "-rcpc" }, + {"rng", "norng", "+rand", "-rand"}}; for (unsigned i = 0; i < array_lengthof(ArchExt); i++) { EXPECT_EQ(StringRef(ArchExt[i][2]),