Adds instruction fence.tso separate from fence. Change operands expected by fence. PiperOrigin-RevId: 692223730 Change-Id: I62c2907bab5d571bbd916d6e5b6e8dfda2ee4c7e
diff --git a/riscv/riscv32g.bin_fmt b/riscv/riscv32g.bin_fmt index cdf2dce..22d8f8d 100644 --- a/riscv/riscv32g.bin_fmt +++ b/riscv/riscv32g.bin_fmt
@@ -169,7 +169,8 @@ 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 : func3 == 0b000, opcode == 0b000'1111; + 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; 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 4415c40..72c368e 100644 --- a/riscv/riscv32g.isa +++ b/riscv/riscv32g.isa
@@ -200,9 +200,12 @@ resources: { next_pc, rs1, rs2 : }, disasm: "sb", "%rs2, %S_imm12(%rs1)", semfunc: "&RV32::RiscVISb"; - fence{: I_imm12 : }, + fence{: pred, succ : }, 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 f86e785..3ac5fa4 100644 --- a/riscv/riscv32g_encoding.cc +++ b/riscv/riscv32g_encoding.cc
@@ -15,7 +15,6 @@ #include "riscv/riscv32g_encoding.h" #include <cstdint> -#include <new> #include <string> #include <utility> @@ -306,6 +305,11 @@ 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 * { @@ -367,6 +371,11 @@ 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 cd553e3..9870382 100644 --- a/riscv/riscv64g.bin_fmt +++ b/riscv/riscv64g.bin_fmt
@@ -202,7 +202,8 @@ 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 : func3 == 0b000, opcode == 0b000'1111; + 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; 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 eb0461d..8d7fcff 100644 --- a/riscv/riscv64g.isa +++ b/riscv/riscv64g.isa
@@ -266,9 +266,12 @@ resources: { next_pc, rs1, rs2 : }, disasm: "sb", "%rs2, %S_imm12(%rs1)", semfunc: "&RV64::RiscVISb"; - fence{: I_imm12 : }, + fence{: pred, succ : }, 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 6f1c68d..cebbc65 100644 --- a/riscv/riscv64g_encoding.cc +++ b/riscv/riscv64g_encoding.cc
@@ -15,7 +15,6 @@ #include "riscv/riscv64g_encoding.h" #include <cstdint> -#include <new> #include <string> #include <utility> @@ -329,6 +328,11 @@ 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; @@ -404,6 +408,11 @@ 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/riscv64g_vec_encoding.cc b/riscv/riscv64g_vec_encoding.cc index 524b005..a7505ed 100644 --- a/riscv/riscv64g_vec_encoding.cc +++ b/riscv/riscv64g_vec_encoding.cc
@@ -15,7 +15,6 @@ #include "riscv/riscv64g_vec_encoding.h" #include <cstdint> -#include <new> #include <string> #include <utility> #include <vector> @@ -422,6 +421,11 @@ 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; @@ -497,6 +501,11 @@ 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]() { uint32_t uimm = encoding64::u_type::ExtractUImm(inst_word_); return new generic::ImmediateOperand<int32_t>(
diff --git a/riscv/riscv_getters.h b/riscv/riscv_getters.h index 1aaccb6..5230372 100644 --- a/riscv/riscv_getters.h +++ b/riscv/riscv_getters.h
@@ -16,7 +16,6 @@ #define THIRD_PARTY_MPACT_RISCV_RISCV_GETTERS_H_ #include <cstdint> -#include <new> #include <string> #include "absl/strings/str_cat.h" @@ -226,6 +225,10 @@ 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}); @@ -274,6 +277,10 @@ 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 648d4b1..a72fe68 100644 --- a/riscv/riscv_i_instructions.cc +++ b/riscv/riscv_i_instructions.cc
@@ -16,7 +16,6 @@ #include <cstdint> #include <functional> -#include <iostream> #include <limits> #include <type_traits> @@ -541,12 +540,17 @@ } // namespace RV64 void RiscVIFence(const Instruction *instruction) { - uint32_t bits = instruction->Source(0)->AsUint32(0); - int fm = (bits >> 8) & 0xf; - int predecessor = (bits >> 4) & 0xf; - int successor = bits & 0xf; + int pred = generic::GetInstructionSource<uint32_t>(instruction, 0) & 0xf; + int succ = generic::GetInstructionSource<uint32_t>(instruction, 1) & 0xf; auto *state = static_cast<RiscVState *>(instruction->state()); - state->Fence(instruction, fm, predecessor, successor); + // 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); } void RiscVIEcall(const Instruction *instruction) {
diff --git a/riscv/riscv_i_instructions.h b/riscv/riscv_i_instructions.h index ace0445..05cdbd9 100644 --- a/riscv/riscv_i_instructions.h +++ b/riscv/riscv_i_instructions.h
@@ -15,6 +15,8 @@ #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 @@ -182,10 +184,11 @@ } // namespace RV64 -// 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. +// The Fence instruction takes two source operands, the 4 bit values of the +// predecessor and successor sets. 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 499d5b8..770757c 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.isa" + #include "riscv/riscv_zimop_instructions.h" } slot riscv32_zimop {