Zfh: Add encoding tests for half precision <-> 64 bit integer conversion instructions PiperOrigin-RevId: 768186277 Change-Id: I00d2d699e9dbdf5edf2ffdccb6c27979754d025c
diff --git a/riscv/riscv_zfh.isa b/riscv/riscv_zfh.isa index 5aec5ae..1ff9bd1 100644 --- a/riscv/riscv_zfh.isa +++ b/riscv/riscv_zfh.isa
@@ -278,11 +278,11 @@ semfunc: "&RV64::RiscVZfhCvtLuh", disasm: "fcvt.lu.h", "%rd, %frs1"; fcvt_hl{: rs1, rm : frd, fflags}, - resources: {next_pc, frs1 : frd[0..]}, + resources: {next_pc, rs1 : frd[0..]}, semfunc: "&RV64::RiscVZfhCvtHl", disasm: "fcvt.h.l", "%frd, %rs1"; fcvt_hlu{: rs1, rm : frd, fflags}, - resources: {next_pc, frs1 : frd[0..]}, + resources: {next_pc, rs1 : frd[0..]}, semfunc: "&RV64::RiscVZfhCvtHlu", disasm: "fcvt.h.lu", "%frd, %rs1"; }
diff --git a/riscv/riscv_zfh32.bin_fmt b/riscv/riscv_zfh32.bin_fmt index 9a49ae9..0bb8708 100644 --- a/riscv/riscv_zfh32.bin_fmt +++ b/riscv/riscv_zfh32.bin_fmt
@@ -44,14 +44,14 @@ fsqrt_h : RType : func7 == 0b0101110, rs2 == 0b00000, opcode == 0b1010011; fcvt_hw : RType : func7 == 0b1101010, rs2 == 0b00000, opcode == 0b1010011; fcvt_wh : RType : func7 == 0b1100010, rs2 == 0b00000, opcode == 0b1010011; - fcvt_hwu : RType : func7 == 0b1101010, rs2 == 0b00001, opcode == 0b1010011; - fcvt_wuh : RType : func7 == 0b1100010, rs2 == 0b00001, opcode == 0b1010011; - fcmpeq_h : RType : func7 == 0b1010010, func3 == 0b010, opcode == 0b1010011; - fcmplt_h : RType : func7 == 0b1010010, func3 == 0b001, opcode == 0b1010011; - fcmple_h : RType : func7 == 0b1010010, func3 == 0b000, opcode == 0b1010011; - fclass_h : RType : func7 == 0b1110010, rs2 == 0b00000, func3 == 0b001, opcode == 0b1010011; - fmadd_h : R4Type : func2 == 0b10, opcode == 0b1000011; - fmsub_h : R4Type : func2 == 0b10, opcode == 0b1000111; - fnmsub_h : R4Type : func2 == 0b10, opcode == 0b1001011; - fnmadd_h : R4Type : func2 == 0b10, opcode == 0b1001111; + fcvt_hwu : RType : func7 == 0b1101010, rs2 == 0b00001, opcode == 0b1010011; + fcvt_wuh : RType : func7 == 0b1100010, rs2 == 0b00001, opcode == 0b1010011; + fcmpeq_h : RType : func7 == 0b1010010, func3 == 0b010, opcode == 0b1010011; + fcmplt_h : RType : func7 == 0b1010010, func3 == 0b001, opcode == 0b1010011; + fcmple_h : RType : func7 == 0b1010010, func3 == 0b000, opcode == 0b1010011; + fclass_h : RType : func7 == 0b1110010, rs2 == 0b00000, func3 == 0b001, opcode == 0b1010011; + fmadd_h : R4Type : func2 == 0b10, opcode == 0b1000011; + fmsub_h : R4Type : func2 == 0b10, opcode == 0b1000111; + fnmsub_h : R4Type : func2 == 0b10, opcode == 0b1001011; + fnmadd_h : R4Type : func2 == 0b10, opcode == 0b1001111; };
diff --git a/riscv/riscv_zfh64.bin_fmt b/riscv/riscv_zfh64.bin_fmt index 538628c..ede34bf 100644 --- a/riscv/riscv_zfh64.bin_fmt +++ b/riscv/riscv_zfh64.bin_fmt
@@ -44,14 +44,18 @@ fsqrt_h : RType : func7 == 0b0101110, rs2 == 0b00000, opcode == 0b1010011; fcvt_hw : RType : func7 == 0b1101010, rs2 == 0b00000, opcode == 0b1010011; fcvt_wh : RType : func7 == 0b1100010, rs2 == 0b00000, opcode == 0b1010011; - fcvt_hwu : RType : func7 == 0b1101010, rs2 == 0b00001, opcode == 0b1010011; - fcvt_wuh : RType : func7 == 0b1100010, rs2 == 0b00001, opcode == 0b1010011; - fcmpeq_h : RType : func7 == 0b1010010, func3 == 0b010, opcode == 0b1010011; - fcmplt_h : RType : func7 == 0b1010010, func3 == 0b001, opcode == 0b1010011; - fcmple_h : RType : func7 == 0b1010010, func3 == 0b000, opcode == 0b1010011; - fclass_h : RType : func7 == 0b1110010, rs2 == 0b00000, func3 == 0b001, opcode == 0b1010011; - fmadd_h : R4Type : func2 == 0b10, opcode == 0b1000011; - fmsub_h : R4Type : func2 == 0b10, opcode == 0b1000111; - fnmsub_h : R4Type : func2 == 0b10, opcode == 0b1001011; - fnmadd_h : R4Type : func2 == 0b10, opcode == 0b1001111; + fcvt_hwu : RType : func7 == 0b1101010, rs2 == 0b00001, opcode == 0b1010011; + fcvt_wuh : RType : func7 == 0b1100010, rs2 == 0b00001, opcode == 0b1010011; + fcmpeq_h : RType : func7 == 0b1010010, func3 == 0b010, opcode == 0b1010011; + fcmplt_h : RType : func7 == 0b1010010, func3 == 0b001, opcode == 0b1010011; + fcmple_h : RType : func7 == 0b1010010, func3 == 0b000, opcode == 0b1010011; + fclass_h : RType : func7 == 0b1110010, rs2 == 0b00000, func3 == 0b001, opcode == 0b1010011; + fmadd_h : R4Type : func2 == 0b10, opcode == 0b1000011; + fmsub_h : R4Type : func2 == 0b10, opcode == 0b1000111; + fnmsub_h : R4Type : func2 == 0b10, opcode == 0b1001011; + fnmadd_h : R4Type : func2 == 0b10, opcode == 0b1001111; + fcvt_lh : RType : func7 == 0b1100010, rs2 == 0b00010, opcode == 0b1010011; + fcvt_luh : RType : func7 == 0b1100010, rs2 == 0b00011, opcode == 0b1010011; + fcvt_hl : RType : func7 == 0b1101010, rs2 == 0b00010, opcode == 0b1010011; + fcvt_hlu : RType : func7 == 0b1101010, rs2 == 0b00011, opcode == 0b1010011; };
diff --git a/riscv/test/zfh_encoding_test.cc b/riscv/test/zfh_encoding_test.cc index 974420d..3f54fc5 100644 --- a/riscv/test/zfh_encoding_test.cc +++ b/riscv/test/zfh_encoding_test.cc
@@ -112,6 +112,14 @@ constexpr uint32_t kFnmaddH = 0b00000'10'00000'00000'000'00000'1001111; // rs3 |f2| rs2 | rs1 |rm | rd | opcode constexpr uint32_t kFnmsubH = 0b00000'10'00000'00000'000'00000'1001011; +// 64 bit only func7 | | rs1 |rm | rd | opcode +constexpr uint32_t kFcvtLh = 0b1100010'00010'00000'000'00000'1010011; +// 64 bit only func7 | | rs1 |rm | rd | opcode +constexpr uint32_t kFcvtLuh = 0b1100010'00011'00000'000'00000'1010011; +// 64 bit only func7 | | rs1 |rm | rd | opcode +constexpr uint32_t kFcvtHl = 0b1101010'00010'00000'000'00000'1010011; +// 64 bit only func7 | | rs1 |rm | rd | opcode +constexpr uint32_t kFcvtHlu = 0b1101010'00011'00000'000'00000'1010011; struct Zfh32Config { using XRegister = ::mpact::sim::riscv::RV32Register; @@ -1054,4 +1062,152 @@ this->FloatFrdHelper(kFnmsubH, TypeParam::OpcodeEnum::kFnmsubH); } +TYPED_TEST(ZfhEncodingTest, FcvtLh) { + if constexpr (TypeParam::kXLen == 64) { + this->enc_->ParseInstruction(kFcvtLh); + EXPECT_EQ(this->GetOpcode(), TypeParam::OpcodeEnum::kFcvtLh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLh_frs1) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatFrs1Helper(kFcvtLh, TypeParam::OpcodeEnum::kFcvtLh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLh_rm) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatRmHelper(kFcvtLh, TypeParam::OpcodeEnum::kFcvtLh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLh_rd) { + using XValue = typename TypeParam::XValue; + if constexpr (TypeParam::kXLen == 64) { + std::vector<int> failed_scalar_destinations; + for (int register_index = 1; register_index < 32; register_index++) { + XValue test_register_value = + this->RandomizeScalarRegister(register_index); + this->ParseInstructionWithRd(kFcvtLh, register_index); + XValue destination_value = + this->GetRdDestinationValue(TypeParam::OpcodeEnum::kFcvtLh); + if (destination_value != test_register_value) { + failed_scalar_destinations.push_back(register_index); + } + } + EXPECT_THAT(failed_scalar_destinations, ::testing::IsEmpty()); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLuh) { + if constexpr (TypeParam::kXLen == 64) { + this->enc_->ParseInstruction(kFcvtLuh); + EXPECT_EQ(this->GetOpcode(), TypeParam::OpcodeEnum::kFcvtLuh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLuh_frs1) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatFrs1Helper(kFcvtLuh, TypeParam::OpcodeEnum::kFcvtLuh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLuh_rm) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatRmHelper(kFcvtLuh, TypeParam::OpcodeEnum::kFcvtLuh); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtLuh_rd) { + using XValue = typename TypeParam::XValue; + if constexpr (TypeParam::kXLen == 64) { + std::vector<int> failed_scalar_destinations; + for (int register_index = 1; register_index < 32; register_index++) { + XValue test_register_value = + this->RandomizeScalarRegister(register_index); + this->ParseInstructionWithRd(kFcvtLuh, register_index); + XValue destination_value = + this->GetRdDestinationValue(TypeParam::OpcodeEnum::kFcvtLuh); + if (destination_value != test_register_value) { + failed_scalar_destinations.push_back(register_index); + } + } + EXPECT_THAT(failed_scalar_destinations, ::testing::IsEmpty()); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHl) { + if constexpr (TypeParam::kXLen == 64) { + this->enc_->ParseInstruction(kFcvtHl); + EXPECT_EQ(this->GetOpcode(), TypeParam::OpcodeEnum::kFcvtHl); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHl_rs1) { + using XValue = typename TypeParam::XValue; + if constexpr (TypeParam::kXLen == 64) { + std::vector<int> failed_scalar_sources; + for (int register_index = 0; register_index < 32; register_index++) { + XValue test_register_value = + this->RandomizeScalarRegister(register_index); + this->ParseInstructionWithRs1(kFcvtHl, register_index); + XValue source_value = + this->GetRs1SourceValue(TypeParam::OpcodeEnum::kFcvtHl); + if (source_value != test_register_value) { + failed_scalar_sources.push_back(register_index); + } + } + EXPECT_THAT(failed_scalar_sources, ::testing::IsEmpty()); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHl_rm) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatRmHelper(kFcvtHl, TypeParam::OpcodeEnum::kFcvtHl); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHl_frd) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatFrdHelper(kFcvtHl, TypeParam::OpcodeEnum::kFcvtHl); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHlu) { + if constexpr (TypeParam::kXLen == 64) { + this->enc_->ParseInstruction(kFcvtHlu); + EXPECT_EQ(this->GetOpcode(), TypeParam::OpcodeEnum::kFcvtHlu); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHlu_rs1) { + using XValue = typename TypeParam::XValue; + if constexpr (TypeParam::kXLen == 64) { + std::vector<int> failed_scalar_sources; + for (int register_index = 0; register_index < 32; register_index++) { + XValue test_register_value = + this->RandomizeScalarRegister(register_index); + this->ParseInstructionWithRs1(kFcvtHlu, register_index); + XValue source_value = + this->GetRs1SourceValue(TypeParam::OpcodeEnum::kFcvtHlu); + if (source_value != test_register_value) { + failed_scalar_sources.push_back(register_index); + } + } + EXPECT_THAT(failed_scalar_sources, ::testing::IsEmpty()); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHlu_rm) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatRmHelper(kFcvtHlu, TypeParam::OpcodeEnum::kFcvtHlu); + } +} + +TYPED_TEST(ZfhEncodingTest, FcvtHlu_frd) { + if constexpr (TypeParam::kXLen == 64) { + this->FloatFrdHelper(kFcvtHlu, TypeParam::OpcodeEnum::kFcvtHlu); + } +} + } // namespace