Index: llvm/trunk/include/llvm/Support/AArch64TargetParser.def =================================================================== --- llvm/trunk/include/llvm/Support/AArch64TargetParser.def +++ llvm/trunk/include/llvm/Support/AArch64TargetParser.def @@ -70,6 +70,7 @@ 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 Index: llvm/trunk/include/llvm/Support/TargetParser.h =================================================================== --- llvm/trunk/include/llvm/Support/TargetParser.h +++ llvm/trunk/include/llvm/Support/TargetParser.h @@ -180,6 +180,7 @@ AEK_SHA2 = 1 << 15, AEK_AES = 1 << 16, AEK_FP16FML = 1 << 17, + AEK_RAND = 1 << 18, }; StringRef getCanonicalArchName(StringRef Arch); Index: llvm/trunk/lib/Target/AArch64/AArch64.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64.td +++ llvm/trunk/lib/Target/AArch64/AArch64.td @@ -220,6 +220,9 @@ 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. // Index: llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h +++ llvm/trunk/lib/Target/AArch64/AArch64Subtarget.h @@ -100,6 +100,7 @@ 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 @@ bool hasSpecCtrl() { return HasSpecCtrl; } bool hasPredCtrl() { return HasPredCtrl; } bool hasCCDP() { return HasCCDP; } + bool hasRandGen() { return HasRandGen; } bool isLittleEndian() const { return IsLittle; } Index: llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td +++ llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td @@ -614,6 +614,13 @@ 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 //===---------------------- Index: llvm/trunk/test/MC/AArch64/armv8.5a-rand-error.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.5a-rand-error.s +++ llvm/trunk/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 Index: llvm/trunk/test/MC/AArch64/armv8.5a-rand.s =================================================================== --- llvm/trunk/test/MC/AArch64/armv8.5a-rand.s +++ llvm/trunk/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 Index: llvm/trunk/test/MC/Disassembler/AArch64/armv8.5a-rand.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/AArch64/armv8.5a-rand.txt +++ llvm/trunk/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 Index: llvm/trunk/unittests/Support/TargetParserTest.cpp =================================================================== --- llvm/trunk/unittests/Support/TargetParserTest.cpp +++ llvm/trunk/unittests/Support/TargetParserTest.cpp @@ -967,7 +967,8 @@ {"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]),