diff --git a/disasm/isa_parser.cc b/disasm/isa_parser.cc index 6dd572eb..76ac88ae 100644 --- a/disasm/isa_parser.cc +++ b/disasm/isa_parser.cc @@ -330,6 +330,8 @@ isa_parser_t::isa_parser_t(const char* str, const char *priv) extension_table[EXT_ZVQBDOT8I] = true; } else if (ext_str == "zvqbdot16i") { extension_table[EXT_ZVQBDOT16I] = true; + } else if (ext_str == "zvfqbdot8f") { + extension_table[EXT_ZVFQBDOT8F] = true; } else if (ext_str == "zvfwbdot16bf") { extension_table[EXT_ZVFWBDOT16BF] = true; } else if (ext_str == "zvfbdot32f") { diff --git a/riscv/insns/vfqbdot_alt_vv.h b/riscv/insns/vfqbdot_alt_vv.h new file mode 100644 index 00000000..f1df781f --- /dev/null +++ b/riscv/insns/vfqbdot_alt_vv.h @@ -0,0 +1,17 @@ +VI_VFP_BASE; +ZVBDOT_INIT(4); + +#define COMMA , + +switch (P.VU.vsew) { + case 8: { + require_extension(EXT_ZVFQBDOT8F); + if (P.VU.altfmt) { + ZVBDOT_LOOP(uint8_t, uint8_t, float32_t, zvfqbdot8f_dot_acc); + } else { + ZVBDOT_LOOP(uint8_t, uint8_t, float32_t, zvfqbdot8f_dot_acc); + } + break; + } + default: require(false); +} diff --git a/riscv/insns/vfqbdot_vv.h b/riscv/insns/vfqbdot_vv.h new file mode 100644 index 00000000..fe3e6528 --- /dev/null +++ b/riscv/insns/vfqbdot_vv.h @@ -0,0 +1,17 @@ +VI_VFP_BASE; +ZVBDOT_INIT(4); + +#define COMMA , + +switch (P.VU.vsew) { + case 8: { + require_extension(EXT_ZVFQBDOT8F); + if (P.VU.altfmt) { + ZVBDOT_LOOP(uint8_t, uint8_t, float32_t, zvfqbdot8f_dot_acc); + } else { + ZVBDOT_LOOP(uint8_t, uint8_t, float32_t, zvfqbdot8f_dot_acc); + } + break; + } + default: require(false); +} diff --git a/riscv/isa_parser.h b/riscv/isa_parser.h index b14166b2..8b8f6373 100644 --- a/riscv/isa_parser.h +++ b/riscv/isa_parser.h @@ -70,6 +70,7 @@ typedef enum { EXT_ZVQDOTQ, EXT_ZVQBDOT8I, EXT_ZVQBDOT16I, + EXT_ZVFQBDOT8F, EXT_ZVFWBDOT16BF, EXT_ZVFBDOT32F, EXT_ZVQLDOT8I, diff --git a/riscv/riscv.mk.in b/riscv/riscv.mk.in index b7f83447..f4766968 100644 --- a/riscv/riscv.mk.in +++ b/riscv/riscv.mk.in @@ -1079,6 +1079,8 @@ riscv_insn_ext_zvbdot = \ vqbdots_vv \ vfwbdot_vv \ vfbdot_vv \ + vfqbdot_vv \ + vfqbdot_alt_vv \ riscv_insn_ext_zvldot = \ vqldotu_vv \ diff --git a/riscv/vector_unit.cc b/riscv/vector_unit.cc index 5fbab5ff..31d11364 100644 --- a/riscv/vector_unit.cc +++ b/riscv/vector_unit.cc @@ -46,6 +46,8 @@ reg_t vectorUnit_t::vectorUnit_t::set_vl(int rd, int rs1, reg_t reqVL, reg_t new ill_altfmt = false; else if (p->extension_enabled(EXT_ZVQBDOT16I) && vsew == 16) ill_altfmt = false; + else if (p->extension_enabled(EXT_ZVFQBDOT8F) && vsew == 8) + ill_altfmt = false; else if (p->extension_enabled(EXT_ZVFWBDOT16BF) && vsew == 16) ill_altfmt = false; else if (p->extension_enabled(EXT_ZVQLDOT8I) && vsew == 8) diff --git a/riscv/zvbdot.h b/riscv/zvbdot.h index 32949e7c..67a204bd 100644 --- a/riscv/zvbdot.h +++ b/riscv/zvbdot.h @@ -41,4 +41,19 @@ static inline float32_t zvfwbdot16bf_dot_acc(const std::vector& a, con return f32_add_odd(f32(res.out), c); } +template +float32_t zvfqbdot8f_dot_acc(const std::vector& a, const std::vector& b, float32_t c) +{ + std::vector fa(a.size()); + std::transform(a.begin(), a.end(), fa.begin(), [](auto f) { return f; }); + + std::vector fb(b.size()); + std::transform(b.begin(), b.end(), fb.begin(), [](auto f) { return f; }); + + DotConfig cfg(a.size(), int_log2(a.size()) + ((a.size() & (a.size() - 1)) != 0)); + auto res = bulk_norm_dot_ofp8(cfg, &fa[0], &fb[0]); + softfloat_exceptionFlags |= res.flags; + return f32_add_odd(f32(res.out), c); +} + #endif