diff --git a/riscv/decode_macros.h b/riscv/decode_macros.h index 892515fa..f9a2f3c7 100644 --- a/riscv/decode_macros.h +++ b/riscv/decode_macros.h @@ -146,10 +146,9 @@ do { \ #define SHAMT (insn.i_imm() & 0x3F) #define BRANCH_TARGET (pc + insn.sb_imm()) #define JUMP_TARGET (pc + insn.uj_imm()) -#define RM ({ int rm = insn.rm(); \ - if (rm == 7) rm = STATE.frm->read(); \ - if (rm > 4) throw trap_illegal_instruction(insn.bits()); \ - rm; }) +#define validate_rm(rm) ({ require(rm < 5); rm; }) +#define VFP_RM validate_rm(STATE.frm->read()) +#define RM (insn.rm() == 7 ? VFP_RM : validate_rm(insn.rm())) static inline bool is_aligned(const unsigned val, const unsigned pos) { diff --git a/riscv/insns/vfbdot_vv.h b/riscv/insns/vfbdot_vv.h index c4db1611..ec81aca1 100644 --- a/riscv/insns/vfbdot_vv.h +++ b/riscv/insns/vfbdot_vv.h @@ -1,5 +1,5 @@ +VI_VFP_BASE; ZVBDOT_INIT(1); -require_fp; switch (P.VU.vsew) { case 32: { diff --git a/riscv/insns/vfmv_f_s.h b/riscv/insns/vfmv_f_s.h index 1ad6bc69..65a3cff3 100644 --- a/riscv/insns/vfmv_f_s.h +++ b/riscv/insns/vfmv_f_s.h @@ -1,12 +1,6 @@ // vfmv_f_s: rd = vs2[0] (rs1=0) -require_vector(true); -require_fp; -require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || - (P.VU.vsew == e32 && p->extension_enabled('F')) || - (P.VU.vsew == e64 && p->extension_enabled('D'))); -require(STATE.frm->read() < 0x5); +VI_VFP_COMMON; -reg_t rs2_num = insn.rs2(); uint64_t vs2_0 = 0; const reg_t sew = P.VU.vsew; switch (sew) { diff --git a/riscv/insns/vfmv_s_f.h b/riscv/insns/vfmv_s_f.h index 4b1b955e..074a583a 100644 --- a/riscv/insns/vfmv_s_f.h +++ b/riscv/insns/vfmv_s_f.h @@ -1,12 +1,5 @@ // vfmv_s_f: vd[0] = rs1 (vs2=0) -require_vector(true); -require_fp; -require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || - (P.VU.vsew == e32 && p->extension_enabled('F')) || - (P.VU.vsew == e64 && p->extension_enabled('D'))); -require(STATE.frm->read() < 0x5); - -reg_t vl = P.VU.vl->read(); +VI_VFP_COMMON; if (vl > 0 && P.VU.vstart->read() < vl) { reg_t rd_num = insn.rd(); diff --git a/riscv/insns/vfwbdot_vv.h b/riscv/insns/vfwbdot_vv.h index f6270410..c4071333 100644 --- a/riscv/insns/vfwbdot_vv.h +++ b/riscv/insns/vfwbdot_vv.h @@ -1,5 +1,5 @@ +VI_VFP_BASE; ZVBDOT_INIT(2); -require_fp; switch (P.VU.vsew) { case 16: { diff --git a/riscv/v_ext_macros.h b/riscv/v_ext_macros.h index 86e6033f..45af2468 100644 --- a/riscv/v_ext_macros.h +++ b/riscv/v_ext_macros.h @@ -1426,29 +1426,24 @@ VI_VX_ULOOP({ \ // // vector: vfp helper // -#define VI_VFP_COMMON \ +#define VI_VFP_BASE \ require_fp; \ - require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || \ - (P.VU.vsew == e32 && p->get_isa().get_zvf()) || \ - (P.VU.vsew == e64 && p->get_isa().get_zvd())); \ require_vector(true); \ - require(STATE.frm->read() < 0x5); \ reg_t UNUSED vl = P.VU.vl->read(); \ reg_t UNUSED rd_num = insn.rd(); \ reg_t UNUSED rs1_num = insn.rs1(); \ reg_t UNUSED rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm->read(); + softfloat_roundingMode = VFP_RM + +#define VI_VFP_COMMON \ + VI_VFP_BASE; \ + require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFH)) || \ + (P.VU.vsew == e32 && p->get_isa().get_zvf()) || \ + (P.VU.vsew == e64 && p->get_isa().get_zvd())); \ #define VI_VFP_BF16_COMMON \ - require_fp; \ + VI_VFP_BASE; \ require((P.VU.vsew == e16 && p->extension_enabled(EXT_ZVFBFWMA))); \ - require_vector(true); \ - require(STATE.frm->read() < 0x5); \ - reg_t UNUSED vl = P.VU.vl->read(); \ - reg_t UNUSED rd_num = insn.rd(); \ - reg_t UNUSED rs1_num = insn.rs1(); \ - reg_t UNUSED rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm->read(); #define VI_VFP_LOOP_BASE \ VI_VFP_COMMON \ @@ -1901,14 +1896,7 @@ VI_VX_ULOOP({ \ VI_VFP_LOOP_END #define VI_VFP_LOOP_SCALE_BASE \ - require_fp; \ - require_vector(true); \ - require(STATE.frm->read() < 0x5); \ - reg_t vl = P.VU.vl->read(); \ - reg_t rd_num = insn.rd(); \ - reg_t UNUSED rs1_num = insn.rs1(); \ - reg_t rs2_num = insn.rs2(); \ - softfloat_roundingMode = STATE.frm->read(); \ + VI_VFP_COMMON \ for (reg_t i = P.VU.vstart->read(); i < vl; ++i) { \ VI_LOOP_ELEMENT_SKIP();