Added fence.tso instruction.

PiperOrigin-RevId: 691535809
Change-Id: If8452e085e8447bff1f2a3a5fa11391193fc8969
diff --git a/riscv/riscv32g.bin_fmt b/riscv/riscv32g.bin_fmt
index 2e50883..cdf2dce 100644
--- a/riscv/riscv32g.bin_fmt
+++ b/riscv/riscv32g.bin_fmt
@@ -169,8 +169,7 @@
   sra    : RType  : func7 == 0b010'0000, func3==0b101, opcode == 0b011'0011;
   or     : RType  : func7 == 0b000'0000, func3==0b110, opcode == 0b011'0011;
   and    : RType  : func7 == 0b000'0000, func3==0b111, opcode == 0b011'0011;
-  fence     : Fence  : fm == 0b0000, succ != 0b0000, func3 == 0b000, opcode == 0b000'1111;
-  fence_tso : Fence : fm == 0b1000, pred == 0b0011, succ == 0b0011, func3 == 0b000, opcode == 0b000'1111;
+  fence  : Fence  : func3 == 0b000, opcode == 0b000'1111;
   ecall  : Inst32Format : bits == 0b0000'0000'0000'00000'000'00000, opcode == 0b111'0011;
   ebreak : Inst32Format : bits == 0b0000'0000'0001'00000'000'00000, opcode == 0b111'0011;
   // RiscV32 Instruction fence.
diff --git a/riscv/riscv32g.isa b/riscv/riscv32g.isa
index 72c368e..4415c40 100644
--- a/riscv/riscv32g.isa
+++ b/riscv/riscv32g.isa
@@ -200,12 +200,9 @@
       resources: { next_pc, rs1, rs2 : },
       disasm: "sb", "%rs2, %S_imm12(%rs1)",
       semfunc: "&RV32::RiscVISb";
-    fence{: pred, succ : },
+    fence{: I_imm12 : },
       disasm: "fence",
       semfunc: "&RiscVIFence";
-    fence_tso{},
-      disasm: "fence.tso",
-      semfunc: "&RiscVIFenceTso";
     ecall{},
       disasm: "ecall",
       semfunc: "&RiscVIEcall";
diff --git a/riscv/riscv32g_encoding.cc b/riscv/riscv32g_encoding.cc
index 3ac5fa4..f86e785 100644
--- a/riscv/riscv32g_encoding.cc
+++ b/riscv/riscv32g_encoding.cc
@@ -15,6 +15,7 @@
 #include "riscv/riscv32g_encoding.h"
 
 #include <cstdint>
+#include <new>
 #include <string>
 #include <utility>
 
@@ -305,11 +306,6 @@
         return new generic::ImmediateOperand<int32_t>(
             encoding::inst32_format::ExtractJImm(inst_word_));
       }));
-  source_op_getters_.insert(
-      std::make_pair(static_cast<int>(SourceOpEnum::kPred), [this]() {
-        return new generic::ImmediateOperand<uint32_t>(
-            encoding::inst32_format::ExtractPred(inst_word_));
-      }));
   source_op_getters_.insert(std::make_pair(
       static_cast<int>(SourceOpEnum::kRd),
       [this]() -> SourceOperandInterface * {
@@ -371,11 +367,6 @@
             encoding::inst32_format::ExtractSImm(inst_word_));
       }));
   source_op_getters_.insert(
-      std::make_pair(static_cast<int>(SourceOpEnum::kSucc), [this]() {
-        return new generic::ImmediateOperand<uint32_t>(
-            encoding::inst32_format::ExtractSucc(inst_word_));
-      }));
-  source_op_getters_.insert(
       std::make_pair(static_cast<int>(SourceOpEnum::kUImm20), [this]() {
         return new generic::ImmediateOperand<int32_t>(
             encoding::inst32_format::ExtractUImm(inst_word_));
diff --git a/riscv/riscv64g.bin_fmt b/riscv/riscv64g.bin_fmt
index 7d02240..cd553e3 100644
--- a/riscv/riscv64g.bin_fmt
+++ b/riscv/riscv64g.bin_fmt
@@ -202,8 +202,7 @@
   sraw   : RType  : func7 == 0b010'0000, func3==0b101, opcode == 0b011'1011;
   or     : RType  : func7 == 0b000'0000, func3==0b110, opcode == 0b011'0011;
   and    : RType  : func7 == 0b000'0000, func3==0b111, opcode == 0b011'0011;
-  fence     : Fence  : fm == 0b0000, succ != 0b0000, func3 == 0b000, opcode == 0b000'1111;
-  fence_tso : Fence : fm == 0b1000, pred == 0b0011, succ == 0b0011, func3 == 0b000, opcode == 0b000'1111;
+  fence  : Fence  : func3 == 0b000, opcode == 0b000'1111;
   ecall  : Inst32Format : bits == 0b0000'0000'0000'00000'000'00000, opcode == 0b111'0011;
   ebreak : Inst32Format : bits == 0b0000'0000'0001'00000'000'00000, opcode == 0b111'0011;
   // RiscV32 Instruction fence.
diff --git a/riscv/riscv64g.isa b/riscv/riscv64g.isa
index 8d7fcff..eb0461d 100644
--- a/riscv/riscv64g.isa
+++ b/riscv/riscv64g.isa
@@ -266,12 +266,9 @@
       resources: { next_pc, rs1, rs2 : },
       disasm: "sb", "%rs2, %S_imm12(%rs1)",
       semfunc: "&RV64::RiscVISb";
-    fence{: pred, succ : },
+    fence{: I_imm12 : },
       disasm: "fence",
       semfunc: "&RiscVIFence";
-    fence_tso{},
-      disasm: "fence.tso",
-      semfunc: "&RiscVIFenceTso";
     ecall{},
       disasm: "ecall",
       semfunc: "&RiscVIEcall";
diff --git a/riscv/riscv64g_encoding.cc b/riscv/riscv64g_encoding.cc
index cebbc65..6f1c68d 100644
--- a/riscv/riscv64g_encoding.cc
+++ b/riscv/riscv64g_encoding.cc
@@ -15,6 +15,7 @@
 #include "riscv/riscv64g_encoding.h"
 
 #include <cstdint>
+#include <new>
 #include <string>
 #include <utility>
 
@@ -328,11 +329,6 @@
             encoding64::inst32_format::ExtractJImm(inst_word_));
       }));
   source_op_getters_.insert(
-      std::make_pair(static_cast<int>(SourceOpEnum::kPred), [this]() {
-        return new generic::ImmediateOperand<uint32_t>(
-            encoding64::fence::ExtractPred(inst_word_));
-      }));
-  source_op_getters_.insert(
       std::make_pair(static_cast<int>(SourceOpEnum::kRm),
                      [this]() -> SourceOperandInterface * {
                        uint32_t rm = (inst_word_ >> 12) & 0x7;
@@ -408,11 +404,6 @@
             encoding64::s_type::ExtractSImm(inst_word_));
       }));
   source_op_getters_.insert(
-      std::make_pair(static_cast<int>(SourceOpEnum::kSucc), [this]() {
-        return new generic::ImmediateOperand<uint32_t>(
-            encoding64::fence::ExtractSucc(inst_word_));
-      }));
-  source_op_getters_.insert(
       std::make_pair(static_cast<int>(SourceOpEnum::kUImm20), [this]() {
         return new generic::ImmediateOperand<int32_t>(
             encoding64::u_type::ExtractUImm(inst_word_));
diff --git a/riscv/riscv_getters.h b/riscv/riscv_getters.h
index 5230372..1aaccb6 100644
--- a/riscv/riscv_getters.h
+++ b/riscv/riscv_getters.h
@@ -16,6 +16,7 @@
 #define THIRD_PARTY_MPACT_RISCV_RISCV_GETTERS_H_
 
 #include <cstdint>
+#include <new>
 #include <string>
 
 #include "absl/strings/str_cat.h"
@@ -225,10 +226,6 @@
     return new ImmediateOperand<int32_t>(
         Extractors::Inst32Format::ExtractJImm(common->inst_word()));
   });
-  Insert(getter_map, *Enum::kPred, [common]() {
-    return new ImmediateOperand<uint32_t>(
-        Extractors::Fence::ExtractPred(common->inst_word()));
-  });
   Insert(getter_map, *Enum::kRd, [common]() -> SourceOperandInterface * {
     int num = Extractors::RType::ExtractRd(common->inst_word());
     if (num == 0) return new generic::IntLiteralOperand<0>({1});
@@ -277,10 +274,6 @@
     return new ImmediateOperand<int32_t>(
         Extractors::SType::ExtractSImm(common->inst_word()));
   });
-  Insert(getter_map, *Enum::kSucc, [common]() {
-    return new ImmediateOperand<uint32_t>(
-        Extractors::Fence::ExtractSucc(common->inst_word()));
-  });
   Insert(getter_map, *Enum::kUImm20, [common]() {
     return new ImmediateOperand<int32_t>(
         Extractors::Inst32Format::ExtractUImm(common->inst_word()));
diff --git a/riscv/riscv_i_instructions.cc b/riscv/riscv_i_instructions.cc
index a72fe68..648d4b1 100644
--- a/riscv/riscv_i_instructions.cc
+++ b/riscv/riscv_i_instructions.cc
@@ -16,6 +16,7 @@
 
 #include <cstdint>
 #include <functional>
+#include <iostream>
 #include <limits>
 #include <type_traits>
 
@@ -540,17 +541,12 @@
 }  // namespace RV64
 
 void RiscVIFence(const Instruction *instruction) {
-  int pred = generic::GetInstructionSource<uint32_t>(instruction, 0) & 0xf;
-  int succ = generic::GetInstructionSource<uint32_t>(instruction, 1) & 0xf;
+  uint32_t bits = instruction->Source(0)->AsUint32(0);
+  int fm = (bits >> 8) & 0xf;
+  int predecessor = (bits >> 4) & 0xf;
+  int successor = bits & 0xf;
   auto *state = static_cast<RiscVState *>(instruction->state());
-  // Fence mode is 0x0
-  state->Fence(instruction, /*fence_mode=*/0x0, pred, succ);
-}
-
-void RiscVIFenceTso(const Instruction *instruction) {
-  auto *state = static_cast<RiscVState *>(instruction->state());
-  state->Fence(instruction, /*fence_mode=*/0b1000, /*pred=*/0b0011,
-               /*succ=*/0b0011);
+  state->Fence(instruction, fm, predecessor, successor);
 }
 
 void RiscVIEcall(const Instruction *instruction) {
diff --git a/riscv/riscv_i_instructions.h b/riscv/riscv_i_instructions.h
index 05cdbd9..ace0445 100644
--- a/riscv/riscv_i_instructions.h
+++ b/riscv/riscv_i_instructions.h
@@ -15,8 +15,6 @@
 #ifndef MPACT_RISCV_RISCV_RISCV_I_INSTRUCTIONS_H_
 #define MPACT_RISCV_RISCV_RISCV_I_INSTRUCTIONS_H_
 
-#include <cstdint>
-
 #include "mpact/sim/generic/instruction.h"
 
 // This file contains the declarations of the instruction semantic functions
@@ -184,11 +182,10 @@
 
 }  // namespace RV64
 
-// The Fence instruction takes two source operands, the 4 bit values of the
-// predecessor and successor sets.
+// The Fence instruction takes a single source operand (index 0) which consists
+// of an immediate value containing the right justified concatenation of the FM,
+// predecessor, and successor bit fields of the instruction.
 void RiscVIFence(const Instruction *instruction);
-// The Fence.tso takes no operands.
-void RiscVIFenceTso(const Instruction *instruction);
 // Ecall and EBreak take no source or destination operands.
 void RiscVIEcall(const Instruction *instruction);
 void RiscVIEbreak(const Instruction *instruction);
diff --git a/riscv/riscv_zimop.isa b/riscv/riscv_zimop.isa
index 770757c..499d5b8 100644
--- a/riscv/riscv_zimop.isa
+++ b/riscv/riscv_zimop.isa
@@ -20,7 +20,7 @@
 
 includes {
   #include "riscv/riscv_i_instructions.h"
-  #include "riscv/riscv_zimop_instructions.h"
+  #include "riscv/riscv_zimop_instructions.isa"
 }
 
 slot riscv32_zimop {