|
@@ -0,0 +1,1449 @@
|
|
|
+From 05cd9526d2438fab6b4b671d682445aae38b5438 Mon Sep 17 00:00:00 2001
|
|
|
+From: "yilun.xie" <yilun.xie@starfivetech.com>
|
|
|
+Date: Fri, 29 Oct 2021 10:16:06 +0800
|
|
|
+Subject: [PATCH 2/3] update B instruction to 1.0 and Merge four Custom CSR
|
|
|
+ cache instruction
|
|
|
+
|
|
|
+---
|
|
|
+ clang/include/clang/Basic/BuiltinsRISCV.def | 33 --
|
|
|
+ clang/lib/CodeGen/CGBuiltin.cpp | 92 +---
|
|
|
+ clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 3 +-
|
|
|
+ llvm/include/llvm/IR/IntrinsicsRISCV.td | 23 -
|
|
|
+ .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 30 --
|
|
|
+ .../MCTargetDesc/RISCVTargetStreamer.cpp | 12 -
|
|
|
+ llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 323 +-----------
|
|
|
+ llvm/lib/Target/RISCV/RISCVInstrFormats.td | 12 +
|
|
|
+ llvm/lib/Target/RISCV/RISCVInstrInfo.td | 13 +
|
|
|
+ llvm/lib/Target/RISCV/RISCVInstrInfoB.td | 473 ++----------------
|
|
|
+ 10 files changed, 68 insertions(+), 946 deletions(-)
|
|
|
+
|
|
|
+diff --git a/clang/include/clang/Basic/BuiltinsRISCV.def b/clang/include/clang/Basic/BuiltinsRISCV.def
|
|
|
+index b2b4950f92bd..583c5712e41d 100644
|
|
|
+--- a/clang/include/clang/Basic/BuiltinsRISCV.def
|
|
|
++++ b/clang/include/clang/Basic/BuiltinsRISCV.def
|
|
|
+@@ -26,38 +26,5 @@ TARGET_BUILTIN(__builtin_riscv_clmul, "LiLiLi", "nc", "experimental-zbc")
|
|
|
+ TARGET_BUILTIN(__builtin_riscv_clmulh, "LiLiLi", "nc", "experimental-zbc")
|
|
|
+ TARGET_BUILTIN(__builtin_riscv_clmulr, "LiLiLi", "nc", "experimental-zbc")
|
|
|
+
|
|
|
+-// Zbe extension
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_bcompress_32, "ZiZiZi", "nc", "experimental-zbe")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_bcompress_64, "WiWiWi", "nc",
|
|
|
+- "experimental-zbe,64bit")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_bdecompress_32, "ZiZiZi", "nc",
|
|
|
+- "experimental-zbe")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_bdecompress_64, "WiWiWi", "nc",
|
|
|
+- "experimental-zbe,64bit")
|
|
|
+-
|
|
|
+-// Zbp extension
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_grev_32, "ZiZiZi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_grev_64, "WiWiWi", "nc", "experimental-zbp,64bit")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_gorc_32, "ZiZiZi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_gorc_64, "WiWiWi", "nc", "experimental-zbp,64bit")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_shfl_32, "ZiZiZi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_shfl_64, "WiWiWi", "nc", "experimental-zbp,64bit")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_unshfl_32, "ZiZiZi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_unshfl_64, "WiWiWi", "nc", "experimental-zbp,64bit")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_xperm_n, "LiLiLi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_xperm_b, "LiLiLi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_xperm_h, "LiLiLi", "nc", "experimental-zbp")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_xperm_w, "WiWiWi", "nc", "experimental-zbp,64bit")
|
|
|
+-
|
|
|
+-// Zbr extension
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32_b, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32_h, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32_w, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32c_b, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32c_h, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32c_w, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32_d, "LiLi", "nc", "experimental-zbr")
|
|
|
+-TARGET_BUILTIN(__builtin_riscv_crc32c_d, "LiLi", "nc", "experimental-zbr")
|
|
|
+-
|
|
|
+ #undef BUILTIN
|
|
|
+ #undef TARGET_BUILTIN
|
|
|
+diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
|
|
|
+index 2a9ab387fa52..b38c8bf7d383 100644
|
|
|
+--- a/clang/lib/CodeGen/CGBuiltin.cpp
|
|
|
++++ b/clang/lib/CodeGen/CGBuiltin.cpp
|
|
|
+@@ -18514,31 +18514,7 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
|
|
|
+ case RISCV::BI__builtin_riscv_orc_b_64:
|
|
|
+ case RISCV::BI__builtin_riscv_clmul:
|
|
|
+ case RISCV::BI__builtin_riscv_clmulh:
|
|
|
+- case RISCV::BI__builtin_riscv_clmulr:
|
|
|
+- case RISCV::BI__builtin_riscv_bcompress_32:
|
|
|
+- case RISCV::BI__builtin_riscv_bcompress_64:
|
|
|
+- case RISCV::BI__builtin_riscv_bdecompress_32:
|
|
|
+- case RISCV::BI__builtin_riscv_bdecompress_64:
|
|
|
+- case RISCV::BI__builtin_riscv_grev_32:
|
|
|
+- case RISCV::BI__builtin_riscv_grev_64:
|
|
|
+- case RISCV::BI__builtin_riscv_gorc_32:
|
|
|
+- case RISCV::BI__builtin_riscv_gorc_64:
|
|
|
+- case RISCV::BI__builtin_riscv_shfl_32:
|
|
|
+- case RISCV::BI__builtin_riscv_shfl_64:
|
|
|
+- case RISCV::BI__builtin_riscv_unshfl_32:
|
|
|
+- case RISCV::BI__builtin_riscv_unshfl_64:
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_n:
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_b:
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_h:
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_w:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_b:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_h:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_w:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_d:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_b:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_h:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_w:
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_d: {
|
|
|
++ case RISCV::BI__builtin_riscv_clmulr: {
|
|
|
+ switch (BuiltinID) {
|
|
|
+ default: llvm_unreachable("unexpected builtin ID");
|
|
|
+ // Zbb
|
|
|
+@@ -18557,72 +18533,6 @@ Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID,
|
|
|
+ case RISCV::BI__builtin_riscv_clmulr:
|
|
|
+ ID = Intrinsic::riscv_clmulr;
|
|
|
+ break;
|
|
|
+-
|
|
|
+- // Zbe
|
|
|
+- case RISCV::BI__builtin_riscv_bcompress_32:
|
|
|
+- case RISCV::BI__builtin_riscv_bcompress_64:
|
|
|
+- ID = Intrinsic::riscv_bcompress;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_bdecompress_32:
|
|
|
+- case RISCV::BI__builtin_riscv_bdecompress_64:
|
|
|
+- ID = Intrinsic::riscv_bdecompress;
|
|
|
+- break;
|
|
|
+-
|
|
|
+- // Zbp
|
|
|
+- case RISCV::BI__builtin_riscv_grev_32:
|
|
|
+- case RISCV::BI__builtin_riscv_grev_64:
|
|
|
+- ID = Intrinsic::riscv_grev;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_gorc_32:
|
|
|
+- case RISCV::BI__builtin_riscv_gorc_64:
|
|
|
+- ID = Intrinsic::riscv_gorc;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_shfl_32:
|
|
|
+- case RISCV::BI__builtin_riscv_shfl_64:
|
|
|
+- ID = Intrinsic::riscv_shfl;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_unshfl_32:
|
|
|
+- case RISCV::BI__builtin_riscv_unshfl_64:
|
|
|
+- ID = Intrinsic::riscv_unshfl;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_n:
|
|
|
+- ID = Intrinsic::riscv_xperm_n;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_b:
|
|
|
+- ID = Intrinsic::riscv_xperm_b;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_h:
|
|
|
+- ID = Intrinsic::riscv_xperm_h;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_xperm_w:
|
|
|
+- ID = Intrinsic::riscv_xperm_w;
|
|
|
+- break;
|
|
|
+-
|
|
|
+- // Zbr
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_b:
|
|
|
+- ID = Intrinsic::riscv_crc32_b;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_h:
|
|
|
+- ID = Intrinsic::riscv_crc32_h;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_w:
|
|
|
+- ID = Intrinsic::riscv_crc32_w;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32_d:
|
|
|
+- ID = Intrinsic::riscv_crc32_d;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_b:
|
|
|
+- ID = Intrinsic::riscv_crc32c_b;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_h:
|
|
|
+- ID = Intrinsic::riscv_crc32c_h;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_w:
|
|
|
+- ID = Intrinsic::riscv_crc32c_w;
|
|
|
+- break;
|
|
|
+- case RISCV::BI__builtin_riscv_crc32c_d:
|
|
|
+- ID = Intrinsic::riscv_crc32c_d;
|
|
|
+- break;
|
|
|
+ }
|
|
|
+
|
|
|
+ IntrinsicTypes = {ResultType};
|
|
|
+diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
|
|
|
+index f54ac5b166d4..e7ac0a6a0e14 100644
|
|
|
+--- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
|
|
|
++++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp
|
|
|
+@@ -61,8 +61,7 @@ isExperimentalExtension(StringRef Ext) {
|
|
|
+ if (Ext == "b" || Ext == "zba" || Ext == "zbb" || Ext == "zbc" ||
|
|
|
+ Ext == "zbs")
|
|
|
+ return RISCVExtensionVersion{"1", "0"};
|
|
|
+- if (Ext == "zbe" || Ext == "zbf" || Ext == "zbm" || Ext == "zbp" ||
|
|
|
+- Ext == "zbr" || Ext == "zbt" || Ext == "zbproposedc")
|
|
|
++ if (Ext == "zbproposedc")
|
|
|
+ return RISCVExtensionVersion{"0", "94"};
|
|
|
+ if (Ext == "v" || Ext == "zvamo" || Ext == "zvlsseg")
|
|
|
+ return RISCVExtensionVersion{"0", "10"};
|
|
|
+diff --git a/llvm/include/llvm/IR/IntrinsicsRISCV.td b/llvm/include/llvm/IR/IntrinsicsRISCV.td
|
|
|
+index b3f82c7022a8..053f98452652 100644
|
|
|
+--- a/llvm/include/llvm/IR/IntrinsicsRISCV.td
|
|
|
++++ b/llvm/include/llvm/IR/IntrinsicsRISCV.td
|
|
|
+@@ -89,29 +89,6 @@ let TargetPrefix = "riscv" in {
|
|
|
+ def int_riscv_clmulh : BitManipGPRGPRIntrinsics;
|
|
|
+ def int_riscv_clmulr : BitManipGPRGPRIntrinsics;
|
|
|
+
|
|
|
+- // Zbe
|
|
|
+- def int_riscv_bcompress : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_bdecompress : BitManipGPRGPRIntrinsics;
|
|
|
+-
|
|
|
+- // Zbp
|
|
|
+- def int_riscv_grev : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_gorc : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_shfl : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_unshfl : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_xperm_n : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_xperm_b : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_xperm_h : BitManipGPRGPRIntrinsics;
|
|
|
+- def int_riscv_xperm_w : BitManipGPRGPRIntrinsics;
|
|
|
+-
|
|
|
+- // Zbr
|
|
|
+- def int_riscv_crc32_b : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32_h : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32_w : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32_d : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32c_b : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32c_h : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32c_w : BitManipGPRIntrinsics;
|
|
|
+- def int_riscv_crc32c_d : BitManipGPRIntrinsics;
|
|
|
+ } // TargetPrefix = "riscv"
|
|
|
+
|
|
|
+ //===----------------------------------------------------------------------===//
|
|
|
+diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
|
|
|
+index 17548b7141a3..14e67bb8c6c9 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
|
|
|
++++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
|
|
|
+@@ -2078,15 +2078,9 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZba, "experimental-zba");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZbb, "experimental-zbb");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZbc, "experimental-zbc");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbe, "experimental-zbe");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbf, "experimental-zbf");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbm, "experimental-zbm");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbp, "experimental-zbp");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZbproposedc,
|
|
|
+ "experimental-zbproposedc");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbr, "experimental-zbr");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZbs, "experimental-zbs");
|
|
|
+- clearFeatureBits(RISCV::FeatureStdExtZbt, "experimental-zbt");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZvamo, "experimental-zvamo");
|
|
|
+ clearFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg");
|
|
|
+
|
|
|
+@@ -2126,23 +2120,11 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
|
|
|
+ setFeatureBits(RISCV::FeatureStdExtZbb, "experimental-zbb");
|
|
|
+ else if (Ext == "zbc")
|
|
|
+ setFeatureBits(RISCV::FeatureStdExtZbc, "experimental-zbc");
|
|
|
+- else if (Ext == "zbe")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbe, "experimental-zbe");
|
|
|
+- else if (Ext == "zbf")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbf, "experimental-zbf");
|
|
|
+- else if (Ext == "zbm")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbm, "experimental-zbm");
|
|
|
+- else if (Ext == "zbp")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbp, "experimental-zbp");
|
|
|
+ else if (Ext == "zbproposedc")
|
|
|
+ setFeatureBits(RISCV::FeatureStdExtZbproposedc,
|
|
|
+ "experimental-zbproposedc");
|
|
|
+- else if (Ext == "zbr")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbr, "experimental-zbr");
|
|
|
+ else if (Ext == "zbs")
|
|
|
+ setFeatureBits(RISCV::FeatureStdExtZbs, "experimental-zbs");
|
|
|
+- else if (Ext == "zbt")
|
|
|
+- setFeatureBits(RISCV::FeatureStdExtZbt, "experimental-zbt");
|
|
|
+ else if (Ext == "zfh")
|
|
|
+ setFeatureBits(RISCV::FeatureStdExtZfh, "experimental-zfh");
|
|
|
+ else if (Ext == "zvamo")
|
|
|
+@@ -2203,22 +2185,10 @@ bool RISCVAsmParser::parseDirectiveAttribute() {
|
|
|
+ formalArchStr = (Twine(formalArchStr) + "_zbb1p0").str();
|
|
|
+ if (getFeatureBits(RISCV::FeatureStdExtZbc))
|
|
|
+ formalArchStr = (Twine(formalArchStr) + "_zbc1p0").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbe))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbe0p94").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbf))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbf0p94").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbm))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbm0p94").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbp))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbp0p94").str();
|
|
|
+ if (getFeatureBits(RISCV::FeatureStdExtZbproposedc))
|
|
|
+ formalArchStr = (Twine(formalArchStr) + "_zbproposedc0p94").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbr))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbr0p94").str();
|
|
|
+ if (getFeatureBits(RISCV::FeatureStdExtZbs))
|
|
|
+ formalArchStr = (Twine(formalArchStr) + "_zbs1p0").str();
|
|
|
+- if (getFeatureBits(RISCV::FeatureStdExtZbt))
|
|
|
+- formalArchStr = (Twine(formalArchStr) + "_zbt0p94").str();
|
|
|
+ if (getFeatureBits(RISCV::FeatureStdExtZvamo))
|
|
|
+ formalArchStr = (Twine(formalArchStr) + "_zvamo0p10").str();
|
|
|
+ if (getFeatureBits(RISCV::FeatureStdExtZvlsseg))
|
|
|
+diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
|
|
|
+index 14b54fb83097..043fb2b8c962 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
|
|
|
++++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVTargetStreamer.cpp
|
|
|
+@@ -72,22 +72,10 @@ void RISCVTargetStreamer::emitTargetAttributes(const MCSubtargetInfo &STI) {
|
|
|
+ Arch += "_zbb1p0";
|
|
|
+ if (STI.hasFeature(RISCV::FeatureStdExtZbc))
|
|
|
+ Arch += "_zbc1p0";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbe))
|
|
|
+- Arch += "_zbe0p94";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbf))
|
|
|
+- Arch += "_zbf0p94";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbm))
|
|
|
+- Arch += "_zbm0p94";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbp))
|
|
|
+- Arch += "_zbp0p94";
|
|
|
+ if (STI.hasFeature(RISCV::FeatureStdExtZbproposedc))
|
|
|
+ Arch += "_zbproposedc0p94";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbr))
|
|
|
+- Arch += "_zbr0p94";
|
|
|
+ if (STI.hasFeature(RISCV::FeatureStdExtZbs))
|
|
|
+ Arch += "_zbs1p0";
|
|
|
+- if (STI.hasFeature(RISCV::FeatureStdExtZbt))
|
|
|
+- Arch += "_zbt0p94";
|
|
|
+ if (STI.hasFeature(RISCV::FeatureStdExtZvamo))
|
|
|
+ Arch += "_zvamo0p10";
|
|
|
+ if (STI.hasFeature(RISCV::FeatureStdExtZvlsseg))
|
|
|
+diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
|
|
|
+index 005f653975dd..55b592ecec58 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
|
|
|
++++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
|
|
|
+@@ -245,7 +245,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|
|
+ setOperationAction(ISD::SRL_PARTS, XLenVT, Custom);
|
|
|
+ setOperationAction(ISD::SRA_PARTS, XLenVT, Custom);
|
|
|
+
|
|
|
+- if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
|
|
|
++ if (Subtarget.hasStdExtZbb()) {
|
|
|
+ if (Subtarget.is64Bit()) {
|
|
|
+ setOperationAction(ISD::ROTL, MVT::i32, Custom);
|
|
|
+ setOperationAction(ISD::ROTR, MVT::i32, Custom);
|
|
|
+@@ -255,26 +255,10 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|
|
+ setOperationAction(ISD::ROTR, XLenVT, Expand);
|
|
|
+ }
|
|
|
+
|
|
|
+- if (Subtarget.hasStdExtZbp()) {
|
|
|
+- // Custom lower bswap/bitreverse so we can convert them to GREVI to enable
|
|
|
+- // more combining.
|
|
|
+- setOperationAction(ISD::BITREVERSE, XLenVT, Custom);
|
|
|
+- setOperationAction(ISD::BSWAP, XLenVT, Custom);
|
|
|
+- setOperationAction(ISD::BITREVERSE, MVT::i8, Custom);
|
|
|
+- // BSWAP i8 doesn't exist.
|
|
|
+- setOperationAction(ISD::BITREVERSE, MVT::i16, Custom);
|
|
|
+- setOperationAction(ISD::BSWAP, MVT::i16, Custom);
|
|
|
+-
|
|
|
+- if (Subtarget.is64Bit()) {
|
|
|
+- setOperationAction(ISD::BITREVERSE, MVT::i32, Custom);
|
|
|
+- setOperationAction(ISD::BSWAP, MVT::i32, Custom);
|
|
|
+- }
|
|
|
+- } else {
|
|
|
+- // With Zbb we have an XLen rev8 instruction, but not GREVI. So we'll
|
|
|
+- // pattern match it directly in isel.
|
|
|
+- setOperationAction(ISD::BSWAP, XLenVT,
|
|
|
+- Subtarget.hasStdExtZbb() ? Legal : Expand);
|
|
|
+- }
|
|
|
++ // With Zbb we have an XLen rev8 instruction, but not GREVI. So we'll
|
|
|
++ // pattern match it directly in isel.
|
|
|
++ setOperationAction(ISD::BSWAP, XLenVT,
|
|
|
++ Subtarget.hasStdExtZbb() ? Legal : Expand);
|
|
|
+
|
|
|
+ if (Subtarget.hasStdExtZbb()) {
|
|
|
+ setOperationAction(ISD::SMIN, XLenVT, Legal);
|
|
|
+@@ -294,18 +278,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|
|
+ setOperationAction(ISD::CTPOP, XLenVT, Expand);
|
|
|
+ }
|
|
|
+
|
|
|
+- if (Subtarget.hasStdExtZbt()) {
|
|
|
+- setOperationAction(ISD::FSHL, XLenVT, Custom);
|
|
|
+- setOperationAction(ISD::FSHR, XLenVT, Custom);
|
|
|
+- setOperationAction(ISD::SELECT, XLenVT, Legal);
|
|
|
+-
|
|
|
+- if (Subtarget.is64Bit()) {
|
|
|
+- setOperationAction(ISD::FSHL, MVT::i32, Custom);
|
|
|
+- setOperationAction(ISD::FSHR, MVT::i32, Custom);
|
|
|
+- }
|
|
|
+- } else {
|
|
|
+- setOperationAction(ISD::SELECT, XLenVT, Custom);
|
|
|
+- }
|
|
|
++ setOperationAction(ISD::SELECT, XLenVT, Custom);
|
|
|
++
|
|
|
+
|
|
|
+ static const ISD::CondCode FPCCToExpand[] = {
|
|
|
+ ISD::SETOGT, ISD::SETOGE, ISD::SETONE, ISD::SETUEQ, ISD::SETUGT,
|
|
|
+@@ -2416,20 +2390,6 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
|
|
|
+ return LowerINTRINSIC_W_CHAIN(Op, DAG);
|
|
|
+ case ISD::INTRINSIC_VOID:
|
|
|
+ return LowerINTRINSIC_VOID(Op, DAG);
|
|
|
+- case ISD::BSWAP:
|
|
|
+- case ISD::BITREVERSE: {
|
|
|
+- // Convert BSWAP/BITREVERSE to GREVI to enable GREVI combinining.
|
|
|
+- assert(Subtarget.hasStdExtZbp() && "Unexpected custom legalisation");
|
|
|
+- MVT VT = Op.getSimpleValueType();
|
|
|
+- SDLoc DL(Op);
|
|
|
+- // Start with the maximum immediate value which is the bitwidth - 1.
|
|
|
+- unsigned Imm = VT.getSizeInBits() - 1;
|
|
|
+- // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits.
|
|
|
+- if (Op.getOpcode() == ISD::BSWAP)
|
|
|
+- Imm &= ~0x7U;
|
|
|
+- return DAG.getNode(RISCVISD::GREV, DL, VT, Op.getOperand(0),
|
|
|
+- DAG.getConstant(Imm, DL, VT));
|
|
|
+- }
|
|
|
+ case ISD::FSHL:
|
|
|
+ case ISD::FSHR: {
|
|
|
+ MVT VT = Op.getSimpleValueType();
|
|
|
+@@ -3841,24 +3801,6 @@ SDValue RISCVTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
|
|
|
+ // Lower to the GORCI encoding for orc.b.
|
|
|
+ return DAG.getNode(RISCVISD::GORC, DL, XLenVT, Op.getOperand(1),
|
|
|
+ DAG.getConstant(7, DL, XLenVT));
|
|
|
+- case Intrinsic::riscv_grev:
|
|
|
+- case Intrinsic::riscv_gorc: {
|
|
|
+- unsigned Opc =
|
|
|
+- IntNo == Intrinsic::riscv_grev ? RISCVISD::GREV : RISCVISD::GORC;
|
|
|
+- return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1), Op.getOperand(2));
|
|
|
+- }
|
|
|
+- case Intrinsic::riscv_shfl:
|
|
|
+- case Intrinsic::riscv_unshfl: {
|
|
|
+- unsigned Opc =
|
|
|
+- IntNo == Intrinsic::riscv_shfl ? RISCVISD::SHFL : RISCVISD::UNSHFL;
|
|
|
+- return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1), Op.getOperand(2));
|
|
|
+- }
|
|
|
+- case Intrinsic::riscv_bcompress:
|
|
|
+- case Intrinsic::riscv_bdecompress: {
|
|
|
+- unsigned Opc = IntNo == Intrinsic::riscv_bcompress ? RISCVISD::BCOMPRESS
|
|
|
+- : RISCVISD::BDECOMPRESS;
|
|
|
+- return DAG.getNode(Opc, DL, XLenVT, Op.getOperand(1), Op.getOperand(2));
|
|
|
+- }
|
|
|
+ case Intrinsic::riscv_vmv_x_s:
|
|
|
+ assert(Op.getValueType() == XLenVT && "Unexpected VT!");
|
|
|
+ return DAG.getNode(RISCVISD::VMV_X_S, DL, Op.getValueType(),
|
|
|
+@@ -5712,26 +5654,6 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
|
|
|
+ Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, NewRes));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+- case ISD::BSWAP:
|
|
|
+- case ISD::BITREVERSE: {
|
|
|
+- MVT VT = N->getSimpleValueType(0);
|
|
|
+- MVT XLenVT = Subtarget.getXLenVT();
|
|
|
+- assert((VT == MVT::i8 || VT == MVT::i16 ||
|
|
|
+- (VT == MVT::i32 && Subtarget.is64Bit())) &&
|
|
|
+- Subtarget.hasStdExtZbp() && "Unexpected custom legalisation");
|
|
|
+- SDValue NewOp0 = DAG.getNode(ISD::ANY_EXTEND, DL, XLenVT, N->getOperand(0));
|
|
|
+- unsigned Imm = VT.getSizeInBits() - 1;
|
|
|
+- // If this is BSWAP rather than BITREVERSE, clear the lower 3 bits.
|
|
|
+- if (N->getOpcode() == ISD::BSWAP)
|
|
|
+- Imm &= ~0x7U;
|
|
|
+- unsigned Opc = Subtarget.is64Bit() ? RISCVISD::GREVW : RISCVISD::GREV;
|
|
|
+- SDValue GREVI =
|
|
|
+- DAG.getNode(Opc, DL, XLenVT, NewOp0, DAG.getConstant(Imm, DL, XLenVT));
|
|
|
+- // ReplaceNodeResults requires we maintain the same type for the return
|
|
|
+- // value.
|
|
|
+- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, VT, GREVI));
|
|
|
+- break;
|
|
|
+- }
|
|
|
+ case ISD::FSHL:
|
|
|
+ case ISD::FSHR: {
|
|
|
+ assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
|
|
|
+@@ -5816,67 +5738,6 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
|
|
|
+ default:
|
|
|
+ llvm_unreachable(
|
|
|
+ "Don't know how to custom type legalize this intrinsic!");
|
|
|
+- case Intrinsic::riscv_orc_b: {
|
|
|
+- // Lower to the GORCI encoding for orc.b with the operand extended.
|
|
|
+- SDValue NewOp =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
|
|
|
+- // If Zbp is enabled, use GORCIW which will sign extend the result.
|
|
|
+- unsigned Opc =
|
|
|
+- Subtarget.hasStdExtZbp() ? RISCVISD::GORCW : RISCVISD::GORC;
|
|
|
+- SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp,
|
|
|
+- DAG.getConstant(7, DL, MVT::i64));
|
|
|
+- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
|
|
|
+- return;
|
|
|
+- }
|
|
|
+- case Intrinsic::riscv_grev:
|
|
|
+- case Intrinsic::riscv_gorc: {
|
|
|
+- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
|
|
|
+- "Unexpected custom legalisation");
|
|
|
+- SDValue NewOp1 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
|
|
|
+- SDValue NewOp2 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
|
|
|
+- unsigned Opc =
|
|
|
+- IntNo == Intrinsic::riscv_grev ? RISCVISD::GREVW : RISCVISD::GORCW;
|
|
|
+- SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp1, NewOp2);
|
|
|
+- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
|
|
|
+- break;
|
|
|
+- }
|
|
|
+- case Intrinsic::riscv_shfl:
|
|
|
+- case Intrinsic::riscv_unshfl: {
|
|
|
+- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
|
|
|
+- "Unexpected custom legalisation");
|
|
|
+- SDValue NewOp1 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
|
|
|
+- SDValue NewOp2 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
|
|
|
+- unsigned Opc =
|
|
|
+- IntNo == Intrinsic::riscv_shfl ? RISCVISD::SHFLW : RISCVISD::UNSHFLW;
|
|
|
+- if (isa<ConstantSDNode>(N->getOperand(2))) {
|
|
|
+- NewOp2 = DAG.getNode(ISD::AND, DL, MVT::i64, NewOp2,
|
|
|
+- DAG.getConstant(0xf, DL, MVT::i64));
|
|
|
+- Opc =
|
|
|
+- IntNo == Intrinsic::riscv_shfl ? RISCVISD::SHFL : RISCVISD::UNSHFL;
|
|
|
+- }
|
|
|
+- SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp1, NewOp2);
|
|
|
+- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
|
|
|
+- break;
|
|
|
+- }
|
|
|
+- case Intrinsic::riscv_bcompress:
|
|
|
+- case Intrinsic::riscv_bdecompress: {
|
|
|
+- assert(N->getValueType(0) == MVT::i32 && Subtarget.is64Bit() &&
|
|
|
+- "Unexpected custom legalisation");
|
|
|
+- SDValue NewOp1 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(1));
|
|
|
+- SDValue NewOp2 =
|
|
|
+- DAG.getNode(ISD::ANY_EXTEND, DL, MVT::i64, N->getOperand(2));
|
|
|
+- unsigned Opc = IntNo == Intrinsic::riscv_bcompress
|
|
|
+- ? RISCVISD::BCOMPRESSW
|
|
|
+- : RISCVISD::BDECOMPRESSW;
|
|
|
+- SDValue Res = DAG.getNode(Opc, DL, MVT::i64, NewOp1, NewOp2);
|
|
|
+- Results.push_back(DAG.getNode(ISD::TRUNCATE, DL, MVT::i32, Res));
|
|
|
+- break;
|
|
|
+- }
|
|
|
+ case Intrinsic::riscv_vmv_x_s: {
|
|
|
+ EVT VT = N->getValueType(0);
|
|
|
+ MVT XLenVT = Subtarget.getXLenVT();
|
|
|
+@@ -6060,91 +5921,6 @@ static Optional<RISCVBitmanipPat> matchGREVIPat(SDValue Op) {
|
|
|
+ return matchRISCVBitmanipPat(Op, BitmanipMasks);
|
|
|
+ }
|
|
|
+
|
|
|
+-// Match the following pattern as a GREVI(W) operation
|
|
|
+-// (or (BITMANIP_SHL x), (BITMANIP_SRL x))
|
|
|
+-static SDValue combineORToGREV(SDValue Op, SelectionDAG &DAG,
|
|
|
+- const RISCVSubtarget &Subtarget) {
|
|
|
+- assert(Subtarget.hasStdExtZbp() && "Expected Zbp extenson");
|
|
|
+- EVT VT = Op.getValueType();
|
|
|
+-
|
|
|
+- if (VT == Subtarget.getXLenVT() || (Subtarget.is64Bit() && VT == MVT::i32)) {
|
|
|
+- auto LHS = matchGREVIPat(Op.getOperand(0));
|
|
|
+- auto RHS = matchGREVIPat(Op.getOperand(1));
|
|
|
+- if (LHS && RHS && LHS->formsPairWith(*RHS)) {
|
|
|
+- SDLoc DL(Op);
|
|
|
+- return DAG.getNode(RISCVISD::GREV, DL, VT, LHS->Op,
|
|
|
+- DAG.getConstant(LHS->ShAmt, DL, VT));
|
|
|
+- }
|
|
|
+- }
|
|
|
+- return SDValue();
|
|
|
+-}
|
|
|
+-
|
|
|
+-// Matches any the following pattern as a GORCI(W) operation
|
|
|
+-// 1. (or (GREVI x, shamt), x) if shamt is a power of 2
|
|
|
+-// 2. (or x, (GREVI x, shamt)) if shamt is a power of 2
|
|
|
+-// 3. (or (or (BITMANIP_SHL x), x), (BITMANIP_SRL x))
|
|
|
+-// Note that with the variant of 3.,
|
|
|
+-// (or (or (BITMANIP_SHL x), (BITMANIP_SRL x)), x)
|
|
|
+-// the inner pattern will first be matched as GREVI and then the outer
|
|
|
+-// pattern will be matched to GORC via the first rule above.
|
|
|
+-// 4. (or (rotl/rotr x, bitwidth/2), x)
|
|
|
+-static SDValue combineORToGORC(SDValue Op, SelectionDAG &DAG,
|
|
|
+- const RISCVSubtarget &Subtarget) {
|
|
|
+- assert(Subtarget.hasStdExtZbp() && "Expected Zbp extenson");
|
|
|
+- EVT VT = Op.getValueType();
|
|
|
+-
|
|
|
+- if (VT == Subtarget.getXLenVT() || (Subtarget.is64Bit() && VT == MVT::i32)) {
|
|
|
+- SDLoc DL(Op);
|
|
|
+- SDValue Op0 = Op.getOperand(0);
|
|
|
+- SDValue Op1 = Op.getOperand(1);
|
|
|
+-
|
|
|
+- auto MatchOROfReverse = [&](SDValue Reverse, SDValue X) {
|
|
|
+- if (Reverse.getOpcode() == RISCVISD::GREV && Reverse.getOperand(0) == X &&
|
|
|
+- isa<ConstantSDNode>(Reverse.getOperand(1)) &&
|
|
|
+- isPowerOf2_32(Reverse.getConstantOperandVal(1)))
|
|
|
+- return DAG.getNode(RISCVISD::GORC, DL, VT, X, Reverse.getOperand(1));
|
|
|
+- // We can also form GORCI from ROTL/ROTR by half the bitwidth.
|
|
|
+- if ((Reverse.getOpcode() == ISD::ROTL ||
|
|
|
+- Reverse.getOpcode() == ISD::ROTR) &&
|
|
|
+- Reverse.getOperand(0) == X &&
|
|
|
+- isa<ConstantSDNode>(Reverse.getOperand(1))) {
|
|
|
+- uint64_t RotAmt = Reverse.getConstantOperandVal(1);
|
|
|
+- if (RotAmt == (VT.getSizeInBits() / 2))
|
|
|
+- return DAG.getNode(RISCVISD::GORC, DL, VT, X,
|
|
|
+- DAG.getConstant(RotAmt, DL, VT));
|
|
|
+- }
|
|
|
+- return SDValue();
|
|
|
+- };
|
|
|
+-
|
|
|
+- // Check for either commutable permutation of (or (GREVI x, shamt), x)
|
|
|
+- if (SDValue V = MatchOROfReverse(Op0, Op1))
|
|
|
+- return V;
|
|
|
+- if (SDValue V = MatchOROfReverse(Op1, Op0))
|
|
|
+- return V;
|
|
|
+-
|
|
|
+- // OR is commutable so canonicalize its OR operand to the left
|
|
|
+- if (Op0.getOpcode() != ISD::OR && Op1.getOpcode() == ISD::OR)
|
|
|
+- std::swap(Op0, Op1);
|
|
|
+- if (Op0.getOpcode() != ISD::OR)
|
|
|
+- return SDValue();
|
|
|
+- SDValue OrOp0 = Op0.getOperand(0);
|
|
|
+- SDValue OrOp1 = Op0.getOperand(1);
|
|
|
+- auto LHS = matchGREVIPat(OrOp0);
|
|
|
+- // OR is commutable so swap the operands and try again: x might have been
|
|
|
+- // on the left
|
|
|
+- if (!LHS) {
|
|
|
+- std::swap(OrOp0, OrOp1);
|
|
|
+- LHS = matchGREVIPat(OrOp0);
|
|
|
+- }
|
|
|
+- auto RHS = matchGREVIPat(Op1);
|
|
|
+- if (LHS && RHS && LHS->formsPairWith(*RHS) && LHS->Op == OrOp1) {
|
|
|
+- return DAG.getNode(RISCVISD::GORC, DL, VT, LHS->Op,
|
|
|
+- DAG.getConstant(LHS->ShAmt, DL, VT));
|
|
|
+- }
|
|
|
+- }
|
|
|
+- return SDValue();
|
|
|
+-}
|
|
|
+-
|
|
|
+ // Matches any of the following bit-manipulation patterns:
|
|
|
+ // (and (shl x, 1), (0x22222222 << 1))
|
|
|
+ // (and (srl x, 1), 0x22222222)
|
|
|
+@@ -6166,80 +5942,6 @@ static Optional<RISCVBitmanipPat> matchSHFLPat(SDValue Op) {
|
|
|
+ return matchRISCVBitmanipPat(Op, BitmanipMasks);
|
|
|
+ }
|
|
|
+
|
|
|
+-// Match (or (or (SHFL_SHL x), (SHFL_SHR x)), (SHFL_AND x)
|
|
|
+-static SDValue combineORToSHFL(SDValue Op, SelectionDAG &DAG,
|
|
|
+- const RISCVSubtarget &Subtarget) {
|
|
|
+- assert(Subtarget.hasStdExtZbp() && "Expected Zbp extenson");
|
|
|
+- EVT VT = Op.getValueType();
|
|
|
+-
|
|
|
+- if (VT != MVT::i32 && VT != Subtarget.getXLenVT())
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- SDValue Op0 = Op.getOperand(0);
|
|
|
+- SDValue Op1 = Op.getOperand(1);
|
|
|
+-
|
|
|
+- // Or is commutable so canonicalize the second OR to the LHS.
|
|
|
+- if (Op0.getOpcode() != ISD::OR)
|
|
|
+- std::swap(Op0, Op1);
|
|
|
+- if (Op0.getOpcode() != ISD::OR)
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- // We found an inner OR, so our operands are the operands of the inner OR
|
|
|
+- // and the other operand of the outer OR.
|
|
|
+- SDValue A = Op0.getOperand(0);
|
|
|
+- SDValue B = Op0.getOperand(1);
|
|
|
+- SDValue C = Op1;
|
|
|
+-
|
|
|
+- auto Match1 = matchSHFLPat(A);
|
|
|
+- auto Match2 = matchSHFLPat(B);
|
|
|
+-
|
|
|
+- // If neither matched, we failed.
|
|
|
+- if (!Match1 && !Match2)
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- // We had at least one match. if one failed, try the remaining C operand.
|
|
|
+- if (!Match1) {
|
|
|
+- std::swap(A, C);
|
|
|
+- Match1 = matchSHFLPat(A);
|
|
|
+- if (!Match1)
|
|
|
+- return SDValue();
|
|
|
+- } else if (!Match2) {
|
|
|
+- std::swap(B, C);
|
|
|
+- Match2 = matchSHFLPat(B);
|
|
|
+- if (!Match2)
|
|
|
+- return SDValue();
|
|
|
+- }
|
|
|
+- assert(Match1 && Match2);
|
|
|
+-
|
|
|
+- // Make sure our matches pair up.
|
|
|
+- if (!Match1->formsPairWith(*Match2))
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- // All the remains is to make sure C is an AND with the same input, that masks
|
|
|
+- // out the bits that are being shuffled.
|
|
|
+- if (C.getOpcode() != ISD::AND || !isa<ConstantSDNode>(C.getOperand(1)) ||
|
|
|
+- C.getOperand(0) != Match1->Op)
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- uint64_t Mask = C.getConstantOperandVal(1);
|
|
|
+-
|
|
|
+- static const uint64_t BitmanipMasks[] = {
|
|
|
+- 0x9999999999999999ULL, 0xC3C3C3C3C3C3C3C3ULL, 0xF00FF00FF00FF00FULL,
|
|
|
+- 0xFF0000FFFF0000FFULL, 0xFFFF00000000FFFFULL,
|
|
|
+- };
|
|
|
+-
|
|
|
+- unsigned Width = Op.getValueType() == MVT::i64 ? 64 : 32;
|
|
|
+- unsigned MaskIdx = Log2_32(Match1->ShAmt);
|
|
|
+- uint64_t ExpMask = BitmanipMasks[MaskIdx] & maskTrailingOnes<uint64_t>(Width);
|
|
|
+-
|
|
|
+- if (Mask != ExpMask)
|
|
|
+- return SDValue();
|
|
|
+-
|
|
|
+- SDLoc DL(Op);
|
|
|
+- return DAG.getNode(RISCVISD::SHFL, DL, VT, Match1->Op,
|
|
|
+- DAG.getConstant(Match1->ShAmt, DL, VT));
|
|
|
+-}
|
|
|
+-
|
|
|
+ // Optimize (add (shl x, c0), (shl y, c1)) ->
|
|
|
+ // (SLLI (SH*ADD x, y), c0), if c1-c0 equals to [1|2|3].
|
|
|
+ static SDValue transformAddShlImm(SDNode *N, SelectionDAG &DAG,
|
|
|
+@@ -6465,15 +6167,6 @@ static SDValue performANDCombine(SDNode *N, SelectionDAG &DAG) {
|
|
|
+
|
|
|
+ static SDValue performORCombine(SDNode *N, SelectionDAG &DAG,
|
|
|
+ const RISCVSubtarget &Subtarget) {
|
|
|
+- if (Subtarget.hasStdExtZbp()) {
|
|
|
+- if (auto GREV = combineORToGREV(SDValue(N, 0), DAG, Subtarget))
|
|
|
+- return GREV;
|
|
|
+- if (auto GORC = combineORToGORC(SDValue(N, 0), DAG, Subtarget))
|
|
|
+- return GORC;
|
|
|
+- if (auto SHFL = combineORToSHFL(SDValue(N, 0), DAG, Subtarget))
|
|
|
+- return SHFL;
|
|
|
+- }
|
|
|
+-
|
|
|
+ // fold (or (select cond, 0, y), x) ->
|
|
|
+ // (select cond, x, (or x, y))
|
|
|
+ return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false);
|
|
|
+@@ -7159,7 +6852,7 @@ bool RISCVTargetLowering::targetShrinkDemandedConstant(
|
|
|
+ return false;
|
|
|
+
|
|
|
+ // Preserve (and X, 0xffff) when zext.h is supported.
|
|
|
+- if (Subtarget.hasStdExtZbb() || Subtarget.hasStdExtZbp()) {
|
|
|
++ if (Subtarget.hasStdExtZbb()) {
|
|
|
+ APInt NewMask = APInt(Mask.getBitWidth(), 0xffff);
|
|
|
+ if (IsLegalMask(NewMask))
|
|
|
+ return UseMask(NewMask);
|
|
|
+diff --git a/llvm/lib/Target/RISCV/RISCVInstrFormats.td b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
|
|
|
+index a6e2710949b2..d82e414a3f98 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/RISCVInstrFormats.td
|
|
|
++++ b/llvm/lib/Target/RISCV/RISCVInstrFormats.td
|
|
|
+@@ -322,6 +322,18 @@ class RVInstI<bits<3> funct3, RISCVOpcode opcode, dag outs, dag ins,
|
|
|
+ let Opcode = opcode.Value;
|
|
|
+ }
|
|
|
+
|
|
|
++class RVInstCache<bits<12> cache, RISCVOpcode opcode, dag outs, dag ins,
|
|
|
++ string opcodestr, string argstr>
|
|
|
++ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
|
|
|
++ bits<5> rs1;
|
|
|
++
|
|
|
++ let Inst{31-20} = cache;
|
|
|
++ let Inst{19-15} = rs1;
|
|
|
++ let Inst{14-12} = 0;
|
|
|
++ let Inst{11-7} = 0;
|
|
|
++ let Opcode = opcode.Value;
|
|
|
++}
|
|
|
++
|
|
|
+ class RVInstIShift<bits<5> imm11_7, bits<3> funct3, RISCVOpcode opcode,
|
|
|
+ dag outs, dag ins, string opcodestr, string argstr>
|
|
|
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatI> {
|
|
|
+diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
|
|
|
+index 575df86d27a8..ea009dc98101 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
|
|
|
++++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
|
|
|
+@@ -446,6 +446,12 @@ class CSR_ir<bits<3> funct3, string opcodestr>
|
|
|
+ : RVInstI<funct3, OPC_SYSTEM, (outs GPR:$rd), (ins csr_sysreg:$imm12, GPR:$rs1),
|
|
|
+ opcodestr, "$rd, $imm12, $rs1">, Sched<[WriteCSR, ReadCSR]>;
|
|
|
+
|
|
|
++let hasNoSchedulingInfo = 1,
|
|
|
++ hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
|
|
|
++class CSR_cache<bits<12> cache, string opcodestr>
|
|
|
++ : RVInstCache<cache, OPC_SYSTEM, (outs), (ins GPR:$rs1),
|
|
|
++ opcodestr, "$rs1">, Sched<[WriteCSR, ReadCSR]>;
|
|
|
++
|
|
|
+ let hasNoSchedulingInfo = 1,
|
|
|
+ hasSideEffects = 1, mayLoad = 0, mayStore = 0 in
|
|
|
+ class CSR_ii<bits<3> funct3, string opcodestr>
|
|
|
+@@ -588,6 +594,13 @@ def UNIMP : RVInstI<0b001, OPC_SYSTEM, (outs), (ins), "unimp", "">,
|
|
|
+ }
|
|
|
+ } // hasSideEffects = 1, mayLoad = 0, mayStore = 0
|
|
|
+
|
|
|
++/* Custom instruction and CSRs */
|
|
|
++def CFLUSH_D_L1 : CSR_cache<0b111111000000, "cflush.d.l1">;
|
|
|
++def CDISCARD_D_L1 : CSR_cache<0b111111000010, "cdiscard.d.l1">;
|
|
|
++def CFLUSH_D_L2 : CSR_cache<0b111111000100, "cflush.d.l2">;
|
|
|
++def CDISCARD_D_L2 : CSR_cache<0b111111000110, "cdiscard.d.l2">;
|
|
|
++/* End */
|
|
|
++
|
|
|
+ def CSRRW : CSR_ir<0b001, "csrrw">;
|
|
|
+ def CSRRS : CSR_ir<0b010, "csrrs">;
|
|
|
+ def CSRRC : CSR_ir<0b011, "csrrc">;
|
|
|
+diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
|
|
|
+index d2e77ae86a83..7f4985ab4940 100644
|
|
|
+--- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
|
|
|
++++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td
|
|
|
+@@ -299,14 +299,14 @@ class RVBTernaryImm5<bits<2> funct2, bits<3> funct3, RISCVOpcode opcode,
|
|
|
+ // Instructions
|
|
|
+ //===----------------------------------------------------------------------===//
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def ANDN : ALU_rr<0b0100000, 0b111, "andn">,
|
|
|
+ Sched<[WriteIALU, ReadIALU, ReadIALU]>;
|
|
|
+ def ORN : ALU_rr<0b0100000, 0b110, "orn">,
|
|
|
+ Sched<[WriteIALU, ReadIALU, ReadIALU]>;
|
|
|
+ def XNOR : ALU_rr<0b0100000, 0b100, "xnor">,
|
|
|
+ Sched<[WriteIALU, ReadIALU, ReadIALU]>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZba] in {
|
|
|
+ def SH1ADD : ALU_rr<0b0010000, 0b010, "sh1add">,
|
|
|
+@@ -317,12 +317,12 @@ def SH3ADD : ALU_rr<0b0010000, 0b110, "sh3add">,
|
|
|
+ Sched<[WriteSHXADD, ReadSHXADD, ReadSHXADD]>;
|
|
|
+ } // Predicates = [HasStdExtZba]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def ROL : ALU_rr<0b0110000, 0b001, "rol">,
|
|
|
+ Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
|
|
|
+ def ROR : ALU_rr<0b0110000, 0b101, "ror">,
|
|
|
+ Sched<[WriteRotateReg, ReadRotateReg, ReadRotateReg]>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZbs] in {
|
|
|
+ def BCLR : ALU_rr<0b0100100, 0b001, "bclr">, Sched<[]>;
|
|
|
+@@ -331,18 +331,7 @@ def BINV : ALU_rr<0b0110100, 0b001, "binv">, Sched<[]>;
|
|
|
+ def BEXT : ALU_rr<0b0100100, 0b101, "bext">, Sched<[]>;
|
|
|
+ } // Predicates = [HasStdExtZbs]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def GORC : ALU_rr<0b0010100, 0b101, "gorc">, Sched<[]>;
|
|
|
+-def GREV : ALU_rr<0b0110100, 0b101, "grev">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def XPERMN : ALU_rr<0b0010100, 0b010, "xperm.n">, Sched<[]>;
|
|
|
+-def XPERMB : ALU_rr<0b0010100, 0b100, "xperm.b">, Sched<[]>;
|
|
|
+-def XPERMH : ALU_rr<0b0010100, 0b110, "xperm.h">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in
|
|
|
++let Predicates = [HasStdExtZbb] in
|
|
|
+ def RORI : RVBShift_ri<0b01100, 0b101, OPC_OP_IMM, "rori">,
|
|
|
+ Sched<[WriteRotateImm, ReadRotateImm]>;
|
|
|
+
|
|
|
+@@ -353,24 +342,6 @@ def BINVI : RVBShift_ri<0b01101, 0b001, OPC_OP_IMM, "binvi">, Sched<[]>;
|
|
|
+ def BEXTI : RVBShift_ri<0b01001, 0b101, OPC_OP_IMM, "bexti">, Sched<[]>;
|
|
|
+ } // Predicates = [HasStdExtZbs]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def GREVI : RVBShift_ri<0b01101, 0b101, OPC_OP_IMM, "grevi">, Sched<[]>;
|
|
|
+-def GORCI : RVBShift_ri<0b00101, 0b101, OPC_OP_IMM, "gorci">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbt] in {
|
|
|
+-def CMIX : RVBTernaryR<0b11, 0b001, OPC_OP, "cmix", "$rd, $rs2, $rs1, $rs3">,
|
|
|
+- Sched<[]>;
|
|
|
+-def CMOV : RVBTernaryR<0b11, 0b101, OPC_OP, "cmov", "$rd, $rs2, $rs1, $rs3">,
|
|
|
+- Sched<[]>;
|
|
|
+-def FSL : RVBTernaryR<0b10, 0b001, OPC_OP, "fsl", "$rd, $rs1, $rs3, $rs2">,
|
|
|
+- Sched<[]>;
|
|
|
+-def FSR : RVBTernaryR<0b10, 0b101, OPC_OP, "fsr", "$rd, $rs1, $rs3, $rs2">,
|
|
|
+- Sched<[]>;
|
|
|
+-def FSRI : RVBTernaryImm6<0b101, OPC_OP_IMM, "fsri",
|
|
|
+- "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbt]
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbb] in {
|
|
|
+ def CLZ : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0010011>, "clz">,
|
|
|
+ Sched<[WriteCLZ, ReadCLZ]>;
|
|
|
+@@ -380,10 +351,6 @@ def CPOP : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0010011>, "cpop">,
|
|
|
+ Sched<[WriteCPOP, ReadCPOP]>;
|
|
|
+ } // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbm, IsRV64] in
|
|
|
+-def BMATFLIP : RVBUnary<0b0110000, 0b00011, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "bmatflip">, Sched<[]>;
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbb] in {
|
|
|
+ def SEXTB : RVBUnary<0b0110000, 0b00100, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+ "sext.b">, Sched<[WriteIALU, ReadIALU]>;
|
|
|
+@@ -391,32 +358,6 @@ def SEXTH : RVBUnary<0b0110000, 0b00101, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+ "sext.h">, Sched<[WriteIALU, ReadIALU]>;
|
|
|
+ } // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbr] in {
|
|
|
+-def CRC32B : RVBUnary<0b0110000, 0b10000, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32.b">, Sched<[]>;
|
|
|
+-def CRC32H : RVBUnary<0b0110000, 0b10001, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32.h">, Sched<[]>;
|
|
|
+-def CRC32W : RVBUnary<0b0110000, 0b10010, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32.w">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbr]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbr, IsRV64] in
|
|
|
+-def CRC32D : RVBUnary<0b0110000, 0b10011, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32.d">, Sched<[]>;
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbr] in {
|
|
|
+-def CRC32CB : RVBUnary<0b0110000, 0b11000, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32c.b">, Sched<[]>;
|
|
|
+-def CRC32CH : RVBUnary<0b0110000, 0b11001, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32c.h">, Sched<[]>;
|
|
|
+-def CRC32CW : RVBUnary<0b0110000, 0b11010, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32c.w">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbr]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbr, IsRV64] in
|
|
|
+-def CRC32CD : RVBUnary<0b0110000, 0b11011, 0b001, RISCVOpcode<0b0010011>,
|
|
|
+- "crc32c.d">, Sched<[]>;
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbc] in {
|
|
|
+ def CLMUL : ALU_rr<0b0000101, 0b001, "clmul">, Sched<[]>;
|
|
|
+ def CLMULR : ALU_rr<0b0000101, 0b010, "clmulr">, Sched<[]>;
|
|
|
+@@ -434,37 +375,6 @@ def MAXU : ALU_rr<0b0000101, 0b111, "maxu">,
|
|
|
+ Sched<[WriteIALU, ReadIALU, ReadIALU]>;
|
|
|
+ } // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def SHFL : ALU_rr<0b0000100, 0b001, "shfl">, Sched<[]>;
|
|
|
+-def UNSHFL : ALU_rr<0b0000100, 0b101, "unshfl">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbe] in {
|
|
|
+-// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
|
|
|
+-// bext in the 0.93 spec.
|
|
|
+-def BDECOMPRESS : ALU_rr<0b0100100, 0b110, "bdecompress">, Sched<[]>;
|
|
|
+-def BCOMPRESS : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbe]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def PACK : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>;
|
|
|
+-def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>;
|
|
|
+-def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbm, IsRV64] in {
|
|
|
+-def BMATOR : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>;
|
|
|
+-def BMATXOR : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbm, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbf] in
|
|
|
+-def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>;
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def SHFLI : RVBShfl_ri<0b0000100, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
|
|
|
+-def UNSHFLI : RVBShfl_ri<0b0000100, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZba, IsRV64] in {
|
|
|
+ def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">,
|
|
|
+ Sched<[WriteShiftImm32, ReadShiftImm32]>;
|
|
|
+@@ -476,14 +386,14 @@ def SH2ADDUW : ALUW_rr<0b0010000, 0b100, "sh2add.uw">,
|
|
|
+ Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
|
|
|
+ def SH3ADDUW : ALUW_rr<0b0010000, 0b110, "sh3add.uw">,
|
|
|
+ Sched<[WriteSHXADD32, ReadSHXADD32, ReadSHXADD32]>;
|
|
|
+-} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZba, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def ROLW : ALUW_rr<0b0110000, 0b001, "rolw">,
|
|
|
+ Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
|
|
|
+ def RORW : ALUW_rr<0b0110000, 0b101, "rorw">,
|
|
|
+ Sched<[WriteRotateReg32, ReadRotateReg32, ReadRotateReg32]>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZbs, IsRV64] in {
|
|
|
+ // NOTE: These instructions have been removed from the 0.94 spec. As a result
|
|
|
+@@ -494,16 +404,7 @@ def BINVW : ALUW_rr<0b0110100, 0b001, "binvw">, Sched<[]>;
|
|
|
+ def BEXTW : ALUW_rr<0b0100100, 0b101, "bextw">, Sched<[]>;
|
|
|
+ } // Predicates = [HasStdExtZbs, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def GORCW : ALUW_rr<0b0010100, 0b101, "gorcw">, Sched<[]>;
|
|
|
+-def GREVW : ALUW_rr<0b0110100, 0b101, "grevw">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def XPERMW : ALU_rr<0b0010100, 0b000, "xperm.w">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in
|
|
|
+ def RORIW : RVBShiftW_ri<0b0110000, 0b101, OPC_OP_IMM_32, "roriw">,
|
|
|
+ Sched<[WriteRotateImm32, ReadRotateImm32]>;
|
|
|
+
|
|
|
+@@ -518,20 +419,6 @@ def BINVIW : RVBShiftW_ri<0b0110100, 0b001, OPC_OP_IMM_32, "binviw">,
|
|
|
+ Sched<[]>;
|
|
|
+ } // Predicates = [HasStdExtZbs, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def GORCIW : RVBShiftW_ri<0b0010100, 0b101, OPC_OP_IMM_32, "gorciw">, Sched<[]>;
|
|
|
+-def GREVIW : RVBShiftW_ri<0b0110100, 0b101, OPC_OP_IMM_32, "greviw">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbt, IsRV64] in {
|
|
|
+-def FSLW : RVBTernaryR<0b10, 0b001, OPC_OP_32,
|
|
|
+- "fslw", "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
|
|
|
+-def FSRW : RVBTernaryR<0b10, 0b101, OPC_OP_32, "fsrw",
|
|
|
+- "$rd, $rs1, $rs3, $rs2">, Sched<[]>;
|
|
|
+-def FSRIW : RVBTernaryImm5<0b10, 0b101, OPC_OP_IMM_32,
|
|
|
+- "fsriw", "$rd, $rs1, $rs3, $shamt">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbt, IsRV64]
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def CLZW : RVBUnary<0b0110000, 0b00000, 0b001, RISCVOpcode<0b0011011>,
|
|
|
+ "clzw">, Sched<[WriteCLZ32, ReadCLZ32]>;
|
|
|
+@@ -541,43 +428,23 @@ def CPOPW : RVBUnary<0b0110000, 0b00010, 0b001, RISCVOpcode<0b0011011>,
|
|
|
+ "cpopw">, Sched<[WriteCPOP32, ReadCPOP32]>;
|
|
|
+ } // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def SHFLW : ALUW_rr<0b0000100, 0b001, "shflw">, Sched<[]>;
|
|
|
+-def UNSHFLW : ALUW_rr<0b0000100, 0b101, "unshflw">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbe, IsRV64] in {
|
|
|
+-// NOTE: These mnemonics are from the 0.94 spec. There is a name conflict with
|
|
|
+-// bextw in the 0.93 spec.
|
|
|
+-def BDECOMPRESSW : ALUW_rr<0b0100100, 0b110, "bdecompressw">, Sched<[]>;
|
|
|
+-def BCOMPRESSW : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbe, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def PACKW : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>;
|
|
|
+-def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbf, IsRV64] in
|
|
|
+-def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>;
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV32] in {
|
|
|
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
|
+ def ZEXTH_RV32 : RVInstR<0b0000100, 0b100, OPC_OP, (outs GPR:$rd),
|
|
|
+ (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
|
|
|
+ Sched<[WriteIALU, ReadIALU]> {
|
|
|
+ let rs2 = 0b00000;
|
|
|
+ }
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV32]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
|
+ def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd),
|
|
|
+ (ins GPR:$rs1), "zext.h", "$rd, $rs1">,
|
|
|
+ Sched<[WriteIALU, ReadIALU]> {
|
|
|
+ let rs2 = 0b00000;
|
|
|
+ }
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+ // We treat rev8 and orc.b as standalone instructions even though they use a
|
|
|
+ // portion of the encodings for grevi and gorci. This allows us to support only
|
|
|
+@@ -586,29 +453,29 @@ def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd),
|
|
|
+ // causes diagnostics to suggest that Zbp rather than Zbb is required for rev8
|
|
|
+ // or gorci. Since Zbb is closer to being finalized than Zbp this will be
|
|
|
+ // misleading to users.
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV32] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV32] in {
|
|
|
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
|
+ def REV8_RV32 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
|
|
|
+ "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
|
|
|
+ let imm12 = { 0b01101, 0b0011000 };
|
|
|
+ }
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV32]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV32]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
|
+ def REV8_RV64 : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
|
|
|
+ "rev8", "$rd, $rs1">, Sched<[WriteREV8, ReadREV8]> {
|
|
|
+ let imm12 = { 0b01101, 0b0111000 };
|
|
|
+ }
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
|
+ def ORCB : RVInstI<0b101, OPC_OP_IMM, (outs GPR:$rd), (ins GPR:$rs1),
|
|
|
+ "orc.b", "$rd, $rs1">, Sched<[WriteORCB, ReadORCB]> {
|
|
|
+ let imm12 = { 0b00101, 0b0000111 };
|
|
|
+ }
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+ //===----------------------------------------------------------------------===//
|
|
|
+ // Future compressed instructions
|
|
|
+@@ -651,138 +518,15 @@ let Predicates = [HasStdExtZba, IsRV64] in {
|
|
|
+ def : InstAlias<"zext.w $rd, $rs", (ADDUW GPR:$rd, GPR:$rs, X0)>;
|
|
|
+ }
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def : InstAlias<"rev.p $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00001)>;
|
|
|
+-def : InstAlias<"rev2.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00010)>;
|
|
|
+-def : InstAlias<"rev.n $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00011)>;
|
|
|
+-def : InstAlias<"rev4.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00100)>;
|
|
|
+-def : InstAlias<"rev2.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00110)>;
|
|
|
+-def : InstAlias<"rev.b $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b00111)>;
|
|
|
+-def : InstAlias<"rev8.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01000)>;
|
|
|
+-def : InstAlias<"rev4.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01100)>;
|
|
|
+-def : InstAlias<"rev2.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01110)>;
|
|
|
+-def : InstAlias<"rev.h $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b01111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"zip.n $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0001)>;
|
|
|
+-def : InstAlias<"unzip.n $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0001)>;
|
|
|
+-def : InstAlias<"zip2.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0010)>;
|
|
|
+-def : InstAlias<"unzip2.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0010)>;
|
|
|
+-def : InstAlias<"zip.b $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0011)>;
|
|
|
+-def : InstAlias<"unzip.b $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0011)>;
|
|
|
+-def : InstAlias<"zip4.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0100)>;
|
|
|
+-def : InstAlias<"unzip4.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0100)>;
|
|
|
+-def : InstAlias<"zip2.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0110)>;
|
|
|
+-def : InstAlias<"unzip2.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0110)>;
|
|
|
+-def : InstAlias<"zip.h $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b0111)>;
|
|
|
+-def : InstAlias<"unzip.h $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b0111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"orc.p $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00001)>;
|
|
|
+-def : InstAlias<"orc2.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00010)>;
|
|
|
+-def : InstAlias<"orc.n $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00011)>;
|
|
|
+-def : InstAlias<"orc4.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00100)>;
|
|
|
+-def : InstAlias<"orc2.b $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b00110)>;
|
|
|
+-// orc.b is considered an instruction rather than an alias.
|
|
|
+-def : InstAlias<"orc8.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01000)>;
|
|
|
+-def : InstAlias<"orc4.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01100)>;
|
|
|
+-def : InstAlias<"orc2.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01110)>;
|
|
|
+-def : InstAlias<"orc.h $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b01111)>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV32] in {
|
|
|
+-def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b10000)>;
|
|
|
+-// rev8 is considered an instruction rather than an alias.
|
|
|
+-def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11100)>;
|
|
|
+-def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11110)>;
|
|
|
+-def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b11111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1000)>;
|
|
|
+-def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1000)>;
|
|
|
+-def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1100)>;
|
|
|
+-def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1100)>;
|
|
|
+-def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1110)>;
|
|
|
+-def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1110)>;
|
|
|
+-def : InstAlias<"zip $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b1111)>;
|
|
|
+-def : InstAlias<"unzip $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b1111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b10000)>;
|
|
|
+-def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11000)>;
|
|
|
+-def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11100)>;
|
|
|
+-def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11110)>;
|
|
|
+-def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b11111)>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV32]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def : InstAlias<"rev16.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b010000)>;
|
|
|
+-def : InstAlias<"rev8.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011000)>;
|
|
|
+-def : InstAlias<"rev4.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011100)>;
|
|
|
+-def : InstAlias<"rev2.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011110)>;
|
|
|
+-def : InstAlias<"rev.w $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b011111)>;
|
|
|
+-def : InstAlias<"rev32 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b100000)>;
|
|
|
+-def : InstAlias<"rev16 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b110000)>;
|
|
|
+-// rev8 is considered an instruction rather than an alias.
|
|
|
+-def : InstAlias<"rev4 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111100)>;
|
|
|
+-def : InstAlias<"rev2 $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111110)>;
|
|
|
+-def : InstAlias<"rev $rd, $rs", (GREVI GPR:$rd, GPR:$rs, 0b111111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"zip8.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01000)>;
|
|
|
+-def : InstAlias<"unzip8.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01000)>;
|
|
|
+-def : InstAlias<"zip4.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01100)>;
|
|
|
+-def : InstAlias<"unzip4.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01100)>;
|
|
|
+-def : InstAlias<"zip2.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01110)>;
|
|
|
+-def : InstAlias<"unzip2.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01110)>;
|
|
|
+-def : InstAlias<"zip.w $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b01111)>;
|
|
|
+-def : InstAlias<"unzip.w $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b01111)>;
|
|
|
+-def : InstAlias<"zip16 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b10000)>;
|
|
|
+-def : InstAlias<"unzip16 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b10000)>;
|
|
|
+-def : InstAlias<"zip8 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11000)>;
|
|
|
+-def : InstAlias<"unzip8 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11000)>;
|
|
|
+-def : InstAlias<"zip4 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11100)>;
|
|
|
+-def : InstAlias<"unzip4 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11100)>;
|
|
|
+-def : InstAlias<"zip2 $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11110)>;
|
|
|
+-def : InstAlias<"unzip2 $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11110)>;
|
|
|
+-def : InstAlias<"zip $rd, $rs", (SHFLI GPR:$rd, GPR:$rs, 0b11111)>;
|
|
|
+-def : InstAlias<"unzip $rd, $rs", (UNSHFLI GPR:$rd, GPR:$rs, 0b11111)>;
|
|
|
+-
|
|
|
+-def : InstAlias<"orc16.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b010000)>;
|
|
|
+-def : InstAlias<"orc8.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011000)>;
|
|
|
+-def : InstAlias<"orc4.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011100)>;
|
|
|
+-def : InstAlias<"orc2.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011110)>;
|
|
|
+-def : InstAlias<"orc.w $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b011111)>;
|
|
|
+-def : InstAlias<"orc32 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b100000)>;
|
|
|
+-def : InstAlias<"orc16 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b110000)>;
|
|
|
+-def : InstAlias<"orc8 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111000)>;
|
|
|
+-def : InstAlias<"orc4 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111100)>;
|
|
|
+-def : InstAlias<"orc2 $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111110)>;
|
|
|
+-def : InstAlias<"orc $rd, $rs", (GORCI GPR:$rd, GPR:$rs, 0b111111)>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def : InstAlias<"ror $rd, $rs1, $shamt",
|
|
|
+ (RORI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def : InstAlias<"rorw $rd, $rs1, $shamt",
|
|
|
+ (RORIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def : InstAlias<"grev $rd, $rs1, $shamt",
|
|
|
+- (GREVI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
|
|
|
+-def : InstAlias<"gorc $rd, $rs1, $shamt",
|
|
|
+- (GORCI GPR:$rd, GPR:$rs1, uimmlog2xlen:$shamt), 0>;
|
|
|
+-def : InstAlias<"shfl $rd, $rs1, $shamt",
|
|
|
+- (SHFLI GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
|
|
|
+-def : InstAlias<"unshfl $rd, $rs1, $shamt",
|
|
|
+- (UNSHFLI GPR:$rd, GPR:$rs1, shfl_uimm:$shamt), 0>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def : InstAlias<"grevw $rd, $rs1, $shamt",
|
|
|
+- (GREVIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
|
|
|
+-def : InstAlias<"gorcw $rd, $rs1, $shamt",
|
|
|
+- (GORCIW GPR:$rd, GPR:$rs1, uimm5:$shamt), 0>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZbs] in {
|
|
|
+ def : InstAlias<"bset $rd, $rs1, $shamt",
|
|
|
+@@ -814,16 +558,16 @@ def : CompressPat<(ADDUW GPRC:$rs1, GPRC:$rs1, X0),
|
|
|
+ // Codegen patterns
|
|
|
+ //===----------------------------------------------------------------------===//
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def : Pat<(and GPR:$rs1, (not GPR:$rs2)), (ANDN GPR:$rs1, GPR:$rs2)>;
|
|
|
+ def : Pat<(or GPR:$rs1, (not GPR:$rs2)), (ORN GPR:$rs1, GPR:$rs2)>;
|
|
|
+ def : Pat<(xor GPR:$rs1, (not GPR:$rs2)), (XNOR GPR:$rs1, GPR:$rs2)>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def : PatGprGpr<rotl, ROL>;
|
|
|
+ def : PatGprGpr<rotr, ROR>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp]
|
|
|
++} // Predicates = [HasStdExtZbb]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZbs] in {
|
|
|
+ def : Pat<(and (not (shiftop<shl> 1, GPR:$rs2)), GPR:$rs1),
|
|
|
+@@ -871,7 +615,7 @@ def : Pat<(and GPR:$r, BCLRIANDIMask:$i),
|
|
|
+
|
|
|
+ // There's no encoding for roli in the the 'B' extension as it can be
|
|
|
+ // implemented with rori by negating the immediate.
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp] in {
|
|
|
++let Predicates = [HasStdExtZbb] in {
|
|
|
+ def : PatGprImm<rotr, RORI, uimmlog2xlen>;
|
|
|
+ def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
|
|
|
+ (RORI GPR:$rs1, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
|
|
|
+@@ -881,80 +625,6 @@ def : Pat<(rotl GPR:$rs1, uimmlog2xlen:$shamt),
|
|
|
+ def : Pat<(riscv_gorc GPR:$rs1, 7), (ORCB GPR:$rs1)>;
|
|
|
+ }
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp] in {
|
|
|
+-def : PatGprGpr<riscv_grev, GREV>;
|
|
|
+-def : PatGprGpr<riscv_gorc, GORC>;
|
|
|
+-def : PatGprGpr<riscv_shfl, SHFL>;
|
|
|
+-def : PatGprGpr<riscv_unshfl, UNSHFL>;
|
|
|
+-def : PatGprGpr<int_riscv_xperm_n, XPERMN>;
|
|
|
+-def : PatGprGpr<int_riscv_xperm_b, XPERMB>;
|
|
|
+-def : PatGprGpr<int_riscv_xperm_h, XPERMH>;
|
|
|
+-def : PatGprGpr<int_riscv_xperm_w, XPERMW>;
|
|
|
+-def : PatGprImm<riscv_shfl, SHFLI, shfl_uimm>;
|
|
|
+-def : PatGprImm<riscv_unshfl, UNSHFLI, shfl_uimm>;
|
|
|
+-def : PatGprImm<riscv_grev, GREVI, uimmlog2xlen>;
|
|
|
+-def : PatGprImm<riscv_gorc, GORCI, uimmlog2xlen>;
|
|
|
+-} // Predicates = [HasStdExtZbp]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV32] in {
|
|
|
+-def : Pat<(i32 (rotr (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
|
|
|
+-def : Pat<(i32 (rotl (riscv_grev GPR:$rs1, 24), (i32 16))), (GREVI GPR:$rs1, 8)>;
|
|
|
+-
|
|
|
+-// We treat rev8 as a separate instruction, so match it directly.
|
|
|
+-def : Pat<(i32 (riscv_grev GPR:$rs1, 24)), (REV8_RV32 GPR:$rs1)>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV32]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-// We treat rev8 as a separate instruction, so match it directly.
|
|
|
+-def : Pat<(i64 (riscv_grev GPR:$rs1, 56)), (REV8_RV64 GPR:$rs1)>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbt] in {
|
|
|
+-def : Pat<(or (and (not GPR:$rs2), GPR:$rs3), (and GPR:$rs2, GPR:$rs1)),
|
|
|
+- (CMIX GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-
|
|
|
+-def : Pat<(select (XLenVT (setne GPR:$rs2, 0)), GPR:$rs1, GPR:$rs3),
|
|
|
+- (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (seteq GPR:$rs2, 0)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setne GPR:$x, simm12_plus1:$y)), GPR:$rs1, GPR:$rs3),
|
|
|
+- (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (seteq GPR:$x, simm12_plus1:$y)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (ADDI GPR:$x, (NegImm simm12_plus1:$y)), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setne GPR:$x, GPR:$y)), GPR:$rs1, GPR:$rs3),
|
|
|
+- (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (seteq GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (XOR GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setuge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setule GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (SLTU GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setge GPR:$x, GPR:$y)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select (XLenVT (setle GPR:$y, GPR:$x)), GPR:$rs3, GPR:$rs1),
|
|
|
+- (CMOV GPR:$rs1, (SLT GPR:$x, GPR:$y), GPR:$rs3)>;
|
|
|
+-def : Pat<(select GPR:$rs2, GPR:$rs1, GPR:$rs3),
|
|
|
+- (CMOV GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-} // Predicates = [HasStdExtZbt]
|
|
|
+-
|
|
|
+-// fshl and fshr concatenate their operands in the same order. fsr and fsl
|
|
|
+-// instruction use different orders. fshl will return its first operand for
|
|
|
+-// shift of zero, fshr will return its second operand. fsl and fsr both return
|
|
|
+-// $rs1 so the patterns need to have different operand orders.
|
|
|
+-let Predicates = [HasStdExtZbt] in {
|
|
|
+-def : Pat<(riscv_fsl GPR:$rs1, GPR:$rs3, GPR:$rs2),
|
|
|
+- (FSL GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-def : Pat<(riscv_fsr GPR:$rs3, GPR:$rs1, GPR:$rs2),
|
|
|
+- (FSR GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-
|
|
|
+-def : Pat<(fshr GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
|
|
|
+- (FSRI GPR:$rs1, GPR:$rs3, uimmlog2xlen:$shamt)>;
|
|
|
+-// We can use FSRI for fshl by immediate if we subtract the immediate from
|
|
|
+-// XLen and swap the operands.
|
|
|
+-def : Pat<(fshl GPR:$rs3, GPR:$rs1, uimmlog2xlen:$shamt),
|
|
|
+- (FSRI GPR:$rs1, GPR:$rs3, (ImmSubFromXLen uimmlog2xlen:$shamt))>;
|
|
|
+-} // Predicates = [HasStdExtZbt]
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbb] in {
|
|
|
+ def : PatGpr<ctlz, CLZ>;
|
|
|
+ def : PatGpr<cttz, CTZ>;
|
|
|
+@@ -981,27 +651,9 @@ let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def : Pat<(i64 (bswap GPR:$rs1)), (REV8_RV64 GPR:$rs1)>;
|
|
|
+ } // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV32] in {
|
|
|
+-def : Pat<(i32 (or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16)))),
|
|
|
+- (PACK GPR:$rs1, GPR:$rs2)>;
|
|
|
+-def : Pat<(i32 (or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16)))),
|
|
|
+- (PACKU GPR:$rs1, GPR:$rs2)>;
|
|
|
+-
|
|
|
+-}
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
|
|
|
+- (PACK GPR:$rs1, GPR:$rs2)>;
|
|
|
+-def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))),
|
|
|
+- (PACKU GPR:$rs1, GPR:$rs2)>;
|
|
|
+-}
|
|
|
+-let Predicates = [HasStdExtZbp] in
|
|
|
+-def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF),
|
|
|
+- (and GPR:$rs1, 0x00FF)),
|
|
|
+- (PACKH GPR:$rs1, GPR:$rs2)>;
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV32] in
|
|
|
++let Predicates = [HasStdExtZbb, IsRV32] in
|
|
|
+ def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>;
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in
|
|
|
+ def : Pat<(i64 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV64 GPR:$rs)>;
|
|
|
+
|
|
|
+ // Pattern to exclude simm12 immediates from matching.
|
|
|
+@@ -1100,35 +752,13 @@ def : Pat<(i64 (add (and (shl GPR:$rs1, (i64 3)), 0x7FFFFFFFF), non_imm12:$rs2))
|
|
|
+ (SH3ADDUW GPR:$rs1, GPR:$rs2)>;
|
|
|
+ } // Predicates = [HasStdExtZba, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbbOrZbp, IsRV64] in {
|
|
|
++let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def : PatGprGpr<riscv_rolw, ROLW>;
|
|
|
+ def : PatGprGpr<riscv_rorw, RORW>;
|
|
|
+ def : PatGprImm<riscv_rorw, RORIW, uimm5>;
|
|
|
+ def : Pat<(riscv_rolw GPR:$rs1, uimm5:$rs2),
|
|
|
+ (RORIW GPR:$rs1, (ImmSubFrom32 uimm5:$rs2))>;
|
|
|
+-} // Predicates = [HasStdExtZbbOrZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def : Pat<(riscv_rorw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
|
|
|
+-def : Pat<(riscv_rolw (riscv_grevw GPR:$rs1, 24), 16), (GREVIW GPR:$rs1, 8)>;
|
|
|
+-def : PatGprGpr<riscv_grevw, GREVW>;
|
|
|
+-def : PatGprGpr<riscv_gorcw, GORCW>;
|
|
|
+-def : PatGprGpr<riscv_shflw, SHFLW>;
|
|
|
+-def : PatGprGpr<riscv_unshflw, UNSHFLW>;
|
|
|
+-def : PatGprImm<riscv_grevw, GREVIW, uimm5>;
|
|
|
+-def : PatGprImm<riscv_gorcw, GORCIW, uimm5>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbt, IsRV64] in {
|
|
|
+-def : Pat<(riscv_fslw GPR:$rs1, GPR:$rs3, GPR:$rs2),
|
|
|
+- (FSLW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, GPR:$rs2),
|
|
|
+- (FSRW GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
|
|
|
+-def : Pat<(riscv_fsrw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
|
|
|
+- (FSRIW GPR:$rs1, GPR:$rs3, uimm5:$shamt)>;
|
|
|
+-def : Pat<(riscv_fslw GPR:$rs3, GPR:$rs1, uimm5:$shamt),
|
|
|
+- (FSRIW GPR:$rs1, GPR:$rs3, (ImmSubFrom32 uimm5:$shamt))>;
|
|
|
+-} // Predicates = [HasStdExtZbt, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+ let Predicates = [HasStdExtZbb, IsRV64] in {
|
|
|
+ def : PatGpr<riscv_clzw, CLZW>;
|
|
|
+@@ -1136,45 +766,8 @@ def : PatGpr<riscv_ctzw, CTZW>;
|
|
|
+ def : Pat<(i64 (ctpop (i64 (zexti32 (i64 GPR:$rs1))))), (CPOPW GPR:$rs1)>;
|
|
|
+ } // Predicates = [HasStdExtZbb, IsRV64]
|
|
|
+
|
|
|
+-let Predicates = [HasStdExtZbp, IsRV64] in {
|
|
|
+-def : Pat<(i64 (sext_inreg (or (shl GPR:$rs2, (i64 16)),
|
|
|
+- (and GPR:$rs1, 0x000000000000FFFF)),
|
|
|
+- i32)),
|
|
|
+- (PACKW GPR:$rs1, GPR:$rs2)>;
|
|
|
+-def : Pat<(i64 (or (sext_inreg (shl GPR:$rs2, (i64 16)), i32),
|
|
|
+- (and GPR:$rs1, 0x000000000000FFFF))),
|
|
|
+- (PACKW GPR:$rs1, GPR:$rs2)>;
|
|
|
+-def : Pat<(i64 (or (and (assertsexti32 GPR:$rs2), 0xFFFFFFFFFFFF0000),
|
|
|
+- (srl (and GPR:$rs1, 0xFFFFFFFF), (i64 16)))),
|
|
|
+- (PACKUW GPR:$rs1, GPR:$rs2)>;
|
|
|
+-} // Predicates = [HasStdExtZbp, IsRV64]
|
|
|
+-
|
|
|
+ let Predicates = [HasStdExtZbc] in {
|
|
|
+ def : PatGprGpr<int_riscv_clmul, CLMUL>;
|
|
|
+ def : PatGprGpr<int_riscv_clmulh, CLMULH>;
|
|
|
+ def : PatGprGpr<int_riscv_clmulr, CLMULR>;
|
|
|
+-} // Predicates = [HasStdExtZbc]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbe] in {
|
|
|
+-def : PatGprGpr<riscv_bcompress, BCOMPRESS>;
|
|
|
+-def : PatGprGpr<riscv_bdecompress, BDECOMPRESS>;
|
|
|
+-} // Predicates = [HasStdExtZbe]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbe, IsRV64] in {
|
|
|
+-def : PatGprGpr<riscv_bcompressw, BCOMPRESSW>;
|
|
|
+-def : PatGprGpr<riscv_bdecompressw, BDECOMPRESSW>;
|
|
|
+-} // Predicates = [HasStdExtZbe, IsRV64]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbr] in {
|
|
|
+-def : PatGpr<int_riscv_crc32_b, CRC32B>;
|
|
|
+-def : PatGpr<int_riscv_crc32_h, CRC32H>;
|
|
|
+-def : PatGpr<int_riscv_crc32_w, CRC32W>;
|
|
|
+-def : PatGpr<int_riscv_crc32c_b, CRC32CB>;
|
|
|
+-def : PatGpr<int_riscv_crc32c_h, CRC32CH>;
|
|
|
+-def : PatGpr<int_riscv_crc32c_w, CRC32CW>;
|
|
|
+-} // Predicates = [HasStdExtZbr]
|
|
|
+-
|
|
|
+-let Predicates = [HasStdExtZbr, IsRV64] in {
|
|
|
+-def : PatGpr<int_riscv_crc32_d, CRC32D>;
|
|
|
+-def : PatGpr<int_riscv_crc32c_d, CRC32CD>;
|
|
|
+-} // Predicates = [HasStdExtZbr, IsRV64]
|
|
|
++} // Predicates = [HasStdExtZbc]
|
|
|
+\ No newline at end of file
|
|
|
+--
|
|
|
+2.33.1
|
|
|
+
|