[llvm] 0aecddc - [RISCV] Add Zce extension.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 13 12:22:12 PDT 2023


Author: Craig Topper
Date: 2023-07-13T12:22:06-07:00
New Revision: 0aecddcee98057300bdf2e2cd00f0eeefced3c81

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

LOG: [RISCV] Add Zce extension.

According to the spec, Zce is an alias for Zca, Zcb, Zcmp, and Zcmt.
If F is enabled on RV32 it also includes Zcf.

This patch adds the Zce and the implication rule which unfortunately
requires custom handling for adding Zcf.

I've also made all the Zc* extensions imply Zca.

I've also added an error for Zcf without RV32.

Reviewed By: asb

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

Added: 
    

Modified: 
    llvm/lib/Support/RISCVISAInfo.cpp
    llvm/lib/Target/RISCV/RISCVFeatures.td
    llvm/lib/Target/RISCV/RISCVInstrInfoC.td
    llvm/test/CodeGen/RISCV/compress-float.ll
    llvm/test/MC/RISCV/attribute-arch.s
    llvm/test/MC/RISCV/option-arch.s
    llvm/test/MC/RISCV/rv32fc-valid.s
    llvm/unittests/Support/RISCVISAInfoTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 3cd1ff4c02e3f4..8494e14a28912e 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -94,6 +94,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
     {"zca", RISCVExtensionVersion{1, 0}},
     {"zcb", RISCVExtensionVersion{1, 0}},
     {"zcd", RISCVExtensionVersion{1, 0}},
+    {"zce", RISCVExtensionVersion{1, 0}},
     {"zcf", RISCVExtensionVersion{1, 0}},
     {"zcmp", RISCVExtensionVersion{1, 0}},
     {"zcmt", RISCVExtensionVersion{1, 0}},
@@ -934,6 +935,10 @@ Error RISCVISAInfo::checkDependency() {
         "' extension is incompatible with '" + (HasC ? "c" : "zcd") +
         "' extension when 'd' extension is enabled");
 
+  if (XLen != 32 && Exts.count("zcf"))
+    return createStringError(errc::invalid_argument,
+                             "'zcf' is only supported for 'rv32'");
+
   // Additional dependency checks.
   // TODO: The 'q' extension requires rv64.
   // TODO: It is illegal to specify 'e' extensions with 'f' and 'd'.
@@ -948,6 +953,9 @@ static const char *ImpliedExtsXTHeadVdot[] = {"v"};
 static const char *ImpliedExtsXsfvcp[] = {"zve32x"};
 static const char *ImpliedExtsZacas[] = {"a"};
 static const char *ImpliedExtsZcb[] = {"zca"};
+static const char *ImpliedExtsZcd[] = {"zca"};
+static const char *ImpliedExtsZce[] = {"zcb", "zcmp", "zcmt"};
+static const char *ImpliedExtsZcf[] = {"zca"};
 static const char *ImpliedExtsZcmp[] = {"zca"};
 static const char *ImpliedExtsZcmt[] = {"zca"};
 static const char *ImpliedExtsZdinx[] = {"zfinx"};
@@ -1011,6 +1019,9 @@ static constexpr ImpliedExtsEntry ImpliedExts[] = {
     {{"xtheadvdot"}, {ImpliedExtsXTHeadVdot}},
     {{"zacas"}, {ImpliedExtsZacas}},
     {{"zcb"}, {ImpliedExtsZcb}},
+    {{"zcd"}, {ImpliedExtsZcd}},
+    {{"zce"}, {ImpliedExtsZce}},
+    {{"zcf"}, {ImpliedExtsZcf}},
     {{"zcmp"}, {ImpliedExtsZcmp}},
     {{"zcmt"}, {ImpliedExtsZcmt}},
     {{"zdinx"}, {ImpliedExtsZdinx}},
@@ -1088,6 +1099,13 @@ void RISCVISAInfo::updateImplication() {
       }
     }
   }
+
+  // Add Zcf if Zce and F are enabled on RV32.
+  if (XLen == 32 && Exts.count("zce") && Exts.count("f") &&
+      !Exts.count("zcf")) {
+    auto Version = findDefaultVersion("zcf");
+    addExtension("zcf", Version->Major, Version->Minor);
+  }
 }
 
 struct CombinedExtsEntry {

diff  --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 0157bfc162ff5e..695c5f6f373209 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -358,15 +358,9 @@ def FeatureStdExtZcf
                        "'Zcf' (Compressed Single-Precision Floating-Point Instructions)",
                        [FeatureStdExtZca]>;
 
-def HasStdExtCOrZcf
-    : Predicate<"Subtarget->hasStdExtC() || Subtarget->hasStdExtZcf()">,
-                AssemblerPredicate<(any_of FeatureStdExtC, FeatureStdExtZcf),
-                                   "'C' (Compressed Instructions) or "
-                                   "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">;
-
 def FeatureStdExtZcmp
     : SubtargetFeature<"zcmp", "HasStdExtZcmp", "true",
-                       "'Zcmp' (sequenced instuctions for code-size reduction)", 
+                       "'Zcmp' (sequenced instuctions for code-size reduction)",
                        [FeatureStdExtZca]>;
 def HasStdExtZcmp : Predicate<"Subtarget->hasStdExtZcmp() && !Subtarget->hasStdExtC()">,
                                AssemblerPredicate<(all_of FeatureStdExtZcmp, (not FeatureStdExtC)),
@@ -374,12 +368,26 @@ def HasStdExtZcmp : Predicate<"Subtarget->hasStdExtZcmp() && !Subtarget->hasStdE
 
 def FeatureStdExtZcmt
     : SubtargetFeature<"zcmt", "HasStdExtZcmt", "true",
-                       "'Zcmt' (table jump instuctions for code-size reduction)", 
-                       [FeatureStdExtZca, FeatureStdExtZicsr]>; 
+                       "'Zcmt' (table jump instuctions for code-size reduction)",
+                       [FeatureStdExtZca, FeatureStdExtZicsr]>;
 def HasStdExtZcmt : Predicate<"Subtarget->hasStdExtZcmt()">,
                            AssemblerPredicate<(all_of FeatureStdExtZcmt),
                            "'Zcmt' (table jump instuctions for code-size reduction)">;
 
+def FeatureStdExtZce
+    : SubtargetFeature<"zce", "HasStdExtZce", "true",
+                       "'Zce' (Compressed extensions for microcontrollers)",
+                       [FeatureStdExtZca, FeatureStdExtZcb, FeatureStdExtZcmp,
+                        FeatureStdExtZcmt]>;
+
+def HasStdExtCOrZcfOrZce
+    : Predicate<"Subtarget->hasStdExtC() || Subtarget->hasStdExtZcf() "
+                "Subtarget->hasStdExtZce()">,
+                AssemblerPredicate<(any_of FeatureStdExtC, FeatureStdExtZcf,
+                                           FeatureStdExtZce),
+                                   "'C' (Compressed Instructions) or "
+                                   "'Zcf' (Compressed Single-Precision Floating-Point Instructions)">;
+
 def FeatureNoRVCHints
     : SubtargetFeature<"no-rvc-hints", "EnableRVCHintInstrs", "false",
                        "Disable RVC Hint Instructions.">;

diff  --git a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
index bf87bc41e74f4b..74439bb67c616e 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoC.td
@@ -348,7 +348,7 @@ def C_LW : CLoad_ri<0b010, "c.lw", GPRC, uimm7_lsb00>,
 }
 
 let DecoderNamespace = "RISCV32Only_",
-    Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
+    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
 def C_FLW  : CLoad_ri<0b011, "c.flw", FPR32C, uimm7_lsb00>,
              Sched<[WriteFLD32, ReadMemBase]> {
   bits<7> imm;
@@ -382,7 +382,7 @@ def C_SW : CStore_rri<0b110, "c.sw", GPRC, uimm7_lsb00>,
 }
 
 let DecoderNamespace = "RISCV32Only_",
-    Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32]  in
+    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32]  in
 def C_FSW  : CStore_rri<0b111, "c.fsw", FPR32C, uimm7_lsb00>,
              Sched<[WriteFST32, ReadStoreData, ReadMemBase]> {
   bits<7> imm;
@@ -534,7 +534,7 @@ def C_LWSP : CStackLoad<0b010, "c.lwsp", GPRNoX0, uimm8_lsb00>,
 }
 
 let DecoderNamespace = "RISCV32Only_",
-    Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
+    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
 def C_FLWSP  : CStackLoad<0b011, "c.flwsp", FPR32, uimm8_lsb00>,
                Sched<[WriteFLD32, ReadMemBase]> {
   let Inst{6-4} = imm{4-2};
@@ -592,7 +592,7 @@ def C_SWSP : CStackStore<0b110, "c.swsp", GPR, uimm8_lsb00>,
 }
 
 let DecoderNamespace = "RISCV32Only_",
-    Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in
+    Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in
 def C_FSWSP  : CStackStore<0b111, "c.fswsp", FPR32, uimm8_lsb00>,
                Sched<[WriteFST32, ReadStoreData, ReadMemBase]> {
   let Inst{12-9} = imm{5-2};
@@ -743,7 +743,7 @@ def : InstAlias<"c.ldsp $rd, (${rs1})", (C_LDSP GPRC:$rd, SPMem:$rs1, 0)>;
 def : InstAlias<"c.sdsp $rs2, (${rs1})", (C_SDSP GPRC:$rs2, SPMem:$rs1, 0)>;
 }
 
-let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
+let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
 def : InstAlias<"c.flw $rd, (${rs1})", (C_FLW FPR32C:$rd, GPRCMem:$rs1, 0)>;
 def : InstAlias<"c.fsw $rs2, (${rs1})", (C_FSW FPR32C:$rs2, GPRCMem:$rs1, 0)>;
 def : InstAlias<"c.flwsp $rd, (${rs1})", (C_FLWSP FPR32C:$rd, SPMem:$rs1, 0)>;
@@ -875,7 +875,7 @@ def : CompressPat<(LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
                   (C_LW GPRC:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
 } // Predicates = [HasStdExtCOrZca]
 
-let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
+let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
 def : CompressPat<(FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm),
                   (C_FLW FPR32C:$rd, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
@@ -895,7 +895,7 @@ def : CompressPat<(SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
                   (C_SW GPRC:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
 } // Predicates = [HasStdExtCOrZca]
 
-let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
+let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
 def : CompressPat<(FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm),
                   (C_FSW FPR32C:$rs2, GPRCMem:$rs1, uimm7_lsb00:$imm)>;
 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
@@ -992,7 +992,7 @@ def : CompressPat<(LW GPRNoX0:$rd, SPMem:$rs1,  uimm8_lsb00:$imm),
                   (C_LWSP GPRNoX0:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
 } // Predicates = [HasStdExtCOrZca]
 
-let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
+let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
 def : CompressPat<(FLW FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm),
                   (C_FLWSP FPR32:$rd, SPMem:$rs1, uimm8_lsb00:$imm)>;
 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]
@@ -1034,7 +1034,7 @@ def : CompressPat<(SW GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
                   (C_SWSP GPR:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
 } // Predicates = [HasStdExtCOrZca]
 
-let Predicates = [HasStdExtCOrZcf, HasStdExtF, IsRV32] in {
+let Predicates = [HasStdExtCOrZcfOrZce, HasStdExtF, IsRV32] in {
 def : CompressPat<(FSW FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm),
                   (C_FSWSP FPR32:$rs2, SPMem:$rs1, uimm8_lsb00:$imm)>;
 } // Predicates = [HasStdExtC, HasStdExtF, IsRV32]

diff  --git a/llvm/test/CodeGen/RISCV/compress-float.ll b/llvm/test/CodeGen/RISCV/compress-float.ll
index 4e0ecaf0d0cb08..a3e9283b06fcce 100644
--- a/llvm/test/CodeGen/RISCV/compress-float.ll
+++ b/llvm/test/CodeGen/RISCV/compress-float.ll
@@ -44,6 +44,27 @@
 ; RUN:   -disable-block-placement < %t.mixedattr \
 ; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+zcf,+f -M no-aliases - \
 ; RUN:   | FileCheck -check-prefix=RV32IFDC %s
+;
+; RUN: cat %s > %t.tgtattr
+; RUN: echo 'attributes #0 = { nounwind }' >> %t.tgtattr
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zce,+f -filetype=obj \
+; RUN:   -disable-block-placement < %t.tgtattr \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+zce,+f -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %s
+;
+; RUN: cat %s > %t.fnattr
+; RUN: echo 'attributes #0 = { nounwind "target-features"="+zce,+f" }' >> %t.fnattr
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f -filetype=obj \
+; RUN:   -disable-block-placement < %t.fnattr \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+zce,+f -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %s
+;
+; RUN: cat %s > %t.mixedattr
+; RUN: echo 'attributes #0 = { nounwind "target-features"="+f" }' >> %t.mixedattr
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zce -filetype=obj \
+; RUN:   -disable-block-placement < %t.mixedattr \
+; RUN:   | llvm-objdump -d --triple=riscv32 --mattr=+zce,+f -M no-aliases - \
+; RUN:   | FileCheck -check-prefix=RV32IFDC %s
 
 ; This acts as a basic correctness check for the codegen instruction compression
 ; path, verifying that the assembled file contains compressed instructions when

diff  --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index 2d4885ab15b43d..7a27d97f9c5584 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -229,10 +229,10 @@
 # CHECK: attribute      5, "rv32i2p1_zca1p0"
 
 .attribute arch, "rv32izcd1p0"
-# CHECK: attribute      5, "rv32i2p1_zcd1p0"
+# CHECK: attribute      5, "rv32i2p1_zca1p0_zcd1p0"
 
 .attribute arch, "rv32izcf1p0"
-# CHECK: attribute      5, "rv32i2p1_zcf1p0"
+# CHECK: attribute      5, "rv32i2p1_zca1p0_zcf1p0"
 
 .attribute arch, "rv32izcb1p0"
 # CHECK: attribute      5, "rv32i2p1_zca1p0_zcb1p0"

diff  --git a/llvm/test/MC/RISCV/option-arch.s b/llvm/test/MC/RISCV/option-arch.s
index 60bd8e6ca31d3f..5d23e2c73c3e83 100644
--- a/llvm/test/MC/RISCV/option-arch.s
+++ b/llvm/test/MC/RISCV/option-arch.s
@@ -118,3 +118,9 @@ addi a0, a1, 0
 # Test extension name that has digits.
 .option arch, +zve32x
 # CHECK: .option arch, +zve32x
+
+.option arch, rv32i
+.option arch, +zce, +f
+# CHECK-INST: flw fa0, 0(a0)
+# CHECK: # encoding: [0x08,0x61]
+c.flw fa0, 0(a0)

diff  --git a/llvm/test/MC/RISCV/rv32fc-valid.s b/llvm/test/MC/RISCV/rv32fc-valid.s
index 477188072ce067..b18800c00143a8 100644
--- a/llvm/test/MC/RISCV/rv32fc-valid.s
+++ b/llvm/test/MC/RISCV/rv32fc-valid.s
@@ -21,9 +21,6 @@
 # RUN: not llvm-mc -triple riscv64 -mattr=+c,+f \
 # RUN:     -riscv-no-aliases -show-encoding < %s 2>&1 \
 # RUN:     | FileCheck -check-prefixes=CHECK-NO-RV32 %s
-# RUN: not llvm-mc -triple riscv64 -mattr=+zcf,+f \
-# RUN:     -riscv-no-aliases -show-encoding < %s 2>&1 \
-# RUN:     | FileCheck -check-prefixes=CHECK-NO-RV32 %s
 
 # FIXME: error messages for rv64fc are misleading
 

diff  --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index cab91c43f1ceb0..3587147fdda99d 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -469,6 +469,11 @@ TEST(ParseArchString, RejectsConflictingExtensions) {
               "'zcmt' extension is incompatible with 'zcd' extension when 'd' "
               "extension is enabled");
   }
+
+  for (StringRef Input : {"rv64if_zcf"}) {
+    EXPECT_EQ(toString(RISCVISAInfo::parseArchString(Input, true).takeError()),
+              "'zcf' is only supported for 'rv32'");
+  }
 }
 
 TEST(ToFeatureVector, IIsDroppedAndExperimentalExtensionsArePrefixed) {
@@ -507,3 +512,95 @@ TEST(OrderedExtensionMap, ExtensionsAreCorrectlyOrdered) {
               ElementsAre("i", "m", "l", "c", "y", "zicsr", "zmfoo", "zfinx",
                            "zzfoo", "sbar", "sfoo", "xbar", "xfoo"));
 }
+
+TEST(ParseArchString, ZceImplication) {
+  auto MaybeRV32IZce = RISCVISAInfo::parseArchString("rv32izce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV32IZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV32IZce =
+      (*MaybeRV32IZce)->getExtensions();
+  EXPECT_EQ(ExtsRV32IZce.size(), 6UL);
+  EXPECT_EQ(ExtsRV32IZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV32IZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV32IZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV32IZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV32IZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV32IZce.count("zcmt"), 1U);
+
+  auto MaybeRV32IFZce = RISCVISAInfo::parseArchString("rv32ifzce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV32IFZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV32IFZce =
+      (*MaybeRV32IFZce)->getExtensions();
+  EXPECT_EQ(ExtsRV32IFZce.size(), 9UL);
+  EXPECT_EQ(ExtsRV32IFZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zicsr"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("f"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zcf"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV32IFZce.count("zcmt"), 1U);
+
+  auto MaybeRV32IDZce = RISCVISAInfo::parseArchString("rv32idzce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV32IDZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV32IDZce =
+      (*MaybeRV32IDZce)->getExtensions();
+  EXPECT_EQ(ExtsRV32IDZce.size(), 10UL);
+  EXPECT_EQ(ExtsRV32IDZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zicsr"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("f"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("d"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zcf"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV32IDZce.count("zcmt"), 1U);
+
+  auto MaybeRV64IZce = RISCVISAInfo::parseArchString("rv64izce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV64IZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV64IZce =
+      (*MaybeRV64IZce)->getExtensions();
+  EXPECT_EQ(ExtsRV64IZce.size(), 6UL);
+  EXPECT_EQ(ExtsRV64IZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV64IZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV64IZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV64IZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV64IZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV64IZce.count("zcmt"), 1U);
+
+  auto MaybeRV64IFZce = RISCVISAInfo::parseArchString("rv64ifzce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV64IFZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV64IFZce =
+      (*MaybeRV64IFZce)->getExtensions();
+  EXPECT_EQ(ExtsRV64IFZce.size(), 8UL);
+  EXPECT_EQ(ExtsRV64IFZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zicsr"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("f"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
+
+  EXPECT_EQ(ExtsRV64IFZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV64IFZce.count("zcmt"), 1U);
+
+  auto MaybeRV64IDZce = RISCVISAInfo::parseArchString("rv64idzce", true);
+  ASSERT_THAT_EXPECTED(MaybeRV64IDZce, Succeeded());
+  RISCVISAInfo::OrderedExtensionMap ExtsRV64IDZce =
+      (*MaybeRV64IDZce)->getExtensions();
+  EXPECT_EQ(ExtsRV64IDZce.size(), 9UL);
+  EXPECT_EQ(ExtsRV64IDZce.count("i"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zicsr"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("f"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("d"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zca"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zcb"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zce"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zcmp"), 1U);
+  EXPECT_EQ(ExtsRV64IDZce.count("zcmt"), 1U);
+}


        


More information about the llvm-commits mailing list