diff --git a/riscv/insns/vsm4r_vs.h b/riscv/insns/vsm4r_vs.h index 6a6ed047..8bbf777b 100644 --- a/riscv/insns/vsm4r_vs.h +++ b/riscv/insns/vsm4r_vs.h @@ -6,6 +6,7 @@ const uint32_t EGS = 4; require_vsm4_constraints; require_align(insn.rd(), P.VU.vflmul); +require_vs2_align_eglmul(128); // No overlap of vd and vs2. require_noover_eglmul(insn.rd(), insn.rs2()); diff --git a/riscv/zvk_ext_macros.h b/riscv/zvk_ext_macros.h index 490de702..702ad917 100644 --- a/riscv/zvk_ext_macros.h +++ b/riscv/zvk_ext_macros.h @@ -86,6 +86,20 @@ // (LMUL * VLEN) <= EGW #define require_egw_fits(EGW) require((EGW) <= (P.VU.VLEN * P.VU.vflmul)) +// Ensures that a register index is aligned to EMUL +// evaluated as EGW / VLEN. +// The check is only enabled if this value is greater +// than one (no index alignment check required for fractional EMUL) +#define require_vreg_align_eglmul(EGW, VREG_NUM) \ + do { \ + float vfeglmul = EGW / P.VU.VLEN; \ + if (vfeglmul > 1) { \ + require_align(VREG_NUM, vfeglmul); \ + }\ + } while (0) + +#define require_vs2_align_eglmul(EGW) require_vreg_align_eglmul(EGW, insn.rs2()) + // ensure that rs2 and rd do not overlap, assuming rd encodes an LMUL wide // vector register group and rs2 encodes an vs2_EMUL=ceil(EGW / VLEN) vector register // group. diff --git a/riscv/zvkned_ext_macros.h b/riscv/zvkned_ext_macros.h index db12d159..d94ddc2e 100644 --- a/riscv/zvkned_ext_macros.h +++ b/riscv/zvkned_ext_macros.h @@ -10,6 +10,8 @@ // vaes*.vs instruction constraints: // - Zvkned is enabled // - EGW (128) <= LMUL * VLEN +// - vd is LMUL aligned +// - vs2 is ceil(EGW / VLEN) aligned // - vd and vs2 cannot overlap // // The constraint that vstart and vl are both EGS (4) aligned @@ -22,6 +24,7 @@ require(P.VU.vsew == 32); \ require_egw_fits(128); \ require_align(insn.rd(), P.VU.vflmul); \ + require_vs2_align_eglmul(128); \ require_noover_eglmul(insn.rd(), insn.rs2()); \ } while (false)