Skip to content

[RISCV][MC] Add support for experimental Zcmop extension #76395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 28, 2023

Conversation

wangpc-pp
Copy link
Contributor

This implements experimental support for the Zcmop extension as
specified here: https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc.

This change adds only MC support.

This implements experimental support for the Zcmop extension as
specified here: https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc.

This change adds only MC support.
@wangpc-pp wangpc-pp requested a review from topperc December 26, 2023 13:02
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:RISC-V mc Machine (object) code llvm:support labels Dec 26, 2023
@wangpc-pp wangpc-pp requested review from asb and yetingk December 26, 2023 13:02
@llvmbot
Copy link
Member

llvmbot commented Dec 26, 2023

@llvm/pr-subscribers-mc

@llvm/pr-subscribers-llvm-support

Author: Wang Pengcheng (wangpc-pp)

Changes

This implements experimental support for the Zcmop extension as
specified here: https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc.

This change adds only MC support.


Full diff: https://github.com/llvm/llvm-project/pull/76395.diff

10 Files Affected:

  • (modified) clang/test/Preprocessor/riscv-target-features.c (+9)
  • (modified) llvm/docs/RISCVUsage.rst (+3)
  • (modified) llvm/lib/Support/RISCVISAInfo.cpp (+2)
  • (modified) llvm/lib/Target/RISCV/RISCVFeatures.td (+7)
  • (modified) llvm/lib/Target/RISCV/RISCVInstrInfo.td (+1)
  • (added) llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td (+30)
  • (modified) llvm/test/CodeGen/RISCV/attributes.ll (+4)
  • (added) llvm/test/MC/RISCV/rv32zcmop-invalid.s (+7)
  • (added) llvm/test/MC/RISCV/rvzcmop-valid.s (+42)
  • (modified) llvm/unittests/Support/RISCVISAInfoTest.cpp (+1)
diff --git a/clang/test/Preprocessor/riscv-target-features.c b/clang/test/Preprocessor/riscv-target-features.c
index 2111b3f1c5832b..661f1fb55159c7 100644
--- a/clang/test/Preprocessor/riscv-target-features.c
+++ b/clang/test/Preprocessor/riscv-target-features.c
@@ -121,6 +121,7 @@
 // CHECK-NOT: __riscv_zicfilp {{.*$}}
 // CHECK-NOT: __riscv_zicond {{.*$}}
 // CHECK-NOT: __riscv_zimop {{.*$}}
+// CHECK-NOT: __riscv_zcmop {{.*$}}
 // CHECK-NOT: __riscv_ztso {{.*$}}
 // CHECK-NOT: __riscv_zvbb {{.*$}}
 // CHECK-NOT: __riscv_zvbc {{.*$}}
@@ -1080,6 +1081,14 @@
 // RUN: -o - | FileCheck --check-prefix=CHECK-ZIMOP-EXT %s
 // CHECK-ZIMOP-EXT: __riscv_zimop  1000{{$}}
 
+// RUN: %clang --target=riscv32 -menable-experimental-extensions \
+// RUN: -march=rv32i_zcmop0p2 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZCMOP-EXT %s
+// RUN: %clang --target=riscv64 -menable-experimental-extensions \
+// RUN: -march=rv32i_zcmop0p2 -x c -E -dM %s \
+// RUN: -o - | FileCheck --check-prefix=CHECK-ZCMOP-EXT %s
+// CHECK-ZCMOP-EXT: __riscv_zcmop  2000{{$}}
+
 // RUN: %clang --target=riscv32-unknown-linux-gnu -menable-experimental-extensions \
 // RUN: -march=rv32iztso0p1 -x c -E -dM %s \
 // RUN: -o - | FileCheck --check-prefix=CHECK-ZTSO-EXT %s
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index 3125f2d7c9cfdb..836a4e9ff08e55 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -224,6 +224,9 @@ The primary goal of experimental support is to assist in the process of ratifica
 ``experimental-zimop``
   LLVM implements the `v0.1 proposed specification <https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc>`__.
 
+``experimental-zcmop``
+  LLVM implements the `v0.2 proposed specification <https://github.com/riscv/riscv-isa-manual/blob/main/src/zimop.adoc>`__.
+
 To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using.  To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`.  Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
 
 Vendor Extensions
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index e71e96e3417e46..36d453a53c1057 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -191,6 +191,8 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
 static const RISCVSupportedExtension SupportedExperimentalExtensions[] = {
     {"zacas", RISCVExtensionVersion{1, 0}},
 
+    {"zcmop", RISCVExtensionVersion{0, 2}},
+
     {"zfbfmin", RISCVExtensionVersion{0, 8}},
 
     {"zicfilp", RISCVExtensionVersion{0, 4}},
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index a6e7c15b50e978..adf3c84b586a25 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -693,6 +693,13 @@ def HasStdExtZimop : Predicate<"Subtarget->hasStdExtZimop()">,
                                AssemblerPredicate<(all_of FeatureStdExtZimop),
                                "'Zimop' (May-Be-Operations)">;
 
+def FeatureStdExtZcmop : SubtargetFeature<"experimental-zcmop", "HasStdExtZcmop", "true",
+                                          "'Zcmop' (Compressed May-Be-Operations)",
+                                          [FeatureStdExtZca]>;
+def HasStdExtZcmop : Predicate<"Subtarget->hasStdExtZcmop()">,
+                               AssemblerPredicate<(all_of FeatureStdExtZcmop),
+                               "'Zcmop' (Compressed May-Be-Operations)">;
+
 def FeatureStdExtSmaia
     : SubtargetFeature<"smaia", "HasStdExtSmaia", "true",
                        "'Smaia' (Smaia encompasses all added CSRs and all "
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index 099cc0abd14240..0e5e663da911c4 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2146,6 +2146,7 @@ include "RISCVInstrInfoZicond.td"
 // Compressed
 include "RISCVInstrInfoC.td"
 include "RISCVInstrInfoZc.td"
+include "RISCVInstrInfoZcmop.td"
 
 //===----------------------------------------------------------------------===//
 // Vendor extensions
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
new file mode 100644
index 00000000000000..0a2d08789aabe1
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZcmop.td
@@ -0,0 +1,30 @@
+//===-- RISCVInstrInfoZcmop.td -----------------------------*- 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 Compressed
+// May-Be-Operations Extension (Zcmop).
+// This version is still experimental as the 'Zcmop' extension hasn't been
+// ratified yet. It is based on v0.2 of the specification.
+//
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class CMOPInst<bits<3> imm3, string opcodestr>
+    : RVInst16CI<0b011, 0b01, (outs), (ins), opcodestr, ""> {
+  let Inst{6-2} = 0;
+  let Inst{7} = 1;
+  let Inst{10-8} = imm3;
+  let Inst{12-11} = 0;
+}
+
+foreach i = 0...7 in {
+    let Predicates = [HasStdExtZcmop, HasStdExtCOrZca] in {
+    defvar n = !add(!mul(i, 2), 1);
+    def CMOP#n : CMOPInst<i, "cmop."#n>, Sched<[]>;
+    } // Predicates = [HasStdExtZcmop, HasStdExtCOrZca]
+}
diff --git a/llvm/test/CodeGen/RISCV/attributes.ll b/llvm/test/CodeGen/RISCV/attributes.ll
index 5841f1a98f23eb..9a6e78c09ad8c3 100644
--- a/llvm/test/CodeGen/RISCV/attributes.ll
+++ b/llvm/test/CodeGen/RISCV/attributes.ll
@@ -86,6 +86,7 @@
 ; RUN: llc -mtriple=riscv32 -mattr=+zvfh %s -o - | FileCheck --check-prefix=RV32ZVFH %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV32ZICOND %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zimop %s -o - | FileCheck --check-prefix=RV32ZIMOP %s
+; RUN: llc -mtriple=riscv32 -mattr=+experimental-zcmop %s -o - | FileCheck --check-prefix=RV32ZCMOP %s
 ; RUN: llc -mtriple=riscv32 -mattr=+smaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SMAIA %s
 ; RUN: llc -mtriple=riscv32 -mattr=+ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV32SSAIA %s
 ; RUN: llc -mtriple=riscv32 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV32ZFBFMIN %s
@@ -179,6 +180,7 @@
 ; RUN: llc -mtriple=riscv64 -mattr=+zvfh %s -o - | FileCheck --check-prefix=RV64ZVFH %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicond %s -o - | FileCheck --check-prefix=RV64ZICOND %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zimop %s -o - | FileCheck --check-prefix=RV64ZIMOP %s
+; RUN: llc -mtriple=riscv64 -mattr=+experimental-zcmop %s -o - | FileCheck --check-prefix=RV64ZCMOP %s
 ; RUN: llc -mtriple=riscv64 -mattr=+smaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SMAIA %s
 ; RUN: llc -mtriple=riscv64 -mattr=+ssaia %s -o - | FileCheck --check-prefixes=CHECK,RV64SSAIA %s
 ; RUN: llc -mtriple=riscv64 -mattr=+experimental-zfbfmin %s -o - | FileCheck --check-prefixes=CHECK,RV64ZFBFMIN %s
@@ -274,6 +276,7 @@
 ; RV32ZVFH: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0"
 ; RV32ZICOND: .attribute 5, "rv32i2p1_zicond1p0"
 ; RV32ZIMOP: .attribute 5, "rv32i2p1_zimop0p1"
+; RV32ZCMOP: .attribute 5, "rv32i2p1_zca1p0_zcmop0p2"
 ; RV32SMAIA: .attribute 5, "rv32i2p1_smaia1p0"
 ; RV32SSAIA: .attribute 5, "rv32i2p1_ssaia1p0"
 ; RV32ZFBFMIN: .attribute 5, "rv32i2p1_f2p2_zicsr2p0_zfbfmin0p8"
@@ -366,6 +369,7 @@
 ; RV64ZVFH: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfhmin1p0_zve32f1p0_zve32x1p0_zvfh1p0_zvfhmin1p0_zvl32b1p0"
 ; RV64ZICOND: .attribute 5, "rv64i2p1_zicond1p0"
 ; RV64ZIMOP: .attribute 5, "rv64i2p1_zimop0p1"
+; RV64ZCMOP: .attribute 5, "rv64i2p1_zca1p0_zcmop0p2"
 ; RV64SMAIA: .attribute 5, "rv64i2p1_smaia1p0"
 ; RV64SSAIA: .attribute 5, "rv64i2p1_ssaia1p0"
 ; RV64ZFBFMIN: .attribute 5, "rv64i2p1_f2p2_zicsr2p0_zfbfmin0p8"
diff --git a/llvm/test/MC/RISCV/rv32zcmop-invalid.s b/llvm/test/MC/RISCV/rv32zcmop-invalid.s
new file mode 100644
index 00000000000000..1641c8ddd00ba4
--- /dev/null
+++ b/llvm/test/MC/RISCV/rv32zcmop-invalid.s
@@ -0,0 +1,7 @@
+# RUN: not llvm-mc -triple riscv32 -mattr=+experimental-zcmop < %s 2>&1 | FileCheck %s
+
+cmop.0 # CHECK: :[[@LINE]]:1: error: unrecognized instruction mnemonic
+
+cmop.1 t0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
+
+cmop.1 0x0 # CHECK: :[[@LINE]]:8: error: invalid operand for instruction
diff --git a/llvm/test/MC/RISCV/rvzcmop-valid.s b/llvm/test/MC/RISCV/rvzcmop-valid.s
new file mode 100644
index 00000000000000..c26bb2959fedef
--- /dev/null
+++ b/llvm/test/MC/RISCV/rvzcmop-valid.s
@@ -0,0 +1,42 @@
+# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zcmop -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zcmop -show-encoding \
+# RUN:     | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zcmop < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zcmop -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zcmop < %s \
+# RUN:     | llvm-objdump --mattr=+experimental-zcmop -d -r - \
+# RUN:     | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
+
+# CHECK-ASM-AND-OBJ: cmop.1
+# CHECK-ASM: encoding: [0x81,0x60]
+cmop.1
+
+# CHECK-ASM-AND-OBJ: cmop.3
+# CHECK-ASM: encoding: [0x81,0x61]
+cmop.3
+
+# CHECK-ASM-AND-OBJ: cmop.5
+# CHECK-ASM: encoding: [0x81,0x62]
+cmop.5
+
+# CHECK-ASM-AND-OBJ: cmop.7
+# CHECK-ASM: encoding: [0x81,0x63]
+cmop.7
+
+# CHECK-ASM-AND-OBJ: cmop.9
+# CHECK-ASM: encoding: [0x81,0x64]
+cmop.9
+
+# CHECK-ASM-AND-OBJ: cmop.11
+# CHECK-ASM: encoding: [0x81,0x65]
+cmop.11
+
+# CHECK-ASM-AND-OBJ: cmop.13
+# CHECK-ASM: encoding: [0x81,0x66]
+cmop.13
+
+# CHECK-ASM-AND-OBJ: cmop.15
+# CHECK-ASM: encoding: [0x81,0x67]
+cmop.15
diff --git a/llvm/unittests/Support/RISCVISAInfoTest.cpp b/llvm/unittests/Support/RISCVISAInfoTest.cpp
index eeac1e81756583..5044177915dbd7 100644
--- a/llvm/unittests/Support/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/Support/RISCVISAInfoTest.cpp
@@ -759,6 +759,7 @@ Experimental extensions
     zimop               0.1
     zacas               1.0
     zfbfmin             0.8
+    zcmop               0.2
     ztso                0.1
     zvfbfmin            0.8
     zvfbfwma            0.8

@@ -693,6 +693,13 @@ def HasStdExtZimop : Predicate<"Subtarget->hasStdExtZimop()">,
AssemblerPredicate<(all_of FeatureStdExtZimop),
"'Zimop' (May-Be-Operations)">;

def FeatureStdExtZcmop : SubtargetFeature<"experimental-zcmop", "HasStdExtZcmop", "true",
"'Zcmop' (Compressed May-Be-Operations)",
[FeatureStdExtZca]>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec says Zcmop requires Zca. Is this means Zcmop imply Zca? I am not sure with this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. The specs have been very inconsistent on terminology. The fundamental issue is that the specs define hardware and don't think about how -march in tools works. What the spec is saying is that if your hardware supports Zcmop, it must support Zca.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding for those terminology on RISC-V ISA spec is: imply == depend == require

See comment from Krste and Andrew in this issue: riscvarchive/riscv-v-spec#723 (comment)

Copy link
Contributor

@yetingk yetingk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. But please wait for @topperc's review.

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@wangpc-pp wangpc-pp merged commit 13cdee9 into llvm:main Dec 28, 2023
@wangpc-pp wangpc-pp deleted the main-riscv-zcmop-mc branch March 29, 2024 04:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:RISC-V clang Clang issues not falling into any other category llvm:support mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants