Adding instruction definitions (isa,bin_fmt,h,cc) for Zimop/Zcmop extension.

PiperOrigin-RevId: 689876961
Change-Id: I88c99ff4bb4a3c890ffeb2da2ad9be8abfc1088c
diff --git a/riscv/BUILD b/riscv/BUILD
index bea5ac3..d3ccbff 100644
--- a/riscv/BUILD
+++ b/riscv/BUILD
@@ -256,9 +256,11 @@
     name = "riscv_rvm23_instructions",
     srcs = [
         "riscv_zicond_instructions.cc",
+        "riscv_zimop_instructions.cc",
     ],
     hdrs = [
         "riscv_zicond_instructions.h",
+        "riscv_zimop_instructions.h",
     ],
     copts = [
         "-O3",
@@ -268,6 +270,7 @@
         ":riscv_g",
         ":riscv_state",
         ":riscv_v",
+        "@com_google_mpact-sim//mpact/sim/generic:arch_state",
         "@com_google_mpact-sim//mpact/sim/generic:core",
         "@com_google_mpact-sim//mpact/sim/generic:instruction",
     ],
@@ -366,6 +369,7 @@
         "riscv32zb.isa",
         "riscv_vector.isa",
         "riscv_zicond.isa",
+        "riscv_zimop.isa",
     ],
     isa_name = "RVM23",
     prefix = "rvm23",
@@ -387,6 +391,7 @@
         "riscv32v.bin_fmt",
         "riscv32zb.bin_fmt",
         "riscv_zicond.bin_fmt",
+        "riscv_zimop.bin_fmt",
     ],
     prefix = "rvm23",
     deps = [
diff --git a/riscv/riscv_zimop.bin_fmt b/riscv/riscv_zimop.bin_fmt
new file mode 100644
index 0000000..20edaaf
--- /dev/null
+++ b/riscv/riscv_zimop.bin_fmt
@@ -0,0 +1,109 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file contains the encoding for the Zimop and Zcmop instructions.
+
+format MopRType[32] : Inst32Format {
+  fields:
+    unsigned func1[1];
+    unsigned n_hi[1];
+    unsigned func2[2];
+    unsigned n_mid[2];
+    unsigned func4[4];
+    unsigned n_lo[2];
+    unsigned rs1[5];
+    unsigned func3[3];
+    unsigned rd[5];
+    unsigned opcode[7];
+  overlays:
+    unsigned mop_no[5] = n_hi, n_mid, n_lo;
+};
+
+format MopRRType[32] : Inst32Format {
+  fields:
+    unsigned func1h[1];
+    unsigned n_hi[1];
+    unsigned func2[2];
+    unsigned n_lo[2];
+    unsigned func1l[1];
+    unsigned rs2[5];
+    unsigned rs1[5];
+    unsigned func3[3];
+    unsigned rd[5];
+    unsigned opcode[7];
+  overlays:
+    unsigned mop_no[3] = n_hi, n_lo;
+};
+
+instruction group RiscVZimop[32] : Inst32Format {
+  mop_r_0: MopRType : mop_no == 0, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_1: MopRType : mop_no == 1, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_2: MopRType : mop_no == 2, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_3: MopRType : mop_no == 3, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_4: MopRType : mop_no == 4, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_5: MopRType : mop_no == 5, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_6: MopRType : mop_no == 6, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_7: MopRType : mop_no == 7, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_8: MopRType : mop_no == 8, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_9: MopRType : mop_no == 9, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_10: MopRType : mop_no == 10, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_11: MopRType : mop_no == 11, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_12: MopRType : mop_no == 12, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_13: MopRType : mop_no == 13, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_14: MopRType : mop_no == 14, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_15: MopRType : mop_no == 15, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_16: MopRType : mop_no == 16, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_17: MopRType : mop_no == 17, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_18: MopRType : mop_no == 18, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_19: MopRType : mop_no == 19, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_20: MopRType : mop_no == 20, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_21: MopRType : mop_no == 21, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_22: MopRType : mop_no == 22, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_23: MopRType : mop_no == 23, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_24: MopRType : mop_no == 24, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_25: MopRType : mop_no == 25, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_26: MopRType : mop_no == 26, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_27: MopRType : mop_no == 27, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_28: MopRType : mop_no == 28, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_29: MopRType : mop_no == 29, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_30: MopRType : mop_no == 30, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_r_31: MopRType : mop_no == 31, func1 == 0b1, func2 == 0b00, func4 == 0b0111, func3 == 0b100, opcode == 0b111'0011;
+  mop_rr_0: MopRRType : mop_no == 0, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_1: MopRRType : mop_no == 1, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_2: MopRRType : mop_no == 2, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_3: MopRRType : mop_no == 3, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_4: MopRRType : mop_no == 4, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_5: MopRRType : mop_no == 5, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_6: MopRRType : mop_no == 6, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+  mop_rr_7: MopRRType : mop_no == 7, func1h == 0b1, func2 == 0b00, func1l == 0b1, opcode == 0b111'0011;
+};
+
+format CMopType[16] : Inst16Format {
+  fields:
+    unsigned func4[4];
+    unsigned num[5];
+    unsigned rd[5];
+    unsigned op[2];
+};
+
+instruction group RiscVZcmop[16] : Inst16Format {
+  c_mop_1:  CMopType : func4 == 0b0110, num == 1, rd == 0, op == 0b01;
+  c_mop_3:  CMopType : func4 == 0b0110, num == 3, rd == 0, op == 0b01;
+  c_mop_5:  CMopType : func4 == 0b0110, num == 5, rd == 0, op == 0b01;
+  c_mop_7:  CMopType : func4 == 0b0110, num == 7, rd == 0, op == 0b01;
+  c_mop_9:  CMopType : func4 == 0b0110, num == 9, rd == 0, op == 0b01;
+  c_mop_11: CMopType : func4 == 0b0110, num == 11, rd == 0, op == 0b01;
+  c_mop_13: CMopType : func4 == 0b0110, num == 13, rd == 0, op == 0b01;
+  c_mop_15: CMopType : func4 == 0b0110, num == 15, rd == 0, op == 0b01;
+}
\ No newline at end of file
diff --git a/riscv/riscv_zimop.isa b/riscv/riscv_zimop.isa
new file mode 100644
index 0000000..499d5b8
--- /dev/null
+++ b/riscv/riscv_zimop.isa
@@ -0,0 +1,266 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file contains the ISA description for the RiscV32/64 Zimop and Zcmop
+// extensions. These are the "may be  operations", which are simply opcodes for
+// instructions that do not generate exceptions, but have no other semantics
+// other than writing zero to the destination register (Zimop) or operate as a
+// nop (Zcmop).
+
+includes {
+  #include "riscv/riscv_i_instructions.h"
+  #include "riscv/riscv_zimop_instructions.isa"
+}
+
+slot riscv32_zimop {
+  resources OneOp = {next_pc : rd[..rd]};
+  opcodes {
+    mop_r_0{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.0", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_1{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.1", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_2{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.2", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_3{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.3", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_4{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.4", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_5{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.5", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_6{: rs1: rd},
+      resources: OneOp,
+      disasm: "mop.r.6", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_7{: rs1: rd},
+      resources: OneOp,
+      disasm: "mop.r.7", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_8{: rs1: rd},
+      resources: OneOp,
+      disasm: "mop.r.8", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_9{: rs1: rd},
+      resources: OneOp,
+      disasm: "mop.r.9", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_10{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.10", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_11{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.11", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_12{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.12", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_13{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.13", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_14{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.14", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_15{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.15", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_16{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.15", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_17{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.17", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_18{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.18", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_19{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.19", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_20{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.20", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_21{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.21", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_22{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.22", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_23{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.23", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_24{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.24", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_25{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.25", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_26{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.26", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_27{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.27", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_28{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.28", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_29{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.29", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_30{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.30", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_r_31{: rs1 : rd},
+      resources: OneOp,
+      disasm: "mop.r.31", "%rd, %rs1",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_0{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.0", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_1{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.1", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_2{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.2", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_3{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.3", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_4{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.4", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_5{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.5", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_6{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.6", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+    mop_rr_7{: rs1, rs2 : rd},
+      resources: OneOp,
+      disasm: "mop.rr.7", "%rd, %rs1, %rs2",
+      semfunc: "&RV32::RiscVMop";
+  }
+}
+
+slot riscv64_zimop : riscv32_zimop {
+  resources OneOp = {next_pc : rd[..rd]};
+  opcodes {
+    mop_r_0 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_1 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_2 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_3 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_4 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_5 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_6 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_7 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_8 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_9 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_10 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_11 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_12 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_13 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_14 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_15 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_16 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_17 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_18 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_19 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_20 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_21 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_22 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_23 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_24 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_25 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_26 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_27 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_28 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_29 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_30 = override, semfunc: "&RV64::RiscVMop";
+    mop_r_31 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_0 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_1 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_2 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_3 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_4 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_5 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_6 = override, semfunc: "&RV64::RiscVMop";
+    mop_rr_7 = override, semfunc: "&RV64::RiscVMop";
+  }
+}
+
+// Compact May-be-operations.
+slot riscv_zcmop {
+  opcodes {
+    c_mop_1{},
+      disasm: "c.mop.1",
+      semfunc: "RiscVINop";
+    c_mop_3{},
+      disasm: "c.mop.3",
+      semfunc: "RiscVINop";
+    c_mop_5{},
+      disasm: "c.mop.5",
+      semfunc: "RiscVINop";
+    c_mop_7{},
+      disasm: "c.mop.7",
+      semfunc: "RiscVINop";
+    c_mop_9{},
+      disasm: "c.mop.9",
+      semfunc: "RiscVINop";
+    c_mop_11{},
+      disasm: "c.mop.11",
+      semfunc: "RiscVINop";
+    c_mop_13{},
+      disasm: "c.mop.13",
+      semfunc: "RiscVINop";
+    c_mop_15{},
+      disasm: "c.mop.15",
+      semfunc: "RiscVINop";
+  }
+}
diff --git a/riscv/riscv_zimop_instructions.cc b/riscv/riscv_zimop_instructions.cc
new file mode 100644
index 0000000..27b3810
--- /dev/null
+++ b/riscv/riscv_zimop_instructions.cc
@@ -0,0 +1,55 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "riscv/riscv_zimop_instructions.h"
+
+#include "mpact/sim/generic/instruction.h"
+#include "mpact/sim/generic/register.h"
+#include "riscv/riscv_register.h"
+
+namespace mpact::sim::riscv {
+
+using ::mpact::sim::generic::Instruction;
+
+namespace RV32 {
+
+using RegType = RV32Register;
+using RegValue = typename RegType::ValueType;
+
+void RiscVMop(const Instruction *inst) {
+  // Get the destination register and set it to zero.
+  auto *reg = static_cast<generic::RegisterDestinationOperand<RegValue> *>(
+                  inst->Destination(0))
+                  ->GetRegister();
+  reg->data_buffer()->template Set<RegValue>(0, 0);
+}
+
+}  // namespace RV32
+
+namespace RV64 {
+
+using RegType = RV64Register;
+using RegValue = typename RegType::ValueType;
+
+void RiscVMop(const Instruction *inst) {
+  // Get the destination register and set it to zero.
+  auto *reg = static_cast<generic::RegisterDestinationOperand<RegValue> *>(
+                  inst->Destination(0))
+                  ->GetRegister();
+  reg->data_buffer()->template Set<RegValue>(0, 0);
+}
+
+}  // namespace RV64
+
+}  // namespace mpact::sim::riscv
diff --git a/riscv/riscv_zimop_instructions.h b/riscv/riscv_zimop_instructions.h
new file mode 100644
index 0000000..ee0e3c2
--- /dev/null
+++ b/riscv/riscv_zimop_instructions.h
@@ -0,0 +1,44 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This file declares the semantic functions for the Zimop instructions.
+
+#ifndef THIRD_PARTY_MPACT_RISCV_RISCV_ZIMOP_INSTRUCTIONS_H_
+#define THIRD_PARTY_MPACT_RISCV_RISCV_ZIMOP_INSTRUCTIONS_H_
+
+#include "mpact/sim/generic/instruction.h"
+
+namespace mpact::sim::riscv {
+
+using ::mpact::sim::generic::Instruction;
+
+namespace RV32 {
+
+// This semantic function ignores the source operand(s) and takes one
+// destination operand.
+void RiscVMop(const Instruction *inst);
+
+}  // namespace RV32
+
+namespace RV64 {
+
+// This semantic function ignores the source operand(s) and takes one
+// destination operand.
+void RiscVMop(const Instruction *inst);
+
+}  // namespace RV64
+
+}  // namespace mpact::sim::riscv
+
+#endif  // THIRD_PARTY_MPACT_RISCV_RISCV_ZIMOP_INSTRUCTIONS_H_
diff --git a/riscv/rvm23.bin_fmt b/riscv/rvm23.bin_fmt
index ffe0e53..5ea41d2 100644
--- a/riscv/rvm23.bin_fmt
+++ b/riscv/rvm23.bin_fmt
@@ -29,12 +29,15 @@
     RiscVZbsInst32,
     // Conditional zero.
     RiscVZicond,
+    RiscVZimop,
   };
   RVM23Inst16 = {
     RiscVCInst16,
+    RiscVZcmop,
   };
 }
 
 #include "riscv/riscv32g.bin_fmt"
 #include "riscv/riscv32zb.bin_fmt"
-#include "riscv/riscv_zicond.bin_fmt"
\ No newline at end of file
+#include "riscv/riscv_zicond.bin_fmt"
+#include "riscv/riscv_zimop.bin_fmt"
diff --git a/riscv/rvm23.isa b/riscv/rvm23.isa
index bd2d869..c4ed17a 100644
--- a/riscv/rvm23.isa
+++ b/riscv/rvm23.isa
@@ -23,6 +23,7 @@
 #include "riscv/riscv32zb.isa"
 #include "riscv/riscv_vector.isa"
 #include "riscv/riscv_zicond.isa"
+#include "riscv/riscv_zimop.isa"
 
 slot rvm23 :
   riscv32i,
@@ -36,7 +37,9 @@
   privileged,
   riscv_vector,
   riscv32_zb,
-  riscv32_zicond {
+  riscv32_zicond,
+  riscv32_zimop,
+  riscv_zcmop {
   default opcode =
     disasm: "Illegal instruction at 0x%(@:08x)",
     semfunc: "&RiscVIllegalInstruction";