[llvm] e29d8fb - [RISCV] Initially support the K-extension instructions on the LLVM MC layer

Wu Xinlong via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 23 22:45:48 PST 2022


Author: Wu Xinlong
Date: 2022-01-24T14:45:35+08:00
New Revision: e29d8fb16978c463c7ea08cb255f5a97eca16d36

URL: https://github.com/llvm/llvm-project/commit/e29d8fb16978c463c7ea08cb255f5a97eca16d36
DIFF: https://github.com/llvm/llvm-project/commit/e29d8fb16978c463c7ea08cb255f5a97eca16d36.diff

LOG: [RISCV] Initially support the K-extension instructions on the LLVM MC layer

This commit is currently implementing supports for scalar cryptography extension for LLVM according to version v1.0.0 of [K Ext specification](https://github.com/riscv/riscv-crypto/releases)(scala crypto has been ratified already). Currently, we are implementing the MC (Machine Code) layer of his extension and the majority of work is done under `llvm/lib/Target/RISCV` directory. There are also some test files in `llvm/test/MC/RISCV` directory.

Remove the subfeature of Zbk* which conflict with b extensions to reduce the size of the patch.
(Zbk* will be resubmit after this patch has been merged)

**Co-author:**@ksyx & @VincentWu & @lihongliang & @achieveartificialintelligence

Reviewed By: craig.topper

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

Added: 
    llvm/lib/Target/RISCV/RISCVInstrInfoZk.td
    llvm/test/MC/RISCV/rv32zknd-only-invalid.s
    llvm/test/MC/RISCV/rv32zknd-only-valid.s
    llvm/test/MC/RISCV/rv32zkne-only-invalid.s
    llvm/test/MC/RISCV/rv32zkne-only-valid.s
    llvm/test/MC/RISCV/rv32zknh-only-valid.s
    llvm/test/MC/RISCV/rv32zknh-valid.s
    llvm/test/MC/RISCV/rv32zksed-invalid.s
    llvm/test/MC/RISCV/rv32zksed-valid.s
    llvm/test/MC/RISCV/rv32zksh-valid.s
    llvm/test/MC/RISCV/rv64zknd-only-valid.s
    llvm/test/MC/RISCV/rv64zkne-only-invalid.s
    llvm/test/MC/RISCV/rv64zkne-only-valid.s
    llvm/test/MC/RISCV/rv64zknh-only-valid.s
    llvm/test/MC/RISCV/rv64zksed-invalid.s
    llvm/test/MC/RISCV/rvk-user-csr-name.s

Modified: 
    llvm/lib/Support/RISCVISAInfo.cpp
    llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
    llvm/lib/Target/RISCV/RISCV.td
    llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
    llvm/lib/Target/RISCV/RISCVInstrInfo.td
    llvm/lib/Target/RISCV/RISCVSchedRocket.td
    llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
    llvm/lib/Target/RISCV/RISCVSubtarget.h
    llvm/lib/Target/RISCV/RISCVSystemOperands.td
    llvm/test/CodeGen/RISCV/attributes.ll
    llvm/test/MC/RISCV/attribute-arch.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index f8a17f7440f6a..c34817920e1bc 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -58,6 +58,16 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
 
     {"zbkb", RISCVExtensionVersion{1, 0}},
     {"zbkc", RISCVExtensionVersion{1, 0}},
+    {"zknd", RISCVExtensionVersion{1, 0}},
+    {"zkne", RISCVExtensionVersion{1, 0}},
+    {"zknh", RISCVExtensionVersion{1, 0}},
+    {"zksed", RISCVExtensionVersion{1, 0}},
+    {"zksh", RISCVExtensionVersion{1, 0}},
+    {"zkr", RISCVExtensionVersion{1, 0}},
+    {"zkn", RISCVExtensionVersion{1, 0}},
+    {"zks", RISCVExtensionVersion{1, 0}},
+    {"zkt", RISCVExtensionVersion{1, 0}},
+    {"zk", RISCVExtensionVersion{1, 0}},
 
     {"v", RISCVExtensionVersion{1, 0}},
     {"zvl32b", RISCVExtensionVersion{1, 0}},
@@ -751,6 +761,9 @@ static const char *ImpliedExtsZvl512b[] = {"zvl256b"};
 static const char *ImpliedExtsZvl256b[] = {"zvl128b"};
 static const char *ImpliedExtsZvl128b[] = {"zvl64b"};
 static const char *ImpliedExtsZvl64b[] = {"zvl32b"};
+static const char *ImpliedExtsZk[] = {"zkn", "zkt", "zkr"};
+static const char *ImpliedExtsZkn[] = {"zbkb", "zbkc", "zkne", "zknd", "zknh"};
+static const char *ImpliedExtsZks[] = {"zbkb", "zbkc", "zksed", "zksh"};
 
 struct ImpliedExtsEntry {
   StringLiteral Name;
@@ -766,6 +779,9 @@ struct ImpliedExtsEntry {
 static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"v"}, {ImpliedExtsV}},
     {{"zfh"}, {ImpliedExtsZfh}},
+    {{"zk"}, {ImpliedExtsZk}},
+    {{"zkn"}, {ImpliedExtsZkn}},
+    {{"zks"}, {ImpliedExtsZks}},
     {{"zve32f"}, {ImpliedExtsZve32f}},
     {{"zve32x"}, {ImpliedExtsZve32x}},
     {{"zve64d"}, {ImpliedExtsZve64d}},

diff  --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 1c8ed0d60d8e8..a2ea34fe11c73 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -566,6 +566,16 @@ struct RISCVOperand : public MCParsedAsmOperand {
     return IsConstantImm && isUInt<7>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
   }
 
+  bool isRnumArg() const {
+    int64_t Imm;
+    RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+    if (!isImm())
+      return false;
+    bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+    return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(10) &&
+           VK == RISCVMCExpr::VK_RISCV_None;
+  }
+
   bool isSImm5() const {
     if (!isImm())
       return false;
@@ -1240,6 +1250,9 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
                                       (1 << 4),
                                       "immediate must be in the range");
   }
+  case Match_InvalidRnumArg: {
+    return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
+  }
   }
 
   llvm_unreachable("Unknown match type detected!");

diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index 9cfd36745f46f..72d91b1044d65 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -192,6 +192,7 @@ enum OperandType : unsigned {
   OPERAND_UIMM20,
   OPERAND_UIMMLOG2XLEN,
   OPERAND_LAST_RISCV_IMM = OPERAND_UIMMLOG2XLEN,
+  OPERAND_RVKRNUM,
   // Operand is either a register or uimm5, this is used by V extension pseudo
   // instructions to represent a value that be passed as AVL to either vsetvli
   // or vsetivli.

diff  --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td
index dea042348d4db..72caa88104e85 100644
--- a/llvm/lib/Target/RISCV/RISCV.td
+++ b/llvm/lib/Target/RISCV/RISCV.td
@@ -178,6 +178,84 @@ def HasStdExtZbcOrZbkc
                                    "'Zbc' (Carry-Less 'B' Instructions) or "
                                    "'Zbkc' (Carry-less multiply instructions for Cryptography)">;
 
+def FeatureStdExtZknd
+    : SubtargetFeature<"zknd", "HasStdExtZknd", "true",
+                       "'Zknd' (NIST Suite: AES Decryption)">;
+def HasStdExtZknd : Predicate<"Subtarget->hasStdExtZknd()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZknd),
+                             "'Zknd' (NIST Suite: AES Decryption)">;
+
+def FeatureStdExtZkne
+    : SubtargetFeature<"zkne", "HasStdExtZkne", "true",
+                       "'Zkne' (NIST Suite: AES Encryption)">;
+def HasStdExtZkne : Predicate<"Subtarget->hasStdExtZkne()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZkne),
+                             "'Zkne' (NIST Suite: AES Encryption)">;
+
+// Some instructions belong to both Zknd and Zkne subextensions.
+// They should be enabled if either has been specified.
+def HasStdExtZkndOrZkne
+    : Predicate<"Subtarget->hasStdExtZknd() || Subtarget->hasStdExtZkne()">,
+                AssemblerPredicate<(any_of FeatureStdExtZknd, FeatureStdExtZkne),
+                                   "'Zknd' (NIST Suite: AES Decryption) or "
+                                   "'Zkne' (NIST Suite: AES Encryption)">;
+
+def FeatureStdExtZknh
+    : SubtargetFeature<"zknh", "HasStdExtZknh", "true",
+                       "'Zknh' (NIST Suite: Hash Function Instructions)">;
+def HasStdExtZknh : Predicate<"Subtarget->hasStdExtZknh()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZknh),
+                             "'Zknh' (NIST Suite: Hash Function Instructions)">;
+
+def FeatureStdExtZksed
+    : SubtargetFeature<"zksed", "HasStdExtZksed", "true",
+                       "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)">;
+def HasStdExtZksed : Predicate<"Subtarget->hasStdExtZksed()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZksed),
+                             "'Zksed' (ShangMi Suite: SM4 Block Cipher Instructions)">;
+
+def FeatureStdExtZksh
+    : SubtargetFeature<"zksh", "HasStdExtZksh", "true",
+                       "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)">;
+def HasStdExtZksh : Predicate<"Subtarget->hasStdExtZksh()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZksh),
+                             "'Zksh' (ShangMi Suite: SM3 Hash Function Instructions)">;
+
+def FeatureStdExtZkr
+    : SubtargetFeature<"zkr", "HasStdExtZkr", "true",
+                       "'Zkr' (Entropy Source Extension)">;
+def HasStdExtZkr : Predicate<"Subtarget->hasStdExtZkr()">,
+                             AssemblerPredicate<(all_of FeatureStdExtZkr),
+                             "'Zkr' (Entropy Source Extension)">;
+
+def FeatureStdExtZkn
+    : SubtargetFeature<"zkn", "HasStdExtZkn", "true",
+                       "'Zkn' (NIST Algorithm Suite)",
+                       [FeatureStdExtZbkb,
+                        FeatureStdExtZbkc,
+                        FeatureStdExtZkne,
+                        FeatureStdExtZknd,
+                        FeatureStdExtZknh]>;
+
+def FeatureStdExtZks
+    : SubtargetFeature<"zks", "HasStdExtZks", "true",
+                       "'Zks' (ShangMi Algorithm Suite)",
+                       [FeatureStdExtZbkb,
+                        FeatureStdExtZbkc,
+                        FeatureStdExtZksed,
+                        FeatureStdExtZksh]>;
+
+def FeatureStdExtZkt
+    : SubtargetFeature<"zkt", "HasStdExtZkt", "true",
+                       "'Zkt' (Data Independent Execution Latency)">;
+
+def FeatureStdExtZk
+    : SubtargetFeature<"zk", "HasStdExtZk", "true",
+                       "'Zk' (Standard scalar cryptography extension)",
+                       [FeatureStdExtZkn,
+                        FeatureStdExtZkr,
+                        FeatureStdExtZkt]>;
+
 def FeatureNoRVCHints
     : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false",
                        "Disable RVC Hint Instructions.">;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
index a4e752b7e8839..2ab9ab653328d 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
@@ -1146,6 +1146,9 @@ bool RISCVInstrInfo::verifyInstruction(const MachineInstr &MI,
           else
             Ok = isUInt<5>(Imm);
           break;
+        case RISCVOp::OPERAND_RVKRNUM:
+          Ok = Imm >= 0 && Imm <= 10;
+          break;
         }
         if (!Ok) {
           ErrInfo = "Invalid immediate";

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index dd1627231db4c..64cd89cda06a8 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -1516,5 +1516,6 @@ include "RISCVInstrInfoF.td"
 include "RISCVInstrInfoD.td"
 include "RISCVInstrInfoC.td"
 include "RISCVInstrInfoZb.td"
+include "RISCVInstrInfoZk.td"
 include "RISCVInstrInfoV.td"
 include "RISCVInstrInfoZfh.td"

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td
new file mode 100644
index 0000000000000..52a29526a541a
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZk.td
@@ -0,0 +1,123 @@
+//===- RISCVInstrInfoZk.td - RISC-V Scalar Crypto instructions - tablegen -*===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the RISC-V instructions from the standard 'Zk',
+// Scalar Cryptography Instructions extension, version 1.0.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+def RnumArg : AsmOperandClass {
+  let Name = "RnumArg";
+  let RenderMethod = "addImmOperands";
+  let DiagnosticType = "InvalidRnumArg";
+}
+
+def rnum : Operand<XLenVT>, ImmLeaf<XLenVT, [{return (Imm >= 0 && Imm <= 10);}]> {
+  let ParserMatchClass = RnumArg;
+  let EncoderMethod = "getImmOpValue";
+  let DecoderMethod = "decodeUImmOperand<4>";
+  let OperandType = "OPERAND_RVKRNUM";
+  let OperandNamespace = "RISCVOp";
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVKUnary<bits<12> imm12_in, bits<3> funct3, string opcodestr>
+    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
+              opcodestr, "$rd, $rs1">{
+  let imm12 = imm12_in;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVKByteSelect<bits<5> funct5, string opcodestr>
+    : RVInstR<{0b00, funct5}, 0b000, OPC_OP, (outs GPR:$rd),
+              (ins GPR:$rs1, GPR:$rs2, uimm2:$bs),
+              opcodestr, "$rd, $rs1, $rs2, $bs">{
+  bits<2> bs;
+  let Inst{31-30} = bs;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVKUnary_rnum<bits<7> funct7, bits<3> funct3, string opcodestr>
+    : RVInstI<funct3, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1, rnum:$rnum),
+              opcodestr, "$rd, $rs1, $rnum">{
+    bits<4> rnum;
+    let Inst{31-25} = funct7;
+    let Inst{24} = 1;
+    let Inst{23-20} = rnum;
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+let Predicates = [HasStdExtZknd, IsRV32] in {
+def AES32DSI  : RVKByteSelect<0b10101, "aes32dsi">;
+def AES32DSMI : RVKByteSelect<0b10111, "aes32dsmi">;
+} // Predicates = [HasStdExtZknd, IsRV32]
+
+let Predicates = [HasStdExtZknd, IsRV64] in {
+def AES64DS  : ALU_rr<0b0011101, 0b000, "aes64ds">;
+def AES64DSM : ALU_rr<0b0011111, 0b000, "aes64dsm">;
+
+def AES64IM  : RVKUnary<0b001100000000, 0b001, "aes64im">;
+} // Predicates = [HasStdExtZknd, IsRV64]
+
+let Predicates = [HasStdExtZkndOrZkne, IsRV64] in {
+def AES64KS2  : ALU_rr<0b0111111, 0b000, "aes64ks2">;
+
+def AES64KS1I : RVKUnary_rnum<0b0011000, 0b001, "aes64ks1i">;
+} // Predicates = [HasStdExtZkndOrZkne, IsRV64]
+
+let Predicates = [HasStdExtZkne, IsRV32] in {
+def AES32ESI  : RVKByteSelect<0b10001, "aes32esi">;
+def AES32ESMI : RVKByteSelect<0b10011, "aes32esmi">;
+} // Predicates = [HasStdExtZkne, IsRV32]
+
+let Predicates = [HasStdExtZkne, IsRV64] in {
+def AES64ES   : ALU_rr<0b0011001, 0b000, "aes64es">;
+def AES64ESM  : ALU_rr<0b0011011, 0b000, "aes64esm">;
+} // Predicates = [HasStdExtZkne, IsRV64]
+
+let Predicates = [HasStdExtZknh] in {
+def SHA256SIG0 : RVKUnary<0b000100000010, 0b001, "sha256sig0">;
+def SHA256SIG1 : RVKUnary<0b000100000011, 0b001, "sha256sig1">;
+def SHA256SUM0 : RVKUnary<0b000100000000, 0b001, "sha256sum0">;
+def SHA256SUM1 : RVKUnary<0b000100000001, 0b001, "sha256sum1">;
+} // Predicates = [HasStdExtZknh]
+
+let Predicates = [HasStdExtZknh, IsRV32] in {
+def SHA512SIG0H : ALU_rr<0b0101110, 0b000, "sha512sig0h">;
+def SHA512SIG0L : ALU_rr<0b0101010, 0b000, "sha512sig0l">;
+def SHA512SIG1H : ALU_rr<0b0101111, 0b000, "sha512sig1h">;
+def SHA512SIG1L : ALU_rr<0b0101011, 0b000, "sha512sig1l">;
+def SHA512SUM0R : ALU_rr<0b0101000, 0b000, "sha512sum0r">;
+def SHA512SUM1R : ALU_rr<0b0101001, 0b000, "sha512sum1r">;
+} // [HasStdExtZknh, IsRV32]
+
+let Predicates = [HasStdExtZknh, IsRV64] in {
+def SHA512SIG0 : RVKUnary<0b000100000110, 0b001, "sha512sig0">;
+def SHA512SIG1 : RVKUnary<0b000100000111, 0b001, "sha512sig1">;
+def SHA512SUM0 : RVKUnary<0b000100000100, 0b001, "sha512sum0">;
+def SHA512SUM1 : RVKUnary<0b000100000101, 0b001, "sha512sum1">;
+} // Predicates = [HasStdExtZknh, IsRV64]
+
+let Predicates = [HasStdExtZksed] in {
+def SM4ED : RVKByteSelect<0b11000, "sm4ed">;
+def SM4KS : RVKByteSelect<0b11010, "sm4ks">;
+} // Predicates = [HasStdExtZksed]
+
+let Predicates = [HasStdExtZksh] in {
+def SM3P0 : RVKUnary<0b000100001000, 0b001, "sm3p0">;
+def SM3P1 : RVKUnary<0b000100001001, 0b001, "sm3p1">;
+} // Predicates = [HasStdExtZksh]

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedRocket.td b/llvm/lib/Target/RISCV/RISCVSchedRocket.td
index 783e65c1aa185..92dd3175a460a 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedRocket.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedRocket.td
@@ -17,7 +17,10 @@ def RocketModel : SchedMachineModel {
   let LoadLatency = 3;
   let MispredictPenalty = 3;
   let CompleteModel = false;
-  let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasVInstructions, HasVInstructionsI64];
+  let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZknd, 
+                             HasStdExtZkne, HasStdExtZknh, HasStdExtZksed,
+                             HasStdExtZksh, HasStdExtZkr, HasVInstructions,
+                             HasVInstructionsI64];
 }
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
index d164514ce70f0..e5eaad2a6dd08 100644
--- a/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
+++ b/llvm/lib/Target/RISCV/RISCVSchedSiFive7.td
@@ -15,7 +15,9 @@ def SiFive7Model : SchedMachineModel {
   let LoadLatency = 3;
   let MispredictPenalty = 3;
   let CompleteModel = 0;
-  let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasVInstructions];
+  let UnsupportedFeatures = [HasStdExtZbkb, HasStdExtZbkc, HasStdExtZknd, 
+                             HasStdExtZkne, HasStdExtZknh, HasStdExtZksed,
+                             HasStdExtZksh, HasStdExtZkr, HasVInstructions];
 }
 
 // The SiFive7 microarchitecture has two pipelines: A and B.

diff  --git a/llvm/lib/Target/RISCV/RISCVSubtarget.h b/llvm/lib/Target/RISCV/RISCVSubtarget.h
index bacb8fae37941..ac1df37345859 100644
--- a/llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ b/llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -85,6 +85,16 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   bool HasStdExtZfh = false;
   bool HasStdExtZbkb = false;
   bool HasStdExtZbkc = false;
+  bool HasStdExtZknd = false;
+  bool HasStdExtZkne = false;
+  bool HasStdExtZknh = false;
+  bool HasStdExtZksed = false;
+  bool HasStdExtZksh = false;
+  bool HasStdExtZkr = false;
+  bool HasStdExtZkn = false;
+  bool HasStdExtZks = false;
+  bool HasStdExtZkt = false;
+  bool HasStdExtZk = false;
   bool HasRV64 = false;
   bool IsRV32E = false;
   bool EnableLinkerRelax = false;
@@ -160,6 +170,12 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
   bool hasStdExtZfh() const { return HasStdExtZfh; }
   bool hasStdExtZbkb() const { return HasStdExtZbkb; }
   bool hasStdExtZbkc() const { return HasStdExtZbkc; }
+  bool hasStdExtZknd() const { return HasStdExtZknd; }
+  bool hasStdExtZkne() const { return HasStdExtZkne; }
+  bool hasStdExtZknh() const { return HasStdExtZknh; }
+  bool hasStdExtZksed() const { return HasStdExtZksed; }
+  bool hasStdExtZksh() const { return HasStdExtZksh; }
+  bool hasStdExtZkr() const { return HasStdExtZkr; }
   bool is64Bit() const { return HasRV64; }
   bool isRV32E() const { return IsRV32E; }
   bool enableLinkerRelax() const { return EnableLinkerRelax; }

diff  --git a/llvm/lib/Target/RISCV/RISCVSystemOperands.td b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
index 3a3d5ba732b60..b9aa25b321b08 100644
--- a/llvm/lib/Target/RISCV/RISCVSystemOperands.td
+++ b/llvm/lib/Target/RISCV/RISCVSystemOperands.td
@@ -372,3 +372,9 @@ foreach i = 0...3 in {
   let isRV32Only = 1 in
   def : SysReg<"hstateen"#i#"h", !add(0x61C, i)>;
 }
+
+//===-----------------------------------------------
+// Entropy Source CSR
+//===-----------------------------------------------
+
+def SEED : SysReg<"seed", 0x015>;

diff  --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index d37d86fc2f04d..3f7ca36844cc5 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -21,6 +21,16 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+zbb,+zfh,+v,+f %s -o - | FileCheck --check-prefix=RV32COMBINED %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zbkb %s -o - | FileCheck --check-prefix=RV32ZBKB %s
 ; RUN: llc -mtriple=riscv32 -mattr=+zbkc %s -o - | FileCheck --check-prefix=RV32ZBKC %s
+; RUN: llc -mtriple=riscv32 -mattr=+zknd %s -o - | FileCheck --check-prefix=RV32ZKND %s
+; RUN: llc -mtriple=riscv32 -mattr=+zkne %s -o - | FileCheck --check-prefix=RV32ZKNE %s
+; RUN: llc -mtriple=riscv32 -mattr=+zknh %s -o - | FileCheck --check-prefix=RV32ZKNH %s
+; RUN: llc -mtriple=riscv32 -mattr=+zksed %s -o - | FileCheck --check-prefix=RV32ZKSED %s
+; RUN: llc -mtriple=riscv32 -mattr=+zksh %s -o - | FileCheck --check-prefix=RV32ZKSH %s
+; RUN: llc -mtriple=riscv32 -mattr=+zkr %s -o - | FileCheck --check-prefix=RV32ZKR %s
+; RUN: llc -mtriple=riscv32 -mattr=+zkn %s -o - | FileCheck --check-prefix=RV32ZKN %s
+; RUN: llc -mtriple=riscv32 -mattr=+zks %s -o - | FileCheck --check-prefix=RV32ZKS %s
+; RUN: llc -mtriple=riscv32 -mattr=+zkt %s -o - | FileCheck --check-prefix=RV32ZKT %s
+; RUN: llc -mtriple=riscv32 -mattr=+zk %s -o - | FileCheck --check-prefix=RV32ZK %s
 ; RUN: llc -mtriple=riscv64 -mattr=+m %s -o - | FileCheck --check-prefix=RV64M %s
 ; RUN: llc -mtriple=riscv64 -mattr=+a %s -o - | FileCheck --check-prefix=RV64A %s
 ; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefix=RV64F %s
@@ -42,7 +52,16 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+zbb,+zfh,+v,+f %s -o - | FileCheck --check-prefix=RV64COMBINED %s
 ; RUN: llc -mtriple=riscv64 -mattr=+zbkb %s -o - | FileCheck --check-prefix=RV64ZBKB %s
 ; RUN: llc -mtriple=riscv64 -mattr=+zbkc %s -o - | FileCheck --check-prefix=RV64ZBKC %s
-
+; RUN: llc -mtriple=riscv64 -mattr=+zknd %s -o - | FileCheck --check-prefix=RV64ZKND %s
+; RUN: llc -mtriple=riscv64 -mattr=+zkne %s -o - | FileCheck --check-prefix=RV64ZKNE %s
+; RUN: llc -mtriple=riscv64 -mattr=+zknh %s -o - | FileCheck --check-prefix=RV64ZKNH %s
+; RUN: llc -mtriple=riscv64 -mattr=+zksed %s -o - | FileCheck --check-prefix=RV64ZKSED %s
+; RUN: llc -mtriple=riscv64 -mattr=+zksh %s -o - | FileCheck --check-prefix=RV64ZKSH %s
+; RUN: llc -mtriple=riscv64 -mattr=+zkr %s -o - | FileCheck --check-prefix=RV64ZKR %s
+; RUN: llc -mtriple=riscv64 -mattr=+zkn %s -o - | FileCheck --check-prefix=RV64ZKN %s
+; RUN: llc -mtriple=riscv64 -mattr=+zks %s -o - | FileCheck --check-prefix=RV64ZKS %s
+; RUN: llc -mtriple=riscv64 -mattr=+zkt %s -o - | FileCheck --check-prefix=RV64ZKT %s
+; RUN: llc -mtriple=riscv64 -mattr=+zk %s -o - | FileCheck --check-prefix=RV64ZK %s
 
 ; RV32M: .attribute 5, "rv32i2p0_m2p0"
 ; RV32A: .attribute 5, "rv32i2p0_a2p0"
@@ -65,6 +84,16 @@
 ; RV32COMBINED: .attribute 5, "rv32i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
 ; RV32ZBKB: .attribute 5, "rv32i2p0_zbkb1p0"
 ; RV32ZBKC: .attribute 5, "rv32i2p0_zbkc1p0"
+; RV32ZKND: .attribute 5, "rv32i2p0_zknd1p0"
+; RV32ZKNE: .attribute 5, "rv32i2p0_zkne1p0"
+; RV32ZKNH: .attribute 5, "rv32i2p0_zknh1p0"
+; RV32ZKSED: .attribute 5, "rv32i2p0_zksed1p0"
+; RV32ZKSH: .attribute 5, "rv32i2p0_zksh1p0"
+; RV32ZKR: .attribute 5, "rv32i2p0_zkr1p0"
+; RV32ZKN: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0"
+; RV32ZKS: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0"
+; RV32ZKT: .attribute 5, "rv32i2p0_zkt1p0"
+; RV32ZK: .attribute 5, "rv32i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0"
 
 ; RV64M: .attribute 5, "rv64i2p0_m2p0"
 ; RV64A: .attribute 5, "rv64i2p0_a2p0"
@@ -87,6 +116,16 @@
 ; RV64COMBINED: .attribute 5, "rv64i2p0_f2p0_d2p0_v1p0_zfh1p0_zfhmin1p0_zbb1p0_zve32f1p0_zve32x1p0_zve64d1p0_zve64f1p0_zve64x1p0_zvl128b1p0_zvl32b1p0_zvl64b1p0"
 ; RV64ZBKB: .attribute 5, "rv64i2p0_zbkb1p0"
 ; RV64ZBKC: .attribute 5, "rv64i2p0_zbkc1p0"
+; RV64ZKND: .attribute 5, "rv64i2p0_zknd1p0"
+; RV64ZKNE: .attribute 5, "rv64i2p0_zkne1p0"
+; RV64ZKNH: .attribute 5, "rv64i2p0_zknh1p0"
+; RV64ZKSED: .attribute 5, "rv64i2p0_zksed1p0"
+; RV64ZKSH: .attribute 5, "rv64i2p0_zksh1p0"
+; RV64ZKR: .attribute 5, "rv64i2p0_zkr1p0"
+; RV64ZKN: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0"
+; RV64ZKS: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0"
+; RV64ZKT: .attribute 5, "rv64i2p0_zkt1p0"
+; RV64ZK: .attribute 5, "rv64i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0"
 
 define i32 @addi(i32 %a) {
   %1 = add i32 %a, 1

diff  --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 15ee933dcdd1d..27dc70a7b6f75 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -130,3 +130,33 @@
 
 .attribute arch, "rv32i_zbkc1p0"
 # CHECK: attribute      5, "rv32i2p0_zbkc1p0"
+
+.attribute arch, "rv32i_zknd1p0"
+# CHECK: attribute      5, "rv32i2p0_zknd1p0"
+
+.attribute arch, "rv32i_zkne1p0"
+# CHECK: attribute      5, "rv32i2p0_zkne1p0"
+
+.attribute arch, "rv32i_zknh1p0"
+# CHECK: attribute      5, "rv32i2p0_zknh1p0"
+
+.attribute arch, "rv32i_zksed1p0"
+# CHECK: attribute      5, "rv32i2p0_zksed1p0"
+
+.attribute arch, "rv32i_zksh1p0"
+# CHECK: attribute      5, "rv32i2p0_zksh1p0"
+
+.attribute arch, "rv32i_zkr1p0"
+# CHECK: attribute      5, "rv32i2p0_zkr1p0"
+
+.attribute arch, "rv32i_zkn1p0"
+# CHECK: attribute      5, "rv32i2p0_zbkb1p0_zbkc1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0"
+
+.attribute arch, "rv32i_zks1p0"
+# CHECK: attribute      5, "rv32i2p0_zbkb1p0_zbkc1p0_zks1p0_zksed1p0_zksh1p0"
+
+.attribute arch, "rv32i_zkt1p0"
+# CHECK: attribute      5, "rv32i2p0_zkt1p0"
+
+.attribute arch, "rv32i_zk1p0"
+# CHECK: attribute      5, "rv32i2p0_zbkb1p0_zbkc1p0_zk1p0_zkn1p0_zknd1p0_zkne1p0_zknh1p0_zkr1p0_zkt1p0"

diff  --git a/llvm/test/MC/RISCV/rv32zknd-only-invalid.s b/llvm/test/MC/RISCV/rv32zknd-only-invalid.s
new file mode 100644
index 0000000000000..05ae48491a037
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zknd-only-invalid.s
@@ -0,0 +1,17 @@
+# With Zk extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zk < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zkn extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zkn < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zknd extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zknd < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+aes32dsmi a0, a1, a2, 8
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+aes32dsi a0, a1, a2, 8

diff  --git a/llvm/test/MC/RISCV/rv32zknd-only-valid.s b/llvm/test/MC/RISCV/rv32zknd-only-valid.s
new file mode 100644
index 0000000000000..db139595879e6
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zknd-only-valid.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zknd -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zknd < %s \
+# RUN:     | llvm-objdump --mattr=+zknd -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: aes32dsi a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xea]
+aes32dsi a0, a1, a2, 3
+
+# CHECK-ASM-AND-OBJ: aes32dsmi a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xee]
+aes32dsmi a0, a1, a2, 3

diff  --git a/llvm/test/MC/RISCV/rv32zkne-only-invalid.s b/llvm/test/MC/RISCV/rv32zkne-only-invalid.s
new file mode 100644
index 0000000000000..9ace21cae5eff
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zkne-only-invalid.s
@@ -0,0 +1,17 @@
+# With Zk extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zk < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zkn extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zkn < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zkne extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zkne < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+aes32esmi a0, a1, a2, 8
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+aes32esi a0, a1, a2, 8

diff  --git a/llvm/test/MC/RISCV/rv32zkne-only-valid.s b/llvm/test/MC/RISCV/rv32zkne-only-valid.s
new file mode 100644
index 0000000000000..de99aedd5ebdf
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zkne-only-valid.s
@@ -0,0 +1,13 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zkne -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zkne < %s \
+# RUN:     | llvm-objdump --mattr=+zkne -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: aes32esi a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xe2]
+aes32esi a0, a1, a2, 3
+
+# CHECK-ASM-AND-OBJ: aes32esmi a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xe6]
+aes32esmi a0, a1, a2, 3

diff  --git a/llvm/test/MC/RISCV/rv32zknh-only-valid.s b/llvm/test/MC/RISCV/rv32zknh-only-valid.s
new file mode 100644
index 0000000000000..d48dd4949dd46
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zknh-only-valid.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zknh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zknh < %s \
+# RUN:     | llvm-objdump --mattr=+zknh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sha512sig0h a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x5c]
+sha512sig0h a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: sha512sig1h a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x5e]
+sha512sig1h a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: sha512sig0l a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x54]
+sha512sig0l a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: sha512sig1l a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x56]
+sha512sig1l a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: sha512sum0r a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x50]
+sha512sum0r a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: sha512sum1r a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x52]
+sha512sum1r a0, a1, a2

diff  --git a/llvm/test/MC/RISCV/rv32zknh-valid.s b/llvm/test/MC/RISCV/rv32zknh-valid.s
new file mode 100644
index 0000000000000..e1dbc0feea34a
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zknh-valid.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zknh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zknh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zknh < %s \
+# RUN:     | llvm-objdump --mattr=+zknh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zknh < %s \
+# RUN:     | llvm-objdump --mattr=+zknh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sha256sig0 a0, a1
+# CHECK-ASM: [0x13,0x95,0x25,0x10]
+sha256sig0 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha256sig1 a0, a1
+# CHECK-ASM: [0x13,0x95,0x35,0x10]
+sha256sig1 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha256sum0 a0, a1
+# CHECK-ASM: [0x13,0x95,0x05,0x10]
+sha256sum0 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha256sum1 a0, a1
+# CHECK-ASM: [0x13,0x95,0x15,0x10]
+sha256sum1 a0, a1

diff  --git a/llvm/test/MC/RISCV/rv32zksed-invalid.s b/llvm/test/MC/RISCV/rv32zksed-invalid.s
new file mode 100644
index 0000000000000..feb9bc09b60bf
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zksed-invalid.s
@@ -0,0 +1,13 @@
+# With Zks extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zks < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zksed extension:
+# RUN: not llvm-mc -triple=riscv32 -mattr=+zksed < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+sm4ed a0, a1, a2, 8
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+sm4ks a0, a1, a2, 8

diff  --git a/llvm/test/MC/RISCV/rv32zksed-valid.s b/llvm/test/MC/RISCV/rv32zksed-valid.s
new file mode 100644
index 0000000000000..25d618c082e6e
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zksed-valid.s
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zksed -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zksed -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zksed < %s \
+# RUN:     | llvm-objdump --mattr=+zksed -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zksed < %s \
+# RUN:     | llvm-objdump --mattr=+zksed -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sm4ed a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xf0]
+sm4ed a0, a1, a2, 3
+
+# CHECK-ASM-AND-OBJ: sm4ks a0, a1, a2, 3
+# CHECK-ASM: [0x33,0x85,0xc5,0xf4]
+sm4ks a0, a1, a2, 3

diff  --git a/llvm/test/MC/RISCV/rv32zksh-valid.s b/llvm/test/MC/RISCV/rv32zksh-valid.s
new file mode 100644
index 0000000000000..48ae6652c850e
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zksh-valid.s
@@ -0,0 +1,18 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+zksh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zksh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zksh < %s \
+# RUN:     | llvm-objdump --mattr=+zksh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zksh < %s \
+# RUN:     | llvm-objdump --mattr=+zksh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sm3p0 a0, a1
+# CHECK-ASM: [0x13,0x95,0x85,0x10]
+sm3p0 a0, a1
+
+# CHECK-ASM-AND-OBJ: sm3p1 a0, a1
+# CHECK-ASM: [0x13,0x95,0x95,0x10]
+sm3p1 a0, a1

diff  --git a/llvm/test/MC/RISCV/rv64zknd-only-valid.s b/llvm/test/MC/RISCV/rv64zknd-only-valid.s
new file mode 100644
index 0000000000000..03656136d20ae
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zknd-only-valid.s
@@ -0,0 +1,25 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zknd -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zknd < %s \
+# RUN:     | llvm-objdump --mattr=+zknd -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: aes64ds a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x3a]
+aes64ds a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: aes64dsm a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x3e]
+aes64dsm a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: aes64im a0, a1
+# CHECK-ASM: [0x13,0x95,0x05,0x30]
+aes64im a0, a1
+
+# CHECK-ASM-AND-OBJ: aes64ks1i a0, a1, 5
+# CHECK-ASM: [0x13,0x95,0x55,0x31]
+aes64ks1i a0, a1, 5
+
+# CHECK-ASM-AND-OBJ: aes64ks2 a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x7e]
+aes64ks2 a0, a1, a2

diff  --git a/llvm/test/MC/RISCV/rv64zkne-only-invalid.s b/llvm/test/MC/RISCV/rv64zkne-only-invalid.s
new file mode 100644
index 0000000000000..5a7331fa0a9bb
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zkne-only-invalid.s
@@ -0,0 +1,17 @@
+# With Zk extension:
+# RUN: not llvm-mc -triple=riscv64 -mattr=+zk < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zkn extension:
+# RUN: not llvm-mc -triple=riscv64 -mattr=+zkn < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zkne extension:
+# RUN: not llvm-mc -triple=riscv64 -mattr=+zkne < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 10]
+aes64ks1i a0, a1, 11
+
+# CHECK-ERROR: immediate must be an integer in the range [0, 10]
+aes64ks1i a0, a1, -1

diff  --git a/llvm/test/MC/RISCV/rv64zkne-only-valid.s b/llvm/test/MC/RISCV/rv64zkne-only-valid.s
new file mode 100644
index 0000000000000..78950b85f51b8
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zkne-only-valid.s
@@ -0,0 +1,21 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zkne -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zkne < %s \
+# RUN:     | llvm-objdump --mattr=+zkne -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: aes64es a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x32]
+aes64es a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: aes64esm a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x36]
+aes64esm a0, a1, a2
+
+# CHECK-ASM-AND-OBJ: aes64ks1i a0, a1, 5
+# CHECK-ASM: [0x13,0x95,0x55,0x31]
+aes64ks1i a0, a1, 5
+
+# CHECK-ASM-AND-OBJ: aes64ks2 a0, a1, a2
+# CHECK-ASM: [0x33,0x85,0xc5,0x7e]
+aes64ks2 a0, a1, a2

diff  --git a/llvm/test/MC/RISCV/rv64zknh-only-valid.s b/llvm/test/MC/RISCV/rv64zknh-only-valid.s
new file mode 100644
index 0000000000000..9478b6004a4a5
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zknh-only-valid.s
@@ -0,0 +1,21 @@
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+zknh -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zknh < %s \
+# RUN:     | llvm-objdump --mattr=+zknh -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: sha512sig0 a0, a1
+# CHECK-ASM: [0x13,0x95,0x65,0x10]
+sha512sig0 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha512sig1 a0, a1
+# CHECK-ASM: [0x13,0x95,0x75,0x10]
+sha512sig1 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha512sum0 a0, a1
+# CHECK-ASM: [0x13,0x95,0x45,0x10]
+sha512sum0 a0, a1
+
+# CHECK-ASM-AND-OBJ: sha512sum1 a0, a1
+# CHECK-ASM: [0x13,0x95,0x55,0x10]
+sha512sum1 a0, a1

diff  --git a/llvm/test/MC/RISCV/rv64zksed-invalid.s b/llvm/test/MC/RISCV/rv64zksed-invalid.s
new file mode 100644
index 0000000000000..2c55ac461f51f
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv64zksed-invalid.s
@@ -0,0 +1,13 @@
+# With Zks extension:
+# RUN: not llvm-mc -triple=riscv64 -mattr=+zks < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+# With Zksed extension:
+# RUN: not llvm-mc -triple=riscv64 -mattr=+zksed < %s 2>&1 \
+# RUN:        | FileCheck %s --check-prefix=CHECK-ERROR
+
+sm4ed a0, a1, a2, 8
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]
+
+sm4ks a0, a1, a2, 8
+# CHECK-ERROR: immediate must be an integer in the range [0, 3]

diff  --git a/llvm/test/MC/RISCV/rvk-user-csr-name.s b/llvm/test/MC/RISCV/rvk-user-csr-name.s
new file mode 100644
index 0000000000000..cacadf794d95b
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvk-user-csr-name.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc %s -triple=riscv32 -riscv-no-aliases -mattr=+f -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s
+# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zkr < %s \
+# RUN:     | llvm-objdump -d --mattr=+zkr - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST-ALIAS %s
+#
+# RUN: llvm-mc %s -triple=riscv64 -riscv-no-aliases -mattr=+f -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-INST,CHECK-ENC %s
+# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zkr < %s \
+# RUN:     | llvm-objdump -d --mattr=+zkr - \
+# RUN:     | FileCheck -check-prefix=CHECK-INST-ALIAS %s
+
+##################################
+# Entropy Source CSR
+##################################
+
+# seed
+# name
+# CHECK-INST: csrrs t1, seed, zero
+# CHECK-ENC:  encoding: [0x73,0x23,0x50,0x01]
+# CHECK-INST-ALIAS: csrr t1, seed
+# uimm12
+# CHECK-INST: csrrs t2, seed, zero
+# CHECK-ENC:  encoding: [0xf3,0x23,0x50,0x01]
+# CHECK-INST-ALIAS: csrr t2, seed
+# name
+csrrs t1, seed, zero
+# uimm12
+csrrs t2, 0x015, zero


        


More information about the llvm-commits mailing list