// any registers that are marked as "vectorised"
insn_bits_t bits = s_insn.bits();
#ifndef USING_NOREGS
- int vlen = 1;
+ int vlen = p->get_state()->vl;
// need to know if register is used as float or int.
// REGS_PATTERN is generated by id_regs.py (per opcode)
unsigned int floatintmap = REGS_PATTERN;
// identify which regs have had their CSR entries set as vectorised.
// really could do with a macro for-loop here... oh well...
// integer ops, RD, RS1, RS2, RS3 (use sv_int_tb)
- bool vectorop =
-#ifdef USING_REG_RD
- insn.sv_check_reg(true, s_insn.rd()) |
-#endif
-#ifdef USING_REG_RS1
- insn.sv_check_reg(true, s_insn.rs1()) |
-#endif
-#ifdef USING_REG_RS2
- insn.sv_check_reg(true, s_insn.rs2()) |
-#endif
-#ifdef USING_REG_RS2
- insn.sv_check_reg(true, s_insn.rs3()) |
-#endif
-#ifdef USING_REG_RVC_RS1
- insn.sv_check_reg(true, s_insn.rvc_rs1()) |
-#endif
-#ifdef USING_REG_RVC_RS1S
- insn.sv_check_reg(true, s_insn.rvc_rs1s()) |
-#endif
-#ifdef USING_REG_RVC_RS2
- insn.sv_check_reg(true, s_insn.rvc_rs2()) |
-#endif
-#ifdef USING_REG_RVC_RS2S
- insn.sv_check_reg(true, s_insn.rvc_rs2s()) |
-#endif
- // fp ops, RD, RS1, RS2, RS3 (use sv_fp_tb)
-#ifdef USING_REG_FRD
- insn.sv_check_reg(false, s_insn.rd()) |
-#endif
-#ifdef USING_REG_FRS1
- insn.sv_check_reg(false, s_insn.rs1()) |
-#endif
-#ifdef USING_REG_FRS2
- insn.sv_check_reg(false, s_insn.rs2()) |
-#endif
-#ifdef USING_REG_FRS3
- insn.sv_check_reg(false, s_insn.rs3()) |
-#endif
-#ifdef USING_REG_RVC_FRS2
- insn.sv_check_reg(false, s_insn.rvc_rs2()) |
-#endif
-#ifdef USING_REG_RVC_FRS2S
- insn.sv_check_reg(false, s_insn.rvc_rs2s()) |
-#endif
- false; // save a few cycles by |ing the checks together.
-
if (insn.sv_check_reg(true, 16))
{
- fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld\n",
- xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2());
+ fprintf(stderr, "reg %s %x rd %ld rs1 %ld rs2 %ld vlen %d\n",
+ xstr(INSN), INSNCODE, s_insn.rd(), s_insn.rs1(), s_insn.rs2(),
+ vlen);
}
// if vectorop is set, one of the regs is not a scalar,
// so we must read the VL CSR and do a loop
- if (vectorop)
+ if (vlen == 0)
{
- vlen = p->get_state()->vl;
- fprintf(stderr, "vectorop %x vlen %d\n", INSNCODE, vlen);
+ vlen = 1; // minimum of one loop
}
for (int voffs=0; voffs < vlen; voffs++)
{
+ insn.reset_vloop_check();
#include INCLUDEFILE
+ if (vlen > 1)
+ {
+ fprintf(stderr, "reg %s %x vloop %d vlen %d stop %d\n",
+ xstr(INSN), INSNCODE, voffs, vlen, insn.stop_vloop());
+ }
insn.reset_caches(); // ready to increment offsets in next iteration
+ if (insn.stop_vloop())
+ {
+ break;
+ }
}
#else
insn_t insn(bits);
{
public:
sv_insn_t(processor_t *pr, insn_bits_t bits, unsigned int f) :
- insn_t(bits), p(pr), fimap(f),
+ insn_t(bits), p(pr), vloop_continue(true), fimap(f),
cached_rd(0xff), cached_rs1(0xff),
cached_rs2(0xff), cached_rs3(0xff),
offs_rd(0), offs_rs1(0),
sv_pred_entry* get_predentry(uint64_t reg, bool isint);
reg_t predicate(uint64_t reg, bool isint, bool &zeroing);
+ void reset_vloop_check(void) { vloop_continue = true; }
+ bool stop_vloop(void) { return !vloop_continue; }
+
private:
processor_t *p;
+ bool vloop_continue;
unsigned int fimap;
uint64_t cached_rd;
uint64_t cached_rs1;
{
cached = remap(reg, isint, offs);
}
+ else if (!sv_check_reg(isint, reg))
+ {
+ vloop_continue = false;
+ }
return cached;
}
};