zfh: fused multiply add encodings PiperOrigin-RevId: 759314983 Change-Id: I7ab0cd8e20807e7af70bdcaa2944b4af7ffddc13
diff --git a/riscv/riscv_zfh.bin_fmt b/riscv/riscv_zfh.bin_fmt index 92c7c9a..7ed55d4 100644 --- a/riscv/riscv_zfh.bin_fmt +++ b/riscv/riscv_zfh.bin_fmt
@@ -50,4 +50,8 @@ 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_zfh.isa b/riscv/riscv_zfh.isa index c4514e7..33d15cc 100644 --- a/riscv/riscv_zfh.isa +++ b/riscv/riscv_zfh.isa
@@ -192,5 +192,21 @@ resources: { next_pc, frs1 : rd[0..]}, semfunc: "&RV32::RiscVZfhFclass", disasm: "fclass.h", "%rd, %frs1"; + fmadd_h{: frs1, frs2, frs3, rm : frd, fflags}, + resources: {next_pc, frs1, frs2, frs3 : frd[0..]}, + semfunc: "&RiscVZfhFmadd", + disasm: "fmadd.h", "%frd, %frs1, %frs2, %frs3"; + fmsub_h{: frs1, frs2, frs3, rm : frd, fflags}, + resources: {next_pc, frs1, frs2, frs3 : frd[0..]}, + semfunc: "&RiscVZfhFmsub", + disasm: "fmsub.h", "%frd, %frs1, %frs2, %frs3"; + fnmadd_h{: frs1, frs2, frs3, rm : frd, fflags}, + resources: {next_pc, frs1, frs2, frs3 : frd[0..]}, + semfunc: "&RiscVZfhFnmadd", + disasm: "fnmadd.h", "%frd, %frs1, %frs2, %frs3"; + fnmsub_h{: frs1, frs2, frs3, rm : frd, fflags}, + resources: {next_pc, frs1, frs2, frs3 : frd[0..]}, + semfunc: "&RiscVZfhFnmsub", + disasm: "fnmsub.h", "%frd, %frs1, %frs2, %frs3"; } }
diff --git a/riscv/test/riscv_getters_zfh.h b/riscv/test/riscv_getters_zfh.h index bdb926c..0722c3e 100644 --- a/riscv/test/riscv_getters_zfh.h +++ b/riscv/test/riscv_getters_zfh.h
@@ -78,6 +78,12 @@ common->state(), absl::StrCat(RiscVState::kFregPrefix, num), kFRegisterAliases[num]); }); + Insert(getter_map, *Enum::kFrs3, [common]() -> SourceOperandInterface * { + int num = Extractors::Inst32Format::ExtractRs3(common->inst_word()); + return GetRegisterSourceOp<FloatRegister>( + common->state(), absl::StrCat(RiscVState::kFregPrefix, num), + kFRegisterAliases[num]); + }); } template <typename Enum, typename Extractors, typename IntegerRegister>
diff --git a/riscv/test/zfh_encoding_test.cc b/riscv/test/zfh_encoding_test.cc index a376c21..f767556 100644 --- a/riscv/test/zfh_encoding_test.cc +++ b/riscv/test/zfh_encoding_test.cc
@@ -111,6 +111,14 @@ constexpr uint32_t kFcmpleH = 0b1010010'00000'00000'000'00000'1010011; // func7 | | rs1 |fn3| rd | opcode constexpr uint32_t kFclassH = 0b1110010'00000'00000'001'00000'1010011; +// rs3 |f2| rs2 | rs1 |rm | rd | opcode +constexpr uint32_t kFmaddH = 0b00000'10'00000'00000'000'00000'1000011; +// rs3 |f2| rs2 | rs1 |rm | rd | opcode +constexpr uint32_t kFmsubH = 0b00001'10'00000'00000'000'00000'1000111; +// rs3 |f2| rs2 | rs1 |rm | rd | opcode +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; class ZfhEncodingTest : public testing::Test { protected: @@ -130,6 +138,7 @@ void FloatSourceHelper(uint32_t, OpcodeEnum, SourceOpEnum, int); void FloatFrs1Helper(uint32_t, OpcodeEnum); void FloatFrs2Helper(uint32_t, OpcodeEnum); + void FloatFrs3Helper(uint32_t, OpcodeEnum); void FloatRmHelper(uint32_t, OpcodeEnum); FlatDemandMemory memory_; @@ -236,6 +245,11 @@ FloatSourceHelper(binary_instruction, opcode_enum, SourceOpEnum::kFrs2, 20); } +void ZfhEncodingTest::FloatFrs3Helper(uint32_t binary_instruction, + OpcodeEnum opcode_enum) { + FloatSourceHelper(binary_instruction, opcode_enum, SourceOpEnum::kFrs3, 27); +} + void ZfhEncodingTest::FloatRmHelper(uint32_t binary_instruction, OpcodeEnum opcode_enum) { for (int rm = 0; rm <= 6; ++rm) { @@ -754,4 +768,104 @@ FloatFrdHelper(kFclassH, OpcodeEnum::kFclassH); } +TEST_F(ZfhEncodingTest, FmaddH) { + enc_->ParseInstruction(kFmaddH); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kRiscv32Zfh, 0), OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmaddH_frs1) { + FloatFrs1Helper(kFmaddH, OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmaddH_frs2) { + FloatFrs2Helper(kFmaddH, OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmaddH_frs3) { + FloatFrs3Helper(kFmaddH, OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmaddH_rm) { + FloatRmHelper(kFmaddH, OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmaddH_frd) { + FloatFrdHelper(kFmaddH, OpcodeEnum::kFmaddH); +} + +TEST_F(ZfhEncodingTest, FmsubH) { + enc_->ParseInstruction(kFmsubH); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kRiscv32Zfh, 0), OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FmsubH_frs1) { + FloatFrs1Helper(kFmsubH, OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FmsubH_frs2) { + FloatFrs2Helper(kFmsubH, OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FmsubH_frs3) { + FloatFrs3Helper(kFmsubH, OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FmsubH_rm) { + FloatRmHelper(kFmsubH, OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FmsubH_frd) { + FloatFrdHelper(kFmsubH, OpcodeEnum::kFmsubH); +} + +TEST_F(ZfhEncodingTest, FnmaddH) { + enc_->ParseInstruction(kFnmaddH); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kRiscv32Zfh, 0), OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmaddH_frs1) { + FloatFrs1Helper(kFnmaddH, OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmaddH_frs2) { + FloatFrs2Helper(kFnmaddH, OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmaddH_frs3) { + FloatFrs3Helper(kFnmaddH, OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmaddH_rm) { + FloatRmHelper(kFnmaddH, OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmaddH_frd) { + FloatFrdHelper(kFnmaddH, OpcodeEnum::kFnmaddH); +} + +TEST_F(ZfhEncodingTest, FnmsubH) { + enc_->ParseInstruction(kFnmsubH); + EXPECT_EQ(enc_->GetOpcode(SlotEnum::kRiscv32Zfh, 0), OpcodeEnum::kFnmsubH); +} + +TEST_F(ZfhEncodingTest, FnmsubH_frs1) { + FloatFrs1Helper(kFnmsubH, OpcodeEnum::kFnmsubH); +} + +TEST_F(ZfhEncodingTest, FnmsubH_frs2) { + FloatFrs2Helper(kFnmsubH, OpcodeEnum::kFnmsubH); +} + +TEST_F(ZfhEncodingTest, FnmsubH_frs3) { + FloatFrs3Helper(kFnmsubH, OpcodeEnum::kFnmsubH); +} + +TEST_F(ZfhEncodingTest, FnmsubH_rm) { + FloatRmHelper(kFnmsubH, OpcodeEnum::kFnmsubH); +} + +TEST_F(ZfhEncodingTest, FnmsubH_frd) { + FloatFrdHelper(kFnmsubH, OpcodeEnum::kFnmsubH); +} + } // namespace