Fix `vsrans.h` support Add encoding unit test coverage PiperOrigin-RevId: 558201551
diff --git a/sim/kelvin_encoding.cc b/sim/kelvin_encoding.cc index 53047f0..9e3eee4 100644 --- a/sim/kelvin_encoding.cc +++ b/sim/kelvin_encoding.cc
@@ -402,14 +402,14 @@ return 2; } - // Func1 0b010 VSrans[u][.r] also needs 2x src1 registers. - if ((func1 == 0b010) && (sz == 0) && + // Func1 0b010 VSrans.[b,h].[u][.r] also needs 2x src1 registers. + if ((func1 == 0b010) && ((sz == 0) || (sz == 1)) && (func2_ignore_unsigned == 0b010000 || func2_ignore_unsigned == 0b010010)) { return 2; } - // Func1 0b010 VSraqs[u][.r] needs 4x src1 registers. + // Func1 0b010 VSraqs.b.[u][.r] needs 4x src1 registers. if ((func1 == 0b010) && (sz == 0) && (func2_ignore_unsigned == 0b011000 || func2_ignore_unsigned == 0b011010)) {
diff --git a/sim/test/BUILD b/sim/test/BUILD index 73a0b56..6e1ac0a 100644 --- a/sim/test/BUILD +++ b/sim/test/BUILD
@@ -17,8 +17,10 @@ ], deps = [ "//sim:kelvin_decoder", + "//sim:kelvin_isa", "//sim:kelvin_state", "@com_google_googletest//:gtest_main", + "@com_google_mpact-riscv//riscv:riscv_state", ], )
diff --git a/sim/test/kelvin_encoding_test.cc b/sim/test/kelvin_encoding_test.cc index 0037c7b..66ec918 100644 --- a/sim/test/kelvin_encoding_test.cc +++ b/sim/test/kelvin_encoding_test.cc
@@ -1,7 +1,11 @@ #include "sim/kelvin_encoding.h" +#include <cstdint> + +#include "sim/kelvin_enums.h" #include "sim/kelvin_state.h" #include "googletest/include/gtest/gtest.h" +#include "riscv/riscv_register.h" namespace { @@ -9,6 +13,8 @@ using kelvin::sim::isa32::KelvinEncoding; using SlotEnum = kelvin::sim::isa32::SlotEnum; using OpcodeEnum = kelvin::sim::isa32::OpcodeEnum; +using SourceOpEnum = kelvin::sim::isa32::SourceOpEnum; +using RV32VectorSourceOperand = mpact::sim::riscv::RV32VectorSourceOperand; // RV32I constexpr uint32_t kLui = 0b0000000000000000000000000'0110111; @@ -94,6 +100,15 @@ delete state_; } + RV32VectorSourceOperand *VectorSourceEncodeHelper( + uint32_t inst_word, OpcodeEnum opcode, SourceOpEnum source_op) const { + enc_->ParseInstruction(inst_word); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), opcode); + auto source = enc_->GetSource(SlotEnum::kKelvin, 0, opcode, source_op, 0); + return reinterpret_cast<mpact::sim::riscv::RV32VectorSourceOperand *>( + source); + } + KelvinState *state_; KelvinEncoding *enc_; }; @@ -300,4 +315,41 @@ enc_->ParseInstruction(kRemu); EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kRemu); } + +TEST_F(KelvinEncodingTest, VsraxsWideningVs1) { + constexpr uint32_t kVSransBase = 0b010000'000001'000000'00'001000'0'010'00; + auto v_src = VectorSourceEncodeHelper(kVSransBase, OpcodeEnum::kVsransBVv, + SourceOpEnum::kVs1); + EXPECT_EQ(v_src->size(), 2); + delete v_src; + + // Test vsrans.b.r.vv + v_src = VectorSourceEncodeHelper(kVSransBase | (1 << 27), + OpcodeEnum::kVsransBRVv, SourceOpEnum::kVs1); + EXPECT_EQ(v_src->size(), 2); + delete v_src; + + // Test vsrans.h.vv + v_src = VectorSourceEncodeHelper(kVSransBase | (1 << 12), + OpcodeEnum::kVsransHVv, SourceOpEnum::kVs1); + EXPECT_EQ(v_src->size(), 2); + delete v_src; + + // Test vsraqs.b.vv + v_src = VectorSourceEncodeHelper(kVSransBase | (1 << 29), + OpcodeEnum::kVsraqsBVv, SourceOpEnum::kVs1); + EXPECT_EQ(v_src->size(), 4); + delete v_src; + + // Test vsraqs.b.r.vv + v_src = VectorSourceEncodeHelper(kVSransBase | (1 << 29) | (1 << 27), + OpcodeEnum::kVsraqsBRVv, SourceOpEnum::kVs1); + EXPECT_EQ(v_src->size(), 4); + delete v_src; + + // Test illegal vsrans (vsrans.w.vv) + enc_->ParseInstruction(kVSransBase | (2 << 12)); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kKelvin, 0), OpcodeEnum::kNone); +} + } // namespace